aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/cask/lib/hbc/audit.rb
diff options
context:
space:
mode:
authorMarkus Reiter2016-09-24 13:52:43 +0200
committerMarkus Reiter2016-09-24 16:00:58 +0200
commitb86c8efb79b3ed835d552c4d7416640ef10caf21 (patch)
tree7e1edc8a8f339e4d2781f43576d40c9c79aebcdc /Library/Homebrew/cask/lib/hbc/audit.rb
parent687f0fcf721c8e36f32570ed72d0988a6eaf986f (diff)
downloadbrew-b86c8efb79b3ed835d552c4d7416640ef10caf21.tar.bz2
Cask: Use nested classes and modules.
Diffstat (limited to 'Library/Homebrew/cask/lib/hbc/audit.rb')
-rw-r--r--Library/Homebrew/cask/lib/hbc/audit.rb352
1 files changed, 177 insertions, 175 deletions
diff --git a/Library/Homebrew/cask/lib/hbc/audit.rb b/Library/Homebrew/cask/lib/hbc/audit.rb
index 98f09ffa4..476f2aec0 100644
--- a/Library/Homebrew/cask/lib/hbc/audit.rb
+++ b/Library/Homebrew/cask/lib/hbc/audit.rb
@@ -2,215 +2,217 @@ require "hbc/checkable"
require "hbc/download"
require "digest"
-class Hbc::Audit
- include Hbc::Checkable
+module Hbc
+ class Audit
+ include Checkable
- attr_reader :cask, :download
+ attr_reader :cask, :download
- def initialize(cask, download: false, check_token_conflicts: false, command: Hbc::SystemCommand)
- @cask = cask
- @download = download
- @check_token_conflicts = check_token_conflicts
- @command = command
- end
+ def initialize(cask, download: false, check_token_conflicts: false, command: SystemCommand)
+ @cask = cask
+ @download = download
+ @check_token_conflicts = check_token_conflicts
+ @command = command
+ end
- def check_token_conflicts?
- @check_token_conflicts
- end
+ def check_token_conflicts?
+ @check_token_conflicts
+ end
- def run!
- check_required_stanzas
- check_version
- check_sha256
- check_appcast
- check_url
- check_generic_artifacts
- check_token_conflicts
- check_download
- self
- rescue StandardError => e
- odebug "#{e.message}\n#{e.backtrace.join("\n")}"
- add_error "exception while auditing #{cask}: #{e.message}"
- self
- end
+ def run!
+ check_required_stanzas
+ check_version
+ check_sha256
+ check_appcast
+ check_url
+ check_generic_artifacts
+ check_token_conflicts
+ check_download
+ self
+ rescue StandardError => e
+ odebug "#{e.message}\n#{e.backtrace.join("\n")}"
+ add_error "exception while auditing #{cask}: #{e.message}"
+ self
+ end
- def success?
- !(errors? || warnings?)
- end
+ def success?
+ !(errors? || warnings?)
+ end
- def summary_header
- "audit for #{cask}"
- end
+ def summary_header
+ "audit for #{cask}"
+ end
- private
+ private
- def check_required_stanzas
- odebug "Auditing required stanzas"
- %i{version sha256 url homepage}.each do |sym|
- add_error "a #{sym} stanza is required" unless cask.send(sym)
+ def check_required_stanzas
+ odebug "Auditing required stanzas"
+ %i{version sha256 url homepage}.each do |sym|
+ add_error "a #{sym} stanza is required" unless cask.send(sym)
+ end
+ add_error "a license stanza is required (:unknown is OK)" unless cask.license
+ add_error "at least one name stanza is required" if cask.name.empty?
+ # TODO: specific DSL knowledge should not be spread around in various files like this
+ # TODO: nested_container should not still be a pseudo-artifact at this point
+ installable_artifacts = cask.artifacts.reject { |k| [:uninstall, :zap, :nested_container].include?(k) }
+ add_error "at least one activatable artifact stanza is required" if installable_artifacts.empty?
end
- add_error "a license stanza is required (:unknown is OK)" unless cask.license
- add_error "at least one name stanza is required" if cask.name.empty?
- # TODO: specific DSL knowledge should not be spread around in various files like this
- # TODO: nested_container should not still be a pseudo-artifact at this point
- installable_artifacts = cask.artifacts.reject { |k| [:uninstall, :zap, :nested_container].include?(k) }
- add_error "at least one activatable artifact stanza is required" if installable_artifacts.empty?
- end
- def check_version
- return unless cask.version
- check_no_string_version_latest
- end
+ def check_version
+ return unless cask.version
+ check_no_string_version_latest
+ end
- def check_no_string_version_latest
- odebug "Verifying version :latest does not appear as a string ('latest')"
- return unless cask.version.raw_version == "latest"
- add_error "you should use version :latest instead of version 'latest'"
- end
+ def check_no_string_version_latest
+ odebug "Verifying version :latest does not appear as a string ('latest')"
+ return unless cask.version.raw_version == "latest"
+ add_error "you should use version :latest instead of version 'latest'"
+ end
- def check_sha256
- return unless cask.sha256
- check_sha256_no_check_if_latest
- check_sha256_actually_256
- check_sha256_invalid
- end
+ def check_sha256
+ return unless cask.sha256
+ check_sha256_no_check_if_latest
+ check_sha256_actually_256
+ check_sha256_invalid
+ end
- def check_sha256_no_check_if_latest
- odebug "Verifying sha256 :no_check with version :latest"
- return unless cask.version.latest? && cask.sha256 != :no_check
- add_error "you should use sha256 :no_check when version is :latest"
- end
+ def check_sha256_no_check_if_latest
+ odebug "Verifying sha256 :no_check with version :latest"
+ return unless cask.version.latest? && cask.sha256 != :no_check
+ add_error "you should use sha256 :no_check when version is :latest"
+ end
- def check_sha256_actually_256(sha256: cask.sha256, stanza: "sha256")
- odebug "Verifying #{stanza} string is a legal SHA-256 digest"
- return unless sha256.is_a?(String)
- return if sha256.length == 64 && sha256[%r{^[0-9a-f]+$}i]
- add_error "#{stanza} string must be of 64 hexadecimal characters"
- end
+ def check_sha256_actually_256(sha256: cask.sha256, stanza: "sha256")
+ odebug "Verifying #{stanza} string is a legal SHA-256 digest"
+ return unless sha256.is_a?(String)
+ return if sha256.length == 64 && sha256[%r{^[0-9a-f]+$}i]
+ add_error "#{stanza} string must be of 64 hexadecimal characters"
+ end
- def check_sha256_invalid(sha256: cask.sha256, stanza: "sha256")
- odebug "Verifying #{stanza} is not a known invalid value"
- empty_sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
- return unless sha256 == empty_sha256
- add_error "cannot use the sha256 for an empty string in #{stanza}: #{empty_sha256}"
- end
+ def check_sha256_invalid(sha256: cask.sha256, stanza: "sha256")
+ odebug "Verifying #{stanza} is not a known invalid value"
+ empty_sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ return unless sha256 == empty_sha256
+ add_error "cannot use the sha256 for an empty string in #{stanza}: #{empty_sha256}"
+ end
- def check_appcast
- return unless cask.appcast
- odebug "Auditing appcast"
- check_appcast_has_checkpoint
- return unless cask.appcast.checkpoint
- check_sha256_actually_256(sha256: cask.appcast.checkpoint, stanza: "appcast :checkpoint")
- check_sha256_invalid(sha256: cask.appcast.checkpoint, stanza: "appcast :checkpoint")
- return unless download
- check_appcast_http_code
- check_appcast_checkpoint_accuracy
- end
+ def check_appcast
+ return unless cask.appcast
+ odebug "Auditing appcast"
+ check_appcast_has_checkpoint
+ return unless cask.appcast.checkpoint
+ check_sha256_actually_256(sha256: cask.appcast.checkpoint, stanza: "appcast :checkpoint")
+ check_sha256_invalid(sha256: cask.appcast.checkpoint, stanza: "appcast :checkpoint")
+ return unless download
+ check_appcast_http_code
+ check_appcast_checkpoint_accuracy
+ end
- def check_appcast_has_checkpoint
- odebug "Verifying appcast has :checkpoint key"
- add_error "a checkpoint sha256 is required for appcast" unless cask.appcast.checkpoint
- end
+ def check_appcast_has_checkpoint
+ odebug "Verifying appcast has :checkpoint key"
+ add_error "a checkpoint sha256 is required for appcast" unless cask.appcast.checkpoint
+ end
- def check_appcast_http_code
- odebug "Verifying appcast returns 200 HTTP response code"
- result = @command.run("/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", Hbc::URL::FAKE_USER_AGENT, "--output", "/dev/null", "--write-out", "%{http_code}", cask.appcast], print_stderr: false)
- if result.success?
- http_code = result.stdout.chomp
- add_warning "unexpected HTTP response code retrieving appcast: #{http_code}" unless http_code == "200"
- else
- add_warning "error retrieving appcast: #{result.stderr}"
+ def check_appcast_http_code
+ odebug "Verifying appcast returns 200 HTTP response code"
+ result = @command.run("/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", URL::FAKE_USER_AGENT, "--output", "/dev/null", "--write-out", "%{http_code}", cask.appcast], print_stderr: false)
+ if result.success?
+ http_code = result.stdout.chomp
+ add_warning "unexpected HTTP response code retrieving appcast: #{http_code}" unless http_code == "200"
+ else
+ add_warning "error retrieving appcast: #{result.stderr}"
+ end
end
- end
- def check_appcast_checkpoint_accuracy
- odebug "Verifying appcast checkpoint is accurate"
- result = @command.run("/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", Hbc::URL::FAKE_USER_AGENT, cask.appcast], print_stderr: false)
- if result.success?
- processed_appcast_text = result.stdout.gsub(%r{<pubDate>[^<]*</pubDate>}, "")
- # This step is necessary to replicate running `sed` from the command line
- processed_appcast_text << "\n" unless processed_appcast_text.end_with?("\n")
- expected = cask.appcast.checkpoint
- actual = Digest::SHA2.hexdigest(processed_appcast_text)
- add_warning <<-EOS.undent unless expected == actual
- appcast checkpoint mismatch
- Expected: #{expected}
- Actual: #{actual}
- EOS
- else
- add_warning "error retrieving appcast: #{result.stderr}"
+ def check_appcast_checkpoint_accuracy
+ odebug "Verifying appcast checkpoint is accurate"
+ result = @command.run("/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", URL::FAKE_USER_AGENT, cask.appcast], print_stderr: false)
+ if result.success?
+ processed_appcast_text = result.stdout.gsub(%r{<pubDate>[^<]*</pubDate>}, "")
+ # This step is necessary to replicate running `sed` from the command line
+ processed_appcast_text << "\n" unless processed_appcast_text.end_with?("\n")
+ expected = cask.appcast.checkpoint
+ actual = Digest::SHA2.hexdigest(processed_appcast_text)
+ add_warning <<-EOS.undent unless expected == actual
+ appcast checkpoint mismatch
+ Expected: #{expected}
+ Actual: #{actual}
+ EOS
+ else
+ add_warning "error retrieving appcast: #{result.stderr}"
+ end
end
- end
- def check_url
- return unless cask.url
- check_download_url_format
- end
+ def check_url
+ return unless cask.url
+ check_download_url_format
+ end
- def check_download_url_format
- odebug "Auditing URL format"
- if bad_sourceforge_url?
- add_warning "SourceForge URL format incorrect. See https://github.com/caskroom/homebrew-cask/blob/master/doc/cask_language_reference/stanzas/url.md#sourceforgeosdn-urls"
- elsif bad_osdn_url?
- add_warning "OSDN URL format incorrect. See https://github.com/caskroom/homebrew-cask/blob/master/doc/cask_language_reference/stanzas/url.md#sourceforgeosdn-urls"
+ def check_download_url_format
+ odebug "Auditing URL format"
+ if bad_sourceforge_url?
+ add_warning "SourceForge URL format incorrect. See https://github.com/caskroom/homebrew-cask/blob/master/doc/cask_language_reference/stanzas/url.md#sourceforgeosdn-urls"
+ elsif bad_osdn_url?
+ add_warning "OSDN URL format incorrect. See https://github.com/caskroom/homebrew-cask/blob/master/doc/cask_language_reference/stanzas/url.md#sourceforgeosdn-urls"
+ end
end
- end
- def bad_url_format?(regex, valid_formats_array)
- return false unless cask.url.to_s =~ regex
- valid_formats_array.none? { |format| cask.url.to_s =~ format }
- end
+ def bad_url_format?(regex, valid_formats_array)
+ return false unless cask.url.to_s =~ regex
+ valid_formats_array.none? { |format| cask.url.to_s =~ format }
+ end
- def bad_sourceforge_url?
- bad_url_format?(%r{sourceforge},
- [
- %r{\Ahttps://sourceforge\.net/projects/[^/]+/files/latest/download\Z},
- %r{\Ahttps://downloads\.sourceforge\.net/(?!(project|sourceforge)\/)},
- # special cases: cannot find canonical format URL
- %r{\Ahttps?://brushviewer\.sourceforge\.net/brushviewql\.zip\Z},
- %r{\Ahttps?://doublecommand\.sourceforge\.net/files/},
- %r{\Ahttps?://excalibur\.sourceforge\.net/get\.php\?id=},
- ])
- end
+ def bad_sourceforge_url?
+ bad_url_format?(%r{sourceforge},
+ [
+ %r{\Ahttps://sourceforge\.net/projects/[^/]+/files/latest/download\Z},
+ %r{\Ahttps://downloads\.sourceforge\.net/(?!(project|sourceforge)\/)},
+ # special cases: cannot find canonical format URL
+ %r{\Ahttps?://brushviewer\.sourceforge\.net/brushviewql\.zip\Z},
+ %r{\Ahttps?://doublecommand\.sourceforge\.net/files/},
+ %r{\Ahttps?://excalibur\.sourceforge\.net/get\.php\?id=},
+ ])
+ end
- def bad_osdn_url?
- bad_url_format?(%r{osd}, [%r{\Ahttps?://([^/]+.)?dl\.osdn\.jp/}])
- end
+ def bad_osdn_url?
+ bad_url_format?(%r{osd}, [%r{\Ahttps?://([^/]+.)?dl\.osdn\.jp/}])
+ end
- def check_generic_artifacts
- cask.artifacts[:artifact].each do |source, target_hash|
- unless target_hash.is_a?(Hash) && target_hash[:target]
- add_error "target required for generic artifact #{source}"
- next
+ def check_generic_artifacts
+ cask.artifacts[:artifact].each do |source, target_hash|
+ unless target_hash.is_a?(Hash) && target_hash[:target]
+ add_error "target required for generic artifact #{source}"
+ next
+ end
+ add_error "target must be absolute path for generic artifact #{source}" unless Pathname.new(target_hash[:target]).absolute?
end
- add_error "target must be absolute path for generic artifact #{source}" unless Pathname.new(target_hash[:target]).absolute?
end
- end
- def check_token_conflicts
- return unless check_token_conflicts?
- return unless core_formula_names.include?(cask.token)
- add_warning "possible duplicate, cask token conflicts with Homebrew core formula: #{core_formula_url}"
- end
+ def check_token_conflicts
+ return unless check_token_conflicts?
+ return unless core_formula_names.include?(cask.token)
+ add_warning "possible duplicate, cask token conflicts with Homebrew core formula: #{core_formula_url}"
+ end
- def core_tap
- @core_tap ||= CoreTap.instance
- end
+ def core_tap
+ @core_tap ||= CoreTap.instance
+ end
- def core_formula_names
- core_tap.formula_names
- end
+ def core_formula_names
+ core_tap.formula_names
+ end
- def core_formula_url
- "#{core_tap.default_remote}/blob/master/Formula/#{cask.token}.rb"
- end
+ def core_formula_url
+ "#{core_tap.default_remote}/blob/master/Formula/#{cask.token}.rb"
+ end
- def check_download
- return unless download && cask.url
- odebug "Auditing download"
- downloaded_path = download.perform
- Hbc::Verify.all(cask, downloaded_path)
- rescue => e
- add_error "download not possible: #{e.message}"
+ def check_download
+ return unless download && cask.url
+ odebug "Auditing download"
+ downloaded_path = download.perform
+ Verify.all(cask, downloaded_path)
+ rescue => e
+ add_error "download not possible: #{e.message}"
+ end
end
end