add optional checking whether appcast contains the version stanza to "brew cask audit"

This commit is contained in:
Julian Mayer 2019-05-07 17:06:54 +02:00
parent 84085bd430
commit a061a8d9f7
4 changed files with 45 additions and 13 deletions

View File

@ -9,11 +9,16 @@ require "utils/git"
module Cask module Cask
class Audit class Audit
include Checkable include Checkable
extend Predicable
attr_reader :cask, :commit_range, :download attr_reader :cask, :commit_range, :download
def initialize(cask, download: false, check_token_conflicts: false, commit_range: nil, command: SystemCommand) attr_predicate :check_appcast?
def initialize(cask, check_appcast: false, download: false, check_token_conflicts: false,
commit_range: nil, command: SystemCommand)
@cask = cask @cask = cask
@check_appcast = check_appcast
@download = download @download = download
@commit_range = commit_range @commit_range = commit_range
@check_token_conflicts = check_token_conflicts @check_token_conflicts = check_token_conflicts
@ -40,6 +45,7 @@ module Cask
check_latest_with_appcast check_latest_with_appcast
check_latest_with_auto_updates check_latest_with_auto_updates
check_stanza_requires_uninstall check_stanza_requires_uninstall
check_appcast_contains_version
self self
rescue => e rescue => e
odebug "#{e.message}\n#{e.backtrace.join("\n")}" odebug "#{e.message}\n#{e.backtrace.join("\n")}"
@ -292,6 +298,22 @@ module Cask
add_error "download not possible: #{e.message}" add_error "download not possible: #{e.message}"
end end
def check_appcast_contains_version
return unless check_appcast?
return if cask.appcast.to_s.empty?
appcast_stanza = cask.appcast.to_s
appcast_contents, = curl_output("--max-time", "5", appcast_stanza)
version_stanza = cask.version.to_s
adjusted_version_stanza = version_stanza.split(",")[0].split("-")[0].split("_")[0]
return if appcast_contents.include? adjusted_version_stanza
add_warning "appcast at URL '#{appcast_stanza}' does not contain"\
" the version number: '#{adjusted_version_stanza}'"
rescue
add_error "appcast at URL '#{appcast_stanza}' offline or looping"
end
def check_https_availability def check_https_availability
return unless download return unless download

View File

@ -4,15 +4,24 @@ require "cask/download"
module Cask module Cask
class Auditor class Auditor
def self.audit(cask, audit_download: false, check_token_conflicts: false, quarantine: true, commit_range: nil) include Checkable
new(cask, audit_download, check_token_conflicts, quarantine, commit_range).audit extend Predicable
def self.audit(cask, audit_download: false, audit_appcast: false,
check_token_conflicts: false, quarantine: true, commit_range: nil)
new(cask, audit_download: audit_download,
audit_appcast: audit_appcast,
check_token_conflicts: check_token_conflicts,
quarantine: quarantine, commit_range: commit_range).audit
end end
attr_reader :cask, :commit_range attr_reader :cask, :commit_range
def initialize(cask, audit_download, check_token_conflicts, quarantine, commit_range) def initialize(cask, audit_download: false, audit_appcast: false,
check_token_conflicts: false, quarantine: true, commit_range: nil)
@cask = cask @cask = cask
@audit_download = audit_download @audit_download = audit_download
@audit_appcast = audit_appcast
@quarantine = quarantine @quarantine = quarantine
@commit_range = commit_range @commit_range = commit_range
@check_token_conflicts = check_token_conflicts @check_token_conflicts = check_token_conflicts
@ -22,9 +31,7 @@ module Cask
@audit_download @audit_download
end end
def quarantine? attr_predicate :audit_appcast?, :quarantine?
@quarantine
end
def check_token_conflicts? def check_token_conflicts?
@check_token_conflicts @check_token_conflicts
@ -57,7 +64,8 @@ module Cask
def audit_cask_instance(cask) def audit_cask_instance(cask)
download = audit_download? && Download.new(cask, quarantine: quarantine?) download = audit_download? && Download.new(cask, quarantine: quarantine?)
audit = Audit.new(cask, download: download, audit = Audit.new(cask, check_appcast: audit_appcast?,
download: download,
check_token_conflicts: check_token_conflicts?, check_token_conflicts: check_token_conflicts?,
commit_range: commit_range) commit_range: commit_range)
audit.run! audit.run!

View File

@ -4,6 +4,7 @@ module Cask
class Cmd class Cmd
class Audit < AbstractCommand class Audit < AbstractCommand
option "--download", :download, false option "--download", :download, false
option "--appcast", :appcast, false
option "--token-conflicts", :token_conflicts, false option "--token-conflicts", :token_conflicts, false
def self.help def self.help
@ -22,6 +23,7 @@ module Cask
def audit(cask) def audit(cask)
odebug "Auditing Cask #{cask}" odebug "Auditing Cask #{cask}"
Auditor.audit(cask, audit_download: download?, Auditor.audit(cask, audit_download: download?,
audit_appcast: appcast?,
check_token_conflicts: token_conflicts?, check_token_conflicts: token_conflicts?,
quarantine: quarantine?) quarantine: quarantine?)
end end

View File

@ -21,7 +21,7 @@ describe Cask::Cmd::Audit, :cask do
expect(Cask::CaskLoader).to receive(:load).with(cask_token).and_return(cask) expect(Cask::CaskLoader).to receive(:load).with(cask_token).and_return(cask)
expect(Cask::Auditor).to receive(:audit) expect(Cask::Auditor).to receive(:audit)
.with(cask, audit_download: false, check_token_conflicts: false, quarantine: true) .with(cask, audit_download: false, audit_appcast: false, check_token_conflicts: false, quarantine: true)
.and_return(true) .and_return(true)
described_class.run(cask_token) described_class.run(cask_token)
@ -32,7 +32,7 @@ describe Cask::Cmd::Audit, :cask do
it "does not download the Cask per default" do it "does not download the Cask per default" do
allow(Cask::CaskLoader).to receive(:load).and_return(cask) allow(Cask::CaskLoader).to receive(:load).and_return(cask)
expect(Cask::Auditor).to receive(:audit) expect(Cask::Auditor).to receive(:audit)
.with(cask, audit_download: false, check_token_conflicts: false, quarantine: true) .with(cask, audit_download: false, audit_appcast: false, check_token_conflicts: false, quarantine: true)
.and_return(true) .and_return(true)
described_class.run("casktoken") described_class.run("casktoken")
@ -41,7 +41,7 @@ describe Cask::Cmd::Audit, :cask do
it "download a Cask if --download flag is set" do it "download a Cask if --download flag is set" do
allow(Cask::CaskLoader).to receive(:load).and_return(cask) allow(Cask::CaskLoader).to receive(:load).and_return(cask)
expect(Cask::Auditor).to receive(:audit) expect(Cask::Auditor).to receive(:audit)
.with(cask, audit_download: true, check_token_conflicts: false, quarantine: true) .with(cask, audit_download: true, audit_appcast: false, check_token_conflicts: false, quarantine: true)
.and_return(true) .and_return(true)
described_class.run("casktoken", "--download") described_class.run("casktoken", "--download")
@ -52,7 +52,7 @@ describe Cask::Cmd::Audit, :cask do
it "does not check for token conflicts per default" do it "does not check for token conflicts per default" do
allow(Cask::CaskLoader).to receive(:load).and_return(cask) allow(Cask::CaskLoader).to receive(:load).and_return(cask)
expect(Cask::Auditor).to receive(:audit) expect(Cask::Auditor).to receive(:audit)
.with(cask, audit_download: false, check_token_conflicts: false, quarantine: true) .with(cask, audit_download: false, audit_appcast: false, check_token_conflicts: false, quarantine: true)
.and_return(true) .and_return(true)
described_class.run("casktoken") described_class.run("casktoken")
@ -61,7 +61,7 @@ describe Cask::Cmd::Audit, :cask do
it "checks for token conflicts if --token-conflicts flag is set" do it "checks for token conflicts if --token-conflicts flag is set" do
allow(Cask::CaskLoader).to receive(:load).and_return(cask) allow(Cask::CaskLoader).to receive(:load).and_return(cask)
expect(Cask::Auditor).to receive(:audit) expect(Cask::Auditor).to receive(:audit)
.with(cask, audit_download: false, check_token_conflicts: true, quarantine: true) .with(cask, audit_download: false, audit_appcast: false, check_token_conflicts: true, quarantine: true)
.and_return(true) .and_return(true)
described_class.run("casktoken", "--token-conflicts") described_class.run("casktoken", "--token-conflicts")