Add internal command to calculate appcast checkpoint.

This commit is contained in:
Markus Reiter 2017-01-22 04:28:33 +01:00
parent 3be56aee71
commit 16f4130dd8
5 changed files with 76 additions and 11 deletions

View File

@ -133,20 +133,19 @@ module Hbc
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")
result = cask.appcast.calculate_checkpoint
actual_checkpoint = result[:checkpoint]
if actual_checkpoint.nil?
add_warning "error retrieving appcast: #{result[:command_result].stderr}"
else
expected = cask.appcast.checkpoint
actual = Digest::SHA2.hexdigest(processed_appcast_text)
add_warning <<-EOS.undent unless expected == actual
add_warning <<-EOS.undent unless expected == actual_checkpoint
appcast checkpoint mismatch
Expected: #{expected}
Actual: #{actual}
Actual: #{actual_checkpoint}
EOS
else
add_warning "error retrieving appcast: #{result.stderr}"
end
end

View File

@ -23,6 +23,7 @@ require "hbc/cli/zap"
require "hbc/cli/internal_use_base"
require "hbc/cli/internal_audit_modified_casks"
require "hbc/cli/internal_appcast_checkpoint"
require "hbc/cli/internal_checkurl"
require "hbc/cli/internal_dump"
require "hbc/cli/internal_help"

View File

@ -0,0 +1,45 @@
module Hbc
class CLI
class InternalAppcastCheckpoint < InternalUseBase
def self.run(*args)
cask_tokens = cask_tokens_from(args)
raise CaskUnspecifiedError if cask_tokens.empty?
appcask_checkpoint(cask_tokens)
end
def self.appcask_checkpoint(cask_tokens)
count = 0
cask_tokens.each do |cask_token|
cask = Hbc.load(cask_token)
if cask.appcast.nil?
opoo "Cask '#{cask}' is missing an `appcast` stanza."
else
result = cask.appcast.calculate_checkpoint
checkpoint = result[:checkpoint]
if checkpoint.nil?
onoe "Could not retrieve `appcast` checkpoint for cask '#{cask}': #{result[:command_result].stderr}"
else
puts cask_tokens.count > 1 ? "#{checkpoint} #{cask}": checkpoint
count += 1
end
end
end
count == cask_tokens.count
end
def self.help
"calculates a given Cask's appcast checkpoint"
end
def self.needs_init?
true
end
end
end
end

View File

@ -1,3 +1,5 @@
require "hbc/system_command"
module Hbc
class DSL
class Appcast
@ -9,6 +11,24 @@ module Hbc
@checkpoint = @parameters[:checkpoint]
end
def calculate_checkpoint
result = SystemCommand.run("/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", URL::FAKE_USER_AGENT, @uri], print_stderr: false)
checkpoint = 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")
Digest::SHA2.hexdigest(processed_appcast_text)
end
{
checkpoint: checkpoint,
command_result: result,
}
end
def to_yaml
[@uri, @parameters].to_yaml
end

View File

@ -162,7 +162,7 @@ describe Hbc::Audit do
before do
allow(audit).to receive(:check_appcast_http_code)
allow(fake_system_command).to receive(:run).and_return(fake_curl_result)
allow(Hbc::SystemCommand).to receive(:run).and_return(fake_curl_result)
allow(fake_curl_result).to receive(:success?).and_return(success)
end