Add audit check to see if both version and checksum changed.
This commit is contained in:
		
							parent
							
								
									6d8c170e50
								
							
						
					
					
						commit
						1a96dc39d1
					
				@ -1,16 +1,18 @@
 | 
			
		||||
require "hbc/checkable"
 | 
			
		||||
require "hbc/download"
 | 
			
		||||
require "digest"
 | 
			
		||||
require "utils/git"
 | 
			
		||||
 | 
			
		||||
module Hbc
 | 
			
		||||
  class Audit
 | 
			
		||||
    include Checkable
 | 
			
		||||
 | 
			
		||||
    attr_reader :cask, :download
 | 
			
		||||
    attr_reader :cask, :commit_range, :download
 | 
			
		||||
 | 
			
		||||
    def initialize(cask, download: false, check_token_conflicts: false, command: SystemCommand)
 | 
			
		||||
    def initialize(cask, download: false, check_token_conflicts: false, commit_range: nil, command: SystemCommand)
 | 
			
		||||
      @cask = cask
 | 
			
		||||
      @download = download
 | 
			
		||||
      @commit_range = commit_range
 | 
			
		||||
      @check_token_conflicts = check_token_conflicts
 | 
			
		||||
      @command = command
 | 
			
		||||
    end
 | 
			
		||||
@ -21,6 +23,7 @@ module Hbc
 | 
			
		||||
 | 
			
		||||
    def run!
 | 
			
		||||
      check_required_stanzas
 | 
			
		||||
      check_version_and_checksum
 | 
			
		||||
      check_version
 | 
			
		||||
      check_sha256
 | 
			
		||||
      check_appcast
 | 
			
		||||
@ -57,6 +60,23 @@ module Hbc
 | 
			
		||||
      add_error "at least one activatable artifact stanza is required" if installable_artifacts.empty?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def check_version_and_checksum
 | 
			
		||||
      return if @cask.sourcefile_path.nil?
 | 
			
		||||
 | 
			
		||||
      tap = Tap.select { |t| t.cask_file?(@cask.sourcefile_path) }.first
 | 
			
		||||
      return if tap.nil?
 | 
			
		||||
 | 
			
		||||
      previous_cask_contents = Git.last_revision_of_file(tap.path, @cask.sourcefile_path, before_commit: commit_range)
 | 
			
		||||
      return if previous_cask_contents.empty?
 | 
			
		||||
 | 
			
		||||
      previous_cask = CaskLoader.load_from_string(previous_cask_contents)
 | 
			
		||||
 | 
			
		||||
      return unless previous_cask.version == cask.version
 | 
			
		||||
      return if previous_cask.sha256 == cask.sha256
 | 
			
		||||
 | 
			
		||||
      add_error "only sha256 changed; needs to be confirmed by the developer"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def check_version
 | 
			
		||||
      return unless cask.version
 | 
			
		||||
      check_no_string_version_latest
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,15 @@
 | 
			
		||||
module Hbc
 | 
			
		||||
  class Auditor
 | 
			
		||||
    def self.audit(cask, audit_download: false, check_token_conflicts: false)
 | 
			
		||||
      new(cask, audit_download, check_token_conflicts).audit
 | 
			
		||||
    def self.audit(cask, audit_download: false, check_token_conflicts: false, commit_range: nil)
 | 
			
		||||
      new(cask, audit_download, check_token_conflicts, commit_range).audit
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    attr_reader :cask
 | 
			
		||||
    attr_reader :cask, :commit_range
 | 
			
		||||
 | 
			
		||||
    def initialize(cask, audit_download, check_token_conflicts)
 | 
			
		||||
    def initialize(cask, audit_download, check_token_conflicts, commit_range)
 | 
			
		||||
      @cask = cask
 | 
			
		||||
      @audit_download = audit_download
 | 
			
		||||
      @commit_range = commit_range
 | 
			
		||||
      @check_token_conflicts = check_token_conflicts
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@ -50,7 +51,8 @@ module Hbc
 | 
			
		||||
    def audit_cask_instance(cask)
 | 
			
		||||
      download = audit_download? && Download.new(cask)
 | 
			
		||||
      audit = Audit.new(cask, download:              download,
 | 
			
		||||
                              check_token_conflicts: check_token_conflicts?)
 | 
			
		||||
                              check_token_conflicts: check_token_conflicts?,
 | 
			
		||||
                              commit_range: commit_range)
 | 
			
		||||
      audit.run!
 | 
			
		||||
      puts audit.summary
 | 
			
		||||
      audit.success?
 | 
			
		||||
 | 
			
		||||
@ -97,7 +97,8 @@ module Hbc
 | 
			
		||||
        audit_download = audit_download?(cask, cask_file)
 | 
			
		||||
        check_token_conflicts = added_cask_files.include?(cask_file)
 | 
			
		||||
        success = Auditor.audit(cask, audit_download:        audit_download,
 | 
			
		||||
                                      check_token_conflicts: check_token_conflicts)
 | 
			
		||||
                                      check_token_conflicts: check_token_conflicts,
 | 
			
		||||
                                      commit_range: commit_range)
 | 
			
		||||
        failed_casks << cask unless success
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,31 @@
 | 
			
		||||
require "open3"
 | 
			
		||||
 | 
			
		||||
module Git
 | 
			
		||||
  module_function
 | 
			
		||||
 | 
			
		||||
  def last_revision_commit_of_file(repo, file, before_commit: nil)
 | 
			
		||||
    args = [before_commit.nil? ? "--skip=1" : before_commit.split("..").first]
 | 
			
		||||
 | 
			
		||||
    out, = Open3.capture3(
 | 
			
		||||
      HOMEBREW_SHIMS_PATH/"scm/git", "-C", repo,
 | 
			
		||||
      "log", "--oneline", "--max-count=1", *args, "--", file
 | 
			
		||||
    )
 | 
			
		||||
    out.split(" ").first
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def last_revision_of_file(repo, file, before_commit: nil)
 | 
			
		||||
    relative_file = Pathname(file).relative_path_from(repo)
 | 
			
		||||
 | 
			
		||||
    commit_hash = last_revision_commit_of_file(repo, file, before_commit: before_commit)
 | 
			
		||||
 | 
			
		||||
    out, = Open3.capture3(
 | 
			
		||||
      HOMEBREW_SHIMS_PATH/"scm/git", "-C", repo,
 | 
			
		||||
      "show", "#{commit_hash}:#{relative_file}"
 | 
			
		||||
    )
 | 
			
		||||
    out
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
module Utils
 | 
			
		||||
  def self.git_available?
 | 
			
		||||
    return @git if instance_variable_defined?(:@git)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user