Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions Library/Homebrew/cask/lib/hbc/audit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -133,20 +133,19 @@ def check_appcast_http_code

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

Expand Down
1 change: 1 addition & 0 deletions Library/Homebrew/cask/lib/hbc/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

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"
Expand Down
61 changes: 61 additions & 0 deletions Library/Homebrew/cask/lib/hbc/cli/internal_appcast_checkpoint.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
module Hbc
class CLI
class InternalAppcastCheckpoint < InternalUseBase
def self.run(*args)
calculate = args.include? "--calculate"
cask_tokens = cask_tokens_from(args)
raise CaskUnspecifiedError if cask_tokens.empty?

if cask_tokens.all? { |t| t =~ %r{^https?://} && t !~ /\.rb$/ }
appcask_checkpoint_for_url(cask_tokens)
else
appcask_checkpoint(cask_tokens, calculate)
end
end

def self.appcask_checkpoint_for_url(urls)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will work the same both with or without --calculate. Just pointing it out in case you intended to do it any other way. It’s fine by me as it is since the only sensical thing to do with a URL is calculate, anyway.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the only sensical thing to do with a URL is calculate

Exactly, you can't not calculate it.

urls.each do |url|
appcast = DSL::Appcast.new(url)
puts appcast.calculate_checkpoint[:checkpoint]
end
end

def self.appcask_checkpoint(cask_tokens, calculate)
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
if calculate
result = cask.appcast.calculate_checkpoint

checkpoint = result[:checkpoint]
else
checkpoint = cask.appcast.checkpoint
end

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
"prints or calculates a given Cask's or URL's appcast checkpoint"
end

def self.needs_init?
true
end
end
end
end
16 changes: 16 additions & 0 deletions Library/Homebrew/cask/lib/hbc/dsl/appcast.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require "hbc/system_command"

module Hbc
class DSL
class Appcast
Expand All @@ -9,6 +11,20 @@ def initialize(uri, parameters = {})
@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>}m, "")
Digest::SHA2.hexdigest(processed_appcast_text)
end

{
checkpoint: checkpoint,
command_result: result,
}
end

def to_yaml
[@uri, @parameters].to_yaml
end
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/cask/spec/cask/audit_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@

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

Expand Down
7 changes: 7 additions & 0 deletions Library/Homebrew/manpages/brew-cask.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@ names, and other aspects of this manual are still subject to change.

**`zap` may remove files which are shared between applications.**

## INTERNAL COMMANDS

* `_appcast_checkpoint` [--calculate] [ <token> ... | <URL> ... ]:
Given a `token`, returns the current appcast checkpoint, or calculates
the appcast checkpoint if the `--calculate` flag is specified.
Given a `URL`, calculates the appcast checkpoint for it.

## OPTIONS

To make these options persistent, see the ENVIRONMENT section, below.
Expand Down
9 changes: 9 additions & 0 deletions manpages/brew-cask.1
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,15 @@ If the Cask definition contains a \fBzap\fR stanza, performs additional \fBzap\f
.
.IP "" 0
.
.SH "INTERNAL COMMANDS"
.
.TP
\fB_appcast_checkpoint\fR [\-\-calculate] [ \fItoken\fR \.\.\. | \fIURL\fR \.\.\. ]
Given a \fBtoken\fR, returns the current appcast checkpoint, or calculates the appcast checkpoint if the \fB\-\-calculate\fR flag is specified\.
.
.br
Given a \fBURL\fR, calculates the appcast checkpoint for it\.
.
.SH "OPTIONS"
To make these options persistent, see the ENVIRONMENT section, below\.
.
Expand Down