diff options
Diffstat (limited to 'Library/Homebrew/cask/lib')
24 files changed, 202 insertions, 255 deletions
| diff --git a/Library/Homebrew/cask/lib/hbc/cask_loader.rb b/Library/Homebrew/cask/lib/hbc/cask_loader.rb index a0c44d9b4..43fd9080d 100644 --- a/Library/Homebrew/cask/lib/hbc/cask_loader.rb +++ b/Library/Homebrew/cask/lib/hbc/cask_loader.rb @@ -32,9 +32,9 @@ module Hbc        end        def load -        raise CaskError, "'#{@path}' does not exist."  unless @path.exist? -        raise CaskError, "'#{@path}' is not readable." unless @path.readable? -        raise CaskError, "'#{@path}' is not a file."   unless @path.file? +        raise CaskUnavailableError.new(@token, "'#{@path}' does not exist.")  unless @path.exist? +        raise CaskUnavailableError.new(@token, "'#{@path}' is not readable.") unless @path.readable? +        raise CaskUnavailableError.new(@token, "'#{@path}' is not a file.")   unless @path.file?          @content = IO.read(@path) @@ -45,7 +45,7 @@ module Hbc        def cask(header_token, &block)          if @token != header_token -          raise CaskTokenDoesNotMatchError.new(@token, header_token) +          raise CaskTokenMismatchError.new(@token, header_token)          end          Cask.new(header_token, sourcefile_path: @path, &block) @@ -57,10 +57,11 @@ module Hbc          ref.to_s.match?(::URI.regexp)        end +      attr_reader :url +        def initialize(url) -        @url = url -        uri = URI(url) -        super Hbc.cache/File.basename(uri.path) +        @url = URI(url) +        super Hbc.cache/File.basename(@url.path)        end        def load @@ -71,7 +72,7 @@ module Hbc            ohai "Downloading #{@url}."            curl @url, "-o", @path          rescue ErrorDuringExecution -          raise CaskUnavailableError, @url +          raise CaskUnavailableError.new(@token, "Failed to download #{Formatter.url(@url)}.")          end          super @@ -108,7 +109,7 @@ module Hbc        end        def load -        raise CaskUnavailableError, @token +        raise CaskUnavailableError.new(@token, "No Cask with this name exists.")        end      end diff --git a/Library/Homebrew/cask/lib/hbc/cli.rb b/Library/Homebrew/cask/lib/hbc/cli.rb index 99980b88d..0108c1621 100644 --- a/Library/Homebrew/cask/lib/hbc/cli.rb +++ b/Library/Homebrew/cask/lib/hbc/cli.rb @@ -66,7 +66,7 @@ module Hbc      option "--help", :help, false      # handled in OS::Mac -    option "--language a,b,c", ->(*) { raise OptionParser::InvalidOption } +    option "--language a,b,c", ->(*) {}      # override default handling of --version      option "--version", ->(*) { raise OptionParser::InvalidOption } @@ -92,10 +92,10 @@ module Hbc        command.is_a?(Class) && !command.abstract? && command.needs_init?      end -    def self.run_command(command, *rest) +    def self.run_command(command, *args)        if command.respond_to?(:run)          # usual case: built-in command verb -        command.run(*rest) +        command.run(*args)        elsif require?(which("brewcask-#{command}.rb"))          # external command as Ruby library on PATH, Homebrew-style        elsif command.to_s.include?("/") && require?(command.to_s) @@ -111,7 +111,7 @@ module Hbc          if klass.respond_to?(:run)            # invoke "run" on a Ruby library which follows our coding conventions            # other Ruby libraries must do everything via "require" -          klass.run(*rest) +          klass.run(*args)          end        elsif which("brewcask-#{command}")          # arbitrary external executable on PATH, Homebrew-style @@ -124,7 +124,7 @@ module Hbc          exec command, *ARGV[1..-1]        else          # failure -        NullCommand.new(command).run +        NullCommand.new(command, *args).run        end      end @@ -136,18 +136,39 @@ module Hbc        @args = process_options(*args)      end +    def detect_command_and_arguments(*args) +      command = args.detect do |arg| +        if self.class.commands.include?(arg) +          true +        else +          break unless arg.start_with?("-") +        end +      end + +      if index = args.index(command) +        args.delete_at(index) +      end + +      [*command, *args] +    end +      def run -      command_name, *args = *@args -      command = help? ? "help" : self.class.lookup_command(command_name) +      command_name, *args = detect_command_and_arguments(*@args) +      command = if help? +        args.unshift(command_name) +        "help" +      else +        self.class.lookup_command(command_name) +      end        MacOS.full_version = ENV["MACOS_VERSION"] unless ENV["MACOS_VERSION"].nil?        Hbc.default_tap.install unless Hbc.default_tap.installed?        Hbc.init if self.class.should_init?(command)        self.class.run_command(command, *args) -    rescue CaskError, CaskSha256MismatchError, ArgumentError, OptionParser::InvalidOption => e +    rescue CaskError, ArgumentError, OptionParser::InvalidOption => e        msg = e.message -      msg << e.backtrace.join("\n") if ARGV.debug? +      msg << e.backtrace.join("\n").prepend("\n") if ARGV.debug?        onoe msg        exit 1      rescue StandardError, ScriptError, NoMemoryError => e @@ -199,18 +220,19 @@ module Hbc      end      class NullCommand -      def initialize(attempted_verb) -        @attempted_verb = attempted_verb +      def initialize(command, *args) +        @command = command +        @args = args        end        def run(*_args)          purpose          usage -        return if @attempted_verb.to_s.strip.empty? -        return if @attempted_verb == "help" +        return if @command == "help" && @args.empty? -        raise ArgumentError, "Unknown command: #{@attempted_verb}" +        unknown_command = @args.empty? ? @command : @args.first +        raise ArgumentError, "Unknown command: #{unknown_command}"        end        def purpose diff --git a/Library/Homebrew/cask/lib/hbc/cli/abstract_command.rb b/Library/Homebrew/cask/lib/hbc/cli/abstract_command.rb index cdb7f5ec8..77f85301e 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/abstract_command.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/abstract_command.rb @@ -9,6 +9,7 @@ module Hbc        option "--debug",         :debug,         false        option "--verbose",       :verbose,       false        option "--outdated",      :outdated_only, false +      option "--require-sha",   :require_sha, false        def self.command_name          @command_name ||= name.sub(/^.*:/, "").gsub(/(.)([A-Z])/, '\1_\2').downcase @@ -40,6 +41,43 @@ module Hbc        def initialize(*args)          @args = process_arguments(*args)        end + +      def self.warn_unavailable_with_suggestion(cask_token, e) +        exact_match, partial_matches = Search.search(cask_token) +        error_message = e.message +        if exact_match +          error_message.concat(" Did you mean:\n#{exact_match}") +        elsif !partial_matches.empty? +          error_message.concat(" Did you mean one of:\n") +                       .concat(Formatter.columns(partial_matches.take(20))) +        end +        onoe error_message +      end + +      private + +      def casks(alternative: -> { [] }) +        return to_enum(:casks, alternative: alternative) unless block_given? + +        count = 0 + +        casks = args.empty? ? alternative.call : args + +        casks.each do |cask_or_token| +          begin +            yield cask_or_token.respond_to?(:token) ? cask_or_token : CaskLoader.load(cask_or_token) +            count += 1 +          rescue CaskUnavailableError => e +            cask_token = cask_or_token +            self.class.warn_unavailable_with_suggestion cask_token, e +          rescue CaskError => e +            onoe e.message +          end +        end + +        return :empty if casks.length.zero? +        (count == casks.length) ? :complete : :incomplete +      end      end    end  end diff --git a/Library/Homebrew/cask/lib/hbc/cli/audit.rb b/Library/Homebrew/cask/lib/hbc/cli/audit.rb index 74d1ebfa7..35d82800c 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/audit.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/audit.rb @@ -9,11 +9,8 @@ module Hbc        end        def run -        casks_to_audit = args.empty? ? Hbc.all : args.map(&CaskLoader.public_method(:load)) - -        failed_casks = casks_to_audit.reject do |cask| -          audit(cask) -        end +        failed_casks = casks(alternative: -> { Hbc.all }) +                       .reject { |cask| audit(cask) }          return if failed_casks.empty?          raise CaskError, "audit failed for casks: #{failed_casks.join(" ")}" diff --git a/Library/Homebrew/cask/lib/hbc/cli/cat.rb b/Library/Homebrew/cask/lib/hbc/cli/cat.rb index e68481b46..d08c87bea 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/cat.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/cat.rb @@ -7,10 +7,12 @@ module Hbc        end        def run -        args.each do |cask_token| -          cask_path = CaskLoader.path(cask_token) -          raise CaskUnavailableError, cask_token.to_s unless cask_path.exist? -          puts File.open(cask_path, &:read) +        raise CaskError, "Cat incomplete." if cat_casks == :incomplete +      end + +      def cat_casks +        casks.each do |cask| +          puts File.open(cask.sourcefile_path, &:read)          end        end diff --git a/Library/Homebrew/cask/lib/hbc/cli/cleanup.rb b/Library/Homebrew/cask/lib/hbc/cli/cleanup.rb index 40b37dd5d..356162db5 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/cleanup.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/cleanup.rb @@ -20,7 +20,7 @@ module Hbc        end        def run -        remove_cache_files(*@args) +        remove_cache_files(*args)        end        def cache_files diff --git a/Library/Homebrew/cask/lib/hbc/cli/edit.rb b/Library/Homebrew/cask/lib/hbc/cli/edit.rb index dec0fe36b..b9485886c 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/edit.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/edit.rb @@ -9,10 +9,12 @@ module Hbc        def run          cask_token = args.first -        cask_path = CaskLoader.path(cask_token) - -        unless cask_path.exist? -          raise CaskUnavailableError, %Q(#{cask_token}, run "brew cask create #{cask_token}" to create a new Cask) +        cask_path = begin +          CaskLoader.load(cask_token).sourcefile_path +        rescue CaskUnavailableError => e +          reason = e.reason.empty? ? "" : "#{e.reason} " +          reason.concat("Run #{Formatter.identifier("brew cask create #{e.token}")} to create a new Cask.") +          raise e.class.new(e.token, reason)          end          odebug "Opening editor for Cask #{cask_token}" diff --git a/Library/Homebrew/cask/lib/hbc/cli/fetch.rb b/Library/Homebrew/cask/lib/hbc/cli/fetch.rb index 2c1cc5f66..e31b1a17c 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/fetch.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/fetch.rb @@ -9,9 +9,12 @@ module Hbc        end        def run -        args.each do |cask_token| -          ohai "Downloading external files for Cask #{cask_token}" -          cask = CaskLoader.load(cask_token) +        raise CaskError, "Fetch incomplete." if fetch_casks == :incomplete +      end + +      def fetch_casks +        casks.each do |cask| +          ohai "Downloading external files for Cask #{cask}"            downloaded_path = Download.new(cask, force: force?).perform            Verify.all(cask, downloaded_path)            ohai "Success! Downloaded to -> #{downloaded_path}" diff --git a/Library/Homebrew/cask/lib/hbc/cli/home.rb b/Library/Homebrew/cask/lib/hbc/cli/home.rb index 009bc1e3e..d496e309e 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/home.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/home.rb @@ -2,9 +2,7 @@ module Hbc    class CLI      class Home < AbstractCommand        def run -        casks = args.map(&CaskLoader.public_method(:load)) - -        if casks.empty? +        if casks.none?            odebug "Opening project homepage"            self.class.open_url "https://caskroom.github.io/"          else diff --git a/Library/Homebrew/cask/lib/hbc/cli/info.rb b/Library/Homebrew/cask/lib/hbc/cli/info.rb index 623c4b737..d26747e17 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/info.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/info.rb @@ -7,10 +7,8 @@ module Hbc        end        def run -        args.each do |cask_token| -          odebug "Getting info for Cask #{cask_token}" -          cask = CaskLoader.load(cask_token) - +        casks.each do |cask| +          odebug "Getting info for Cask #{cask}"            self.class.info(cask)          end        end diff --git a/Library/Homebrew/cask/lib/hbc/cli/install.rb b/Library/Homebrew/cask/lib/hbc/cli/install.rb index 72f85fc69..0f1a5dd34 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/install.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/install.rb @@ -3,7 +3,6 @@ module Hbc      class Install < AbstractCommand        option "--force",          :force,          false        option "--skip-cask-deps", :skip_cask_deps, false -      option "--require-sha",    :require_sha,    false        def initialize(*)          super @@ -11,53 +10,21 @@ module Hbc        end        def run -        retval = install_casks -        # retval is ternary: true/false/nil - -        raise CaskError, "nothing to install" if retval.nil? -        raise CaskError, "install incomplete" unless retval +        raise CaskError, "Install incomplete." if install_casks == :incomplete        end        def install_casks -        count = 0 -        args.each do |cask_token| +        casks.each do |cask|            begin -            cask = CaskLoader.load(cask_token)              Installer.new(cask, binaries:       binaries?, -                                verbose: verbose?, +                                verbose:        verbose?,                                  force:          force?,                                  skip_cask_deps: skip_cask_deps?,                                  require_sha:    require_sha?).install -            count += 1            rescue CaskAlreadyInstalledError => e              opoo e.message -            count += 1 -          rescue CaskAlreadyInstalledAutoUpdatesError => e -            opoo e.message -            count += 1 -          rescue CaskUnavailableError => e -            self.class.warn_unavailable_with_suggestion cask_token, e -          rescue CaskNoShasumError => e -            opoo e.message -            count += 1 -          rescue CaskError => e -            onoe e.message            end          end - -        count.zero? ? nil : count == args.length -      end - -      def self.warn_unavailable_with_suggestion(cask_token, e) -        exact_match, partial_matches = Search.search(cask_token) -        error_message = e.message -        if exact_match -          error_message.concat(". Did you mean:\n#{exact_match}") -        elsif !partial_matches.empty? -          error_message.concat(". Did you mean one of:\n") -                       .concat(Formatter.columns(partial_matches.take(20))) -        end -        onoe error_message        end        def self.help diff --git a/Library/Homebrew/cask/lib/hbc/cli/internal_dump.rb b/Library/Homebrew/cask/lib/hbc/cli/internal_dump.rb index 78dbf1622..e21ce86b6 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/internal_dump.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/internal_dump.rb @@ -7,25 +7,11 @@ module Hbc        end        def run -        retval = dump_casks -        # retval is ternary: true/false/nil - -        raise CaskError, "nothing to dump" if retval.nil? -        raise CaskError, "dump incomplete" unless retval +        raise CaskError, "Dump incomplete." if dump_casks == :incomplet        end        def dump_casks -        count = 0 -        args.each do |cask_token| -          begin -            cask = CaskLoader.load(cask_token) -            count += 1 -            cask.dumpcask -          rescue StandardError => e -            opoo "#{cask_token} was not found or would not load: #{e}" -          end -        end -        count.zero? ? nil : count == args.length +        casks.each(&:dumpcask)        end        def self.help diff --git a/Library/Homebrew/cask/lib/hbc/cli/internal_stanza.rb b/Library/Homebrew/cask/lib/hbc/cli/internal_stanza.rb index 86dee7c9c..4515fe931 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/internal_stanza.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/internal_stanza.rb @@ -72,38 +72,22 @@ module Hbc        end        def run -        retval = print_stanzas -        # retval is ternary: true/false/nil -        if retval.nil? -          exit 1 if quiet? -          raise CaskError, "nothing to print" -        elsif !retval -          exit 1 if quiet? -          raise CaskError, "print incomplete" -        end +        return unless print_stanzas == :incomplete +        exit 1 if quiet? +        raise CaskError, "Print incomplete."        end        def print_stanzas -        count = 0          if ARTIFACTS.include?(stanza)            artifact_name = stanza            @stanza = :artifacts          end -        cask_tokens = args.empty? ? Hbc.all_tokens : args -        cask_tokens.each do |cask_token| -          print "#{cask_token}\t" if table? - -          begin -            cask = CaskLoader.load(cask_token) -          rescue StandardError -            opoo "Cask '#{cask_token}' was not found" unless quiet? -            puts "" -            next -          end +        casks(alternative: -> { Hbc.all }).each do |cask| +          print "#{cask}\t" if table?            unless cask.respond_to?(stanza) -            opoo "no such stanza '#{stanza}' on Cask '#{cask_token}'" unless quiet? +            opoo "no such stanza '#{stanza}' on Cask '#{cask}'" unless quiet?              puts ""              next            end @@ -111,13 +95,13 @@ module Hbc            begin              value = cask.send(@stanza)            rescue StandardError -            opoo "failure calling '#{stanza}' on Cask '#{cask_token}'" unless quiet? +            opoo "failure calling '#{stanza}' on Cask '#{cask}'" unless quiet?              puts ""              next            end            if artifact_name && !value.key?(artifact_name) -            opoo "no such stanza '#{artifact_name}' on Cask '#{cask_token}'" unless quiet? +            opoo "no such stanza '#{artifact_name}' on Cask '#{cask}'" unless quiet?              puts ""              next            end @@ -131,10 +115,7 @@ module Hbc            else              puts value.to_s            end - -          count += 1          end -        count.zero? ? nil : count == cask_tokens.length        end        def self.help diff --git a/Library/Homebrew/cask/lib/hbc/cli/list.rb b/Library/Homebrew/cask/lib/hbc/cli/list.rb index 9d2ded4be..9d978360e 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/list.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/list.rb @@ -11,44 +11,22 @@ module Hbc        def run          retval = args.any? ? list : list_installed -        # retval is ternary: true/false/nil -        if retval.nil? && args.none? -          opoo "nothing to list" # special case: avoid exit code -        elsif retval.nil? -          raise CaskError, "nothing to list" -        elsif !retval -          raise CaskError, "listing incomplete" -        end +        raise CaskError, "Listing incomplete." if retval == :incomplete        end        def list -        count = 0 - -        args.each do |cask_token| -          odebug "Listing files for Cask #{cask_token}" -          begin -            cask = CaskLoader.load(cask_token) +        casks.each do |cask| +          raise CaskNotInstalledError, cask unless cask.installed? -            if cask.installed? -              if one? -                puts cask.token -              elsif versions? -                puts self.class.format_versioned(cask) -              else -                cask = CaskLoader.load_from_file(cask.installed_caskfile) -                self.class.list_artifacts(cask) -              end - -              count += 1 -            else -              opoo "#{cask} is not installed" -            end -          rescue CaskUnavailableError => e -            onoe e +          if one? +            puts cask.token +          elsif versions? +            puts self.class.format_versioned(cask) +          else +            cask = CaskLoader.load_from_file(cask.installed_caskfile) +            self.class.list_artifacts(cask)            end          end - -        count.zero? ? nil : count == args.length        end        def self.list_artifacts(cask) @@ -69,7 +47,7 @@ module Hbc            puts Formatter.columns(installed_casks.map(&:to_s))          end -        installed_casks.empty? ? nil : true +        installed_casks.empty? ? :empty : :complete        end        def self.format_versioned(cask) diff --git a/Library/Homebrew/cask/lib/hbc/cli/outdated.rb b/Library/Homebrew/cask/lib/hbc/cli/outdated.rb index 7877ead05..b0a84e8d2 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/outdated.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/outdated.rb @@ -10,9 +10,7 @@ module Hbc        end        def run -        casks_to_check = args.empty? ? Hbc.installed : args.map(&CaskLoader.public_method(:load)) - -        casks_to_check.each do |cask| +        casks(alternative: -> { Hbc.installed }).each do |cask|            odebug "Checking update info of Cask #{cask}"            self.class.list_if_outdated(cask, greedy?, verbose?)          end diff --git a/Library/Homebrew/cask/lib/hbc/cli/reinstall.rb b/Library/Homebrew/cask/lib/hbc/cli/reinstall.rb index eb5f45c90..337a2eb9d 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/reinstall.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/reinstall.rb @@ -2,28 +2,13 @@ module Hbc    class CLI      class Reinstall < Install        def install_casks -        count = 0 -        args.each do |cask_token| -          begin -            cask = CaskLoader.load(cask_token) - -            Installer.new(cask, -                          binaries:       binaries?, -                          verbose: verbose?, -                          force:          force?, -                          skip_cask_deps: skip_cask_deps?, -                          require_sha:    require_sha?).reinstall - -            count += 1 -          rescue CaskUnavailableError => e -            self.class.warn_unavailable_with_suggestion cask_token, e -          rescue CaskNoShasumError => e -            opoo e.message -            count += 1 -          end +        casks.each do |cask| +          Installer.new(cask, binaries:       binaries?, +                              verbose:        verbose?, +                              force:          force?, +                              skip_cask_deps: skip_cask_deps?, +                              require_sha:    require_sha?).reinstall          end - -        count.zero? ? nil : count == args.length        end        def self.help diff --git a/Library/Homebrew/cask/lib/hbc/cli/search.rb b/Library/Homebrew/cask/lib/hbc/cli/search.rb index b24091aef..9d1a16f15 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/search.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/search.rb @@ -1,10 +1,6 @@  module Hbc    class CLI      class Search < AbstractCommand -      def initialize(*args) -        @args = args -      end -        def run          results = self.class.search(*args)          self.class.render_results(*results) diff --git a/Library/Homebrew/cask/lib/hbc/cli/style.rb b/Library/Homebrew/cask/lib/hbc/cli/style.rb index 97208232b..86fc98eaa 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/style.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/style.rb @@ -1,5 +1,3 @@ -require "English" -  module Hbc    class CLI      class Style < AbstractCommand @@ -33,7 +31,7 @@ module Hbc          elsif args.any? { |file| File.exist?(file) }            args          else -          args.map { |token| CaskLoader.path(token) } +          casks.map(&:sourcefile_path)          end        end diff --git a/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb b/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb index 33ee5afa9..c0697c808 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb @@ -9,9 +9,12 @@ module Hbc        end        def run -        args.each do |cask_token| -          odebug "Uninstalling Cask #{cask_token}" -          cask = CaskLoader.load(cask_token) +        raise CaskError, "Uninstall incomplete." if uninstall_casks == :incomplete +      end + +      def uninstall_casks +        casks.each do |cask| +          odebug "Uninstalling Cask #{cask}"            raise CaskNotInstalledError, cask unless cask.installed? || force? @@ -27,8 +30,8 @@ module Hbc            single = versions.count == 1            puts <<-EOS.undent -            #{cask_token} #{versions.join(", ")} #{single ? "is" : "are"} still installed. -            Remove #{single ? "it" : "them all"} with `brew cask uninstall --force #{cask_token}`. +            #{cask} #{versions.join(", ")} #{single ? "is" : "are"} still installed. +            Remove #{single ? "it" : "them all"} with `brew cask uninstall --force #{cask}`.            EOS          end        end diff --git a/Library/Homebrew/cask/lib/hbc/cli/zap.rb b/Library/Homebrew/cask/lib/hbc/cli/zap.rb index 3c07ff9e8..d12943106 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/zap.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/zap.rb @@ -7,9 +7,12 @@ module Hbc        end        def run -        args.each do |cask_token| -          odebug "Zapping Cask #{cask_token}" -          cask = CaskLoader.load(cask_token) +        raise CaskError, "Zap incomplete." if zap_casks == :incomplete +      end + +      def zap_casks +        casks.each do |cask| +          odebug "Zapping Cask #{cask}"            Installer.new(cask, verbose: verbose?).zap          end        end diff --git a/Library/Homebrew/cask/lib/hbc/exceptions.rb b/Library/Homebrew/cask/lib/hbc/exceptions.rb index b9d305a9b..d9e1b07db 100644 --- a/Library/Homebrew/cask/lib/hbc/exceptions.rb +++ b/Library/Homebrew/cask/lib/hbc/exceptions.rb @@ -3,56 +3,40 @@ module Hbc    class AbstractCaskErrorWithToken < CaskError      attr_reader :token +    attr_reader :reason -    def initialize(token) +    def initialize(token, reason = nil)        @token = token +      @reason = reason.to_s      end    end    class CaskNotInstalledError < AbstractCaskErrorWithToken      def to_s -      "#{token} is not installed" +      "Cask '#{token}' is not installed."      end    end    class CaskUnavailableError < AbstractCaskErrorWithToken      def to_s -      "No available Cask for #{token}" +      "Cask '#{token}' is unavailable" << (reason.empty? ? "." : ": #{reason}")      end    end    class CaskAlreadyCreatedError < AbstractCaskErrorWithToken      def to_s -      %Q(A Cask for #{token} already exists. Run "brew cask cat #{token}" to see it.) +      %Q(Cask '#{token}' already exists. Run #{Formatter.identifier("brew cask cat #{token}")} to edit it.)      end    end    class CaskAlreadyInstalledError < AbstractCaskErrorWithToken      def to_s -      s = <<-EOS.undent -        A Cask for #{token} is already installed. -      EOS - -      s.concat("\n").concat(reinstall_message) -    end - -    private - -    def reinstall_message        <<-EOS.undent -        To re-install #{token}, run: -          brew cask reinstall #{token} -      EOS -    end -  end +        Cask '#{token}' is already installed. -  class CaskAlreadyInstalledAutoUpdatesError < CaskAlreadyInstalledError -    def to_s -      s = <<-EOS.undent -        A Cask for #{token} is already installed and using auto-updates. +        To re-install #{token}, run: +          #{Formatter.identifier("brew cask reinstall #{token}")}        EOS - -      s.concat("\n").concat(reinstall_message)      end    end @@ -84,8 +68,8 @@ module Hbc    class CaskX11DependencyError < AbstractCaskErrorWithToken      def to_s        <<-EOS.undent -        #{token} requires XQuartz/X11, which can be installed using Homebrew-Cask by running -          brew cask install xquartz +        Cask '#{token}' requires XQuartz/X11, which can be installed using Homebrew-Cask by running +          #{Formatter.identifier("brew cask install xquartz")}          or manually, by downloading the package from            #{Formatter.url("https://www.xquartz.org/")} @@ -101,60 +85,67 @@ module Hbc    class CaskUnspecifiedError < CaskError      def to_s -      "This command requires a Cask token" +      "This command requires a Cask token."      end    end    class CaskInvalidError < AbstractCaskErrorWithToken -    attr_reader :submsg -    def initialize(token, *submsg) -      super(token) -      @submsg = submsg.join(" ") -    end -      def to_s -      "Cask '#{token}' definition is invalid#{": #{submsg}" unless submsg.empty?}" +      "Cask '#{token}' definition is invalid" << (reason.empty? ? ".": ": #{reason}")      end    end -  class CaskTokenDoesNotMatchError < CaskInvalidError +  class CaskTokenMismatchError < CaskInvalidError      def initialize(token, header_token) -      super(token, "Bad header line: '#{header_token}' does not match file name") +      super(token, "Token '#{header_token}' in header line does not match the file name.")      end    end -  class CaskSha256MissingError < ArgumentError -  end +  class CaskSha256Error < AbstractCaskErrorWithToken +    attr_reader :expected, :actual -  class CaskSha256MismatchError < RuntimeError -    attr_reader :path, :expected, :actual -    def initialize(path, expected, actual) -      @path = path +    def initialize(token, expected = nil, actual = nil) +      super(token)        @expected = expected        @actual = actual      end +  end +  class CaskSha256MissingError < CaskSha256Error      def to_s        <<-EOS.undent -        sha256 mismatch -        Expected: #{expected} -        Actual: #{actual} -        File: #{path} -        To retry an incomplete download, remove the file above. +        Cask '#{token}' requires a checksum: +          #{Formatter.identifier("sha256 '#{actual}'")}        EOS      end    end -  class CaskNoShasumError < CaskError -    attr_reader :token -    def initialize(token) -      @token = token +  class CaskSha256MismatchError < CaskSha256Error +    attr_reader :path + +    def initialize(token, expected, actual, path) +      super(token, expected, actual) +      @path = path +    end + +    def to_s +      <<-EOS.undent +        Checksum for Cask '#{token}' does not match. + +        Expected: #{Formatter.success(expected.to_s)} +        Actual:   #{Formatter.error(actual.to_s)} +        File:     #{path} + +        To retry an incomplete download, remove the file above. +      EOS      end +  end +  class CaskNoShasumError < CaskSha256Error      def to_s        <<-EOS.undent          Cask '#{token}' does not have a sha256 checksum defined and was not installed. -        This means you have the "--require-sha" option set, perhaps in your HOMEBREW_CASK_OPTS. +        This means you have the #{Formatter.identifier("--require-sha")} option set, perhaps in your HOMEBREW_CASK_OPTS.        EOS      end    end diff --git a/Library/Homebrew/cask/lib/hbc/installer.rb b/Library/Homebrew/cask/lib/hbc/installer.rb index 7da9731e5..aa6d600f7 100644 --- a/Library/Homebrew/cask/lib/hbc/installer.rb +++ b/Library/Homebrew/cask/lib/hbc/installer.rb @@ -94,7 +94,6 @@ module Hbc        odebug "Hbc::Installer#install"        if @cask.installed? && !force? && !@reinstall -        raise CaskAlreadyInstalledAutoUpdatesError, @cask if @cask.auto_updates          raise CaskAlreadyInstalledError, @cask        end @@ -143,7 +142,7 @@ module Hbc      def verify_has_sha        odebug "Checking cask has checksum"        return unless @cask.sha256 == :no_check -      raise CaskNoShasumError, @cask +      raise CaskNoShasumError, @cask.token      end      def verify diff --git a/Library/Homebrew/cask/lib/hbc/scopes.rb b/Library/Homebrew/cask/lib/hbc/scopes.rb index 149c2c343..a469ae0fa 100644 --- a/Library/Homebrew/cask/lib/hbc/scopes.rb +++ b/Library/Homebrew/cask/lib/hbc/scopes.rb @@ -27,6 +27,7 @@ module Hbc          # TODO: speed up Hbc::Source::Tapped (main perf drag is calling Hbc.all_tokens repeatedly)          # TODO: ability to specify expected source when calling CaskLoader.load (minor perf benefit)          Pathname.glob(caskroom.join("*")) +                .sort                  .map do |caskroom_path|                    token = caskroom_path.basename.to_s diff --git a/Library/Homebrew/cask/lib/hbc/verify/checksum.rb b/Library/Homebrew/cask/lib/hbc/verify/checksum.rb index d079a4446..620703d31 100644 --- a/Library/Homebrew/cask/lib/hbc/verify/checksum.rb +++ b/Library/Homebrew/cask/lib/hbc/verify/checksum.rb @@ -33,13 +33,13 @@ module Hbc        end        def verify_checksum -        raise CaskSha256MissingError, "sha256 required: sha256 '#{computed}'" if expected.nil? || expected.empty? +        raise CaskSha256MissingError.new(cask.token, expected, computed) if expected.nil? || expected.empty?          if expected == computed            odebug "SHA256 checksums match"          else            ohai 'Note: running "brew update" may fix sha256 checksum errors' -          raise CaskSha256MismatchError.new(downloaded_path, expected, computed) +          raise CaskSha256MismatchError.new(cask.token, expected, computed, downloaded_path)          end        end      end | 
