checksum: simplify, use only sha256

We use only one sha type right now.

Needed for https://github.com/Homebrew/brew/pull/10186
This commit is contained in:
Michka Popoff 2021-01-07 08:33:57 +01:00
parent db0b69ac6a
commit 5e91802470
14 changed files with 38 additions and 50 deletions

View File

@ -214,7 +214,7 @@ module Cask
when :no_check when :no_check
arg arg
when String when String
Checksum.new(:sha256, arg) Checksum.new(arg)
else else
raise CaskInvalidError.new(cask, "invalid 'sha256' value: '#{arg.inspect}'") raise CaskInvalidError.new(cask, "invalid 'sha256' value: '#{arg.inspect}'")
end end

View File

@ -7,12 +7,9 @@
class Checksum class Checksum
extend Forwardable extend Forwardable
attr_reader :hash_type, :hexdigest attr_reader :hexdigest
TYPES = [:sha256].freeze def initialize(hexdigest)
def initialize(hash_type, hexdigest)
@hash_type = hash_type
@hexdigest = hexdigest.downcase @hexdigest = hexdigest.downcase
end end
@ -23,7 +20,7 @@ class Checksum
when String when String
to_s == other.downcase to_s == other.downcase
when Checksum when Checksum
hash_type == other.hash_type && hexdigest == other.hexdigest hexdigest == other.hexdigest
else else
false false
end end

View File

@ -94,7 +94,7 @@ module Homebrew
if resource_name == "patch" if resource_name == "patch"
patch_hashes = formula.stable&.patches&.select(&:external?)&.map(&:resource)&.map(&:version) patch_hashes = formula.stable&.patches&.select(&:external?)&.map(&:resource)&.map(&:version)
return true unless patch_hashes&.include?(Checksum.new(:sha256, version.to_s)) return true unless patch_hashes&.include?(Checksum.new(version.to_s))
elsif resource_name && resource_version = formula.stable&.resources&.dig(resource_name)&.version elsif resource_name && resource_version = formula.stable&.resources&.dig(resource_name)&.version
return true if resource_version != version return true if resource_version != version
elsif version.is_a?(PkgVersion) elsif version.is_a?(PkgVersion)

View File

@ -132,28 +132,28 @@ module Homebrew
fetch_fetchable r, args: args fetch_fetchable r, args: args
rescue ChecksumMismatchError => e rescue ChecksumMismatchError => e
retry if retry_fetch?(r, args: args) retry if retry_fetch?(r, args: args)
opoo "Resource #{r.name} reports different #{e.hash_type}: #{e.expected}" opoo "Resource #{r.name} reports different sha256: #{e.expected}"
end end
def fetch_formula(f, args:) def fetch_formula(f, args:)
fetch_fetchable f, args: args fetch_fetchable f, args: args
rescue ChecksumMismatchError => e rescue ChecksumMismatchError => e
retry if retry_fetch?(f, args: args) retry if retry_fetch?(f, args: args)
opoo "Formula reports different #{e.hash_type}: #{e.expected}" opoo "Formula reports different sha256: #{e.expected}"
end end
def fetch_cask(cask_download, args:) def fetch_cask(cask_download, args:)
fetch_fetchable cask_download, args: args fetch_fetchable cask_download, args: args
rescue ChecksumMismatchError => e rescue ChecksumMismatchError => e
retry if retry_fetch?(cask_download, args: args) retry if retry_fetch?(cask_download, args: args)
opoo "Cask reports different #{e.hash_type}: #{e.expected}" opoo "Cask reports different sha256: #{e.expected}"
end end
def fetch_patch(p, args:) def fetch_patch(p, args:)
fetch_fetchable p, args: args fetch_fetchable p, args: args
rescue ChecksumMismatchError => e rescue ChecksumMismatchError => e
Homebrew.failed = true Homebrew.failed = true
opoo "Patch reports different #{e.hash_type}: #{e.expected}" opoo "Patch reports different sha256: #{e.expected}"
end end
def retry_fetch?(f, args:) def retry_fetch?(f, args:)
@ -183,7 +183,7 @@ module Homebrew
return unless download.file? return unless download.file?
puts "Downloaded to: #{download}" unless already_fetched puts "Downloaded to: #{download}" unless already_fetched
puts Checksum::TYPES.map { |t| "#{t.to_s.upcase}: #{download.send(t)}" } puts "SHA256: #{download.sha256}"
f.verify_download_integrity(download) f.verify_download_integrity(download)
end end

View File

@ -162,11 +162,8 @@ module Homebrew
check_for_mirrors(formula, old_mirrors, new_mirrors, args: args) if new_url.present? check_for_mirrors(formula, old_mirrors, new_mirrors, args: args) if new_url.present?
hash_type, old_hash = if (checksum = formula_spec.checksum) old_hash = formula_spec.checksum&.hexdigest
[checksum.hash_type, checksum.hexdigest] new_hash = args.sha256
end
new_hash = args[hash_type] if hash_type.present?
new_tag = args.tag new_tag = args.tag
new_revision = args.revision new_revision = args.revision
old_url = formula_spec.url old_url = formula_spec.url
@ -180,7 +177,7 @@ module Homebrew
elsif new_tag && new_revision elsif new_tag && new_revision
check_closed_pull_requests(formula, tap_full_name, url: old_url, tag: new_tag, args: args) if new_version.blank? check_closed_pull_requests(formula, tap_full_name, url: old_url, tag: new_tag, args: args) if new_version.blank?
false false
elsif hash_type.blank? elsif old_hash.blank?
if new_tag.blank? && new_version.blank? && new_revision.blank? if new_tag.blank? && new_version.blank? && new_revision.blank?
raise UsageError, "#{formula}: no --tag= or --version= argument specified!" raise UsageError, "#{formula}: no --tag= or --version= argument specified!"
end end

View File

@ -626,14 +626,13 @@ class ChecksumMissingError < ArgumentError; end
# Raised by {Pathname#verify_checksum} when verification fails. # Raised by {Pathname#verify_checksum} when verification fails.
class ChecksumMismatchError < RuntimeError class ChecksumMismatchError < RuntimeError
attr_reader :expected, :hash_type attr_reader :expected
def initialize(path, expected, actual) def initialize(path, expected, actual)
@expected = expected @expected = expected
@hash_type = expected.hash_type.to_s.upcase
super <<~EOS super <<~EOS
#{@hash_type} mismatch SHA256 mismatch
Expected: #{Formatter.success(expected.to_s)} Expected: #{Formatter.success(expected.to_s)}
Actual: #{Formatter.error(actual.to_s)} Actual: #{Formatter.error(actual.to_s)}
File: #{path} File: #{path}

View File

@ -303,7 +303,7 @@ class Pathname
def verify_checksum(expected) def verify_checksum(expected)
raise ChecksumMissingError if expected.blank? raise ChecksumMissingError if expected.blank?
actual = Checksum.new(expected.hash_type, send(expected.hash_type).downcase) actual = Checksum.new(sha256.downcase)
raise ChecksumMismatchError.new(self, expected, actual) unless expected == actual raise ChecksumMismatchError.new(self, expected, actual) unless expected == actual
end end

View File

@ -1824,7 +1824,7 @@ class Formula
checksum = bottle_spec.collector[os] checksum = bottle_spec.collector[os]
bottle_info["files"][os] = { bottle_info["files"][os] = {
"url" => bottle_url, "url" => bottle_url,
checksum.hash_type.to_s => checksum.hexdigest, "sha256" => checksum.hexdigest,
} }
end end
hsh["bottle"]["stable"] = bottle_info hsh["bottle"]["stable"] = bottle_info
@ -2418,8 +2418,8 @@ class Formula
# tell you the currently valid value. # tell you the currently valid value.
# #
# <pre>sha256 "2a2ba417eebaadcb4418ee7b12fe2998f26d6e6f7fda7983412ff66a741ab6f7"</pre> # <pre>sha256 "2a2ba417eebaadcb4418ee7b12fe2998f26d6e6f7fda7983412ff66a741ab6f7"</pre>
Checksum::TYPES.each do |type| def sha256(val)
define_method(type) { |val| stable.send(type, val) } stable.sha256(val)
end end
# @!attribute [w] bottle # @!attribute [w] bottle

View File

@ -162,8 +162,8 @@ class Resource
EOS EOS
end end
Checksum::TYPES.each do |type| def sha256(val)
define_method(type) { |val| @checksum = Checksum.new(type, val) } @checksum = Checksum.new(val)
end end
def url(val = nil, **specs) def url(val = nil, **specs)

View File

@ -33,7 +33,7 @@ class SoftwareSpec
:cached_download, :clear_cache, :checksum, :mirrors, :specs, :using, :version, :mirror, :cached_download, :clear_cache, :checksum, :mirrors, :specs, :using, :version, :mirror,
:downloader :downloader
def_delegators :@resource, *Checksum::TYPES def_delegators :@resource, :sha256
def initialize(flags: []) def initialize(flags: [])
@resource = Resource.new @resource = Resource.new
@ -411,11 +411,9 @@ class BottleSpecification
# Checksum methods in the DSL's bottle block optionally take # Checksum methods in the DSL's bottle block optionally take
# a Hash, which indicates the platform the checksum applies on. # a Hash, which indicates the platform the checksum applies on.
Checksum::TYPES.each do |cksum| def sha256(val)
define_method(cksum) do |val|
digest, tag = val.shift digest, tag = val.shift
collector[tag] = Checksum.new(cksum, digest) collector[tag] = Checksum.new(digest)
end
end end
def checksum_for(tag) def checksum_for(tag)
@ -429,13 +427,12 @@ class BottleSpecification
# Sort non-MacOS tags below MacOS tags. # Sort non-MacOS tags below MacOS tags.
"0.#{tag}" "0.#{tag}"
end end
checksums = {} sha256s = []
tags.reverse_each do |tag| tags.reverse_each do |tag|
checksum = collector[tag] checksum = collector[tag]
checksums[checksum.hash_type] ||= [] sha256s << { checksum => tag }
checksums[checksum.hash_type] << { checksum => tag }
end end
checksums { sha256: sha256s }
end end
end end

View File

@ -25,7 +25,7 @@ module Cask
end end
context "when expected and computed checksums match" do context "when expected and computed checksums match" do
let(:expected_sha256) { Checksum.new(:sha256, cafebabe) } let(:expected_sha256) { Checksum.new(cafebabe) }
it "does not raise an error" do it "does not raise an error" do
expect { verification }.not_to raise_error expect { verification }.not_to raise_error
@ -41,7 +41,7 @@ module Cask
end end
context "when the expected checksum is empty" do context "when the expected checksum is empty" do
let(:expected_sha256) { Checksum.new(:sha256, "") } let(:expected_sha256) { Checksum.new("") }
it "outputs an error" do it "outputs an error" do
expect { verification }.to output(/sha256 "#{computed_sha256}"/).to_stderr expect { verification }.to output(/sha256 "#{computed_sha256}"/).to_stderr
@ -49,7 +49,7 @@ module Cask
end end
context "when expected and computed checksums do not match" do context "when expected and computed checksums do not match" do
let(:expected_sha256) { Checksum.new(:sha256, deadbeef) } let(:expected_sha256) { Checksum.new(deadbeef) }
it "raises an error" do it "raises an error" do
expect { verification }.to raise_error ChecksumMismatchError expect { verification }.to raise_error ChecksumMismatchError

View File

@ -5,21 +5,19 @@ require "checksum"
describe Checksum do describe Checksum do
describe "#empty?" do describe "#empty?" do
subject { described_class.new(:sha256, "") } subject { described_class.new("") }
it { is_expected.to be_empty } it { is_expected.to be_empty }
end end
describe "#==" do describe "#==" do
subject { described_class.new(:sha256, TEST_SHA256) } subject { described_class.new(TEST_SHA256) }
let(:other) { described_class.new(:sha256, TEST_SHA256) } let(:other) { described_class.new(TEST_SHA256) }
let(:other_reversed) { described_class.new(:sha256, TEST_SHA256.reverse) } let(:other_reversed) { described_class.new(TEST_SHA256.reverse) }
let(:other_sha1) { described_class.new(:sha1, TEST_SHA1) }
it { is_expected.to eq(other) } it { is_expected.to eq(other) }
it { is_expected.not_to eq(other_reversed) } it { is_expected.not_to eq(other_reversed) }
it { is_expected.not_to eq(other_sha1) }
it { is_expected.not_to eq(nil) } it { is_expected.not_to eq(nil) }
end end
end end

View File

@ -108,7 +108,7 @@ describe Resource do
it "returns the checksum set with #sha256" do it "returns the checksum set with #sha256" do
subject.sha256(TEST_SHA256) subject.sha256(TEST_SHA256)
expect(subject.checksum).to eq(Checksum.new(:sha256, TEST_SHA256)) expect(subject.checksum).to eq(Checksum.new(TEST_SHA256))
end end
end end

View File

@ -194,7 +194,7 @@ describe BottleSpecification do
checksums.each_pair do |cat, digest| checksums.each_pair do |cat, digest|
subject.sha256(digest => cat) subject.sha256(digest => cat)
checksum, = subject.checksum_for(cat) checksum, = subject.checksum_for(cat)
expect(Checksum.new(:sha256, digest)).to eq(checksum) expect(Checksum.new(digest)).to eq(checksum)
end end
end end