homebrew-cask/lib/hbc/audit.rb

100 lines
3.2 KiB
Ruby

require 'hbc/checkable'
require 'hbc/download'
class Hbc::Audit
attr_reader :cask
include Hbc::Checkable
def initialize(cask)
@cask = cask
end
def run!(download = false)
_check_required_stanzas
_check_no_string_version_latest
_check_sha256_no_check_if_latest
_check_sha256_actually_256
_check_sha256_invalid
_check_sourceforge_download_url_format
_check_download(download) if download
return !(errors? or warnings?)
end
def summary_header
"audit for #{cask}"
end
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 value is required (:unknown is OK)' unless cask.license
# 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,v| [:uninstall, :zap, :nested_container].include?(k)}
add_error 'at least one activatable artifact stanza is required' unless installable_artifacts.size > 0
end
def _check_no_string_version_latest
odebug "Verifying version :latest does not appear as a string ('latest')"
if (cask.version == 'latest')
add_error "you should use version :latest instead of version 'latest'"
end
end
def _check_sha256_no_check_if_latest
odebug "Verifying sha256 :no_check with version :latest"
if cask.version == :latest and cask.sha256 != :no_check
add_error "you should use sha256 :no_check when version is :latest"
end
end
def _check_sha256_actually_256
odebug "Verifying sha256 string is a legal SHA-256 digest"
if cask.sha256.kind_of?(String)
unless cask.sha256.length == 64 && cask.sha256[/^[0-9a-f]+$/i]
add_error "sha256 string must be of 64 hexadecimal characters"
end
end
end
def _check_sha256_invalid
odebug "Verifying sha256 is not a known invalid value"
empty_sha256 = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
if cask.sha256 == empty_sha256
add_error "cannot use the sha256 for an empty string: #{empty_sha256}"
end
end
def _check_download(download)
odebug "Auditing download"
download.perform
rescue => e
add_error "download not possible: #{e.message}"
end
def _check_sourceforge_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/CONTRIBUTING.md#sourceforge-urls"
end
end
def _bad_sourceforge_url?
return false unless cask.url.to_s =~ /sourceforge/
valid_url_formats = [
%r{\Ahttps?://sourceforge\.net/projects/[^/]+/files/latest/download\Z},
%r{\Ahttps?://downloads\.sourceforge\.net/},
%r{\Ahttps?://[^/]+\.sourceforge\.jp/},
# 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=},
]
valid_url_formats.none? { |format| cask.url.to_s =~ format }
end
end