diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index 540a06feac80cf22270cbfb988b0cd9aa320fc57..f7fbf0ac0f1ceb232376ffa0ef3c6af461c7a8e0 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -21,10 +21,13 @@ jobs:
           persist-credentials: false
       - name: Fetch origin/master from Git
         run: git fetch origin master
+
       - name: Build Docker image
         run: docker build -t brew --build-arg=version=${{matrix.version}} .
+
       - name: Run brew test-bot --only-setup
         run: docker run --rm brew brew test-bot --only-setup
+
       - name: Deploy the tagged Docker image to GitHub
         if: startsWith(github.ref, 'refs/tags/')
         run: |
@@ -35,6 +38,7 @@ jobs:
           docker push "docker.pkg.github.com/homebrew/brew/ubuntu${{matrix.version}}:$brew_version"
           docker tag brew "docker.pkg.github.com/homebrew/brew/ubuntu${{matrix.version}}:latest"
           docker push "docker.pkg.github.com/homebrew/brew/ubuntu${{matrix.version}}:latest"
+
       - name: Deploy the tagged Docker image to Docker Hub
         if: startsWith(github.ref, 'refs/tags/')
         run: |
@@ -43,6 +47,7 @@ jobs:
           docker push "homebrew/ubuntu${{matrix.version}}:$brew_version"
           docker tag brew "homebrew/ubuntu${{matrix.version}}:latest"
           docker push "homebrew/ubuntu${{matrix.version}}:latest"
+
       - name: Deploy the homebrew/brew Docker image to GitHub and Docker Hub
         if: startsWith(github.ref, 'refs/tags/') && matrix.version == '20.04'
         run: |
diff --git a/.github/workflows/doctor.yml b/.github/workflows/doctor.yml
index d99a1d52605c1421d9452ceaa38b3ffd6fe0d166..757a558d1fad0f9ef3e42b1f9fdaaca93315a39e 100644
--- a/.github/workflows/doctor.yml
+++ b/.github/workflows/doctor.yml
@@ -25,12 +25,9 @@ jobs:
         id: set-up-homebrew
         uses: Homebrew/actions/setup-homebrew@master
 
-      - name: Run brew test-bot --only-cleanup-before
-        run: brew test-bot --only-cleanup-before
+      - run: brew test-bot --only-cleanup-before
 
-      - name: Run brew test-bot --only-setup
-        run: brew test-bot --only-setup
+      - run: brew test-bot --only-setup
 
-      - name: Run brew test-bot --only-cleanup-after
+      - run: brew test-bot --only-cleanup-after
         if: always()
-        run: brew test-bot --only-cleanup-after
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index b595877acf8c68ede8a3a3b6e0af9a55802ab14e..dffdbb2675653f43aa575725fe8f98a5756300b1 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -2,7 +2,7 @@ name: GitHub Actions CI
 on:
   push:
     branches: master
-  pull_request: []
+  pull_request:
 env:
   HOMEBREW_DEVELOPER: 1
   HOMEBREW_NO_AUTO_UPDATE: 1
@@ -36,7 +36,7 @@ jobs:
 
     - name: Cache Bundler RubyGems
       id: cache
-      uses: actions/cache@main
+      uses: actions/cache@v1
       with:
         path: ${{ steps.set-up-homebrew.outputs.gems-path }}
         key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
diff --git a/Library/Homebrew/Gemfile.lock b/Library/Homebrew/Gemfile.lock
index 0d01fc7f5af712d66e13ade17c27429bdd57cdc0..6ac6cff31a52a0183bc42e933855ae6eced53862 100644
--- a/Library/Homebrew/Gemfile.lock
+++ b/Library/Homebrew/Gemfile.lock
@@ -120,10 +120,10 @@ GEM
       docile (~> 1.1)
       simplecov-html (~> 0.11)
     simplecov-html (0.12.2)
-    sorbet (0.5.5866)
-      sorbet-static (= 0.5.5866)
-    sorbet-runtime (0.5.5866)
-    sorbet-static (0.5.5866-universal-darwin-14)
+    sorbet (0.5.5869)
+      sorbet-static (= 0.5.5869)
+    sorbet-runtime (0.5.5869)
+    sorbet-static (0.5.5869-universal-darwin-14)
     tapioca (0.4.1)
       parlour (>= 2.1.0)
       pry (>= 0.12.2)
diff --git a/Library/Homebrew/cask/auditor.rb b/Library/Homebrew/cask/auditor.rb
index 91c7c88c279a808d8a84807117057a2ffcb01ad1..cc31909c8f3d09e928af16f36039f633c9c52db3 100644
--- a/Library/Homebrew/cask/auditor.rb
+++ b/Library/Homebrew/cask/auditor.rb
@@ -9,22 +9,22 @@ module Cask
     def self.audit(cask, audit_download: false, audit_appcast: false,
                    audit_online: false, audit_strict: false,
                    audit_token_conflicts: false, audit_new_cask: false,
-                   quarantine: true, commit_range: nil)
+                   quarantine: true, commit_range: nil, language: nil)
       new(cask, audit_download: audit_download,
                 audit_appcast: audit_appcast,
                 audit_online: audit_online,
                 audit_new_cask: audit_new_cask,
                 audit_strict: audit_strict,
                 audit_token_conflicts: audit_token_conflicts,
-                quarantine: quarantine, commit_range: commit_range).audit
+                quarantine: quarantine, commit_range: commit_range, language: language).audit
     end
 
-    attr_reader :cask, :commit_range
+    attr_reader :cask, :commit_range, :language
 
     def initialize(cask, audit_download: false, audit_appcast: false,
                    audit_online: false, audit_strict: false,
                    audit_token_conflicts: false, audit_new_cask: false,
-                   quarantine: true, commit_range: nil)
+                   quarantine: true, commit_range: nil, language: nil)
       @cask = cask
       @audit_download = audit_download
       @audit_appcast = audit_appcast
@@ -34,6 +34,7 @@ module Cask
       @quarantine = quarantine
       @commit_range = commit_range
       @audit_token_conflicts = audit_token_conflicts
+      @language = language
     end
 
     attr_predicate :audit_appcast?, :audit_download?, :audit_online?,
@@ -43,7 +44,7 @@ module Cask
       warnings = Set.new
       errors = Set.new
 
-      if !Homebrew.args.value("language") && language_blocks
+      if !language && language_blocks
         language_blocks.each_key do |l|
           audit = audit_languages(l)
           puts audit.summary
diff --git a/Library/Homebrew/cask/cmd.rb b/Library/Homebrew/cask/cmd.rb
index b3d4b5e33af2e236da9b800ed4f00aca92897ace..1ce1cb3f2b05aa509589c42ce5d56fd8c0d66407 100644
--- a/Library/Homebrew/cask/cmd.rb
+++ b/Library/Homebrew/cask/cmd.rb
@@ -3,12 +3,11 @@
 require "optparse"
 require "shellwords"
 
+require "cli/parser"
 require "extend/optparse"
 
 require "cask/config"
 
-require "cask/cmd/options"
-
 require "cask/cmd/abstract_command"
 require "cask/cmd/--cache"
 require "cask/cmd/audit"
@@ -48,33 +47,87 @@ module Cask
       "dr"       => "doctor",
     }.freeze
 
-    include Options
-
-    option "--appdir=PATH",               ->(value) { Config.global.appdir               = value }
-    option "--colorpickerdir=PATH",       ->(value) { Config.global.colorpickerdir       = value }
-    option "--prefpanedir=PATH",          ->(value) { Config.global.prefpanedir          = value }
-    option "--qlplugindir=PATH",          ->(value) { Config.global.qlplugindir          = value }
-    option "--mdimporterdir=PATH",        ->(value) { Config.global.mdimporterdir        = value }
-    option "--dictionarydir=PATH",        ->(value) { Config.global.dictionarydir        = value }
-    option "--fontdir=PATH",              ->(value) { Config.global.fontdir              = value }
-    option "--servicedir=PATH",           ->(value) { Config.global.servicedir           = value }
-    option "--input_methoddir=PATH",      ->(value) { Config.global.input_methoddir      = value }
-    option "--internet_plugindir=PATH",   ->(value) { Config.global.internet_plugindir   = value }
-    option "--audio_unit_plugindir=PATH", ->(value) { Config.global.audio_unit_plugindir = value }
-    option "--vst_plugindir=PATH",        ->(value) { Config.global.vst_plugindir        = value }
-    option "--vst3_plugindir=PATH",       ->(value) { Config.global.vst3_plugindir       = value }
-    option "--screen_saverdir=PATH",      ->(value) { Config.global.screen_saverdir      = value }
+    def self.description
+      max_command_len = Cmd.commands.map(&:length).max
+
+      <<~EOS +
+        Homebrew Cask provides a friendly CLI workflow for the administration of macOS applications distributed as binaries.
+
+        Commands:
+      EOS
+        Cmd.command_classes
+           .select(&:visible?)
+           .map do |klass|
+             "  - #{"`#{klass.command_name}`".ljust(max_command_len + 2)}  #{klass.short_description}\n"
+           end
+           .join +
+        "\nSee also: `man brew`"
+    end
 
-    option "--help", :help, false
+    def self.parser(&block)
+      Homebrew::CLI::Parser.new do
+        if block_given?
+          instance_eval(&block)
+        else
+          usage_banner <<~EOS
+            `cask` <command> [<options>] [<cask>]
 
-    option "--language=a,b,c", ->(value) { Config.global.languages = value }
+            #{Cmd.description}
+          EOS
+        end
 
-    # override default handling of --version
-    option "--version", ->(*) { raise OptionParser::InvalidOption }
+        flag "--appdir=",
+             description: "Target location for Applications. " \
+                          "Default: `#{Config::DEFAULT_DIRS[:appdir]}`"
+        flag "--colorpickerdir=",
+             description: "Target location for Color Pickers. " \
+                          "Default: `#{Config::DEFAULT_DIRS[:colorpickerdir]}`"
+        flag "--prefpanedir=",
+             description: "Target location for Preference Panes. " \
+                          "Default: `#{Config::DEFAULT_DIRS[:prefpanedir]}`"
+        flag "--qlplugindir=",
+             description: "Target location for QuickLook Plugins. " \
+                          "Default: `#{Config::DEFAULT_DIRS[:qlplugindir]}`"
+        flag "--mdimporterdir=",
+             description: "Target location for Spotlight Plugins. " \
+                          "Default: `#{Config::DEFAULT_DIRS[:mdimporterdir]}`"
+        flag "--dictionarydir=",
+             description: "Target location for Dictionaries. " \
+                          "Default: `#{Config::DEFAULT_DIRS[:dictionarydir]}`"
+        flag "--fontdir=",
+             description: "Target location for Fonts. " \
+                          "Default: `#{Config::DEFAULT_DIRS[:fontdir]}`"
+        flag "--servicedir=",
+             description: "Target location for Services. " \
+                          "Default: `#{Config::DEFAULT_DIRS[:servicedir]}`"
+        flag "--input_methoddir=",
+             description: "Target location for Input Methods. " \
+                          "Default: `#{Config::DEFAULT_DIRS[:input_methoddir]}`"
+        flag "--internet_plugindir=",
+             description: "Target location for Internet Plugins. " \
+                          "Default: `#{Config::DEFAULT_DIRS[:internet_plugindir]}`"
+        flag "--audio_unit_plugindir=",
+             description: "Target location for Audio Unit Plugins. " \
+                          "Default: `#{Config::DEFAULT_DIRS[:audio_unit_plugindir]}`"
+        flag "--vst_plugindir=",
+             description: "Target location for VST Plugins. " \
+                          "Default: `#{Config::DEFAULT_DIRS[:vst_plugindir]}`"
+        flag "--vst3_plugindir=",
+             description: "Target location for VST3 Plugins. " \
+                          "Default: `#{Config::DEFAULT_DIRS[:vst3_plugindir]}`"
+        flag "--screen_saverdir=",
+             description: "Target location for Screen Savers. " \
+                          "Default: `#{Config::DEFAULT_DIRS[:screen_saverdir]}`"
+        comma_array "--language",
+                    description: "Set language of the Cask to install. The first matching " \
+                                 "language is used, otherwise the default language on the Cask. " \
+                                 "The default value is the `language of your system`"
+      end
+    end
 
     def self.command_classes
       @command_classes ||= constants.map(&method(:const_get))
-                                    .select { |klass| klass.respond_to?(:run) }
+                                    .select { |klass| klass.is_a?(Class) && klass < AbstractCommand }
                                     .reject(&:abstract?)
                                     .sort_by(&:command_name)
     end
@@ -98,7 +151,7 @@ module Cask
     end
 
     def initialize(*args)
-      @args = process_options(*args)
+      @argv = args
     end
 
     def find_external_command(command)
@@ -143,83 +196,31 @@ module Cask
     end
 
     def run
-      MacOS.full_version = ENV["MACOS_VERSION"] unless ENV["MACOS_VERSION"].nil?
-      Tap.default_cask_tap.install unless Tap.default_cask_tap.installed?
-
-      args = @args.dup
-      command, args = detect_internal_command(*args) || detect_external_command(*args) || [NullCommand.new, args]
-
-      if help?
-        Help.new(command.command_name).run
-      else
-        command.run(*args)
-      end
-    rescue CaskError, MethodDeprecatedError, ArgumentError, OptionParser::InvalidOption => e
-      onoe e.message
-      $stderr.puts e.backtrace if debug?
-      exit 1
-    rescue StandardError, ScriptError, NoMemoryError => e
-      onoe e.message
-      $stderr.puts Utils.error_message_with_suggestions
-      $stderr.puts e.backtrace
-      exit 1
-    end
-
-    def self.nice_listing(cask_list)
-      cask_taps = {}
-      cask_list.each do |c|
-        user, repo, token = c.split "/"
-        repo.sub!(/^homebrew-/i, "")
-        cask_taps[token] ||= []
-        cask_taps[token].push "#{user}/#{repo}"
-      end
-      list = []
-      cask_taps.each do |token, taps|
-        if taps.length == 1
-          list.push token
-        else
-          taps.each { |r| list.push [r, token].join "/" }
-        end
-      end
-      list.sort
-    end
+      argv = @argv
 
-    def process_options(*args)
-      non_options = []
+      args = self.class.parser.parse(argv, ignore_invalid_options: true)
 
-      if idx = args.index("--")
-        non_options += args.drop(idx)
-        args = args.first(idx)
+      Config::DEFAULT_DIRS.each_key do |name|
+        Config.global.public_send(:"#{name}=", args[name]) if args[name]
       end
 
-      exclude_regex = /^--#{Regexp.union(*Config::DEFAULT_DIRS.keys.map(&Regexp.public_method(:escape)))}=/
-      cask_opts = Shellwords.shellsplit(ENV.fetch("HOMEBREW_CASK_OPTS", ""))
-                            .reject { |arg| arg.match?(exclude_regex) }
-
-      all_args = cask_opts + args
-
-      i = 0
-      remaining = []
+      Config.global.languages = args.language if args.language
 
-      while i < all_args.count
-        begin
-          arg = all_args[i]
-
-          remaining << arg unless process_arguments([arg]).empty?
-        rescue OptionParser::MissingArgument
-          raise if i + 1 >= all_args.count
+      Tap.default_cask_tap.install unless Tap.default_cask_tap.installed?
 
-          args = all_args[i..(i + 1)]
-          process_arguments(args)
-          i += 1
-        rescue OptionParser::InvalidOption
-          remaining << arg
-        end
+      command, argv = detect_internal_command(*argv) ||
+                      detect_external_command(*argv) ||
+                      [args.remaining.empty? ? NullCommand : UnknownSubcommand.new(args.remaining.first), argv]
 
-        i += 1
+      if args.help?
+        puts command.help
+      else
+        command.run(*argv)
       end
-
-      remaining + non_options
+    rescue CaskError, MethodDeprecatedError, ArgumentError => e
+      onoe e.message
+      $stderr.puts e.backtrace if args.debug?
+      exit 1
     end
 
     class ExternalRubyCommand
@@ -229,15 +230,25 @@ module Cask
       end
 
       def run(*args)
+        command_class&.run(*args)
+      end
+
+      def help
+        command_class&.help
+      end
+
+      private
+
+      def command_class
+        return @command_class if defined?(@command_class)
+
         require @path
 
-        klass = begin
+        @command_class = begin
           Cmd.const_get(@command_name)
         rescue NameError
-          return
+          nil
         end
-
-        klass.run(*args)
       end
     end
 
@@ -246,26 +257,37 @@ module Cask
         @path = path
       end
 
-      def run(*)
-        exec @path, *ARGV[1..]
+      def run(*argv)
+        exec @path, *argv
+      end
+
+      def help
+        exec @path, "--help"
       end
     end
 
-    class NullCommand
-      def run(*args)
-        if args.empty?
-          ofail "No subcommand given.\n"
-        else
-          ofail "Unknown subcommand: #{args.first}"
-        end
+    class UnknownSubcommand
+      def initialize(command_name)
+        @command_name = command_name
+      end
 
-        $stderr.puts
-        $stderr.puts Help.usage
+      def run(*)
+        raise UsageError, "Subcommand `#{@command_name}` does not exist."
       end
 
       def help
         run
       end
     end
+
+    class NullCommand
+      def self.run(*)
+        raise UsageError, "No subcommand given."
+      end
+
+      def self.help
+        Cmd.parser.generate_help_text
+      end
+    end
   end
 end
diff --git a/Library/Homebrew/cask/cmd/--cache.rb b/Library/Homebrew/cask/cmd/--cache.rb
index 7aa96ec33fd0c7b58d52ddecf52bdd5ae230747a..54aebf6c98762d42dfb29d6628f04695ec4d409c 100644
--- a/Library/Homebrew/cask/cmd/--cache.rb
+++ b/Library/Homebrew/cask/cmd/--cache.rb
@@ -5,13 +5,16 @@ require "cask/download"
 module Cask
   class Cmd
     class Cache < AbstractCommand
-      def self.command_name
-        "--cache"
+      def self.min_named
+        :cask
+      end
+
+      def self.description
+        "Display the file used to cache a <cask>."
       end
 
-      def initialize(*)
-        super
-        raise CaskUnspecifiedError if args.empty?
+      def self.command_name
+        "--cache"
       end
 
       def run
@@ -23,10 +26,6 @@ module Cask
       def self.cached_location(cask)
         Download.new(cask).downloader.cached_location
       end
-
-      def self.help
-        "display the file used to cache the Cask"
-      end
     end
   end
 end
diff --git a/Library/Homebrew/cask/cmd/abstract_command.rb b/Library/Homebrew/cask/cmd/abstract_command.rb
index 1646ddb9430e1682dcb7f5666157f530d2a148f2..2b768e69c21fd89a603e0ab5a4534ef24be56d54 100644
--- a/Library/Homebrew/cask/cmd/abstract_command.rb
+++ b/Library/Homebrew/cask/cmd/abstract_command.rb
@@ -1,20 +1,66 @@
 # frozen_string_literal: true
 
-require_relative "options"
 require "search"
 
 module Cask
   class Cmd
     class AbstractCommand
-      include Options
       include Homebrew::Search
 
-      option "--[no-]binaries",   :binaries,      true
-      option "--debug",           :debug,         false
-      option "--verbose",         :verbose,       false
-      option "--outdated",        :outdated_only, false
-      option "--require-sha",     :require_sha,   false
-      option "--[no-]quarantine", :quarantine,    true
+      def self.min_named
+        nil
+      end
+
+      def self.max_named
+        nil
+      end
+
+      def self.banner_args
+        if min_named == :cask && max_named != 1
+          " <cask>"
+        elsif max_named&.zero?
+          ""
+        else
+          " [<cask>]"
+        end
+      end
+
+      def self.banner_headline
+        "`#{command_name}` [<options>]#{banner_args}"
+      end
+
+      def self.parser(&block)
+        banner = <<~EOS
+          `cask` #{banner_headline}
+
+          #{description}
+        EOS
+
+        min_n = min_named
+        max_n = max_named
+
+        Cmd.parser do
+          usage_banner banner
+
+          instance_eval(&block) if block_given?
+
+          switch "--[no-]binaries",
+                 description: "Disable/enable linking of helper executables to `#{Config.global.binarydir}`. " \
+                              "Default: enabled",
+                 env:         :cask_opts_binaries
+
+          switch "--require-sha",
+                 description: "Require all casks to have a checksum.",
+                 env:         :cask_opts_require_sha
+
+          switch "--[no-]quarantine",
+                 description: "Disable/enable quarantining of downloads. Default: enabled",
+                 env:         :cask_opts_quarantine
+
+          min_named min_n unless min_n.nil?
+          max_named max_n unless max_n.nil?
+        end
+      end
 
       def self.command_name
         @command_name ||= name.sub(/^.*:/, "").gsub(/(.)([A-Z])/, '\1_\2').downcase
@@ -29,19 +75,21 @@ module Cask
       end
 
       def self.help
-        nil
+        parser.generate_help_text
+      end
+
+      def self.short_description
+        description.split(".").first
       end
 
       def self.run(*args)
         new(*args).run
       end
 
-      attr_accessor :args
-
-      private :args=
+      attr_reader :args
 
       def initialize(*args)
-        @args = process_arguments(*args)
+        @args = self.class.parser.parse(args)
       end
 
       private
@@ -49,7 +97,7 @@ module Cask
       def casks(alternative: -> { [] })
         return @casks if defined?(@casks)
 
-        casks = args.empty? ? alternative.call : args
+        casks = args.named.empty? ? alternative.call : args.named
         @casks = casks.map { |cask| CaskLoader.load(cask) }
       rescue CaskUnavailableError => e
         reason = [e.reason, *suggestion_message(e.token)].join(" ")
diff --git a/Library/Homebrew/cask/cmd/audit.rb b/Library/Homebrew/cask/cmd/audit.rb
index fbc16e3bb238e3bf1f329073347a4ef347a6c098..612aeb370ff65d5b7837bcab31a99ec38a704e85 100644
--- a/Library/Homebrew/cask/cmd/audit.rb
+++ b/Library/Homebrew/cask/cmd/audit.rb
@@ -6,56 +6,56 @@ require "cask/auditor"
 module Cask
   class Cmd
     class Audit < AbstractCommand
-      option "--download",        :download_arg,        false
-      option "--appcast",         :appcast_arg,         false
-      option "--token-conflicts", :token_conflicts_arg, false
-      option "--strict",          :strict_arg,          false
-      option "--online",          :online_arg,          false
-      option "--new-cask",        :new_cask_arg,        false
-
-      def self.usage
+      def self.description
         <<~EOS
-          `cask audit` [<options>] [<cask>]
-
-          --strict          - Run additional, stricter style checks.
-          --online          - Run additional, slower style checks that require a network connection.
-          --new-cask        - Run various additional style checks to determine if a new cask is eligible
-                              for Homebrew. This should be used when creating new casks and implies
-                              `--strict` and `--online`.
-          --download        - Audit the downloaded file
-          --appcast         - Audit the appcast
-          --token-conflicts - Audit for token conflicts
-
           Check <cask> for Homebrew coding style violations. This should be run before
-          submitting a new cask. If no <casks> are provided, check all locally
+          submitting a new cask. If no <cask> is provided, checks all locally
           available casks. Will exit with a non-zero status if any errors are
           found, which can be useful for implementing pre-commit hooks.
         EOS
       end
 
-      def self.help
-        "verifies installability of Casks"
+      def self.parser
+        super do
+          switch "--download",
+                 description: "Audit the downloaded file"
+          switch "--appcast",
+                 description: "Audit the appcast"
+          switch "--token-conflicts",
+                 description: "Audit for token conflicts"
+          switch "--strict",
+                 description: "Run additional, stricter style checks"
+          switch "--online",
+                 description: "Run additional, slower style checks that require a network connection"
+          switch "--new-cask",
+                 description: "Run various additional style checks to determine if a new cask is eligible
+                               for Homebrew. This should be used when creating new casks and implies
+                               `--strict` and `--online`"
+        end
       end
 
       def run
         Homebrew.auditing = true
-        strict = new_cask_arg? || strict_arg?
-        token_conflicts = strict || token_conflicts_arg?
+        strict = args.new_cask? || args.strict?
+        online = args.new_cask? || args.online?
+
+        options = {
+          audit_download:        online || args.download?,
+          audit_appcast:         online || args.appcast?,
+          audit_online:          online,
+          audit_strict:          strict,
+          audit_new_cask:        args.new_cask?,
+          audit_token_conflicts: strict || args.token_conflicts?,
+          quarantine:            args.quarantine?,
+          language:              args.language,
+        }.compact
 
-        online = new_cask_arg? || online_arg?
-        download = online || download_arg?
-        appcast = online || appcast_arg?
+        options[:quarantine] = true if options[:quarantine].nil?
 
         failed_casks = casks(alternative: -> { Cask.to_a })
                        .reject do |cask|
           odebug "Auditing Cask #{cask}"
-          result = Auditor.audit(cask, audit_download:        download,
-                                       audit_appcast:         appcast,
-                                       audit_online:          online,
-                                       audit_strict:          strict,
-                                       audit_new_cask:        new_cask_arg?,
-                                       audit_token_conflicts: token_conflicts,
-                                       quarantine:            quarantine?)
+          result = Auditor.audit(cask, **options)
 
           result[:warnings].empty? && result[:errors].empty?
         end
diff --git a/Library/Homebrew/cask/cmd/cat.rb b/Library/Homebrew/cask/cmd/cat.rb
index 47552a8a21b4080f2dd2bd73d40ac1071c07f6d1..a75158ae305c6a6169836c7384b197c3b967ce3d 100644
--- a/Library/Homebrew/cask/cmd/cat.rb
+++ b/Library/Homebrew/cask/cmd/cat.rb
@@ -3,9 +3,12 @@
 module Cask
   class Cmd
     class Cat < AbstractCommand
-      def initialize(*)
-        super
-        raise CaskUnspecifiedError if args.empty?
+      def self.min_named
+        :cask
+      end
+
+      def self.description
+        "Dump raw source of a <cask> to the standard output."
       end
 
       def run
@@ -18,10 +21,6 @@ module Cask
           end
         end
       end
-
-      def self.help
-        "dump raw source of the given Cask to the standard output"
-      end
     end
   end
 end
diff --git a/Library/Homebrew/cask/cmd/create.rb b/Library/Homebrew/cask/cmd/create.rb
index 0c9e44ed42297c31343ea6a210ae0950fa820ba5..099b5fd737ae44e3bd3eb5341a56f08cb0f9c71c 100644
--- a/Library/Homebrew/cask/cmd/create.rb
+++ b/Library/Homebrew/cask/cmd/create.rb
@@ -3,14 +3,26 @@
 module Cask
   class Cmd
     class Create < AbstractCommand
+      def self.min_named
+        :cask
+      end
+
+      def self.max_named
+        1
+      end
+
+      def self.description
+        "Creates the given <cask> and opens it in an editor."
+      end
+
       def initialize(*)
         super
-        raise CaskUnspecifiedError if args.empty?
-        raise ArgumentError, "Only one Cask can be created at a time." if args.count > 1
+      rescue Homebrew::CLI::MaxNamedArgumentsError
+        raise UsageError, "Only one cask can be created at a time."
       end
 
       def run
-        cask_token = args.first
+        cask_token = args.named.first
         cask_path = CaskLoader.path(cask_token)
         raise CaskAlreadyCreatedError, cask_token if cask_path.exist?
 
@@ -37,10 +49,6 @@ module Cask
           end
         RUBY
       end
-
-      def self.help
-        "creates the given Cask and opens it in an editor"
-      end
     end
   end
 end
diff --git a/Library/Homebrew/cask/cmd/doctor.rb b/Library/Homebrew/cask/cmd/doctor.rb
index 3ddc83ff51f99bf83e64143929d07313f2c8b0dd..c283724a733736edc183f34b699571e57ebac2b3 100644
--- a/Library/Homebrew/cask/cmd/doctor.rb
+++ b/Library/Homebrew/cask/cmd/doctor.rb
@@ -6,15 +6,12 @@ require "diagnostic"
 module Cask
   class Cmd
     class Doctor < AbstractCommand
-      def initialize(*)
-        super
-        return if args.empty?
-
-        raise ArgumentError, "#{self.class.command_name} does not take arguments."
+      def self.max_named
+        0
       end
 
-      def summary_header
-        "Cask's Doctor Checkup"
+      def self.description
+        "Checks for configuration issues."
       end
 
       def run
@@ -32,10 +29,6 @@ module Cask
 
         raise CaskError, "There are some problems with your setup." unless success
       end
-
-      def self.help
-        "checks for configuration issues"
-      end
     end
   end
 end
diff --git a/Library/Homebrew/cask/cmd/edit.rb b/Library/Homebrew/cask/cmd/edit.rb
index ff5f7569c29900c87cdcb21240c4471c0b6abab8..94798b786f171e843d62d47ddb74842e6c15a04f 100644
--- a/Library/Homebrew/cask/cmd/edit.rb
+++ b/Library/Homebrew/cask/cmd/edit.rb
@@ -3,10 +3,22 @@
 module Cask
   class Cmd
     class Edit < AbstractCommand
+      def self.min_named
+        :cask
+      end
+
+      def self.max_named
+        1
+      end
+
+      def self.description
+        "Open the given <cask> for editing."
+      end
+
       def initialize(*)
         super
-        raise CaskUnspecifiedError if args.empty?
-        raise ArgumentError, "Only one Cask can be edited at a time." if args.count > 1
+      rescue Homebrew::CLI::MaxNamedArgumentsError
+        raise UsageError, "Only one cask can be edited at a time."
       end
 
       def run
@@ -25,10 +37,6 @@ module Cask
 
         raise
       end
-
-      def self.help
-        "edits the given Cask"
-      end
     end
   end
 end
diff --git a/Library/Homebrew/cask/cmd/fetch.rb b/Library/Homebrew/cask/cmd/fetch.rb
index cebf3d8d894df196f8633a676327c638d8f4f484..4715087a957a9a084f4f9e7e7f3c3d579b119e72 100644
--- a/Library/Homebrew/cask/cmd/fetch.rb
+++ b/Library/Homebrew/cask/cmd/fetch.rb
@@ -5,26 +5,37 @@ require "cask/download"
 module Cask
   class Cmd
     class Fetch < AbstractCommand
-      option "--force", :force, false
+      def self.min_named
+        :cask
+      end
+
+      def self.parser
+        super do
+          switch "--force",
+                 description: "Force redownloading even if files already exist in local cache."
+        end
+      end
 
-      def initialize(*)
-        super
-        raise CaskUnspecifiedError if args.empty?
+      def self.description
+        "Downloads remote application files to local cache."
       end
 
       def run
+        options = {
+          force:      args.force?,
+          quarantine: args.quarantine?,
+        }.compact
+
+        options[:quarantine] = true if options[:quarantine].nil?
+
         casks.each do |cask|
           puts Installer.caveats(cask)
           ohai "Downloading external files for Cask #{cask}"
-          downloaded_path = Download.new(cask, force: force?, quarantine: quarantine?).perform
+          downloaded_path = Download.new(cask, **options).perform
           Verify.all(cask, downloaded_path)
           ohai "Success! Downloaded to -> #{downloaded_path}"
         end
       end
-
-      def self.help
-        "downloads remote application files to local cache"
-      end
     end
   end
 end
diff --git a/Library/Homebrew/cask/cmd/help.rb b/Library/Homebrew/cask/cmd/help.rb
index 28db5331b70b03dc9160f1ebb76eee5ef107d550..bef0e9b0ce15cf2c5081562bb048d787b72aa5cc 100644
--- a/Library/Homebrew/cask/cmd/help.rb
+++ b/Library/Homebrew/cask/cmd/help.rb
@@ -3,53 +3,31 @@
 module Cask
   class Cmd
     class Help < AbstractCommand
+      def self.max_named
+        1
+      end
+
+      def self.description
+        "Print help for `cask` commands."
+      end
+
       def run
-        if args.empty?
-          puts self.class.purpose
-          puts
-          puts self.class.usage
-        elsif args.count == 1
-          command_name = args.first
+        if args.named.empty?
+          puts Cmd.parser.generate_help_text
+        else
+          command_name = args.named.first
 
           unless command = self.class.commands[command_name]
             raise "No help information found for command '#{command_name}'."
           end
 
-          if command.respond_to?(:usage)
-            puts command.usage
-          else
-            puts command.help
-          end
-        else
-          raise ArgumentError, "#{self.class.command_name} only takes up to one argument."
+          puts command.help
         end
       end
 
-      def self.purpose
-        <<~EOS
-          Homebrew Cask provides a friendly CLI workflow for the administration
-          of macOS applications distributed as binaries.
-        EOS
-      end
-
       def self.commands
         Cmd.command_classes.select(&:visible?).map { |klass| [klass.command_name, klass] }.to_h
       end
-
-      def self.usage
-        max_command_len = Cmd.commands.map(&:length).max
-
-        "Commands:\n" +
-          Cmd.command_classes
-             .select(&:visible?)
-             .map { |klass| "    #{klass.command_name.ljust(max_command_len)}  #{klass.help}\n" }
-             .join +
-          %Q(\nSee also "man brew-cask")
-      end
-
-      def self.help
-        "print help strings for commands"
-      end
     end
   end
 end
diff --git a/Library/Homebrew/cask/cmd/home.rb b/Library/Homebrew/cask/cmd/home.rb
index 16adc13a5d22a5a6b87ad8af19c4529d78cadb77..7774ed6544239507d11fac8fefd5a9a1f7cbf2e0 100644
--- a/Library/Homebrew/cask/cmd/home.rb
+++ b/Library/Homebrew/cask/cmd/home.rb
@@ -3,7 +3,13 @@
 module Cask
   class Cmd
     class Home < AbstractCommand
+      def self.description
+        "Opens the homepage of the given <cask>. If no cask is given, opens the Homebrew homepage."
+      end
+
       def run
+        # odeprecated "brew cask home", "brew home"
+
         if casks.none?
           odebug "Opening project homepage"
           self.class.open_url "https://brew.sh/"
@@ -18,10 +24,6 @@ module Cask
       def self.open_url(url)
         SystemCommand.run!(OS::PATH_OPEN, args: ["--", url])
       end
-
-      def self.help
-        "opens the homepage of the given Cask"
-      end
     end
   end
 end
diff --git a/Library/Homebrew/cask/cmd/info.rb b/Library/Homebrew/cask/cmd/info.rb
index 49806cd131f13a98e107e4aad0b68418648eabbd..11efcf29761d5c40122e50cb67b30266cdfc8e15 100644
--- a/Library/Homebrew/cask/cmd/info.rb
+++ b/Library/Homebrew/cask/cmd/info.rb
@@ -6,15 +6,23 @@ require "cask/installer"
 module Cask
   class Cmd
     class Info < AbstractCommand
-      option "--json=VERSION", :json
+      def self.min_named
+        :cask
+      end
 
-      def initialize(*)
-        super
-        raise CaskUnspecifiedError if args.empty?
+      def self.description
+        "Displays information about the given <cask>."
+      end
+
+      def self.parser
+        super do
+          flag "--json=",
+               description: "Output information in JSON format."
+        end
       end
 
       def run
-        if json == "v1"
+        if args.json == "v1"
           puts JSON.generate(casks.map(&:to_h))
         else
           casks.each_with_index do |cask, i|
@@ -25,10 +33,6 @@ module Cask
         end
       end
 
-      def self.help
-        "displays information about the given Cask"
-      end
-
       def self.get_info(cask)
         output = title_info(cask) + "\n"
         output << Formatter.url(cask.homepage) + "\n" if cask.homepage
@@ -36,6 +40,7 @@ module Cask
         repo = repo_info(cask)
         output << repo + "\n" if repo
         output << name_info(cask)
+        output << desc_info(cask)
         language = language_info(cask)
         output << language if language
         output << artifact_info(cask) + "\n"
@@ -82,6 +87,13 @@ module Cask
         EOS
       end
 
+      def self.desc_info(cask)
+        <<~EOS
+          #{ohai_title("Description")}
+          #{cask.desc.nil? ? Formatter.error("None") : cask.desc}
+        EOS
+      end
+
       def self.language_info(cask)
         return if cask.languages.empty?
 
diff --git a/Library/Homebrew/cask/cmd/install.rb b/Library/Homebrew/cask/cmd/install.rb
index 5c82efc12b218e1c67125a038c95d9eac41c0cd2..da74e0958dcb80bc4c6d86f4d826289e74e9721b 100644
--- a/Library/Homebrew/cask/cmd/install.rb
+++ b/Library/Homebrew/cask/cmd/install.rb
@@ -3,31 +3,44 @@
 module Cask
   class Cmd
     class Install < AbstractCommand
-      option "--force",          :force,          false
-      option "--skip-cask-deps", :skip_cask_deps, false
+      def self.min_named
+        :cask
+      end
+
+      def self.description
+        "Installs the given <cask>."
+      end
 
-      def initialize(*)
-        super
-        raise CaskUnspecifiedError if args.empty?
+      def self.parser(&block)
+        super do
+          switch "--force",
+                 description: "Force overwriting existing files."
+          switch "--skip-cask-deps",
+                 description: "Skip installing cask dependencies."
+
+          instance_eval(&block) if block_given?
+        end
       end
 
       def run
+        options = {
+          binaries:       args.binaries?,
+          verbose:        args.verbose?,
+          force:          args.force?,
+          skip_cask_deps: args.skip_cask_deps?,
+          require_sha:    args.require_sha?,
+          quarantine:     args.quarantine?,
+        }.compact
+
+        options[:quarantine] = true if options[:quarantine].nil?
+
         odie "Installing casks is supported only on macOS" unless OS.mac?
         casks.each do |cask|
-          Installer.new(cask, binaries:       binaries?,
-                              verbose:        verbose?,
-                              force:          force?,
-                              skip_cask_deps: skip_cask_deps?,
-                              require_sha:    require_sha?,
-                              quarantine:     quarantine?).install
+          Installer.new(cask, **options).install
         rescue CaskAlreadyInstalledError => e
           opoo e.message
         end
       end
-
-      def self.help
-        "installs the given Cask"
-      end
     end
   end
 end
diff --git a/Library/Homebrew/cask/cmd/internal_help.rb b/Library/Homebrew/cask/cmd/internal_help.rb
index ec544a2a06522e5ba680c9a8c6658b718d09d1a8..878a07bad8c8939f380ae853a7836d282ab31352 100644
--- a/Library/Homebrew/cask/cmd/internal_help.rb
+++ b/Library/Homebrew/cask/cmd/internal_help.rb
@@ -3,11 +3,12 @@
 module Cask
   class Cmd
     class InternalHelp < AbstractInternalCommand
-      def initialize(*)
-        super
-        return if args.empty?
+      def self.max_named
+        0
+      end
 
-        raise ArgumentError, "#{self.class.command_name} does not take arguments."
+      def self.description
+        "Print help for unstable internal-use commands."
       end
 
       def run
@@ -20,10 +21,6 @@ module Cask
         end
         puts "\n"
       end
-
-      def self.help
-        "print help strings for unstable internal-use commands"
-      end
     end
   end
 end
diff --git a/Library/Homebrew/cask/cmd/internal_stanza.rb b/Library/Homebrew/cask/cmd/internal_stanza.rb
index 106bd91560d3dd36bf49c553deed8ae4e491988a..5db74bd0126ceff10f8bd1cf4edfbdf5ec65da83 100644
--- a/Library/Homebrew/cask/cmd/internal_stanza.rb
+++ b/Library/Homebrew/cask/cmd/internal_stanza.rb
@@ -13,24 +13,45 @@ module Cask
       #
       # On failure, a blank line is returned on the standard output.
       #
-      # Examples
-      #
-      #     brew cask _stanza appcast   --table
-      #     brew cask _stanza app       --table           alfred google-chrome adium vagrant
-      #     brew cask _stanza url       --table           alfred google-chrome adium vagrant
-      #     brew cask _stanza version   --table           alfred google-chrome adium vagrant
-      #     brew cask _stanza artifacts --table           alfred google-chrome adium vagrant
-      #     brew cask _stanza artifacts --table --yaml    alfred google-chrome adium vagrant
-      #
 
       ARTIFACTS =
         (DSL::ORDINARY_ARTIFACT_CLASSES.map(&:dsl_key) +
          DSL::ARTIFACT_BLOCK_CLASSES.map(&:dsl_key)).freeze
 
-      option "--table",   :table,   false
-      option "--quiet",   :quiet,   false
-      option "--yaml",    :yaml,    false
-      option "--inspect", :inspect, false
+      def self.min_named
+        1
+      end
+
+      def self.banner_args
+        " <stanza_name> [<cask>]"
+      end
+
+      def self.description
+        <<~EOS
+          Extract and render a specific stanza for the given <cask>.
+
+          Examples:
+            `brew cask _stanza appcast   --table`
+            `brew cask _stanza app       --table           alfred google-chrome vagrant`
+            `brew cask _stanza url       --table           alfred google-chrome vagrant`
+            `brew cask _stanza version   --table           alfred google-chrome vagrant`
+            `brew cask _stanza artifacts --table           alfred google-chrome vagrant`
+            `brew cask _stanza artifacts --table --yaml    alfred google-chrome vagrant`
+        EOS
+      end
+
+      def self.parser
+        super do
+          switch "--table",
+                 description: "Print stanza in table format."
+          switch "--quiet",
+                 description: ""
+          switch "--yaml",
+                 description: ""
+          switch "--inspect",
+                 description: ""
+        end
+      end
 
       attr_accessor :format, :stanza
       private :format, :format=
@@ -38,19 +59,19 @@ module Cask
 
       def initialize(*)
         super
-        raise ArgumentError, "No stanza given." if args.empty?
 
-        @stanza = args.shift.to_sym
+        named = args.named.dup
+        @stanza = named.shift.to_sym
+        args.freeze_named_args!(named)
 
-        @format = :to_yaml if yaml?
+        @format = :to_yaml if args.yaml?
 
         return if DSL::DSL_METHODS.include?(stanza)
 
-        raise ArgumentError,
-              <<~EOS
-                Unknown/unsupported stanza: '#{stanza}'
-                Check Cask reference for supported stanzas.
-              EOS
+        raise UsageError, <<~EOS
+          Unknown/unsupported stanza: '#{stanza}'
+          Check cask reference for supported stanzas.
+        EOS
       end
 
       def run
@@ -60,12 +81,12 @@ module Cask
         end
 
         casks(alternative: -> { Cask.to_a }).each do |cask|
-          print "#{cask}\t" if table?
+          print "#{cask}\t" if args.table?
 
           begin
             value = cask.send(stanza)
           rescue
-            opoo "failure calling '#{stanza}' on Cask '#{cask}'" unless quiet?
+            opoo "failure calling '#{stanza}' on Cask '#{cask}'" unless args.quiet?
             puts ""
             next
           end
@@ -89,10 +110,6 @@ module Cask
           end
         end
       end
-
-      def self.help
-        "extract and render a specific stanza for the given Casks"
-      end
     end
   end
 end
diff --git a/Library/Homebrew/cask/cmd/list.rb b/Library/Homebrew/cask/cmd/list.rb
index 9cb1e11ececd9db61277a1ad9588b65413c05fa3..87098cf91755f3668be4dec17281d153893225a2 100644
--- a/Library/Homebrew/cask/cmd/list.rb
+++ b/Library/Homebrew/cask/cmd/list.rb
@@ -1,42 +1,34 @@
 # frozen_string_literal: true
 
+require "cask/artifact/relocated"
+
 module Cask
   class Cmd
     class List < AbstractCommand
-      option "-1",             :one, false
-      option "--versions",     :versions, false
-      option "--full-name",    :full_name, false
-      option "--json",         :json, false
-
-      def self.usage
-        <<~EOS
-          `cask list`, `cask ls` [<options>] [<casks>]
-
-          -1          - Force output to be one entry per line.
-                        This is the default when output is not to a terminal.
-          --versions  - Show the version number for installed formulae, or only the specified
-                        casks if <casks> are provided.
-          --full-name - Print casks with fully-qualified names.
-          --json      - Print a JSON representation of <cask>. See the docs for examples of using the JSON
-                        output: <https://docs.brew.sh/Querying-Brew>
-
-          List all installed casks.
-
-          If <casks> are provided, limit information to just those casks.
-        EOS
+      def self.description
+        "Lists installed casks or the casks provided in the arguments."
       end
 
-      def self.help
-        "lists installed Casks or the casks provided in the arguments"
+      def self.parser
+        super do
+          switch "-1",
+                 description: "Force output to be one entry per line."
+          switch "--versions",
+                 description: "Show the version number the listed casks."
+          switch "--full-name",
+                 description: "Print casks with fully-qualified names."
+          switch "--json",
+                 description: "Print a JSON representation of the listed casks. "
+        end
       end
 
       def run
         self.class.list_casks(
           *casks,
-          json:      json?,
-          one:       one?,
-          full_name: full_name?,
-          versions:  versions?,
+          json:      args.json?,
+          one:       args.public_send(:'1?'),
+          full_name: args.full_name?,
+          versions:  args.versions?,
         )
       end
 
@@ -58,17 +50,23 @@ module Cask
         elsif versions
           puts output.map(&method(:format_versioned))
         elsif !output.empty? && casks.any?
-          puts output.map(&method(:list_artifacts))
+          output.map(&method(:list_artifacts))
         elsif !output.empty?
           puts Formatter.columns(output.map(&:to_s))
         end
       end
 
       def self.list_artifacts(cask)
-        cask.artifacts.group_by(&:class).each do |klass, artifacts|
-          next unless klass.respond_to?(:english_description)
+        cask.artifacts.group_by(&:class).sort_by { |klass, _| klass.english_name }.each do |klass, artifacts|
+          next if [Artifact::Uninstall, Artifact::Zap].include? klass
 
-          return "==> #{klass.english_description}", artifacts.map(&:summarize_installed)
+          ohai klass.english_name
+          artifacts.each do |artifact|
+            puts artifact.summarize_installed if artifact.respond_to?(:summarize_installed)
+            next if artifact.respond_to?(:summarize_installed)
+
+            puts artifact
+          end
         end
       end
 
diff --git a/Library/Homebrew/cask/cmd/options.rb b/Library/Homebrew/cask/cmd/options.rb
deleted file mode 100644
index c6bb42789235357efaa281bdc378870204dd5bc5..0000000000000000000000000000000000000000
--- a/Library/Homebrew/cask/cmd/options.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-# frozen_string_literal: true
-
-module Cask
-  class Cmd
-    module Options
-      def self.included(klass)
-        klass.extend(ClassMethods)
-      end
-
-      module ClassMethods
-        def options
-          @options ||= {}
-          return @options unless superclass.respond_to?(:options)
-
-          superclass.options.merge(@options)
-        end
-
-        def option(name, method, default_value = nil)
-          @options ||= {}
-          @options[name] = method
-
-          return if method.respond_to?(:call)
-
-          define_method(:"#{method}=") do |value|
-            instance_variable_set(:"@#{method}", value)
-          end
-
-          if [true, false].include?(default_value)
-            define_method(:"#{method}?") do
-              return default_value unless instance_variable_defined?(:"@#{method}")
-
-              instance_variable_get(:"@#{method}") == true
-            end
-          else
-            define_method(:"#{method}") do
-              return default_value unless instance_variable_defined?(:"@#{method}")
-
-              instance_variable_get(:"@#{method}")
-            end
-          end
-        end
-      end
-
-      def process_arguments(*arguments)
-        parser = OptionParser.new do |opts|
-          next if self.class.options.nil?
-
-          self.class.options.each do |option_name, option_method|
-            option_type = case option_name.split(/(\ |=)/).last
-            when "PATH"
-              Pathname
-            when /\w+(,\w+)+/
-              Array
-            end
-
-            opts.on(option_name, *option_type) do |value|
-              if option_method.respond_to?(:call)
-                option_method.call(value)
-              else
-                send(:"#{option_method}=", value)
-              end
-            end
-          end
-        end
-        parser.parse(*arguments)
-      end
-    end
-  end
-end
diff --git a/Library/Homebrew/cask/cmd/outdated.rb b/Library/Homebrew/cask/cmd/outdated.rb
index 98611244daf53c4eb0415b232f46aa683f333740..33d989d84f9a73cf49f419305fb9a472f9e39a31 100644
--- a/Library/Homebrew/cask/cmd/outdated.rb
+++ b/Library/Homebrew/cask/cmd/outdated.rb
@@ -3,27 +3,29 @@
 module Cask
   class Cmd
     class Outdated < AbstractCommand
-      option "--greedy", :greedy, false
-      option "--quiet",  :quiet, false
-      option "--json",   :json, false
+      def self.description
+        "List the outdated installed casks."
+      end
 
-      def initialize(*)
-        super
-        self.verbose = ($stdout.tty? || verbose?) && !quiet?
-        @outdated_casks = casks(alternative: -> { Caskroom.casks }).select do |cask|
-          odebug "Checking update info of Cask #{cask}"
-          cask.outdated?(greedy?)
+      def self.parser
+        super do
+          switch "--greedy",
+                 description: "Also include casks which specify `auto_updates true` or `version :latest`."
+          switch "--json",
+                 description: "Print a JSON representation of outdated casks."
         end
       end
 
       def run
-        output = @outdated_casks.map { |cask| cask.outdated_info(greedy?, verbose?, json?) }
+        outdated_casks = casks(alternative: -> { Caskroom.casks }).select do |cask|
+          odebug "Checking update info of Cask #{cask}"
+          cask.outdated?(args.greedy?)
+        end
 
-        puts json? ? JSON.generate(output) : output
-      end
+        verbose = ($stdout.tty? || args.verbose?) && !args.quiet?
+        output = outdated_casks.map { |cask| cask.outdated_info(args.greedy?, verbose, args.json?) }
 
-      def self.help
-        "list the outdated installed Casks"
+        puts args.json? ? JSON.generate(output) : output
       end
     end
   end
diff --git a/Library/Homebrew/cask/cmd/reinstall.rb b/Library/Homebrew/cask/cmd/reinstall.rb
index a0228158f48bed4176063ea785f778b73b2a5065..75edc85813216b2fa9296102736e233b868e0d99 100644
--- a/Library/Homebrew/cask/cmd/reinstall.rb
+++ b/Library/Homebrew/cask/cmd/reinstall.rb
@@ -3,15 +3,19 @@
 module Cask
   class Cmd
     class Reinstall < Install
+      def self.description
+        "Reinstalls the given <cask>."
+      end
+
       def run
         self.class.reinstall_casks(
           *casks,
-          binaries:       binaries?,
-          verbose:        verbose?,
-          force:          force?,
-          skip_cask_deps: skip_cask_deps?,
-          require_sha:    require_sha?,
-          quarantine:     quarantine?,
+          binaries:       args.binaries?,
+          verbose:        args.verbose?,
+          force:          args.force?,
+          skip_cask_deps: args.skip_cask_deps?,
+          require_sha:    args.require_sha?,
+          quarantine:     args.quarantine?,
         )
       end
 
@@ -24,25 +28,22 @@ module Cask
         require_sha: nil,
         quarantine: nil
       )
-        # TODO: Handle this in `CLI::Parser`.
-        binaries = Homebrew::EnvConfig.cask_opts_binaries? if binaries.nil?
-        quarantine = Homebrew::EnvConfig.cask_opts_quarantine? if quarantine.nil?
-        require_sha = Homebrew::EnvConfig.cask_opts_require_sha? if require_sha.nil?
+
+        options = {
+          binaries:       binaries,
+          verbose:        verbose,
+          force:          force,
+          skip_cask_deps: skip_cask_deps,
+          require_sha:    require_sha,
+          quarantine:     quarantine,
+        }.compact
+
+        options[:quarantine] = true if options[:quarantine].nil?
 
         casks.each do |cask|
-          Installer.new(cask,
-                        binaries:       binaries,
-                        verbose:        verbose,
-                        force:          force,
-                        skip_cask_deps: skip_cask_deps,
-                        require_sha:    require_sha,
-                        quarantine:     quarantine).reinstall
+          Installer.new(cask, **options).reinstall
         end
       end
-
-      def self.help
-        "reinstalls the given Cask"
-      end
     end
   end
 end
diff --git a/Library/Homebrew/cask/cmd/style.rb b/Library/Homebrew/cask/cmd/style.rb
index 06dfc45f821af7594f9b9db23efcde403d22bbd6..b24b1b5c204fad3120784e25af3335aff90ffb92 100644
--- a/Library/Homebrew/cask/cmd/style.rb
+++ b/Library/Homebrew/cask/cmd/style.rb
@@ -5,8 +5,15 @@ require "json"
 module Cask
   class Cmd
     class Style < AbstractCommand
-      def self.help
-        "checks Cask style using RuboCop"
+      def self.description
+        "Checks style of the given <cask> using RuboCop."
+      end
+
+      def self.parser
+        super do
+          switch "--fix",
+                 description: "Fix style violations automatically using RuboCop's auto-correct feature."
+        end
       end
 
       def self.rubocop(*paths, auto_correct: false, debug: false, json: false)
@@ -48,18 +55,16 @@ module Cask
         result
       end
 
-      option "--fix", :fix, false
-
       def run
-        result = self.class.rubocop(*cask_paths, auto_correct: fix?, debug: debug?)
+        result = self.class.rubocop(*cask_paths, auto_correct: args.fix?, debug: args.debug?)
         raise CaskError, "Style check failed." unless result.status.success?
       end
 
       def cask_paths
-        @cask_paths ||= if args.empty?
+        @cask_paths ||= if args.named.empty?
           Tap.map(&:cask_dir).select(&:directory?).concat(test_cask_paths)
-        elsif args.any? { |file| File.exist?(file) }
-          args.map { |path| Pathname(path).expand_path }
+        elsif args.named.any? { |file| File.exist?(file) }
+          args.named.map { |path| Pathname(path).expand_path }
         else
           casks.map(&:sourcefile_path)
         end
diff --git a/Library/Homebrew/cask/cmd/uninstall.rb b/Library/Homebrew/cask/cmd/uninstall.rb
index 47d3e42b3613448ba17c9791a45fe1f3bc7d565c..cde416c65d396d2932ea45037f333c55b9f35400 100644
--- a/Library/Homebrew/cask/cmd/uninstall.rb
+++ b/Library/Homebrew/cask/cmd/uninstall.rb
@@ -3,24 +3,37 @@
 module Cask
   class Cmd
     class Uninstall < AbstractCommand
-      option "--force", :force, false
+      def self.min_named
+        :cask
+      end
+
+      def self.description
+        "Uninstalls the given <cask>."
+      end
 
-      def initialize(*)
-        super
-        raise CaskUnspecifiedError if args.empty?
+      def self.parser
+        super do
+          switch "--force",
+                 description: "Uninstall even if the <cask> is not installed, overwrite " \
+                              "existing files and ignore errors when removing files."
+        end
       end
 
       def run
         self.class.uninstall_casks(
           *casks,
-          binaries: binaries?,
-          verbose:  verbose?,
-          force:    force?,
+          binaries: args.binaries?,
+          verbose:  args.verbose?,
+          force:    args.force?,
         )
       end
 
-      def self.uninstall_casks(*casks, verbose: false, force: false, binaries: nil)
-        binaries = Homebrew::EnvConfig.cask_opts_binaries? if binaries.nil?
+      def self.uninstall_casks(*casks, binaries: nil, force: false, verbose: false)
+        options = {
+          binaries: binaries,
+          force:    force,
+          verbose:  verbose,
+        }.compact
 
         casks.each do |cask|
           odebug "Uninstalling Cask #{cask}"
@@ -32,7 +45,7 @@ module Cask
             cask = CaskLoader.load(cask.installed_caskfile) if cask.installed_caskfile.exist?
           end
 
-          Installer.new(cask, binaries: binaries, verbose: verbose, force: force).uninstall
+          Installer.new(cask, **options).uninstall
 
           next if (versions = cask.versions).empty?
 
@@ -42,10 +55,6 @@ module Cask
           EOS
         end
       end
-
-      def self.help
-        "uninstalls the given Cask"
-      end
     end
   end
 end
diff --git a/Library/Homebrew/cask/cmd/upgrade.rb b/Library/Homebrew/cask/cmd/upgrade.rb
index e07bc473bd98fc5da0cbcac7376741738643a9ef..92dafc317e5384f8b440c67295cf002973669db8 100644
--- a/Library/Homebrew/cask/cmd/upgrade.rb
+++ b/Library/Homebrew/cask/cmd/upgrade.rb
@@ -6,28 +6,35 @@ require "cask/config"
 module Cask
   class Cmd
     class Upgrade < AbstractCommand
-      option "--greedy", :greedy, false
-      option "--quiet",  :quiet, false
-      option "--force", :force, false
-      option "--skip-cask-deps", :skip_cask_deps, false
-      option "--dry-run", :dry_run, false
-
-      def initialize(*)
-        super
-        self.verbose = ($stdout.tty? || verbose?) && !quiet?
+      def self.description
+        "Upgrades all outdated casks or the specified casks."
+      end
+
+      def self.parser
+        super do
+          switch "--force",
+                 description: "Force overwriting existing files."
+          switch "--skip-cask-deps",
+                 description: "Skip installing cask dependencies."
+          switch "--greedy",
+                 description: "Also include casks which specify `auto_updates true` or `version :latest`."
+          switch "--dry-run",
+                 description: "Show what would be upgraded, but do not actually upgrade anything."
+        end
       end
 
       def run
+        verbose = ($stdout.tty? || args.verbose?) && !args.quiet?
         self.class.upgrade_casks(
           *casks,
-          force:          force?,
-          greedy:         greedy?,
-          dry_run:        dry_run?,
-          binaries:       binaries?,
-          quarantine:     quarantine?,
-          require_sha:    require_sha?,
-          skip_cask_deps: skip_cask_deps?,
-          verbose:        verbose?,
+          force:          args.force?,
+          greedy:         args.greedy?,
+          dry_run:        args.dry_run?,
+          binaries:       args.binaries?,
+          quarantine:     args.quarantine?,
+          require_sha:    args.require_sha?,
+          skip_cask_deps: args.skip_cask_deps?,
+          verbose:        verbose,
         )
       end
 
@@ -42,10 +49,8 @@ module Cask
         quarantine: nil,
         require_sha: nil
       )
-        # TODO: Handle this in `CLI::Parser`.
-        binaries = Homebrew::EnvConfig.cask_opts_binaries? if binaries.nil?
-        quarantine = Homebrew::EnvConfig.cask_opts_quarantine? if quarantine.nil?
-        require_sha = Homebrew::EnvConfig.cask_opts_require_sha? if require_sha.nil?
+
+        quarantine = true if quarantine.nil?
 
         outdated_casks = if casks.empty?
           Caskroom.casks.select do |cask|
@@ -98,22 +103,30 @@ module Cask
         odebug "Started upgrade process for Cask #{old_cask}"
         old_config = old_cask.config
 
+        old_options = {
+          binaries: binaries,
+          verbose:  verbose,
+          force:    force,
+          upgrade:  true,
+        }.compact
+
         old_cask_installer =
-          Installer.new(old_cask, binaries: binaries,
-                                  verbose:  verbose,
-                                  force:    force,
-                                  upgrade:  true)
+          Installer.new(old_cask, **old_options)
 
         new_cask.config = Config.global.merge(old_config)
 
+        new_options = {
+          binaries:       binaries,
+          verbose:        verbose,
+          force:          force,
+          skip_cask_deps: skip_cask_deps,
+          require_sha:    require_sha,
+          upgrade:        true,
+          quarantine:     quarantine,
+        }.compact
+
         new_cask_installer =
-          Installer.new(new_cask, binaries:       binaries,
-                                  verbose:        verbose,
-                                  force:          force,
-                                  skip_cask_deps: skip_cask_deps,
-                                  require_sha:    require_sha,
-                                  upgrade:        true,
-                                  quarantine:     quarantine)
+          Installer.new(new_cask, **new_options)
 
         started_upgrade = false
         new_artifacts_installed = false
@@ -148,10 +161,6 @@ module Cask
           raise e
         end
       end
-
-      def self.help
-        "upgrades all outdated casks"
-      end
     end
   end
 end
diff --git a/Library/Homebrew/cask/cmd/zap.rb b/Library/Homebrew/cask/cmd/zap.rb
index 73a8b685810a5a3d6bbfa4df86ae92b69fe957c3..7b7eecee8ecd5cf3b70abb0750d2f195aac5288b 100644
--- a/Library/Homebrew/cask/cmd/zap.rb
+++ b/Library/Homebrew/cask/cmd/zap.rb
@@ -3,26 +3,34 @@
 module Cask
   class Cmd
     class Zap < AbstractCommand
-      option "--force", :force, false
+      def self.min_named
+        :cask
+      end
+
+      def self.description
+        <<~EOS
+          Zaps all files associated with the given <cask>. Implicitly also performs all actions associated with `uninstall`.
 
-      def initialize(*)
-        super
-        raise CaskUnspecifiedError if args.empty?
+          *May remove files which are shared between applications.*
+        EOS
+      end
+
+      def self.parser
+        super do
+          switch "--force",
+                 description: "Ignore errors when removing files."
+        end
       end
 
       def run
         casks.each do |cask|
           odebug "Zapping Cask #{cask}"
 
-          raise CaskNotInstalledError, cask unless cask.installed? || force?
+          raise CaskNotInstalledError, cask unless cask.installed? || args.force?
 
-          Installer.new(cask, verbose: verbose?, force: force?).zap
+          Installer.new(cask, verbose: args.verbose?, force: args.force?).zap
         end
       end
-
-      def self.help
-        "zaps all files associated with the given Cask"
-      end
     end
   end
 end
diff --git a/Library/Homebrew/cask/config.rb b/Library/Homebrew/cask/config.rb
index 74c68bc24321c07c928dd42ea2f6b7d29a8a175a..ebfe171701d2caaaeae0ed9b17ebcd18014b45e8 100644
--- a/Library/Homebrew/cask/config.rb
+++ b/Library/Homebrew/cask/config.rb
@@ -12,12 +12,12 @@ module Cask
   class Config
     DEFAULT_DIRS = {
       appdir:               "/Applications",
+      colorpickerdir:       "~/Library/ColorPickers",
       prefpanedir:          "~/Library/PreferencePanes",
       qlplugindir:          "~/Library/QuickLook",
       mdimporterdir:        "~/Library/Spotlight",
       dictionarydir:        "~/Library/Dictionaries",
       fontdir:              "~/Library/Fonts",
-      colorpickerdir:       "~/Library/ColorPickers",
       servicedir:           "~/Library/Services",
       input_methoddir:      "~/Library/Input Methods",
       internet_plugindir:   "~/Library/Internet Plug-Ins",
diff --git a/Library/Homebrew/cask/dsl.rb b/Library/Homebrew/cask/dsl.rb
index 585b93ebb9110ba928be69d4f4b842315b84e6f7..b1d5085e759abb3ffb18c25cceb7268cbc89b70d 100644
--- a/Library/Homebrew/cask/dsl.rb
+++ b/Library/Homebrew/cask/dsl.rb
@@ -21,6 +21,7 @@ require "cask/dsl/uninstall_preflight"
 require "cask/dsl/version"
 
 require "cask/url"
+require "cask/utils"
 
 module Cask
   class DSL
diff --git a/Library/Homebrew/cli/parser.rb b/Library/Homebrew/cli/parser.rb
index c034f63024659f449fbedf7636bbc968f5adc872..1f6ab8a08d2b1e7f0857692c385e250d0b79b41a 100644
--- a/Library/Homebrew/cli/parser.rb
+++ b/Library/Homebrew/cli/parser.rb
@@ -1,9 +1,11 @@
 # frozen_string_literal: true
 
+require "env_config"
 require "cli/args"
 require "optparse"
 require "set"
 require "formula"
+require "utils/tty"
 
 COMMAND_DESC_WIDTH = 80
 OPTION_DESC_WIDTH = 43
@@ -27,15 +29,24 @@ module Homebrew
 
       def self.global_options
         [
+          ["-d", "--debug", "Display any debugging information."],
           ["-q", "--quiet", "Suppress any warnings."],
           ["-v", "--verbose", "Make some output more verbose."],
-          ["-d", "--debug", "Display any debugging information."],
+          ["-h", "--help", "Show this message."],
         ]
       end
 
       def initialize(&block)
         @parser = OptionParser.new
 
+        @parser.summary_indent = " " * 2
+
+        # Disable default handling of `--version` switch.
+        @parser.base.long.delete("version")
+
+        # Disable default handling of `--help` switch.
+        @parser.base.long.delete("help")
+
         @args = Homebrew::CLI::Args.new
 
         @constraints = []
@@ -49,54 +60,50 @@ module Homebrew
         @formula_options = false
 
         self.class.global_options.each do |short, long, desc|
-          switch short, long, description: desc, env: option_to_name(long)
+          switch short, long, description: desc, env: option_to_name(long), method: :on_tail
         end
 
         instance_eval(&block) if block_given?
-
-        post_initialize
       end
 
-      def post_initialize
-        # Disable default handling of `--version` switch.
-        @parser.base.long.delete("version")
-
-        # Disable default handling of `--help` switch.
-        @parser.on_tail("-h", "--help", "Show this message.") do
-          # Handled in `brew.rb`.
-        end
-      end
-
-      def switch(*names, description: nil, env: nil, required_for: nil, depends_on: nil)
+      def switch(*names, description: nil, env: nil, required_for: nil, depends_on: nil, method: :on)
         global_switch = names.first.is_a?(Symbol)
         return if global_switch
 
         description = option_to_description(*names) if description.nil?
         process_option(*names, description)
-        @parser.on(*names, *wrap_option_desc(description)) do
-          enable_switch(*names, from: :args)
+        @parser.public_send(method, *names, *wrap_option_desc(description)) do |value|
+          value = if names.any? { |name| name.start_with?("--[no-]") }
+            value
+          else
+            true
+          end
+
+          set_switch(*names, value: value, from: :args)
         end
 
         names.each do |name|
           set_constraints(name, required_for: required_for, depends_on: depends_on)
         end
 
-        enable_switch(*names, from: :env) if env?(env)
+        env_value = env?(env)
+        set_switch(*names, value: env_value, from: :env) unless env_value.nil?
       end
       alias switch_option switch
 
       def env?(env)
-        return false if env.blank?
+        return if env.blank?
 
         Homebrew::EnvConfig.try(:"#{env}?")
       end
 
       def usage_banner(text)
-        @parser.banner = Formatter.wrap("#{text}\n", COMMAND_DESC_WIDTH)
+        @parser.banner = "#{text}\n"
       end
 
       def usage_banner_text
         @parser.banner
+               .gsub(/^  - (`[^`]+`)\s+/, "\n- \\1  \n  ") # Format `cask` subcommands as MarkDown list.
       end
 
       def comma_array(name, description: nil)
@@ -133,7 +140,7 @@ module Homebrew
       end
 
       def option_to_name(option)
-        option.sub(/\A--?/, "")
+        option.sub(/\A--?(\[no-\])?/, "")
               .tr("-", "_")
               .delete("=")
       end
@@ -150,10 +157,6 @@ module Homebrew
         names.map { |name| name.to_s.sub(/\A--?/, "").tr("-", " ") }.max
       end
 
-      def summary
-        @parser.to_s
-      end
-
       def parse_remaining(argv, ignore_invalid_options: false)
         i = 0
         remaining = []
@@ -221,23 +224,35 @@ module Homebrew
           remaining + non_options
         end
 
-        check_constraint_violations unless ignore_invalid_options
-        check_named_args(named_args) unless ignore_invalid_options
+        unless ignore_invalid_options
+          check_constraint_violations
+          check_named_args(named_args)
+        end
+
         @args.freeze_named_args!(named_args)
         @args.freeze_remaining_args!(non_options.empty? ? remaining : [*remaining, "--", non_options])
         @args.freeze_processed_options!(@processed_options)
 
         @args_parsed = true
+
+        if !ignore_invalid_options && @args.help?
+          puts generate_help_text
+          exit
+        end
+
         @args
       end
 
       def generate_help_text
-        @parser.to_s
-               .sub(/^/, "#{Tty.bold}Usage: brew#{Tty.reset} ")
-               .gsub(/`(.*?)`/m, "#{Tty.bold}\\1#{Tty.reset}")
-               .gsub(%r{<([^\s]+?://[^\s]+?)>}) { |url| Formatter.url(url) }
-               .gsub(/<(.*?)>/m, "#{Tty.underline}\\1#{Tty.reset}")
-               .gsub(/\*(.*?)\*/m, "#{Tty.underline}\\1#{Tty.reset}")
+        Formatter.wrap(
+          @parser.to_s.gsub(/^  - (`[^`]+`\s+)/, "  \\1"), # Remove `-` from `cask` subcommand listing.
+          COMMAND_DESC_WIDTH,
+        )
+                 .sub(/^/, "#{Tty.bold}Usage: brew#{Tty.reset} ")
+                 .gsub(/`(.*?)`/m, "#{Tty.bold}\\1#{Tty.reset}")
+                 .gsub(%r{<([^\s]+?://[^\s]+?)>}) { |url| Formatter.url(url) }
+                 .gsub(/<(.*?)>/m, "#{Tty.underline}\\1#{Tty.reset}")
+                 .gsub(/\*(.*?)\*/m, "#{Tty.underline}\\1#{Tty.reset}")
       end
 
       def formula_options
@@ -282,10 +297,10 @@ module Homebrew
 
       private
 
-      def enable_switch(*names, from:)
+      def set_switch(*names, value:, from:)
         names.each do |name|
           @switch_sources[option_to_name(name)] = from
-          @args["#{option_to_name(name)}?"] = true
+          @args["#{option_to_name(name)}?"] = value
         end
       end
 
diff --git a/Library/Homebrew/cmd/cask.rb b/Library/Homebrew/cmd/cask.rb
index 07d827803fe2538f1cb81f30d903491197f6bc00..1a51405ecd1998c0c857f68d975bfae84bb49b50 100644
--- a/Library/Homebrew/cmd/cask.rb
+++ b/Library/Homebrew/cmd/cask.rb
@@ -1,11 +1,16 @@
 # frozen_string_literal: true
 
-require "cask"
+require "cask/cmd"
 
 module Homebrew
   module_function
 
+  def cask_args
+    Cask::Cmd.parser
+  end
+
   def cask
+    ARGV.freeze
     Cask::Cmd.run(*ARGV)
   end
 end
diff --git a/Library/Homebrew/cmd/home.rb b/Library/Homebrew/cmd/home.rb
index 318c7ffb02197220e30a65af2d2578b7388fafd7..cce7a1439ba93042e322d681ee3f249b1446fcd0 100644
--- a/Library/Homebrew/cmd/home.rb
+++ b/Library/Homebrew/cmd/home.rb
@@ -25,7 +25,10 @@ module Homebrew
     end
 
     homepages = args.formulae_and_casks.map do |formula_or_cask|
-      puts "Opening homepage for #{name_of(formula_or_cask)}"
+      disclaimer = disclaimers(formula_or_cask)
+      disclaimer = " (#{disclaimer})" if disclaimer.present?
+
+      puts "Opening homepage for #{name_of(formula_or_cask)}#{disclaimer}"
       formula_or_cask.homepage
     end
 
@@ -39,4 +42,15 @@ module Homebrew
       "Cask #{formula_or_cask.token}"
     end
   end
+
+  def disclaimers(formula_or_cask)
+    return unless formula_or_cask.is_a? Formula
+
+    begin
+      cask = Cask::CaskLoader.load formula_or_cask.name
+      "for the cask, use #{cask.tap.name}/#{cask.token}"
+    rescue Cask::CaskUnavailableError
+      nil
+    end
+  end
 end
diff --git a/Library/Homebrew/cmd/list.rb b/Library/Homebrew/cmd/list.rb
index ede8a2c600198d57dc683f517f4b244422e3d582..6da7c17e59228573514cd56cb607cf51814196be 100644
--- a/Library/Homebrew/cmd/list.rb
+++ b/Library/Homebrew/cmd/list.rb
@@ -111,7 +111,6 @@ module Homebrew
     lib/ruby/site_ruby/[12].*
     lib/ruby/vendor_ruby/[12].*
     manpages/brew.1
-    manpages/brew-cask.1
     share/pypy/*
     share/pypy3/*
     share/info/dir
diff --git a/Library/Homebrew/cmd/reinstall.rb b/Library/Homebrew/cmd/reinstall.rb
index cd57578a132c8fd37fa8e759bc32c32c9e7c8ec1..f18f02df6583dcaced89af14ca0355bec0e86cb6 100644
--- a/Library/Homebrew/cmd/reinstall.rb
+++ b/Library/Homebrew/cmd/reinstall.rb
@@ -80,12 +80,12 @@ module Homebrew
 
     Cask::Cmd::Reinstall.reinstall_casks(
       *casks,
-      binaries:       args.binaries?,
+      binaries:       EnvConfig.cask_opts_binaries?,
       verbose:        args.verbose?,
       force:          args.force?,
-      require_sha:    args.require_sha?,
+      require_sha:    EnvConfig.cask_opts_require_sha?,
       skip_cask_deps: args.skip_cask_deps?,
-      quarantine:     args.quarantine?,
+      quarantine:     EnvConfig.cask_opts_quarantine?,
     )
   end
 end
diff --git a/Library/Homebrew/cmd/uninstall.rb b/Library/Homebrew/cmd/uninstall.rb
index 6c73e2694a2826153e2a54f2204a3c30bdccb9ca..584b20ceeb727a92b114a7706028258bfde37a2c 100644
--- a/Library/Homebrew/cmd/uninstall.rb
+++ b/Library/Homebrew/cmd/uninstall.rb
@@ -128,7 +128,7 @@ module Homebrew
 
     Cask::Cmd::Uninstall.uninstall_casks(
       *casks,
-      binaries: args.binaries?,
+      binaries: EnvConfig.cask_opts_binaries?,
       verbose:  args.verbose?,
       force:    args.force?,
     )
diff --git a/Library/Homebrew/cmd/upgrade.rb b/Library/Homebrew/cmd/upgrade.rb
index 64a24c3b1754b92541bdbfd24e0681928e375a27..21be88389cc6fc09211871cccf6e39232e35587f 100644
--- a/Library/Homebrew/cmd/upgrade.rb
+++ b/Library/Homebrew/cmd/upgrade.rb
@@ -152,9 +152,9 @@ module Homebrew
       force:          args.force?,
       greedy:         args.greedy?,
       dry_run:        args.dry_run?,
-      binaries:       args.binaries?,
-      quarantine:     args.quarantine?,
-      require_sha:    args.require_sha?,
+      binaries:       EnvConfig.cask_opts_binaries?,
+      quarantine:     EnvConfig.cask_opts_quarantine?,
+      require_sha:    EnvConfig.cask_opts_require_sha?,
       skip_cask_deps: args.skip_cask_deps?,
       verbose:        args.verbose?,
     )
diff --git a/Library/Homebrew/dev-cmd/bump-formula-pr.rb b/Library/Homebrew/dev-cmd/bump-formula-pr.rb
index 74a22d27f2d9d1d220ce88ab9266b18ffd59d491..8fc81124d962b7307d3b01094caa891374647fc6 100644
--- a/Library/Homebrew/dev-cmd/bump-formula-pr.rb
+++ b/Library/Homebrew/dev-cmd/bump-formula-pr.rb
@@ -105,8 +105,10 @@ module Homebrew
         end
       end
     end
-    origin_branch = Utils.popen_read("git", "-C", formula.tap.path.to_s, "symbolic-ref", "-q", "--short",
-                                     "refs/remotes/origin/HEAD").chomp.presence
+    if formula.tap
+      origin_branch = Utils.popen_read("git", "-C", formula.tap.path.to_s, "symbolic-ref", "-q", "--short",
+                                       "refs/remotes/origin/HEAD").chomp.presence
+    end
     origin_branch ||= "origin/master"
     [formula.tap&.full_name, origin_branch, "-"]
   end
@@ -133,6 +135,9 @@ module Homebrew
     new_version = args.version
     check_closed_pull_requests(formula, tap_full_name, version: new_version, args: args) if new_version
 
+    opoo "This formula has patches that may be resolved upstream." if formula.patchlist.present?
+    opoo "This formula has resources that may need to be updated." if formula.resources.present?
+
     requested_spec = :stable
     formula_spec = formula.stable
     odie "#{formula}: no #{requested_spec} specification found!" unless formula_spec
@@ -145,16 +150,7 @@ module Homebrew
     new_tag = args.tag
     new_revision = args.revision
     new_mirrors ||= args.mirror
-    new_mirror ||= case new_url
-    when %r{.*ftp.gnu.org/gnu.*}
-      new_url.sub "ftp.gnu.org/gnu", "ftpmirror.gnu.org"
-    when %r{.*download.savannah.gnu.org/*}
-      new_url.sub "download.savannah.gnu.org", "download-mirror.savannah.gnu.org"
-    when %r{.*www.apache.org/dyn/closer.lua\?path=.*}
-      new_url.sub "www.apache.org/dyn/closer.lua?path=", "archive.apache.org/dist/"
-    when %r{.*mirrors.ocf.berkeley.edu/debian.*}
-      new_url.sub "mirrors.ocf.berkeley.edu/debian", "mirrorservice.org/sites/ftp.debian.org/debian"
-    end
+    new_mirror ||= determine_mirror(new_url)
     new_mirrors ||= [new_mirror] unless new_mirror.nil?
     old_url = formula_spec.url
     old_tag = formula_spec.specs[:tag]
@@ -424,6 +420,19 @@ module Homebrew
     odie "Couldn't guess formula for sure; could be one of these:\n#{guesses.map(&:name).join(", ")}"
   end
 
+  def determine_mirror(url)
+    case url
+    when %r{.*ftp.gnu.org/gnu.*}
+      url.sub "ftp.gnu.org/gnu", "ftpmirror.gnu.org"
+    when %r{.*download.savannah.gnu.org/*}
+      url.sub "download.savannah.gnu.org", "download-mirror.savannah.gnu.org"
+    when %r{.*www.apache.org/dyn/closer.lua\?path=.*}
+      url.sub "www.apache.org/dyn/closer.lua?path=", "archive.apache.org/dist/"
+    when %r{.*mirrors.ocf.berkeley.edu/debian.*}
+      url.sub "mirrors.ocf.berkeley.edu/debian", "mirrorservice.org/sites/ftp.debian.org/debian"
+    end
+  end
+
   def fetch_resource(formula, new_version, url, **specs)
     resource = Resource.new
     resource.url(url, specs)
diff --git a/Library/Homebrew/dev-cmd/bump-revision.rb b/Library/Homebrew/dev-cmd/bump-revision.rb
index 2b71a91d7f49b31bb88ed8598d90fa5cb1489d16..094f362cb0e9447c20e1c4190021a2a66ccd9c65 100644
--- a/Library/Homebrew/dev-cmd/bump-revision.rb
+++ b/Library/Homebrew/dev-cmd/bump-revision.rb
@@ -9,7 +9,7 @@ module Homebrew
   def bump_revision_args
     Homebrew::CLI::Parser.new do
       usage_banner <<~EOS
-        `bump-revision` [<options>] <formula>
+        `bump-revision` [<options>] <formula> [<formula> ...]
 
         Create a commit to increment the revision of <formula>. If no revision is
         present, "revision 1" will be added.
@@ -19,7 +19,7 @@ module Homebrew
       flag   "--message=",
              description: "Append <message> to the default commit message."
 
-      named :formula
+      min_named :formula
     end
   end
 
@@ -30,63 +30,64 @@ module Homebrew
     # user path, too.
     ENV["PATH"] = ENV["HOMEBREW_PATH"]
 
-    formula = args.formulae.first
-    current_revision = formula.revision
+    args.formulae.each do |formula|
+      current_revision = formula.revision
 
-    if current_revision.zero?
-      formula_spec = formula.stable
-      hash_type, old_hash = if (checksum = formula_spec.checksum)
-        [checksum.hash_type, checksum.hexdigest]
-      end
+      if current_revision.zero?
+        formula_spec = formula.stable
+        hash_type, old_hash = if (checksum = formula_spec.checksum)
+          [checksum.hash_type, checksum.hexdigest]
+        end
 
-      old = if formula.license
-        license_string = if formula.license.length > 1
-          formula.license
+        old = if formula.license
+          license_string = if formula.license.length > 1
+            formula.license
+          else
+            "\"#{formula.license.first}\""
+          end
+          # insert replacement revision after license
+          <<~EOS
+            license #{license_string}
+          EOS
+        elsif formula.path.read.include?("stable do\n")
+          # insert replacement revision after homepage
+          <<~EOS
+            homepage "#{formula.homepage}"
+          EOS
+        elsif hash_type
+          # insert replacement revision after hash
+          <<~EOS
+            #{hash_type} "#{old_hash}"
+          EOS
         else
-          "\"#{formula.license.first}\""
+          # insert replacement revision after :revision
+          <<~EOS
+            revision: "#{formula_spec.specs[:revision]}"
+          EOS
         end
-        # insert replacement revision after license
-        <<~EOS
-          license #{license_string}
-        EOS
-      elsif formula.path.read.include?("stable do\n")
-        # insert replacement revision after homepage
-        <<~EOS
-          homepage "#{formula.homepage}"
-        EOS
-      elsif hash_type
-        # insert replacement revision after hash
-        <<~EOS
-          #{hash_type} "#{old_hash}"
-        EOS
+        replacement = old + "  revision 1\n"
+
       else
-        # insert replacement revision after :revision
-        <<~EOS
-          revision: "#{formula_spec.specs[:revision]}"
-        EOS
+        old = "revision #{current_revision}"
+        replacement = "revision #{current_revision+1}"
       end
-      replacement = old + "  revision 1\n"
-
-    else
-      old = "revision #{current_revision}"
-      replacement = "revision #{current_revision+1}"
-    end
 
-    if args.dry_run?
-      ohai "replace #{old.inspect} with #{replacement.inspect}" unless args.quiet?
-    else
-      Utils::Inreplace.inreplace(formula.path) do |s|
-        s.gsub!(old, replacement)
+      if args.dry_run?
+        ohai "replace #{old.inspect} with #{replacement.inspect}" unless args.quiet?
+      else
+        Utils::Inreplace.inreplace(formula.path) do |s|
+          s.gsub!(old, replacement)
+        end
       end
-    end
 
-    message = "#{formula.name}: revision bump #{args.message}"
-    if args.dry_run?
-      ohai "git commit --no-edit --verbose --message=#{message} -- #{formula.path}"
-    else
-      formula.path.parent.cd do
-        safe_system "git", "commit", "--no-edit", "--verbose",
-                    "--message=#{message}", "--", formula.path
+      message = "#{formula.name}: revision bump #{args.message}"
+      if args.dry_run?
+        ohai "git commit --no-edit --verbose --message=#{message} -- #{formula.path}"
+      else
+        formula.path.parent.cd do
+          safe_system "git", "commit", "--no-edit", "--verbose",
+                      "--message=#{message}", "--", formula.path
+        end
       end
     end
   end
diff --git a/Library/Homebrew/dev-cmd/man.rb b/Library/Homebrew/dev-cmd/man.rb
index 1a76bb2d42a474662a2ee96823e9f512e28ca2a0..7e1f3ca0d9967a42f04f5ff2a10b0b5e5cce2950 100644
--- a/Library/Homebrew/dev-cmd/man.rb
+++ b/Library/Homebrew/dev-cmd/man.rb
@@ -51,9 +51,6 @@ module Homebrew
     markup = build_man_page
     convert_man_page(markup, TARGET_DOC_PATH/"Manpage.md", preserve_date: preserve_date)
     convert_man_page(markup, TARGET_MAN_PATH/"brew.1", preserve_date: preserve_date)
-
-    cask_markup = (SOURCE_PATH/"brew-cask.1.md").read
-    convert_man_page(cask_markup, TARGET_MAN_PATH/"brew-cask.1", preserve_date: preserve_date)
   end
 
   def build_man_page
diff --git a/Library/Homebrew/dev-cmd/pr-pull.rb b/Library/Homebrew/dev-cmd/pr-pull.rb
index 052e5dbdbc50ca7e9f7e6821860690d0870847c8..0b0951c8b4567a23794b8a32f1f8545a1a9985cc 100644
--- a/Library/Homebrew/dev-cmd/pr-pull.rb
+++ b/Library/Homebrew/dev-cmd/pr-pull.rb
@@ -28,6 +28,9 @@ module Homebrew
              description: "Print what would be done rather than doing it."
       switch "--clean",
              description: "Do not amend the commits from pull requests."
+      switch "--keep-old",
+             description: "If the formula specifies a rebuild version, " \
+                          "attempt to preserve its value in the generated DSL."
       switch "--branch-okay",
              description: "Do not warn if pulling to a branch besides master (useful for testing)."
       switch "--resolve",
@@ -262,8 +265,9 @@ module Homebrew
           upload_args << "--verbose" if args.verbose?
           upload_args << "--no-publish" if args.no_publish?
           upload_args << "--dry-run" if args.dry_run?
+          upload_args << "--keep-old" if args.keep_old?
           upload_args << "--warn-on-upload-failure" if args.warn_on_upload_failure?
-          upload_args << "--root_url=#{args.root_url}" if args.root_url
+          upload_args << "--root-url=#{args.root_url}" if args.root_url
           upload_args << "--bintray-org=#{bintray_org}"
           safe_system HOMEBREW_BREW_FILE, *upload_args
         end
diff --git a/Library/Homebrew/dev-cmd/tap-new.rb b/Library/Homebrew/dev-cmd/tap-new.rb
index 686bcdcf88ddfbe7f44372e7dc75c1ef315840ea..a1d5363273a6108258d42a7d7c921d1c2cb4dd05 100644
--- a/Library/Homebrew/dev-cmd/tap-new.rb
+++ b/Library/Homebrew/dev-cmd/tap-new.rb
@@ -64,7 +64,7 @@ module Homebrew
 
             - name: Cache Homebrew Bundler RubyGems
               id: cache
-              uses: actions/cache@main
+              uses: actions/cache@v1
               with:
                 path: ${{ steps.set-up-homebrew.outputs.gems-path }}
                 key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
@@ -74,18 +74,14 @@ module Homebrew
               if: steps.cache.outputs.cache-hit != 'true'
               run: brew install-bundler-gems
 
-            - name: Run brew test-bot --only-cleanup-before
-              run: brew test-bot --only-cleanup-before
+            - run: brew test-bot --only-cleanup-before
 
-            - name: Run brew test-bot --only-setup
-              run: brew test-bot --only-setup
+            - run: brew test-bot --only-setup
 
-            - name: Run brew test-bot --only-tap-syntax
-              run: brew test-bot --only-tap-syntax
+            - run: brew test-bot --only-tap-syntax
 
-            - name: Run brew test-bot --only-formulae
+            - run: brew test-bot --only-formulae
               if: github.event_name == 'pull_request'
-              run: brew test-bot --only-formulae
     YAML
 
     (tap.path/".github/workflows").mkpath
diff --git a/Library/Homebrew/env_config.rb b/Library/Homebrew/env_config.rb
index 893bc26bc327562ffc96161db92d0b09e022d6a2..f6a578b1acaa77ff74e07d74eb7d896e5733541c 100644
--- a/Library/Homebrew/env_config.rb
+++ b/Library/Homebrew/env_config.rb
@@ -55,7 +55,12 @@ module Homebrew
         default:      HOMEBREW_DEFAULT_CACHE,
       },
       HOMEBREW_CASK_OPTS:                 {
-        description: "Options which should be used for all `cask` commands.",
+        description: "Options which should be used for all `cask` commands. All `--*dir` options, " \
+                     "`--language`, `--require-sha`, `--no-quarantine` and `--no-binaries` are supported." \
+                     "\n" \
+                     "For example, you might add something like the following to your " \
+                     "~/.profile, ~/.bash_profile, or ~/.zshenv:\n\n" \
+                     "`export HOMEBREW_CASK_OPTS='--appdir=~/Applications --fontdir=/Library/Fonts'`",
       },
       HOMEBREW_CLEANUP_MAX_AGE_DAYS:      {
         description: "Cleanup all cached files older than this many days.",
@@ -276,6 +281,9 @@ module Homebrew
         description: "A comma-separated list of hostnames and domain names excluded " \
                      "from proxying by `curl`(1), `git`(1) and `svn`(1) when downloading through Homebrew.",
       },
+      SUDO_ASKPASS:                       {
+        description: "When this variable is set, the `-A` option is passed when calling `sudo`(8)",
+      },
     }.freeze
 
     def env_method_name(env, hash)
diff --git a/Library/Homebrew/manpages/brew-cask.1.md b/Library/Homebrew/manpages/brew-cask.1.md
index 32da99944a5f332c13b1aa78670cb6d0c5b76e94..8b137891791fe96927ad78e64b0aad7bded08bdc 100644
--- a/Library/Homebrew/manpages/brew-cask.1.md
+++ b/Library/Homebrew/manpages/brew-cask.1.md
@@ -1,278 +1 @@
-brew-cask(1) - a friendly binary installer for macOS
-====================================================
 
-## SYNOPSIS
-
-`brew cask` command [options] [ <token> ... ]
-
-## DESCRIPTION
-
-Homebrew Cask is a tool for installing precompiled macOS binaries (such as
-Applications) from the command line. The user is never required to use the
-graphical user interface.
-
-## FREQUENTLY USED COMMANDS
-
-  * `install` [--force] [--skip-cask-deps] [--require-sha] [--no-quarantine] [--language=<iso-language>[,<iso-language> ... ]] <token> [ <token> ... ]:
-    Install Cask identified by <token>.
-
-  * `uninstall` [--force] <token> [ <token> ... ]:
-    Uninstall Cask identified by <token>.
-
-## COMMANDS
-
-  * `--cache` <token> [ <token> ... ]:
-    Display the file used to cache the Cask identified by <token>.
-
-  * `audit` [--language=<iso-language>[,<iso-language> ... ]] [ <token> ... ]:
-    Check the given Casks for installability.
-    If no tokens are given on the command line, all Casks are audited.
-
-  * `cat` <token> [ <token> ... ]:
-    Dump the given Cask definition file to the standard output.
-
-  * `create` <token>:
-    Generate a Cask definition file for the Cask identified by <token>
-    and open a template for it in your favorite editor.
-
-  * `doctor` or `dr`:
-    Check for configuration issues. Can be useful to upload as a gist for
-    developers along with a bug report.
-
-  * `edit` <token>:
-    Open the given Cask definition file for editing.
-
-  * `fetch` [--force] [--no-quarantine] <token> [ <token> ... ]:
-    Download remote application files for the given Cask to the local
-    cache. With `--force`, force re-download even if the files are already
-    cached. `--no-quarantine` will prevent Gatekeeper from
-    enforcing its security restrictions on the Cask.
-
-  * `home` or `homepage` [ <token> ... ]:
-    Display the homepage associated with a given Cask in a browser.
-
-    With no arguments, display the project page <https://brew.sh/>.
-
-  * `info` or `abv` <token> [ <token> ... ]:
-    Display information about the given Cask.
-
-  * `install` [--force] [--skip-cask-deps] [--require-sha] [--no-quarantine] <token> [ <token> ... ]:
-    Install the given Cask. With `--force`, re-install even if the Cask
-    appears to be already present. With `--skip-cask-deps`, skip any Cask
-    dependencies. `--require-sha` will abort installation if the Cask does not
-    have a checksum defined. `--no-quarantine` will prevent Gatekeeper from
-    enforcing its security restrictions on the Cask.
-
-    <token> is usually the ID of a Cask,
-    but see [OTHER WAYS TO SPECIFY A CASK][] for variations.
-
-  * `list` or `ls` [-1] [--versions] [ <token> ... ]:
-    Without any arguments, list all installed Casks. With `-1`, always
-    format the output in a single column. With `--versions`, show all installed
-    versions.
-
-    If <token> is given, summarize the staged files associated with the
-    given Cask.
-
-  * `outdated` [--greedy] [--verbose|--quiet] [ <token> ... ]:
-    Without token arguments, display all the installed Casks that have newer
-    versions available in the tap; otherwise check only the tokens given
-    in the command line.
-    If `--greedy` is given then also include in the output the Casks having
-    `auto_updates true` or `version :latest`. Otherwise they are skipped
-    because there is no reliable way to know when updates are available for
-    them.<br>
-    `--verbose` forces the display of the outdated and latest version.<br>
-    `--quiet` suppresses the display of versions.
-
-  * `reinstall` [--no-quarantine] <token> [ <token> ... ]:
-    Reinstall the given Cask.
-
-  * `style` [--fix] [ <token> ... ]:
-    Check the given Casks for correct style using RuboCop (with custom Cask cops).
-    If no tokens are given on the command line, all Casks are checked.
-    With `--fix`, auto-correct any style errors if possible.
-
-  * `uninstall` or `rm` or `remove` [--force] <token> [ <token> ... ]:
-    Uninstall the given Cask. With `--force`, uninstall even if the Cask
-    does not appear to be present.
-
-  * `upgrade` [--force] [--greedy] [--dry-run] <token> [ <token> ... ]:
-    Without token arguments, upgrade all the installed Casks that have newer
-    versions available in the tap; otherwise update the tokens given
-    in the command line.
-    If `--greedy` is given then also upgrade the Casks having `auto_updates true`
-    or `version :latest`.
-
-    If `--dry-run` is given, show what would be upgraded, but do not actually
-    upgrade anything.
-
-  * `zap` [--force] <token> [ <token> ... ]:
-    Unconditionally remove _all_ files associated with the given Cask.
-    With `--force`, zap even if the Cask does not appear to be currently installed.
-
-    Implicitly performs all actions associated with `uninstall`.
-
-    Removes all staged versions of the Cask distribution found under
-    `<Caskroom_path>/`<token>.
-
-    If the Cask definition contains a `zap` stanza, performs additional
-    `zap` actions as defined there, such as removing local preference
-    files. `zap` actions are variable, depending on the level of detail
-    defined by the Cask author.
-
-    **`zap` may remove files which are shared between applications.**
-
-## INTERNAL COMMANDS
-
-  * `_stanza` <stanza_name> [ --table | --yaml | --inspect | --quiet ] [ <token> ... ]:
-    Given a <stanza_name> and a <token>, returns the current stanza for a
-    given Cask. If no <token> is given, then data for all Casks is returned.
-
-## OPTIONS
-
-To make these options persistent, see the [ENVIRONMENT](#environment) section, below.
-
-Some of these (such as `--prefpanedir`) may be subject to removal
-in a future version.
-
-  * `--force`:
-    Force an install to proceed even when a previously-existing install
-    is detected.
-
-  * `--skip-cask-deps`:
-    Skip Cask dependencies when installing.
-
-  *  `--require-sha`:
-    Abort Cask installation if the Cask does not have a checksum defined.
-
-  *  `--no-quarantine`:
-    Prevent Gatekeeper from enforcing its security restrictions on the Cask.
-    This will let you run it straightaway.
-
-  * `--verbose`:
-    Give additional feedback during installation.
-
-  * `--appdir=<path>`:
-    Target location for Applications. The default value is `/Applications`.
-
-  * `--language=<iso-language>[,<iso-language> ... ]]`:
-    Set language of the Cask to install. The first matching language is used, otherwise the default language on the Cask. The default value is the `language of your system`.
-
-  * `--colorpickerdir=<path>`:
-    Target location for Color Pickers. The default value is `~/Library/ColorPickers`.
-
-  * `--prefpanedir=<path>`:
-    Target location for Preference Panes. The default value is `~/Library/PreferencePanes`.
-
-  * `--qlplugindir=<path>`:
-    Target location for QuickLook Plugins. The default value is `~/Library/QuickLook`.
-
-  * `--dictionarydir=<path>`:
-    Target location for Dictionaries. The default value is `~/Library/Dictionaries`.
-
-  * `--fontdir=<path>`:
-    Target location for Fonts. The default value is `~/Library/Fonts`.
-
-  * `--servicedir=<path>`:
-    Target location for Services. The default value is `~/Library/Services`.
-
-  * `--input_methoddir=<path>`:
-    Target location for Input Methods. The default value is `~/Library/Input Methods`.
-
-  * `--internet_plugindir=<path>`:
-    Target location for Internet Plugins. The default value is `~/Library/Internet Plug-Ins`.
-
-  * `--audio_unit_plugindir=<path>`:
-    Target location for Audio Unit Plugins. The default value is `~/Library/Audio/Plug-Ins/Components`.
-
-  * `--vst_plugindir=<path>`:
-    Target location for VST Plugins. The default value is `~/Library/Audio/Plug-Ins/VST`.
-
-  * `--vst3_plugindir=<path>`:
-    Target location for VST3 Plugins. The default value is `~/Library/Audio/Plug-Ins/VST3`.
-
-  * `--screen_saverdir=<path>`:
-    Target location for Screen Savers. The default value is `~/Library/Screen Savers`.
-
-  * `--no-binaries`:
-    Do not link "helper" executables to `/usr/local/bin`.
-
-  * `--debug`:
-    Output debugging information of use to Cask authors and developers.
-
-## INTERACTION WITH HOMEBREW
-
-Homebrew Cask is implemented as a external command for Homebrew. That means
-this project is entirely built upon the Homebrew infrastructure. For
-example, upgrades to the Homebrew Cask tool are received through Homebrew:
-
-    brew update; brew cask upgrade; brew cleanup
-
-And updates to individual Cask definitions are received whenever you issue
-the Homebrew command:
-
-    brew update
-
-## OTHER WAYS TO SPECIFY A CASK
-
-Most Homebrew Cask commands can accept a Cask token as an argument. As
-described above, the argument can take the form of:
-
-  * A simple token, e.g. `google-chrome`
-
-Homebrew Cask also accepts three other forms in place of plain tokens:
-
-  * A fully-qualified token which includes the Tap name, e.g.
-    `homebrew/cask-fonts/font-symbola`
-
-  * A fully-qualified pathname to a Cask file, e.g.
-    `/usr/local/Library/Taps/homebrew/homebrew-cask/Casks/google-chrome.rb`
-
-  * A `curl`-retrievable URI to a Cask file, e.g.
-    `https://raw.githubusercontent.com/Homebrew/homebrew-cask/f25b6babcd398abf48e33af3d887b2d00de1d661/Casks/google-chrome.rb`
-
-## ENVIRONMENT
-
-Homebrew Cask respects many of the environment variables used by the
-parent command `brew`. Please refer to the `brew`(1) man page for more
-information.
-
-Environment variables specific to Homebrew Cask:
-
-  * `HOMEBREW_CASK_OPTS`:
-    This variable may contain any arguments normally used as options on
-    the command-line. This is particularly useful to make options persistent.
-    For example, you might add to your ~/.profile, ~/.bash_profile, or ~/.zshenv
-    something like:
-
-               export HOMEBREW_CASK_OPTS='--appdir=~/Applications --fontdir=/Library/Fonts'
-
-Other environment variables:
-
-  * `SUDO_ASKPASS`:
-    When this variable is set, Homebrew Cask will call `sudo`(8) with the `-A` option.
-
-
-## SEE ALSO
-
-The Homebrew home page: <https://brew.sh/>
-
-The Homebrew Cask GitHub page: <https://github.com/Homebrew/homebrew-cask>
-
-`brew`(1), `curl`(1)
-
-## AUTHORS
-
-Paul Hinze and Contributors.
-
-Man page format based on `brew.1.md` from Homebrew.
-
-## BUGS
-
-We still have bugs - and we are busy fixing them!  If you have a problem, don't
-be shy about reporting it on our [GitHub issues page](https://github.com/Homebrew/homebrew-cask/issues?state=open).
-
-When reporting bugs, remember that Homebrew Cask is an separate repository within
-Homebrew. Do your best to direct bug reports to the appropriate repository. If
-your command-line started with `brew cask`, bring the bug to us first!
diff --git a/Library/Homebrew/manpages/brew.1.md.erb b/Library/Homebrew/manpages/brew.1.md.erb
index cea0745e3374ca764ef11b78bcb36f71d0dc3460..593037011fe76d63745fff8a5193bcc9104021f1 100644
--- a/Library/Homebrew/manpages/brew.1.md.erb
+++ b/Library/Homebrew/manpages/brew.1.md.erb
@@ -65,12 +65,6 @@ If no search term is provided, all locally available formulae are listed.
 
 ## OFFICIAL EXTERNAL COMMANDS
 
-### `cask` <subcommand>
-
-Install macOS applications distributed as binaries. See `brew-cask`(1).
-
-**Homebrew/homebrew-cask**: <https://github.com/Homebrew/homebrew-cask>
-
 <%= official_external_commands %>
 
 ## CUSTOM EXTERNAL COMMANDS
@@ -101,6 +95,12 @@ can take several different forms:
     Homebrew can install formulae from a local path. It can point to either a
     formula file or a bottle.
 
+## SPECIFYING CASKS
+
+Many Homebrew Cask commands accept one or more <cask> arguments. These can be
+specified the same way as the <formula> arguments described in
+`SPECIFYING FORMULAE` above.
+
 ## ENVIRONMENT
 
 Note that environment variables must have a value set to be detected. For example, run
@@ -130,7 +130,7 @@ Homebrew Documentation: <https://docs.brew.sh>
 
 Homebrew API: <https://rubydoc.brew.sh>
 
-`brew-cask`(1), `git`(1), `git-log`(1)
+`git`(1), `git-log`(1)
 
 ## AUTHORS
 
@@ -155,3 +155,6 @@ See our issues on GitHub:
 
   * **Homebrew/homebrew-core**:
     <https://github.com/Homebrew/homebrew-core/issues>
+
+  * **Homebrew/homebrew-cask**:
+    <https://github.com/Homebrew/homebrew-cask/issues>
diff --git a/Library/Homebrew/rubocops/shared/desc_helper.rb b/Library/Homebrew/rubocops/shared/desc_helper.rb
index 6496e0ed7def1d38ffa791335756c56a0cdbf34a..3ed62a036ba4653b95e06ebe6393f30cfbdee48c 100644
--- a/Library/Homebrew/rubocops/shared/desc_helper.rb
+++ b/Library/Homebrew/rubocops/shared/desc_helper.rb
@@ -8,7 +8,11 @@ module RuboCop
     module DescHelper
       include HelperFunctions
 
+      MAX_DESC_LENGTH = 80
+
       VALID_LOWERCASE_WORDS = %w[
+        iOS
+        iPhone
         macOS
       ].freeze
 
@@ -25,8 +29,8 @@ module RuboCop
         desc = desc_call.first_argument
 
         # Check if the desc is empty.
-        pure_desc_length = string_content(desc).length
-        if pure_desc_length.zero?
+        desc_length = string_content(desc).length
+        if desc_length.zero?
           problem "The desc (description) should not be an empty string."
           return
         end
@@ -62,13 +66,11 @@ module RuboCop
           problem "Description shouldn't end with a full stop."
         end
 
-        # Check if the desc length exceeds 80 characters.
-        desc_length = "#{name}: #{string_content(desc)}".length
-        max_desc_length = 80
-        return if desc_length <= max_desc_length
+        # Check if the desc length exceeds maximum length.
+        return if desc_length <= MAX_DESC_LENGTH
 
-        problem "Description is too long. \"name: desc\" should be less than #{max_desc_length} characters. " \
-                "The current combined length is #{desc_length}."
+        problem "Description is too long. It should be less than #{MAX_DESC_LENGTH} characters. " \
+                "The current length is #{desc_length}."
       end
 
       def autocorrect_desc(node, name)
diff --git a/Library/Homebrew/sorbet/files.yaml b/Library/Homebrew/sorbet/files.yaml
index 25b5b856ddbd49ce62ce866259d0e8d9fc2d3511..444006e5f3d9d8fefcb9ac1af3828bbfa2f868fe 100644
--- a/Library/Homebrew/sorbet/files.yaml
+++ b/Library/Homebrew/sorbet/files.yaml
@@ -449,7 +449,6 @@ false:
 false:
   - ./PATH.rb
   - ./build_environment.rb
-  - ./cask/cmd/options.rb
   - ./cask/config.rb
   - ./cask/dsl/appcast.rb
   - ./cask/dsl/container.rb
@@ -505,7 +504,6 @@ false:
   - ./test/cache_store_spec.rb
   - ./test/cask/cask_loader/from_content_loader_spec.rb
   - ./test/cask/cask_loader/from_uri_loader_spec.rb
-  - ./test/cask/cmd/options_spec.rb
   - ./test/cask/cmd/shared_examples/invalid_option.rb
   - ./test/cask/config_spec.rb
   - ./test/cask/denylist_spec.rb
diff --git a/Library/Homebrew/test/cask/cmd/audit_spec.rb b/Library/Homebrew/test/cask/cmd/audit_spec.rb
index c9028ec3b764d5c64cdd62656769b8385f4e9dbf..96e295f618cf226dd77b590d912a6a003d3e9726 100644
--- a/Library/Homebrew/test/cask/cmd/audit_spec.rb
+++ b/Library/Homebrew/test/cask/cmd/audit_spec.rb
@@ -22,176 +22,100 @@ describe Cask::Cmd::Audit, :cask do
       expect(Cask::CaskLoader).to receive(:load).with(cask_token).and_return(cask)
 
       expect(Cask::Auditor).to receive(:audit)
-        .with(cask, audit_download:        false,
-                    audit_appcast:         false,
-                    audit_token_conflicts: false,
-                    audit_new_cask:        false,
-                    audit_online:          false,
-                    audit_strict:          false,
-                    quarantine:            true)
+        .with(cask, quarantine: true)
         .and_return(result)
 
       described_class.run(cask_token)
     end
   end
 
-  describe "rules for downloading a Cask" do
-    it "does not download the Cask per default" do
-      allow(Cask::CaskLoader).to receive(:load).and_return(cask)
-      expect(Cask::Auditor).to receive(:audit)
-        .with(cask, audit_download:        false,
-                    audit_appcast:         false,
-                    audit_token_conflicts: false,
-                    audit_new_cask:        false,
-                    audit_online:          false,
-                    audit_strict:          false,
-                    quarantine:            true)
-        .and_return(result)
+  it "does not pass anything if no flags are specified" do
+    allow(Cask::CaskLoader).to receive(:load).and_return(cask)
+    expect(Cask::Auditor).to receive(:audit)
+      .with(cask, quarantine: true)
+      .and_return(result)
 
-      described_class.run("casktoken")
-    end
+    described_class.run("casktoken")
+  end
 
-    it "download a Cask if --download flag is set" do
-      allow(Cask::CaskLoader).to receive(:load).and_return(cask)
-      expect(Cask::Auditor).to receive(:audit)
-        .with(cask, audit_download:        true,
-                    audit_appcast:         false,
-                    audit_token_conflicts: false,
-                    audit_new_cask:        false,
-                    audit_online:          false,
-                    audit_strict:          false,
-                    quarantine:            true)
-        .and_return(result)
+  it "passes `audit_download` if the `--download` flag is specified" do
+    allow(Cask::CaskLoader).to receive(:load).and_return(cask)
+    expect(Cask::Auditor).to receive(:audit)
+      .with(cask, audit_download: true, quarantine: true)
+      .and_return(result)
 
-      described_class.run("casktoken", "--download")
-    end
+    described_class.run("casktoken", "--download")
   end
 
-  describe "rules for checking token conflicts" do
-    it "does not check for token conflicts per default" do
-      allow(Cask::CaskLoader).to receive(:load).and_return(cask)
-      expect(Cask::Auditor).to receive(:audit)
-        .with(cask, audit_download:        false,
-                    audit_appcast:         false,
-                    audit_token_conflicts: false,
-                    audit_new_cask:        false,
-                    audit_online:          false,
-                    audit_strict:          false,
-                    quarantine:            true)
-        .and_return(result)
+  it "passes `audit_token_conflicts` if the `--token-conflicts` flag is specified" do
+    allow(Cask::CaskLoader).to receive(:load).and_return(cask)
+    expect(Cask::Auditor).to receive(:audit)
+      .with(cask, audit_token_conflicts: true, quarantine: true)
+      .and_return(result)
 
-      described_class.run("casktoken")
-    end
+    described_class.run("casktoken", "--token-conflicts")
+  end
 
-    it "checks for token conflicts if --token-conflicts flag is set" do
-      allow(Cask::CaskLoader).to receive(:load).and_return(cask)
-      expect(Cask::Auditor).to receive(:audit)
-        .with(cask, audit_download:        false,
-                    audit_appcast:         false,
-                    audit_token_conflicts: true,
-                    audit_new_cask:        false,
-                    audit_online:          false,
-                    audit_strict:          false,
-                    quarantine:            true)
-        .and_return(result)
+  it "passes `audit_strict` and `audit_token_conflicts` if the `--strict` flag is specified" do
+    allow(Cask::CaskLoader).to receive(:load).and_return(cask)
+    expect(Cask::Auditor).to receive(:audit)
+      .with(cask, audit_strict: true, audit_token_conflicts: true, quarantine: true)
+      .and_return(result)
 
-      described_class.run("casktoken", "--token-conflicts")
-    end
+    described_class.run("casktoken", "--strict")
   end
 
-  describe "rules for checking strictly" do
-    it "does not check strictly per default" do
-      allow(Cask::CaskLoader).to receive(:load).and_return(cask)
-      expect(Cask::Auditor).to receive(:audit)
-        .with(cask, audit_download:        false,
-                    audit_appcast:         false,
-                    audit_token_conflicts: false,
-                    audit_new_cask:        false,
-                    audit_online:          false,
-                    audit_strict:          false,
-                    quarantine:            true)
-        .and_return(result)
-
-      described_class.run("casktoken")
-    end
+  it "passes `audit_online` if the `--online` flag is specified" do
+    allow(Cask::CaskLoader).to receive(:load).and_return(cask)
+    expect(Cask::Auditor).to receive(:audit)
+      .with(cask, audit_online: true, audit_appcast: true, audit_download: true, quarantine: true)
+      .and_return(result)
 
-    it "checks strictly if --strict flag is set" do
-      allow(Cask::CaskLoader).to receive(:load).and_return(cask)
-      expect(Cask::Auditor).to receive(:audit)
-        .with(cask, audit_download:        false,
-                    audit_appcast:         false,
-                    audit_token_conflicts: true,
-                    audit_new_cask:        false,
-                    audit_online:          false,
-                    audit_strict:          true,
-                    quarantine:            true)
-        .and_return(result)
+    described_class.run("casktoken", "--online")
+  end
 
-      described_class.run("casktoken", "--strict")
-    end
+  it "passes `audit_appcast`, `audit_download`, `audit_new_cask`, `audit_online`, `audit_strict` " \
+     "and `audit_token_conflicts` if the `--new-cask` flag is specified" do
+    allow(Cask::CaskLoader).to receive(:load).and_return(cask)
+    expect(Cask::Auditor).to receive(:audit)
+      .with(cask, audit_appcast:         true,
+                  audit_download:        true,
+                  audit_new_cask:        true,
+                  audit_online:          true,
+                  audit_strict:          true,
+                  audit_token_conflicts: true,
+                  quarantine:            true)
+      .and_return(result)
+
+    described_class.run("casktoken", "--new-cask")
   end
 
-  describe "rules for checking online" do
-    it "does not check online per default" do
-      allow(Cask::CaskLoader).to receive(:load).and_return(cask)
-      expect(Cask::Auditor).to receive(:audit)
-        .with(cask, audit_download:        false,
-                    audit_appcast:         false,
-                    audit_token_conflicts: false,
-                    audit_new_cask:        false,
-                    audit_online:          false,
-                    audit_strict:          false,
-                    quarantine:            true)
-        .and_return(result)
+  it "passes `language` if the `--language` flag is specified" do
+    allow(Cask::CaskLoader).to receive(:load).and_return(cask)
+    expect(Cask::Auditor).to receive(:audit)
+      .with(cask, quarantine: true, language: ["de-AT"])
+      .and_return(result)
 
-      described_class.run("casktoken")
-    end
+    described_class.run("casktoken", "--language=de-AT")
+  end
 
-    it "checks online if --online flag is set" do
-      allow(Cask::CaskLoader).to receive(:load).and_return(cask)
-      expect(Cask::Auditor).to receive(:audit)
-        .with(cask, audit_download:        true,
-                    audit_appcast:         true,
-                    audit_token_conflicts: false,
-                    audit_new_cask:        false,
-                    audit_online:          true,
-                    audit_strict:          false,
-                    quarantine:            true)
-        .and_return(result)
+  it "passes `quarantine` if the `--no-quarantine` flag is specified" do
+    allow(Cask::CaskLoader).to receive(:load).and_return(cask)
+    expect(Cask::Auditor).to receive(:audit)
+      .with(cask, quarantine: false)
+      .and_return(result)
 
-      described_class.run("casktoken", "--online")
-    end
+    described_class.run("casktoken", "--no-quarantine")
   end
 
-  describe "rules for checking new casks" do
-    it "does not check new casks per default" do
-      allow(Cask::CaskLoader).to receive(:load).and_return(cask)
-      expect(Cask::Auditor).to receive(:audit)
-        .with(cask, audit_download:        false,
-                    audit_appcast:         false,
-                    audit_token_conflicts: false,
-                    audit_new_cask:        false,
-                    audit_online:          false,
-                    audit_strict:          false,
-                    quarantine:            true)
-        .and_return(result)
+  it "passes `quarantine` if the `--no-quarantine` flag is in HOMEBREW_CASK_OPTS" do
+    ENV["HOMEBREW_CASK_OPTS"] = "--no-quarantine"
 
-      described_class.run("casktoken")
-    end
+    allow(Cask::CaskLoader).to receive(:load).and_return(cask)
+    expect(Cask::Auditor).to receive(:audit)
+      .with(cask, quarantine: false)
+      .and_return(result)
 
-    it "checks new casks if --new-cask flag is set" do
-      allow(Cask::CaskLoader).to receive(:load).and_return(cask)
-      expect(Cask::Auditor).to receive(:audit)
-        .with(cask, audit_download:        true,
-                    audit_appcast:         true,
-                    audit_token_conflicts: true,
-                    audit_new_cask:        true,
-                    audit_online:          true,
-                    audit_strict:          true,
-                    quarantine:            true)
-        .and_return(result)
-
-      described_class.run("casktoken", "--new-cask")
-    end
+    described_class.run("casktoken")
   end
 end
diff --git a/Library/Homebrew/test/cask/cmd/create_spec.rb b/Library/Homebrew/test/cask/cmd/create_spec.rb
index ab9a0c95b228a43277393858f7a5766f87d89868..d0f0334632ebf71c2affefe3e900c0d2ace18604 100644
--- a/Library/Homebrew/test/cask/cmd/create_spec.rb
+++ b/Library/Homebrew/test/cask/cmd/create_spec.rb
@@ -46,7 +46,7 @@ describe Cask::Cmd::Create, :cask do
   it "raises an exception when more than one Cask is given" do
     expect {
       described_class.run("additional-cask", "another-cask")
-    }.to raise_error(/Only one Cask can be created at a time\./)
+    }.to raise_error(UsageError, /Only one cask can be created at a time\./)
   end
 
   it "raises an exception when the Cask already exists" do
diff --git a/Library/Homebrew/test/cask/cmd/doctor_spec.rb b/Library/Homebrew/test/cask/cmd/doctor_spec.rb
index 166808389dedf92baa3d148e2464fcb8a6084dc5..5351f93e54fe3577c572df7fc678e8dc859774cb 100644
--- a/Library/Homebrew/test/cask/cmd/doctor_spec.rb
+++ b/Library/Homebrew/test/cask/cmd/doctor_spec.rb
@@ -14,6 +14,6 @@ describe Cask::Cmd::Doctor, :cask do
   it "raises an exception when arguments are given" do
     expect {
       described_class.run("argument")
-    }.to raise_error(ArgumentError)
+    }.to raise_error(UsageError, /does not take named arguments/)
   end
 end
diff --git a/Library/Homebrew/test/cask/cmd/edit_spec.rb b/Library/Homebrew/test/cask/cmd/edit_spec.rb
index 676debf587e77714d86e1885ef4287d8407c4a48..e6a7d8fd14a3c8a267483596b35158a0899a0440 100644
--- a/Library/Homebrew/test/cask/cmd/edit_spec.rb
+++ b/Library/Homebrew/test/cask/cmd/edit_spec.rb
@@ -20,7 +20,7 @@ describe Cask::Cmd::Edit, :cask do
   it "raises an error when given more than one argument" do
     expect {
       described_class.new("local-caffeine", "local-transmission")
-    }.to raise_error(/Only one Cask can be edited at a time\./)
+    }.to raise_error(UsageError, /Only one cask can be edited at a time\./)
   end
 
   it "raises an exception when the Cask doesn't exist" do
diff --git a/Library/Homebrew/test/cask/cmd/home_spec.rb b/Library/Homebrew/test/cask/cmd/home_spec.rb
index ca9e5481f0fd1198ae34caa371a317c851ac27fb..f94229f27920cc06cf03dc8f4547bdec8024e61e 100644
--- a/Library/Homebrew/test/cask/cmd/home_spec.rb
+++ b/Library/Homebrew/test/cask/cmd/home_spec.rb
@@ -8,20 +8,4 @@ describe Cask::Cmd::Home, :cask do
   end
 
   it_behaves_like "a command that handles invalid options"
-
-  it "opens the homepage for the specified Cask" do
-    expect(described_class).to receive(:open_url).with("https://brew.sh/")
-    described_class.run("local-caffeine")
-  end
-
-  it "works for multiple Casks" do
-    expect(described_class).to receive(:open_url).with("https://brew.sh/")
-    expect(described_class).to receive(:open_url).with("https://brew.sh/")
-    described_class.run("local-caffeine", "local-transmission")
-  end
-
-  it "opens the project page when no Cask is specified" do
-    expect(described_class).to receive(:open_url).with("https://brew.sh/")
-    described_class.run
-  end
 end
diff --git a/Library/Homebrew/test/cask/cmd/info_spec.rb b/Library/Homebrew/test/cask/cmd/info_spec.rb
index ea3385dc52ec272c322533081d51d14c4f5644cb..3828d4d95e1f73a8af291eae9325b5cd538d7823 100644
--- a/Library/Homebrew/test/cask/cmd/info_spec.rb
+++ b/Library/Homebrew/test/cask/cmd/info_spec.rb
@@ -10,16 +10,18 @@ describe Cask::Cmd::Info, :cask do
 
   it "displays some nice info about the specified Cask" do
     expect {
-      described_class.run("local-caffeine")
+      described_class.run("local-transmission")
     }.to output(<<~EOS).to_stdout
-      local-caffeine: 1.2.3
-      https://brew.sh/
+      local-transmission: 2.61
+      https://transmissionbt.com/
       Not installed
-      From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/local-caffeine.rb
+      From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/local-transmission.rb
       ==> Name
-      None
+      Transmission
+      ==> Description
+      BitTorrent client
       ==> Artifacts
-      Caffeine.app (App)
+      Transmission.app (App)
     EOS
   end
 
@@ -33,6 +35,8 @@ describe Cask::Cmd::Info, :cask do
       From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/with-auto-updates.rb
       ==> Name
       AutoUpdates
+      ==> Description
+      None
       ==> Artifacts
       AutoUpdates.app (App)
     EOS
@@ -47,15 +51,19 @@ describe Cask::Cmd::Info, :cask do
         From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/local-caffeine.rb
         ==> Name
         None
+        ==> Description
+        None
         ==> Artifacts
         Caffeine.app (App)
 
         local-transmission: 2.61
-        https://brew.sh/
+        https://transmissionbt.com/
         Not installed
         From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/local-transmission.rb
         ==> Name
         Transmission
+        ==> Description
+        BitTorrent client
         ==> Artifacts
         Transmission.app (App)
       EOS
@@ -78,6 +86,8 @@ describe Cask::Cmd::Info, :cask do
       From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/with-caveats.rb
       ==> Name
       None
+      ==> Description
+      None
       ==> Artifacts
       Caffeine.app (App)
       ==> Caveats
@@ -103,6 +113,8 @@ describe Cask::Cmd::Info, :cask do
       From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/with-conditional-caveats.rb
       ==> Name
       None
+      ==> Description
+      None
       ==> Artifacts
       Caffeine.app (App)
     EOS
@@ -118,6 +130,8 @@ describe Cask::Cmd::Info, :cask do
       From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/with-languages.rb
       ==> Name
       None
+      ==> Description
+      None
       ==> Languages
       zh, en-US
       ==> Artifacts
@@ -135,6 +149,8 @@ describe Cask::Cmd::Info, :cask do
       From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/without-languages.rb
       ==> Name
       None
+      ==> Description
+      None
       ==> Artifacts
       Caffeine.app (App)
     EOS
@@ -163,6 +179,8 @@ describe Cask::Cmd::Info, :cask do
       ==> Names
       Docker Community Edition
       Docker CE
+      ==> Description
+      None
       ==> Artifacts
       Docker.app (App)
       ==> Analytics
@@ -174,6 +192,8 @@ describe Cask::Cmd::Info, :cask do
       ==> Names
       Docker Community Edition
       Docker CE
+      ==> Description
+      None
       ==> Artifacts
       Docker.app (App)
       ==> Analytics
diff --git a/Library/Homebrew/test/cask/cmd/list_spec.rb b/Library/Homebrew/test/cask/cmd/list_spec.rb
index b3af63e31f324ea9024c726d682bf396c0f10356..5ae6ed8f10156c7323b83d93733c191a0ab93ea0 100644
--- a/Library/Homebrew/test/cask/cmd/list_spec.rb
+++ b/Library/Homebrew/test/cask/cmd/list_spec.rb
@@ -90,7 +90,7 @@ describe Cask::Cmd::List, :cask do
     let(:casks) { ["local-caffeine", "local-transmission"] }
     let(:expected_output) {
       <<~EOS
-        [{"token":"local-caffeine","name":[],"desc":null,"homepage":"https://brew.sh/","url":"file:///usr/local/Homebrew/Library/Homebrew/test/support/fixtures/cask/caffeine.zip","appcast":null,"version":"1.2.3","sha256":"67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94","artifacts":[["Caffeine.app"]],"caveats":null,"depends_on":{},"conflicts_with":null,"container":null,"auto_updates":null},{"token":"local-transmission","name":["Transmission"],"desc":null,"homepage":"https://brew.sh/","url":"file:///usr/local/Homebrew/Library/Homebrew/test/support/fixtures/cask/transmission-2.61.dmg","appcast":null,"version":"2.61","sha256":"e44ffa103fbf83f55c8d0b1bea309a43b2880798dae8620b1ee8da5e1095ec68","artifacts":[["Transmission.app"]],"caveats":null,"depends_on":{},"conflicts_with":null,"container":null,"auto_updates":null}]
+        [{"token":"local-caffeine","name":[],"desc":null,"homepage":"https://brew.sh/","url":"file:///usr/local/Homebrew/Library/Homebrew/test/support/fixtures/cask/caffeine.zip","appcast":null,"version":"1.2.3","sha256":"67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94","artifacts":[["Caffeine.app"]],"caveats":null,"depends_on":{},"conflicts_with":null,"container":null,"auto_updates":null},{"token":"local-transmission","name":["Transmission"],"desc":"BitTorrent client","homepage":"https://transmissionbt.com/","url":"file:///usr/local/Homebrew/Library/Homebrew/test/support/fixtures/cask/transmission-2.61.dmg","appcast":null,"version":"2.61","sha256":"e44ffa103fbf83f55c8d0b1bea309a43b2880798dae8620b1ee8da5e1095ec68","artifacts":[["Transmission.app"]],"caveats":null,"depends_on":{},"conflicts_with":null,"container":null,"auto_updates":null}]
       EOS
     }
 
@@ -126,9 +126,9 @@ describe Cask::Cmd::List, :cask do
       expect {
         described_class.run("local-transmission", "local-caffeine")
       }.to output(<<~EOS).to_stdout
-        ==> Apps
+        ==> App
         #{transmission.config.appdir.join("Transmission.app")} (#{transmission.config.appdir.join("Transmission.app").abv})
-        ==> Apps
+        ==> App
         Missing App: #{caffeine.config.appdir.join("Caffeine.app")}
       EOS
     end
diff --git a/Library/Homebrew/test/cask/cmd/options_spec.rb b/Library/Homebrew/test/cask/cmd/options_spec.rb
deleted file mode 100644
index 6035b3a1bee4d4aa90b012aaef6239c185220109..0000000000000000000000000000000000000000
--- a/Library/Homebrew/test/cask/cmd/options_spec.rb
+++ /dev/null
@@ -1,129 +0,0 @@
-# frozen_string_literal: true
-
-describe Cask::Cmd, :cask do
-  it "supports setting the appdir" do
-    described_class.new.process_options("help", "--appdir=/some/path/foo")
-
-    expect(Cask::Config.global.appdir).to eq(Pathname.new("/some/path/foo"))
-  end
-
-  it "supports setting the appdir from ENV" do
-    ENV["HOMEBREW_CASK_OPTS"] = "--appdir=/some/path/bar"
-
-    described_class.new.process_options("help")
-
-    expect(Cask::Config.global.appdir).to eq(Pathname.new("/some/path/bar"))
-  end
-
-  it "supports setting the prefpanedir" do
-    described_class.new.process_options("help", "--prefpanedir=/some/path/foo")
-
-    expect(Cask::Config.global.prefpanedir).to eq(Pathname.new("/some/path/foo"))
-  end
-
-  it "supports setting the prefpanedir from ENV" do
-    ENV["HOMEBREW_CASK_OPTS"] = "--prefpanedir=/some/path/bar"
-
-    described_class.new.process_options("help")
-
-    expect(Cask::Config.global.prefpanedir).to eq(Pathname.new("/some/path/bar"))
-  end
-
-  it "supports setting the qlplugindir" do
-    described_class.new.process_options("help", "--qlplugindir=/some/path/foo")
-
-    expect(Cask::Config.global.qlplugindir).to eq(Pathname.new("/some/path/foo"))
-  end
-
-  it "supports setting the qlplugindir from ENV" do
-    ENV["HOMEBREW_CASK_OPTS"] = "--qlplugindir=/some/path/bar"
-
-    described_class.new.process_options("help")
-
-    expect(Cask::Config.global.qlplugindir).to eq(Pathname.new("/some/path/bar"))
-  end
-
-  it "supports setting the mdimporterdir" do
-    described_class.new.process_options("help", "--mdimporterdir=/some/path/foo")
-
-    expect(Cask::Config.global.mdimporterdir).to eq(Pathname.new("/some/path/foo"))
-  end
-
-  it "supports setting the mdimporterdir from ENV" do
-    ENV["HOMEBREW_CASK_OPTS"] = "--mdimporterdir=/some/path/bar"
-
-    described_class.new.process_options("help")
-
-    expect(Cask::Config.global.mdimporterdir).to eq(Pathname.new("/some/path/bar"))
-  end
-
-  it "supports setting the colorpickerdir" do
-    described_class.new.process_options("help", "--colorpickerdir=/some/path/foo")
-
-    expect(Cask::Config.global.colorpickerdir).to eq(Pathname.new("/some/path/foo"))
-  end
-
-  it "supports setting the colorpickerdir from ENV" do
-    ENV["HOMEBREW_CASK_OPTS"] = "--colorpickerdir=/some/path/bar"
-
-    described_class.new.process_options("help")
-
-    expect(Cask::Config.global.colorpickerdir).to eq(Pathname.new("/some/path/bar"))
-  end
-
-  it "supports setting the dictionarydir" do
-    described_class.new.process_options("help", "--dictionarydir=/some/path/foo")
-
-    expect(Cask::Config.global.dictionarydir).to eq(Pathname.new("/some/path/foo"))
-  end
-
-  it "supports setting the dictionarydir from ENV" do
-    ENV["HOMEBREW_CASK_OPTS"] = "--dictionarydir=/some/path/bar"
-
-    described_class.new.process_options("help")
-
-    expect(Cask::Config.global.dictionarydir).to eq(Pathname.new("/some/path/bar"))
-  end
-
-  it "supports setting the fontdir" do
-    described_class.new.process_options("help", "--fontdir=/some/path/foo")
-
-    expect(Cask::Config.global.fontdir).to eq(Pathname.new("/some/path/foo"))
-  end
-
-  it "supports setting the fontdir from ENV" do
-    ENV["HOMEBREW_CASK_OPTS"] = "--fontdir=/some/path/bar"
-
-    described_class.new.process_options("help")
-
-    expect(Cask::Config.global.fontdir).to eq(Pathname.new("/some/path/bar"))
-  end
-
-  it "supports setting the servicedir" do
-    described_class.new.process_options("help", "--servicedir=/some/path/foo")
-
-    expect(Cask::Config.global.servicedir).to eq(Pathname.new("/some/path/foo"))
-  end
-
-  it "supports setting the servicedir from ENV" do
-    ENV["HOMEBREW_CASK_OPTS"] = "--servicedir=/some/path/bar"
-
-    described_class.new.process_options("help")
-
-    expect(Cask::Config.global.servicedir).to eq(Pathname.new("/some/path/bar"))
-  end
-
-  it "allows additional options to be passed through" do
-    rest = described_class.new.process_options("edit", "foo", "--create", "--appdir=/some/path/qux")
-
-    expect(Cask::Config.global.appdir).to eq(Pathname.new("/some/path/qux"))
-    expect(rest).to eq(%w[edit foo --create])
-  end
-
-  describe "--help" do
-    it "sets the Cask help method to true" do
-      command = described_class.new("foo", "--help")
-      expect(command.help?).to be true
-    end
-  end
-end
diff --git a/Library/Homebrew/test/cask/cmd/outdated_spec.rb b/Library/Homebrew/test/cask/cmd/outdated_spec.rb
index c1c7e0547a31999b0dc837636925043a1dc963fa..18aa70a01de5012912520af8fdd36adc6ba4e071 100644
--- a/Library/Homebrew/test/cask/cmd/outdated_spec.rb
+++ b/Library/Homebrew/test/cask/cmd/outdated_spec.rb
@@ -15,8 +15,6 @@ describe Cask::Cmd::Outdated, :cask do
 
   before do
     installed.each { |cask| InstallHelper.install_with_caskfile(cask) }
-
-    allow_any_instance_of(described_class).to receive(:verbose?).and_return(true)
   end
 
   it_behaves_like "a command that handles invalid options"
@@ -25,7 +23,7 @@ describe Cask::Cmd::Outdated, :cask do
     it "checks all the installed Casks when no token is provided" do
       expect {
         described_class.run
-      }.to output(<<~EOS).to_stdout
+      }.to output(<<~EOS).to_stdout.as_tty
         local-caffeine (1.2.2) != 1.2.3
         local-transmission (2.60) != 2.61
       EOS
@@ -34,7 +32,7 @@ describe Cask::Cmd::Outdated, :cask do
     it "checks only the tokens specified in the command line" do
       expect {
         described_class.run("local-caffeine")
-      }.to output(<<~EOS).to_stdout
+      }.to output(<<~EOS).to_stdout.as_tty
         local-caffeine (1.2.2) != 1.2.3
       EOS
     end
@@ -42,17 +40,24 @@ describe Cask::Cmd::Outdated, :cask do
     it 'ignores "auto_updates" and "latest" Casks even when their tokens are provided in the command line' do
       expect {
         described_class.run("local-caffeine", "auto-updates", "version-latest-string")
-      }.to output(<<~EOS).to_stdout
+      }.to output(<<~EOS).to_stdout.as_tty
         local-caffeine (1.2.2) != 1.2.3
       EOS
     end
   end
 
-  describe "--quiet overrides --verbose" do
-    before do
-      allow_any_instance_of(described_class).to receive(:verbose?).and_call_original
+  describe "--quiet overrides TTY" do
+    it "lists only the names (no versions) of the outdated Casks with --quiet" do
+      expect {
+        described_class.run("--quiet")
+      }.to output(<<~EOS).to_stdout.as_tty
+        local-caffeine
+        local-transmission
+      EOS
     end
+  end
 
+  describe "--quiet overrides --verbose" do
     it "lists only the names (no versions) of the outdated Casks with --quiet" do
       expect {
         described_class.run("--verbose", "--quiet")
@@ -67,7 +72,7 @@ describe Cask::Cmd::Outdated, :cask do
     it 'includes the Casks with "auto_updates true" or "version latest" with --greedy' do
       expect {
         described_class.run("--greedy")
-      }.to output(<<~EOS).to_stdout
+      }.to output(<<~EOS).to_stdout.as_tty
         auto-updates (2.57) != 2.61
         local-caffeine (1.2.2) != 1.2.3
         local-transmission (2.60) != 2.61
@@ -81,7 +86,7 @@ describe Cask::Cmd::Outdated, :cask do
 
       expect {
         described_class.run("--greedy")
-      }.to output(<<~EOS).to_stdout
+      }.to output(<<~EOS).to_stdout.as_tty
         local-caffeine (1.2.2) != 1.2.3
         local-transmission (2.60) != 2.61
         version-latest-string (latest) != latest
diff --git a/Library/Homebrew/test/cask/cmd/style_spec.rb b/Library/Homebrew/test/cask/cmd/style_spec.rb
index 529e384c4f2b0a15ef69677912eb3d672b482134..0d7e8ea68e69b4d987f03c01138ba85e9f974f9e 100644
--- a/Library/Homebrew/test/cask/cmd/style_spec.rb
+++ b/Library/Homebrew/test/cask/cmd/style_spec.rb
@@ -46,7 +46,7 @@ describe Cask::Cmd::Style, :cask do
     subject { cli.cask_paths }
 
     before do
-      allow(cli).to receive(:args).and_return(tokens)
+      allow(cli).to receive(:args).and_return(instance_double(Homebrew::CLI::Args, named: tokens))
     end
 
     context "when no cask tokens are given" do
diff --git a/Library/Homebrew/test/cask/cmd_spec.rb b/Library/Homebrew/test/cask/cmd_spec.rb
index 6e5c3be8289265d46e49f6c0616fc7c5936c894d..a41b64f1e1c8e9dc6f3f8b8099093c79280d3754 100644
--- a/Library/Homebrew/test/cask/cmd_spec.rb
+++ b/Library/Homebrew/test/cask/cmd_spec.rb
@@ -1,31 +1,9 @@
 # frozen_string_literal: true
 
 describe Cask::Cmd, :cask do
-  it "lists the taps for Casks that show up in two taps" do
-    listing = described_class.nice_listing(%w[
-                                             homebrew/cask/adium
-                                             homebrew/cask/google-chrome
-                                             passcod/homebrew-cask/adium
-                                           ])
-
-    expect(listing).to eq(%w[
-                            google-chrome
-                            homebrew/cask/adium
-                            passcod/cask/adium
-                          ])
-  end
-
-  context "when given no arguments" do
-    it "exits successfully" do
-      expect(subject).not_to receive(:exit).with(be_nonzero)
-      subject.run
-    end
-  end
-
-  context "when no option is specified" do
-    it "--binaries is true by default" do
-      command = Cask::Cmd::Install.new("some-cask")
-      expect(command.binaries?).to be true
+  context "when no subcommand is given" do
+    it "raises an error" do
+      expect { subject.run }.to raise_error(UsageError, /subcommand/)
     end
   end
 
@@ -33,10 +11,9 @@ describe Cask::Cmd, :cask do
     let(:noop_command) { double("Cmd::Noop", run: nil) }
 
     it "prints help output when subcommand receives `--help` flag" do
-      command = described_class.new("info", "--help")
-
-      expect { command.run }.to output(/displays information about the given Cask/).to_stdout
-      expect(command.help?).to eq(true)
+      expect {
+        described_class.run("info", "--help")
+      }.to output(/Displays information about the given cask/).to_stdout
     end
 
     it "respects the env variable when choosing what appdir to create" do
diff --git a/Library/Homebrew/test/cli/parser_spec.rb b/Library/Homebrew/test/cli/parser_spec.rb
index c85a78d03be189bc73844a78514b97855096494b..97ac930d4daeefa503f06a01e188fe9d6c408b5a 100644
--- a/Library/Homebrew/test/cli/parser_spec.rb
+++ b/Library/Homebrew/test/cli/parser_spec.rb
@@ -15,6 +15,48 @@ describe Homebrew::CLI::Parser do
       allow(Homebrew::EnvConfig).to receive(:pry?).and_return(true)
     end
 
+    context "when using binary options" do
+      subject(:parser) {
+        described_class.new do
+          switch "--[no-]positive"
+        end
+      }
+
+      it "sets the positive name to false if the negative flag is passed" do
+        args = parser.parse(["--no-positive"])
+        expect(args).not_to be_positive
+      end
+
+      it "sets the positive name to true if the positive flag is passed" do
+        args = parser.parse(["--positive"])
+        expect(args).to be_positive
+      end
+    end
+
+    context "when using negative options" do
+      subject(:parser) {
+        described_class.new do
+          switch "--no-positive"
+        end
+      }
+
+      it "does not set the positive name" do
+        args = parser.parse(["--no-positive"])
+        expect(args.positive?).to be nil
+      end
+
+      it "fails when using the positive name" do
+        expect {
+          parser.parse(["--positive"])
+        }.to raise_error(/invalid option/)
+      end
+
+      it "sets the negative name to true if the negative flag is passed" do
+        args = parser.parse(["--no-positive"])
+        expect(args.no_positive?).to be true
+      end
+    end
+
     context "when `ignore_invalid_options` is true" do
       it "passes through invalid options" do
         args = parser.parse(["-v", "named-arg", "--not-a-valid-option"], ignore_invalid_options: true)
diff --git a/Library/Homebrew/test/cmd/home_spec.rb b/Library/Homebrew/test/cmd/home_spec.rb
index be1084ea51a1e0c03098077df98b0bab102ea41d..7fce3ed4bfeef1ad3ea40d62e515915127a93d32 100644
--- a/Library/Homebrew/test/cmd/home_spec.rb
+++ b/Library/Homebrew/test/cmd/home_spec.rb
@@ -20,6 +20,13 @@ describe "brew home", :integration_test do
     Cask::CaskLoader.load(local_caffeine_path).homepage
   }
 
+  it "opens the project page when no formula or cask is specified" do
+    expect { brew "home", "HOMEBREW_BROWSER" => "echo" }
+      .to output("https://brew.sh\n").to_stdout
+      .and not_to_output.to_stderr
+      .and be_a_success
+  end
+
   it "opens the homepage for a given Formula" do
     setup_test_formula "testballhome"
 
@@ -30,7 +37,7 @@ describe "brew home", :integration_test do
   end
 
   it "opens the homepage for a given Cask" do
-    expect { brew "home", cask_path("local-caffeine"), "HOMEBREW_BROWSER" => "echo" }
+    expect { brew "home", local_caffeine_path, "HOMEBREW_BROWSER" => "echo" }
       .to output(/#{local_caffeine_homepage}/).to_stdout
       .and not_to_output.to_stderr
       .and be_a_success
@@ -39,7 +46,7 @@ describe "brew home", :integration_test do
   it "opens the homepages for a given formula and Cask" do
     setup_test_formula "testballhome"
 
-    expect { brew "home", "testballhome", cask_path("local-caffeine"), "HOMEBREW_BROWSER" => "echo" }
+    expect { brew "home", "testballhome", local_caffeine_path, "HOMEBREW_BROWSER" => "echo" }
       .to output(/#{testballhome_homepage} #{local_caffeine_homepage}/).to_stdout
       .and not_to_output.to_stderr
       .and be_a_success
diff --git a/Library/Homebrew/test/rubocops/formula_desc_spec.rb b/Library/Homebrew/test/rubocops/formula_desc_spec.rb
index 8f7ea8f8063e9850284a046d750fa580d8e00501..e7c7509e41305edf31bf7d6dbd18f194e1d48cf0 100644
--- a/Library/Homebrew/test/rubocops/formula_desc_spec.rb
+++ b/Library/Homebrew/test/rubocops/formula_desc_spec.rb
@@ -30,7 +30,7 @@ describe RuboCop::Cop::FormulaAudit::Desc do
         class Foo < Formula
           url 'https://brew.sh/foo-1.0.tgz'
           desc 'Bar#{"bar" * 29}'
-          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Description is too long. "name: desc" should be less than 80 characters. The current combined length is 95.
+          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Description is too long. It should be less than 80 characters. The current length is 90.
         end
       RUBY
     end
@@ -41,7 +41,7 @@ describe RuboCop::Cop::FormulaAudit::Desc do
           url 'https://brew.sh/foo-1.0.tgz'
           desc 'Bar#{"bar" * 9}'\
             '#{"foo" * 21}'
-          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Description is too long. "name: desc" should be less than 80 characters. The current combined length is 98.
+          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Description is too long. It should be less than 80 characters. The current length is 93.
         end
       RUBY
     end
diff --git a/Library/Homebrew/test/support/fixtures/cask/Casks/local-transmission.rb b/Library/Homebrew/test/support/fixtures/cask/Casks/local-transmission.rb
index eada3e74c06bca82461ecc661dd6a053d25777d5..a4820e1c552ba4d78f986e09b931931fc8406dd2 100644
--- a/Library/Homebrew/test/support/fixtures/cask/Casks/local-transmission.rb
+++ b/Library/Homebrew/test/support/fixtures/cask/Casks/local-transmission.rb
@@ -4,7 +4,8 @@ cask "local-transmission" do
 
   url "file://#{TEST_FIXTURE_DIR}/cask/transmission-2.61.dmg"
   name "Transmission"
-  homepage "https://brew.sh/"
+  desc "BitTorrent client"
+  homepage "https://transmissionbt.com/"
 
   app "Transmission.app"
 end
diff --git a/Library/Homebrew/test/support/helper/spec/shared_context/homebrew_cask.rb b/Library/Homebrew/test/support/helper/spec/shared_context/homebrew_cask.rb
index 2f414c643a95f28f57c4167089ff7ca644ae3143..80328827a90329d4a79979649618a50d77aa77f3 100644
--- a/Library/Homebrew/test/support/helper/spec/shared_context/homebrew_cask.rb
+++ b/Library/Homebrew/test/support/helper/spec/shared_context/homebrew_cask.rb
@@ -8,8 +8,6 @@ require "test/support/helper/cask/never_sudo_system_command"
 
 module Cask
   class Config
-    remove_const :DEFAULT_DIRS
-
     DEFAULT_DIRS_PATHNAMES = {
       appdir:               Pathname(TEST_TMPDIR)/"cask-appdir",
       prefpanedir:          Pathname(TEST_TMPDIR)/"cask-prefpanedir",
@@ -27,6 +25,7 @@ module Cask
       screen_saverdir:      Pathname(TEST_TMPDIR)/"cask-screen_saverdir",
     }.freeze
 
+    remove_const :DEFAULT_DIRS
     DEFAULT_DIRS = DEFAULT_DIRS_PATHNAMES.transform_values(&:to_s).freeze
   end
 end
@@ -51,7 +50,7 @@ RSpec.shared_context "Homebrew Cask", :needs_macos do
 
       example.run
     ensure
-      FileUtils.rm_rf Cask::Config::DEFAULT_DIRS.values
+      FileUtils.rm_rf Cask::Config::DEFAULT_DIRS_PATHNAMES.values
       FileUtils.rm_rf [Cask::Config.global.binarydir, Cask::Caskroom.path, Cask::Cache.path]
       Tap.default_cask_tap.path.unlink
       third_party_tap.path.unlink
diff --git a/Library/Homebrew/utils/pypi.rb b/Library/Homebrew/utils/pypi.rb
index d60b09c30b62175c9d535eebd4d03917965509b0..eeb143b34df962b2807dc10115ec5e543754919b 100644
--- a/Library/Homebrew/utils/pypi.rb
+++ b/Library/Homebrew/utils/pypi.rb
@@ -12,6 +12,7 @@ module PyPI
     cloudformation-cli
     diffoscope
     dxpy
+    ipython
     molecule
     xonsh
   ].freeze
diff --git a/Library/Homebrew/utils/ruby.sh b/Library/Homebrew/utils/ruby.sh
index 3b07d3781651ae5fffef58c1313f6605a45416c2..ba73affb9d379f1babc67980cc0c811fb41a3911 100644
--- a/Library/Homebrew/utils/ruby.sh
+++ b/Library/Homebrew/utils/ruby.sh
@@ -9,6 +9,35 @@ test_ruby () {
               Gem::Version.new('$required_ruby_version').to_s.split('.').first(2)" 2>/dev/null
 }
 
+find_ruby() {
+  if [[ -n "$HOMEBREW_MACOS" ]]
+  then
+    echo "/System/Library/Frameworks/Ruby.framework/Versions/Current/usr/bin/ruby"
+  else
+    IFS=$'\n' # Do word splitting on new lines only
+    for ruby_exec in $(which -a ruby) $(PATH=$HOMEBREW_PATH which -a ruby)
+    do
+      if test_ruby "$ruby_exec"; then
+        echo "$ruby_exec"
+        break
+      fi
+    done
+    IFS=$' \t\n' # Restore IFS to its default value
+  fi
+}
+
+unusable_ruby() {
+  if [[ -n "$HOMEBREW_MACOS_SYSTEM_RUBY_NEW_ENOUGH" ]]
+  then
+    return 1
+  elif [[ -n "$HOMEBREW_RUBY_PATH" && -z "$HOMEBREW_FORCE_VENDOR_RUBY" ]] && test_ruby "$HOMEBREW_RUBY_PATH"
+  then
+    return 1
+  else
+    return 0
+  fi
+}
+
 setup-ruby-path() {
   local vendor_dir
   local vendor_ruby_root
@@ -16,17 +45,27 @@ setup-ruby-path() {
   local vendor_ruby_terminfo
   local vendor_ruby_latest_version
   local vendor_ruby_current_version
-  local usable_ruby
   # When bumping check if HOMEBREW_MACOS_SYSTEM_RUBY_NEW_ENOUGH (in brew.sh)
   # also needs to be changed.
   local required_ruby_version="2.6"
   local ruby_exec
-  local advice="
+  local upgrade_fail
+  local install_fail
+
+  if [[ -n $HOMEBREW_MACOS ]]
+  then
+    upgrade_fail="Failed to upgrade Homebrew Portable Ruby!"
+    install_fail="Failed to install Homebrew Portable Ruby (and your system version is too old)!"
+  else
+    local advice="
 If there's no Homebrew Portable Ruby available for your processor:
 - install Ruby $required_ruby_version with your system package manager (or rbenv/ruby-build)
 - make it first in your PATH
 - try again
 "
+    upgrade_fail="Failed to upgrade Homebrew Portable Ruby!$advice"
+    install_fail="Failed to install Homebrew Portable Ruby and cannot find another Ruby $required_ruby_version!$advice"
+  fi
 
   vendor_dir="$HOMEBREW_LIBRARY/Homebrew/vendor"
   vendor_ruby_root="$vendor_dir/portable-ruby/current"
@@ -45,60 +84,21 @@ If there's no Homebrew Portable Ruby available for your processor:
   if [[ -x "$vendor_ruby_path" ]]
   then
     HOMEBREW_RUBY_PATH="$vendor_ruby_path"
-    [[ -z "$HOMEBREW_MACOS" ]] && TERMINFO_DIRS="$vendor_ruby_terminfo"
+    TERMINFO_DIRS="$vendor_ruby_terminfo"
     if [[ $vendor_ruby_current_version != "$vendor_ruby_latest_version" ]]
     then
-      if ! brew vendor-install ruby
-      then
-        if [[ -n "$HOMEBREW_MACOS" ]]
-        then
-          odie "Failed to upgrade Homebrew Portable Ruby!"
-        else
-          odie "Failed to upgrade Homebrew Portable Ruby!$advice"
-        fi
-      fi
+      brew vendor-install ruby || odie "$upgrade_fail"
     fi
   else
-    if [[ -n "$HOMEBREW_MACOS" ]]
-    then
-      HOMEBREW_RUBY_PATH="/System/Library/Frameworks/Ruby.framework/Versions/Current/usr/bin/ruby"
-    else
-      IFS=$'\n' # Do word splitting on new lines only
-      for ruby_exec in $(which -a ruby) $(PATH=$HOMEBREW_PATH which -a ruby)
-      do
-        if test_ruby "$ruby_exec"; then
-          HOMEBREW_RUBY_PATH=$ruby_exec
-          break
-        fi
-      done
-      IFS=$' \t\n' # Restore IFS to its default value
-    fi
-
-    if [[ -n "$HOMEBREW_MACOS_SYSTEM_RUBY_NEW_ENOUGH" ]]
+    HOMEBREW_RUBY_PATH=$(find_ruby)
+    if [[ -z "$HOMEBREW_RUBY_PATH" || -n "$HOMEBREW_FORCE_VENDOR_RUBY" ]] || unusable_ruby
     then
-      usable_ruby=true
-    elif [[ -n "$HOMEBREW_RUBY_PATH" && -z "$HOMEBREW_FORCE_VENDOR_RUBY" ]] && test_ruby "$HOMEBREW_RUBY_PATH"
-    then
-      usable_ruby=true
-    fi
-
-    if [[ -z "$HOMEBREW_RUBY_PATH" || -n "$HOMEBREW_FORCE_VENDOR_RUBY" || -z $usable_ruby ]]
-    then
-      brew vendor-install ruby
-      if [[ ! -x "$vendor_ruby_path" ]]
-      then
-        if [[ -n "$HOMEBREW_MACOS" ]]
-        then
-          odie "Failed to install Homebrew Portable Ruby (and your system version is too old)!"
-        else
-          odie "Failed to install Homebrew Portable Ruby and cannot find another Ruby $required_ruby_version!$advice"
-        fi
-      fi
+      brew vendor-install ruby || odie "$install_fail"
       HOMEBREW_RUBY_PATH="$vendor_ruby_path"
-      [[ -z "$HOMEBREW_MACOS" ]] && TERMINFO_DIRS="$vendor_ruby_terminfo"
+      TERMINFO_DIRS="$vendor_ruby_terminfo"
     fi
   fi
 
   export HOMEBREW_RUBY_PATH
-  export TERMINFO_DIRS
+  [[ -n "$HOMEBREW_LINUX" && -n "$TERMINFO_DIRS" ]] && export TERMINFO_DIRS
 }
diff --git a/docs/Manpage.md b/docs/Manpage.md
index 424f86840368daa4500ea2608fe5910d63614259..8c2a62b3dcc8bf09da047b87667057b16a549f39 100644
--- a/docs/Manpage.md
+++ b/docs/Manpage.md
@@ -44,24 +44,117 @@ If no search term is provided, all locally available formulae are listed.
 
 ### `analytics` [*`subcommand`*]
 
-Control Homebrew's anonymous aggregate user behaviour analytics. Read more at
-<https://docs.brew.sh/Analytics>.
+Control Homebrew's anonymous aggregate user behaviour analytics.
+Read more at <https://docs.brew.sh/Analytics>.
 
 `brew analytics` [`state`]:
-    Display the current state of Homebrew's analytics.
+Display the current state of Homebrew's analytics.
 
 `brew analytics` [`on`|`off`]:
-    Turn Homebrew's analytics on or off respectively.
+Turn Homebrew's analytics on or off respectively.
 
 `brew analytics regenerate-uuid`:
-    Regenerate the UUID used for Homebrew's analytics.
+Regenerate the UUID used for Homebrew's analytics.
+
+### `cask` *`command`* [*`options`*] [*`cask`*]
+
+Homebrew Cask provides a friendly CLI workflow for the administration of macOS applications distributed as binaries.
+
+Commands:
+
+- `--cache`  
+  Display the file used to cache a *`cask`*
+
+- `audit`  
+  Check *`cask`* for Homebrew coding style violations
+
+- `cat`  
+  Dump raw source of a *`cask`* to the standard output
+
+- `create`  
+  Creates the given *`cask`* and opens it in an editor
+
+- `doctor`  
+  Checks for configuration issues
+
+- `edit`  
+  Open the given *`cask`* for editing
+
+- `fetch`  
+  Downloads remote application files to local cache
+
+- `help`  
+  Print help for `cask` commands
+
+- `home`  
+  Opens the homepage of the given *`cask`*
+
+- `info`  
+  Displays information about the given *`cask`*
+
+- `install`  
+  Installs the given *`cask`*
+
+- `list`  
+  Lists installed casks or the casks provided in the arguments
+
+- `outdated`  
+  List the outdated installed casks
+
+- `reinstall`  
+  Reinstalls the given *`cask`*
+
+- `style`  
+  Checks style of the given *`cask`* using RuboCop
+
+- `uninstall`  
+  Uninstalls the given *`cask`*
+
+- `upgrade`  
+  Upgrades all outdated casks or the specified casks
+
+- `zap`  
+  Zaps all files associated with the given *`cask`*
+
+See also: `man brew`
+
+* `--appdir`:
+  Target location for Applications. Default: `/Applications`
+* `--colorpickerdir`:
+  Target location for Color Pickers. Default: `~/Library/ColorPickers`
+* `--prefpanedir`:
+  Target location for Preference Panes. Default: `~/Library/PreferencePanes`
+* `--qlplugindir`:
+  Target location for QuickLook Plugins. Default: `~/Library/QuickLook`
+* `--mdimporterdir`:
+  Target location for Spotlight Plugins. Default: `~/Library/Spotlight`
+* `--dictionarydir`:
+  Target location for Dictionaries. Default: `~/Library/Dictionaries`
+* `--fontdir`:
+  Target location for Fonts. Default: `~/Library/Fonts`
+* `--servicedir`:
+  Target location for Services. Default: `~/Library/Services`
+* `--input_methoddir`:
+  Target location for Input Methods. Default: `~/Library/Input Methods`
+* `--internet_plugindir`:
+  Target location for Internet Plugins. Default: `~/Library/Internet Plug-Ins`
+* `--audio_unit_plugindir`:
+  Target location for Audio Unit Plugins. Default: `~/Library/Audio/Plug-Ins/Components`
+* `--vst_plugindir`:
+  Target location for VST Plugins. Default: `~/Library/Audio/Plug-Ins/VST`
+* `--vst3_plugindir`:
+  Target location for VST3 Plugins. Default: `~/Library/Audio/Plug-Ins/VST3`
+* `--screen_saverdir`:
+  Target location for Screen Savers. Default: `~/Library/Screen Savers`
+* `--language`:
+  Set language of the Cask to install. The first matching language is used, otherwise the default language on the Cask. The default value is the `language of your system`
 
 ### `cleanup` [*`options`*] [*`formula`*|*`cask`*]
 
-Remove stale lock files and outdated downloads for all formulae and casks, and
-remove old versions of installed formulae. If arguments are specified, only do
-this for the given formulae and casks. Removes all downloads more than 120 days
-old. This can be adjusted with `HOMEBREW_CLEANUP_MAX_AGE_DAYS`.
+Remove stale lock files and outdated downloads for all formulae and casks,
+and remove old versions of installed formulae. If arguments are specified,
+only do this for the given formulae and casks. Removes all downloads more than
+120 days old. This can be adjusted with `HOMEBREW_CLEANUP_MAX_AGE_DAYS`.
 
 * `--prune`:
   Remove all cache files older than specified *`days`*.
@@ -83,14 +176,14 @@ Show lists of built-in and external commands.
 
 ### `config`
 
-Show Homebrew and system configuration info useful for debugging. If you file a
-bug report, you will be required to provide this information.
+Show Homebrew and system configuration info useful for debugging. If you file
+a bug report, you will be required to provide this information.
 
 ### `deps` [*`options`*] [*`formula`*]
 
-Show dependencies for *`formula`*. Additional options specific to *`formula`* may be
-appended to the command. When given multiple formula arguments, show the
-intersection of dependencies for each formula.
+Show dependencies for *`formula`*. Additional options specific to *`formula`*
+may be appended to the command. When given multiple formula arguments,
+show the intersection of dependencies for each formula.
 
 * `-n`:
   Sort dependencies in topological order.
@@ -123,9 +216,9 @@ intersection of dependencies for each formula.
 
 ### `desc` [*`options`*] (*`text`*|`/`*`text`*`/`|*`formula`*)
 
-Display *`formula`*'s name and one-line description. Formula descriptions are
-cached; the cache is created on the first search, making that search slower than
-subsequent ones.
+Display *`formula`*'s name and one-line description.
+Formula descriptions are cached; the cache is created on the
+first search, making that search slower than subsequent ones.
 
 * `-s`, `--search`:
   Search both names and descriptions for *`text`*. If *`text`* is flanked by slashes, it is interpreted as a regular expression.
@@ -136,11 +229,11 @@ subsequent ones.
 
 ### `doctor` [*`options`*]
 
-Check your system for potential problems. Will exit with a non-zero status if
-any potential problems are found. Please note that these warnings are just used
-to help the Homebrew maintainers with debugging if you file an issue. If
-everything you use Homebrew for is working fine: please don't worry or file an
-issue; just ignore this.
+Check your system for potential problems. Will exit with a non-zero status
+if any potential problems are found. Please note that these warnings are just
+used to help the Homebrew maintainers with debugging if you file an issue. If
+everything you use Homebrew for is working fine: please don't worry or file
+an issue; just ignore this.
 
 * `--list-checks`:
   List all audit methods, which can be run individually if provided as arguments.
@@ -149,8 +242,8 @@ issue; just ignore this.
 
 ### `fetch` [*`options`*] *`formula`*
 
-Download a bottle (if available) or source packages for *`formula`*. For tarballs,
-also print SHA-256 checksums.
+Download a bottle (if available) or source packages for *`formula`*.
+For tarballs, also print SHA-256 checksums.
 
 * `--HEAD`:
   Fetch HEAD version instead of stable version.
@@ -173,8 +266,8 @@ also print SHA-256 checksums.
 
 ### `gist-logs` [*`options`*] *`formula`*
 
-Upload logs for a failed build of *`formula`* to a new Gist. Presents an error
-message if no logs are found.
+Upload logs for a failed build of *`formula`* to a new Gist. Presents an
+error message if no logs are found.
 
 * `--with-hostname`:
   Include the hostname in the Gist.
@@ -185,8 +278,8 @@ message if no logs are found.
 
 ### `home` [*`formula`*]
 
-Open *`formula`*'s homepage in a browser, or open Homebrew's own homepage if no
-formula is provided.
+Open *`formula`*'s homepage in a browser, or open Homebrew's own homepage
+if no formula is provided.
 
 ### `info` [*`options`*] [*`formula`*]
 
@@ -213,11 +306,10 @@ If *`formula`* is provided, show summary of information about *`formula`*.
 
 ### `install` [*`options`*] *`formula`*
 
-Install *`formula`*. Additional options specific to *`formula`* may be appended to
-the command.
+Install *`formula`*. Additional options specific to *`formula`* may be appended to the command.
 
-Unless `HOMEBREW_NO_INSTALL_CLEANUP` is set, `brew cleanup` will then be run for
-the installed formulae or, every 30 days, for all formulae.
+Unless `HOMEBREW_NO_INSTALL_CLEANUP` is set, `brew cleanup` will then be run for the
+installed formulae or, every 30 days, for all formulae.
 
 * `-d`, `--debug`:
   If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory.
@@ -264,8 +356,9 @@ List installed formulae that are not dependencies of another installed formula.
 
 ### `link`, `ln` [*`options`*] *`formula`*
 
-Symlink all of *`formula`*'s installed files into Homebrew's prefix. This is done
-automatically when you install formulae but can be useful for DIY installations.
+Symlink all of *`formula`*'s installed files into Homebrew's prefix. This
+is done automatically when you install formulae but can be useful for DIY
+installations.
 
 * `--overwrite`:
   Delete files that already exist in the prefix while linking.
@@ -305,8 +398,8 @@ If *`formula`* is provided, summarise the paths within its current keg.
 
 ### `log` [*`options`*] [*`formula`*]
 
-Show the `git log` for *`formula`*, or show the log for the Homebrew repository if
-no formula is provided.
+Show the `git log` for *`formula`*, or show the log for the Homebrew repository
+if no formula is provided.
 
 * `-p`, `--patch`:
   Also print patch from commit.
@@ -351,9 +444,8 @@ Show install options specific to *`formula`*.
 
 ### `outdated` [*`options`*] [*`formula`*|*`cask`*]
 
-List installed casks and formulae that have an updated version available. By
-default, version information is displayed in interactive shells, and suppressed
-otherwise.
+List installed casks and formulae that have an updated version available. By default, version
+information is displayed in interactive shells, and suppressed otherwise.
 
 * `-q`, `--quiet`:
   List only the names of outdated kegs (takes precedence over `--verbose`).
@@ -372,8 +464,8 @@ otherwise.
 
 ### `pin` *`formula`*
 
-Pin the specified *`formula`*, preventing them from being upgraded when issuing
-the `brew upgrade` *`formula`* command. See also `unpin`.
+Pin the specified *`formula`*, preventing them from being upgraded when
+issuing the `brew upgrade` *`formula`* command. See also `unpin`.
 
 ### `postinstall` *`formula`*
 
@@ -381,10 +473,10 @@ Rerun the post-install steps for *`formula`*.
 
 ### `readall` [*`options`*] [*`tap`*]
 
-Import all items from the specified *`tap`*, or from all installed taps if none is
-provided. This can be useful for debugging issues across all items when making
-significant changes to `formula.rb`, testing the performance of loading all
-items or checking if any current formulae/casks have Ruby issues.
+Import all items from the specified *`tap`*, or from all installed taps if none is provided.
+This can be useful for debugging issues across all items when making
+significant changes to `formula.rb`, testing the performance of loading
+all items or checking if any current formulae/casks have Ruby issues.
 
 * `--aliases`:
   Verify any alias symlinks in each tap.
@@ -396,8 +488,8 @@ items or checking if any current formulae/casks have Ruby issues.
 Uninstall and then install *`formula`* using the same options it was originally
 installed with, plus any appended brew formula options.
 
-Unless `HOMEBREW_NO_INSTALL_CLEANUP` is set, `brew cleanup` will then be run for
-the reinstalled formulae or, every 30 days, for all formulae.
+Unless `HOMEBREW_NO_INSTALL_CLEANUP` is set, `brew cleanup` will then be run for the
+reinstalled formulae or, every 30 days, for all formulae.
 
 * `-d`, `--debug`:
   If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory.
@@ -418,12 +510,12 @@ the reinstalled formulae or, every 30 days, for all formulae.
 
 ### `search` [*`options`*] [*`text`*|`/`*`text`*`/`]
 
-Perform a substring search of cask tokens and formula names for *`text`*. If
-*`text`* is flanked by slashes, it is interpreted as a regular expression. The
-search for *`text`* is extended online to `homebrew/core` and `homebrew/cask`.
+Perform a substring search of cask tokens and formula names for *`text`*. If *`text`*
+is flanked by slashes, it is interpreted as a regular expression.
+The search for *`text`* is extended online to `homebrew/core` and `homebrew/cask`.
 
-If no *`text`* is provided, list all locally available formulae (including tapped
-ones). No online search is performed.
+If no *`text`* is provided, list all locally available formulae (including tapped ones).
+No online search is performed.
 
 * `--formula`:
   Without *`text`*, list all locally available formulae (no online search is performed). With *`text`*, search online and locally for formulae.
@@ -453,8 +545,7 @@ Consider adding evaluation of this command's output to your dotfiles (e.g. `~/.p
 
 ### `switch` *`formula`* *`version`*
 
-Symlink all of the specified *`version`* of *`formula`*'s installation into
-Homebrew's prefix.
+Symlink all of the specified *`version`* of *`formula`*'s installation into Homebrew's prefix.
 
 ### `tap` [*`options`*] [*`user`*`/`*`repo`*] [*`URL`*]
 
@@ -462,15 +553,15 @@ Tap a formula repository.
 
 If no arguments are provided, list all installed taps.
 
-With *`URL`* unspecified, tap a formula repository from GitHub using HTTPS. Since
-so many taps are hosted on GitHub, this command is a shortcut for `brew tap`
-*`user`*`/`*`repo`* `https://github.com/`*`user`*`/homebrew-`*`repo`*.
+With *`URL`* unspecified, tap a formula repository from GitHub using HTTPS.
+Since so many taps are hosted on GitHub, this command is a shortcut for
+`brew tap` *`user`*`/`*`repo`* `https://github.com/`*`user`*`/homebrew-`*`repo`*.
 
-With *`URL`* specified, tap a formula repository from anywhere, using any
-transport protocol that `git`(1) handles. The one-argument form of `tap`
-simplifies but also limits. This two-argument command makes no assumptions, so
-taps can be cloned from places other than GitHub and using protocols other than
-HTTPS, e.g. SSH, git, HTTP, FTP(S), rsync.
+With *`URL`* specified, tap a formula repository from anywhere, using
+any transport protocol that `git`(1) handles. The one-argument form of `tap`
+simplifies but also limits. This two-argument command makes no
+assumptions, so taps can be cloned from places other than GitHub and
+using protocols other than HTTPS, e.g. SSH, git, HTTP, FTP(S), rsync.
 
 * `--full`:
   Convert a shallow clone to a full clone without untapping. Taps are only cloned as shallow clones on continuous integration, or if `--shallow` was originally passed.
@@ -505,17 +596,17 @@ Uninstall *`formula`*.
 
 ### `unlink` [*`options`*] *`formula`*
 
-Remove symlinks for *`formula`* from Homebrew's prefix. This can be useful for
-temporarily disabling a formula: `brew unlink` *`formula`* `&&` *`commands`* `&&
-brew link` *`formula`*
+Remove symlinks for *`formula`* from Homebrew's prefix. This can be useful
+for temporarily disabling a formula:
+`brew unlink` *`formula`* `&&` *`commands`* `&& brew link` *`formula`*
 
 * `-n`, `--dry-run`:
   List files which would be unlinked without actually unlinking or deleting any files.
 
 ### `unpin` *`formula`*
 
-Unpin *`formula`*, allowing them to be upgraded by `brew upgrade` *`formula`*. See
-also `pin`.
+Unpin *`formula`*, allowing them to be upgraded by `brew upgrade` *`formula`*.
+See also `pin`.
 
 ### `untap` *`tap`*
 
@@ -540,13 +631,12 @@ Fetch and reset Homebrew and all tap repositories (or any specified *`repository
 
 ### `upgrade` [*`options`*] [*`formula`*|*`cask`*]
 
-Upgrade outdated casks and outdated, unpinned formulae using the same options
-they were originally installed with, plus any appended brew formula options. If
-*`cask`* or *`formula`* are specified, upgrade only the given *`cask`* or *`formula`*
-kegs (unless they are pinned; see `pin`, `unpin`).
+Upgrade outdated casks and outdated, unpinned formulae using the same options they were originally
+installed with, plus any appended brew formula options. If *`cask`* or *`formula`* are specified,
+upgrade only the given *`cask`* or *`formula`* kegs (unless they are pinned; see `pin`, `unpin`).
 
-Unless `HOMEBREW_NO_INSTALL_CLEANUP` is set, `brew cleanup` will then be run for
-the upgraded formulae or, every 30 days, for all formulae.
+Unless `HOMEBREW_NO_INSTALL_CLEANUP` is set, `brew cleanup` will then be run for the
+upgraded formulae or, every 30 days, for all formulae.
 
 * `-d`, `--debug`:
   If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory.
@@ -579,10 +669,10 @@ the upgraded formulae or, every 30 days, for all formulae.
 
 ### `uses` [*`options`*] *`formula`*
 
-Show formulae that specify *`formula`* as a dependency (i.e. show dependents of
-*`formula`*). When given multiple formula arguments, show the intersection of
-formulae that use *`formula`*. By default, `uses` shows all formulae that specify
-*`formula`* as a required or recommended dependency for their stable builds.
+Show formulae that specify *`formula`* as a dependency (i.e. show dependents
+of *`formula`*). When given multiple formula arguments, show the intersection
+of formulae that use *`formula`*. By default, `uses` shows all formulae that
+specify *`formula`* as a required or recommended dependency for their stable builds.
 
 * `--recursive`:
   Resolve more than one level of dependencies.
@@ -620,13 +710,13 @@ If *`formula`* is provided, display the file or directory used to cache *`formul
 
 Display Homebrew's Caskroom path.
 
-If *`cask`* is provided, display the location in the Caskroom where *`cask`* would
-be installed, without any sort of versioned directory as the last path.
+If *`cask`* is provided, display the location in the Caskroom where *`cask`*
+would be installed, without any sort of versioned directory as the last path.
 
 ### `--cellar` [*`formula`*]
 
-Display Homebrew's Cellar path. *Default:* `$(brew --prefix)/Cellar`, or if that
-directory doesn't exist, `$(brew --repository)/Cellar`.
+Display Homebrew's Cellar path. *Default:* `$(brew --prefix)/Cellar`, or if
+that directory doesn't exist, `$(brew --repository)/Cellar`.
 
 If *`formula`* is provided, display the location in the Cellar where *`formula`*
 would be installed, without any sort of versioned directory as the last path.
@@ -635,8 +725,8 @@ would be installed, without any sort of versioned directory as the last path.
 
 Summarise Homebrew's build environment as a plain list.
 
-If the command's output is sent through a pipe and no shell is specified, the
-list is formatted for export to `bash`(1) unless `--plain` is passed.
+If the command's output is sent through a pipe and no shell is specified,
+the list is formatted for export to `bash`(1) unless `--plain` is passed.
 
 * `--shell`:
   Generate a list of environment variables for the specified shell, or `--shell=auto` to detect the current shell.
@@ -648,20 +738,19 @@ list is formatted for export to `bash`(1) unless `--plain` is passed.
 Display Homebrew's install path. *Default:* `/usr/local` on macOS and
 `/home/linuxbrew/.linuxbrew` on Linux.
 
-If *`formula`* is provided, display the location in the Cellar where *`formula`* is
-or would be installed.
+If *`formula`* is provided, display the location in the Cellar where *`formula`*
+is or would be installed.
 
 ### `--repository`, `--repo` [*`user`*`/`*`repo`*]
 
 Display where Homebrew's `.git` directory is located.
 
-If *`user`*`/`*`repo`* are provided, display where tap *`user`*`/`*`repo`*'s directory
-is located.
+If *`user`*`/`*`repo`* are provided, display where tap *`user`*`/`*`repo`*'s directory is located.
 
 ### `--version`
 
-Print the version numbers of Homebrew, Homebrew/homebrew-core and
-Homebrew/homebrew-cask (if tapped) to standard output.
+Print the version numbers of Homebrew, Homebrew/homebrew-core and Homebrew/homebrew-cask
+(if tapped) to standard output.
 
 ## DEVELOPER COMMANDS
 
@@ -669,8 +758,8 @@ Homebrew/homebrew-cask (if tapped) to standard output.
 
 Check *`formula`* for Homebrew coding style violations. This should be run before
 submitting a new formula. If no *`formula`* are provided, check all locally
-available formulae and skip style checks. Will exit with a non-zero status if
-any errors are found.
+available formulae and skip style checks. Will exit with a non-zero status if any
+errors are found.
 
 * `--strict`:
   Run additional, stricter style checks.
@@ -704,9 +793,10 @@ any errors are found.
 ### `bottle` [*`options`*] *`formula`*
 
 Generate a bottle (binary package) from a formula that was installed with
-`--build-bottle`. If the formula specifies a rebuild version, it will be
-incremented in the generated DSL. Passing `--keep-old` will attempt to keep it
-at its original value, while `--no-rebuild` will remove it.
+`--build-bottle`.
+If the formula specifies a rebuild version, it will be incremented in the
+generated DSL. Passing `--keep-old` will attempt to keep it at its original
+value, while `--no-rebuild` will remove it.
 
 * `--skip-relocation`:
   Do not check if the bottle can be marked as relocatable.
@@ -747,14 +837,12 @@ If a *`tag`* is specified, the Git commit *`revision`* corresponding to that tag
 should also be specified. A best effort to determine the *`revision`* will be made
 if the value is not supplied by the user.
 
-If a *`version`* is specified, a best effort to determine the *`URL`* and *`SHA-256`*
-or the *`tag`* and *`revision`* will be made if both values are not supplied by the
-user.
+If a *`version`* is specified, a best effort to determine the *`URL`* and *`SHA-256`* or
+the *`tag`* and *`revision`* will be made if both values are not supplied by the user.
 
 *Note:* this command cannot be used to transition a formula from a
 URL-and-SHA-256 style specification into a tag-and-revision style specification,
-nor vice versa. It must use whichever style specification the formula already
-uses.
+nor vice versa. It must use whichever style specification the formula already uses.
 
 * `-n`, `--dry-run`:
   Print what would be done rather than doing it.
@@ -785,7 +873,7 @@ uses.
 * `-f`, `--force`:
   Ignore duplicate open PRs. Remove all mirrors if --mirror= was not specified.
 
-### `bump-revision` [*`options`*] *`formula`*
+### `bump-revision` [*`options`*] *`formula`* [*`formula`* ...]
 
 Create a commit to increment the revision of *`formula`*. If no revision is
 present, "revision 1" will be added.
@@ -808,7 +896,8 @@ Display the path to the file being used when invoking `brew` *`cmd`*.
 Generate a formula for the downloadable file at *`URL`* and open it in the editor.
 Homebrew will attempt to automatically derive the formula name and version, but
 if it fails, you'll have to make your own template. The `wget` formula serves as
-a simple example. For the complete API, see: <https://rubydoc.brew.sh/Formula>
+a simple example. For the complete API, see:
+<https://rubydoc.brew.sh/Formula>
 
 * `--autotools`:
   Create a basic template for an Autotools-style build.
@@ -847,9 +936,9 @@ a simple example. For the complete API, see: <https://rubydoc.brew.sh/Formula>
 
 ### `diy` [*`options`*]
 
-Automatically determine the installation prefix for non-Homebrew software. Using
-the output from this command, you can install your own software into the Cellar
-and then link it into Homebrew's prefix with `brew link`.
+Automatically determine the installation prefix for non-Homebrew software.
+Using the output from this command, you can install your own software into
+the Cellar and then link it into Homebrew's prefix with `brew link`.
 
 * `--name`:
   Explicitly set the *`name`* of the package being installed.
@@ -865,8 +954,8 @@ Homebrew repository for editing if no formula is provided.
 
 Look through repository history to find the most recent version of *`formula`* and
 create a copy in *`tap`*`/Formula/`*`formula`*`@`*`version`*`.rb`. If the tap is not
-installed yet, attempt to install/clone the tap before continuing. To extract a
-formula from a tap that is not `homebrew/core` use its fully-qualified form of
+installed yet, attempt to install/clone the tap before continuing. To extract
+a formula from a tap that is not `homebrew/core` use its fully-qualified form of
 *`user`*`/`*`repo`*`/`*`formula`*.
 
 * `--version`:
@@ -931,8 +1020,8 @@ Find pull requests that can be automatically merged using `brew pr-publish`.
 
 ### `pr-publish` [*`options`*] *`pull_request`* [*`pull_request`* ...]
 
-Publish bottles for a pull request with GitHub Actions. Requires write access to
-the repository.
+Publish bottles for a pull request with GitHub Actions.
+Requires write access to the repository.
 
 * `--tap`:
   Target tap repository (default: `homebrew/core`).
@@ -941,9 +1030,9 @@ the repository.
 
 ### `pr-pull` [*`options`*] *`pull_request`* [*`pull_request`* ...]
 
-Download and publish bottles, and apply the bottle commit from a pull request
-with artifacts generated by GitHub Actions. Requires write access to the
-repository.
+Download and publish bottles, and apply the bottle commit from a
+pull request with artifacts generated by GitHub Actions.
+Requires write access to the repository.
 
 * `--no-publish`:
   Download the bottles, apply the bottle commit and upload the bottles to Bintray, but don't publish them.
@@ -953,6 +1042,8 @@ repository.
   Print what would be done rather than doing it.
 * `--clean`:
   Do not amend the commits from pull requests.
+* `--keep-old`:
+  If the formula specifies a rebuild version, attempt to preserve its value in the generated DSL.
 * `--branch-okay`:
   Do not warn if pulling to a branch besides master (useful for testing).
 * `--resolve`:
@@ -995,17 +1086,17 @@ Run Homebrew with the Ruby profiler, e.g. `brew prof readall`.
 
 ### `release-notes` [*`options`*] [*`previous_tag`*] [*`end_ref`*]
 
-Print the merged pull requests on Homebrew/brew between two Git refs. If no
-*`previous_tag`* is provided it defaults to the latest tag. If no *`end_ref`* is
-provided it defaults to `origin/master`.
+Print the merged pull requests on Homebrew/brew between two Git refs.
+If no *`previous_tag`* is provided it defaults to the latest tag.
+If no *`end_ref`* is provided it defaults to `origin/master`.
 
 * `--markdown`:
   Print as a Markdown list.
 
 ### `ruby` (`-e` *`text`*|*`file`*)
 
-Run a Ruby instance with Homebrew's libraries loaded, e.g. `brew ruby -e "puts
-:gcc.f.deps"` or `brew ruby script.rb`.
+Run a Ruby instance with Homebrew's libraries loaded, e.g.
+`brew ruby -e "puts :gcc.f.deps"` or `brew ruby script.rb`.
 
 * `-r`:
   Load a library using `require`.
@@ -1015,26 +1106,25 @@ Run a Ruby instance with Homebrew's libraries loaded, e.g. `brew ruby -e "puts
 ### `sh` [*`options`*]
 
 Start a Homebrew build environment shell. Uses our years-battle-hardened
-Homebrew build logic to help your `./configure && make && make install` or even
-your `gem install` succeed. Especially handy if you run Homebrew in an
-Xcode-only configuration since it adds tools like `make` to your `PATH` which
-build systems would not find otherwise.
+Homebrew build logic to help your `./configure && make && make install`
+or even your `gem install` succeed. Especially handy if you run Homebrew
+in an Xcode-only configuration since it adds tools like `make` to your `PATH`
+which build systems would not find otherwise.
 
 * `--env`:
   Use the standard `PATH` instead of superenv's when `std` is passed.
 
 ### `sponsors`
 
-Print a Markdown summary of Homebrew's GitHub Sponsors, suitable for pasting
-into a README.
+Print a Markdown summary of Homebrew's GitHub Sponsors, suitable for pasting into a README.
 
 ### `style` [*`options`*] [*`file`*|*`tap`*|*`formula`*]
 
 Check formulae or files for conformance to Homebrew style guidelines.
 
-Lists of *`file`*, *`tap`* and *`formula`* may not be combined. If none are provided,
-`style` will run style checks on the whole Homebrew library, including core code
-and all formulae.
+Lists of *`file`*, *`tap`* and *`formula`* may not be combined. If none are
+provided, `style` will run style checks on the whole Homebrew library,
+including core code and all formulae.
 
 * `--fix`:
   Fix style violations automatically using RuboCop's auto-correct feature.
@@ -1051,9 +1141,9 @@ Generate the template files for a new tap.
 
 ### `test` [*`options`*] *`formula`*
 
-Run the test method provided by an installed formula. There is no standard
-output or return code, but generally it should notify the user if something is
-wrong with the installed formula.
+Run the test method provided by an installed formula.
+There is no standard output or return code, but generally it should notify the
+user if something is wrong with the installed formula.
 
 *Example:* `brew install jruby && brew test jruby`
 
@@ -1087,8 +1177,8 @@ Run Homebrew's unit and integration tests.
 
 ### `unpack` [*`options`*] *`formula`*
 
-Unpack the source files for *`formula`* into subdirectories of the current working
-directory.
+Unpack the source files for *`formula`* into subdirectories of the current
+working directory.
 
 * `--destdir`:
   Create subdirectories in the directory named by *`path`* instead.
@@ -1123,8 +1213,8 @@ Update versions for PyPI resource blocks in *`formula`*.
 
 ### `update-test` [*`options`*]
 
-Run a test of `brew update` with a new repository clone. If no options are
-passed, use `origin/master` as the start commit.
+Run a test of `brew update` with a new repository clone.
+If no options are passed, use `origin/master` as the start commit.
 
 * `--to-tag`:
   Set `HOMEBREW_UPDATE_TO_TAG` to test updating between tags.
@@ -1143,75 +1233,53 @@ Install and commit Homebrew's vendored gems.
 
 These options are applicable across multiple subcommands.
 
+* `-d`, `--debug`:
+  Display any debugging information.
+
 * `-q`, `--quiet`:
   Suppress any warnings.
 
 * `-v`, `--verbose`:
   Make some output more verbose.
 
-* `-d`, `--debug`:
-  Display any debugging information.
+* `-h`, `--help`:
+  Show this message.
 
 ## OFFICIAL EXTERNAL COMMANDS
 
-### `cask` *`subcommand`*
-
-Install macOS applications distributed as binaries. See `brew-cask`(1).
-
-**Homebrew/homebrew-cask**: <https://github.com/Homebrew/homebrew-cask>
-
 ### `bundle` [*`subcommand`*]
 
-Bundler for non-Ruby dependencies from Homebrew, Homebrew Cask, Mac App Store
-and Whalebrew.
+Bundler for non-Ruby dependencies from Homebrew, Homebrew Cask, Mac App Store and Whalebrew.
 
 `brew bundle` [`install`]:
-    Install and upgrade (by default) all dependencies from the `Brewfile`.
-
-You can skip the installation of dependencies by adding space-separated values
-to one or more of the following environment variables:
-`HOMEBREW_BUNDLE_BREW_SKIP`, `HOMEBREW_BUNDLE_CASK_SKIP`,
-`HOMEBREW_BUNDLE_MAS_SKIP`, `HOMEBREW_BUNDLE_WHALEBREW_SKIP`,
-`HOMEBREW_BUNDLE_TAP_SKIP`
-
-`brew bundle` will output a `Brewfile.lock.json` in the same directory as the
-`Brewfile` if all dependencies are installed successfully. This contains
-dependency and system status information which can be useful in debugging `brew
-bundle` failures and replicating a "last known good build" state. You can
-opt-out of this behaviour by setting the `HOMEBREW_BUNDLE_NO_LOCK` environment
-variable or passing the `--no-lock` option. You may wish to check this file into
-the same version control system as your `Brewfile` (or ensure your version
-control system ignores it if you'd prefer to rely on debugging information from
-a local machine).
+Install and upgrade (by default) all dependencies from the `Brewfile`.
+
+You can skip the installation of dependencies by adding space-separated values to one or more of the following environment variables: `HOMEBREW_BUNDLE_BREW_SKIP`, `HOMEBREW_BUNDLE_CASK_SKIP`, `HOMEBREW_BUNDLE_MAS_SKIP`, `HOMEBREW_BUNDLE_WHALEBREW_SKIP`, `HOMEBREW_BUNDLE_TAP_SKIP`
+
+`brew bundle` will output a `Brewfile.lock.json` in the same directory as the `Brewfile` if all dependencies are installed successfully. This contains dependency and system status information which can be useful in debugging `brew bundle` failures and replicating a "last known good build" state. You can opt-out of this behaviour by setting the `HOMEBREW_BUNDLE_NO_LOCK` environment variable or passing the `--no-lock` option. You may wish to check this file into the same version control system as your `Brewfile` (or ensure your version control system ignores it if you'd prefer to rely on debugging information from a local machine).
 
 `brew bundle dump`:
-    Write all installed casks/formulae/images/taps into a `Brewfile`.
+Write all installed casks/formulae/images/taps into a `Brewfile`.
 
 `brew bundle cleanup`:
-    Uninstall all dependencies not listed from the `Brewfile`.
+Uninstall all dependencies not listed from the `Brewfile`.
 
-This workflow is useful for maintainers or testers who regularly install lots of
-formulae.
+This workflow is useful for maintainers or testers who regularly install lots of formulae.
 
 `brew bundle check`:
-    Check if all dependencies are installed from the `Brewfile` .
+Check if all dependencies are installed from the `Brewfile` .
 
-This provides a successful exit code if everything is up-to-date, making it
-useful for scripting.
+This provides a successful exit code if everything is up-to-date, making it useful for scripting.
 
 `brew bundle list`:
-    List all dependencies present in a `Brewfile`.
+List all dependencies present in a `Brewfile`.
 
 By default, only Homebrew dependencies are listed.
 
 `brew bundle exec` *`command`*:
-    Run an external command in an isolated build environment based on the
-`Brewfile` dependencies.
+Run an external command in an isolated build environment based on the `Brewfile` dependencies.
 
-This sanitized build environment ignores unrequested dependencies, which makes
-sure that things you didn't specify in your `Brewfile` won't get picked up by
-commands like `bundle install`, `npm install`, etc. It will also add compiler
-flags which will help find keg-only dependencies like `openssl`, `icu4c`, etc.
+This sanitized build environment ignores unrequested dependencies, which makes sure that things you didn't specify in your `Brewfile` won't get picked up by commands like `bundle install`, `npm install`, etc. It will also add compiler flags which will help find keg-only dependencies like `openssl`, `icu4c`, etc.
 
 * `--file`:
   Read the `Brewfile` from this location. Use `--file=-` to pipe to stdin/stdout.
@@ -1248,41 +1316,31 @@ If `sudo` is passed, operate on `/Library/LaunchDaemons` (started at boot).
 Otherwise, operate on `~/Library/LaunchAgents` (started at login).
 
 [`sudo`] `brew services` [`list`]:
-    List all managed services for the current user (or root).
+List all managed services for the current user (or root).
 
 [`sudo`] `brew services run` (*`formula`*|`--all`):
-    Run the service *`formula`* without registering to launch at login (or boot).
+Run the service *`formula`* without registering to launch at login (or boot).
 
 [`sudo`] `brew services start` (*`formula`*|`--all`):
-    Start the service *`formula`* immediately and register it to launch at login
-(or boot).
+Start the service *`formula`* immediately and register it to launch at login (or boot).
 
 [`sudo`] `brew services stop` (*`formula`*|`--all`):
-    Stop the service *`formula`* immediately and unregister it from launching at
-login (or boot).
+Stop the service *`formula`* immediately and unregister it from launching at login (or boot).
 
 [`sudo`] `brew services restart` (*`formula`*|`--all`):
-    Stop (if necessary) and start the service *`formula`* immediately and register
-it to launch at login (or boot).
+Stop (if necessary) and start the service *`formula`* immediately and register it to launch at login (or boot).
 
 [`sudo`] `brew services cleanup`:
-    Remove all unused services.
+Remove all unused services.
 
 * `--all`:
   Run *`subcommand`* on all services.
 
 ### `test-bot` [*`options`*] [*`formula`*]:
 
-Tests the full lifecycle of a Homebrew change to a tap (Git repository). For
-example, for a GitHub Actions pull request that changes a formula `brew
-test-bot` will ensure the system is cleaned and setup to test the formula,
-install the formula, run various tests and checks on it, bottle (package) the
-binaries and test formulae that depend on it to ensure they aren't broken by
-these changes.
+Tests the full lifecycle of a Homebrew change to a tap (Git repository). For example, for a GitHub Actions pull request that changes a formula `brew test-bot` will ensure the system is cleaned and setup to test the formula, install the formula, run various tests and checks on it, bottle (package) the binaries and test formulae that depend on it to ensure they aren't broken by these changes.
 
-Only supports GitHub Actions as a CI provider. This is because Homebrew uses
-GitHub Actions and it's freely available for public and private use with macOS
-and Linux workers.
+Only supports GitHub Actions as a CI provider. This is because Homebrew uses GitHub Actions and it's freely available for public and private use with macOS and Linux workers.
 
 * `--dry-run`:
   print what would be done rather than doing it.
@@ -1355,6 +1413,12 @@ can take several different forms:
     Homebrew can install formulae from a local path. It can point to either a
     formula file or a bottle.
 
+## SPECIFYING CASKS
+
+Many Homebrew Cask commands accept one or more *`cask`* arguments. These can be
+specified the same way as the *`formula`* arguments described in
+`SPECIFYING FORMULAE` above.
+
 ## ENVIRONMENT
 
 Note that environment variables must have a value set to be detected. For example, run
@@ -1409,7 +1473,10 @@ Note that environment variables must have a value set to be detected. For exampl
     *Default:* macOS: `$HOME/Library/Caches/Homebrew`, Linux: `$XDG_CACHE_HOME/Homebrew` or `$HOME/.cache/Homebrew`.
 
   * `HOMEBREW_CASK_OPTS`:
-    Options which should be used for all `cask` commands.
+    Options which should be used for all `cask` commands. All `--*dir` options, `--language`, `--require-sha`, `--no-quarantine` and `--no-binaries` are supported.
+For example, you might add something like the following to your ~/.profile, ~/.bash_profile, or ~/.zshenv:
+
+`export HOMEBREW_CASK_OPTS='--appdir=~/Applications --fontdir=/Library/Fonts'`
 
   * `HOMEBREW_CLEANUP_MAX_AGE_DAYS`:
     Cleanup all cached files older than this many days.
@@ -1581,6 +1648,9 @@ Note that environment variables must have a value set to be detected. For exampl
   * `no_proxy`:
     A comma-separated list of hostnames and domain names excluded from proxying by `curl`(1), `git`(1) and `svn`(1) when downloading through Homebrew.
 
+  * `SUDO_ASKPASS`:
+    When this variable is set, the `-A` option is passed when calling `sudo`(8)
+
 ## USING HOMEBREW BEHIND A PROXY
 
 Set the `http_proxy`, `https_proxy`, `all_proxy`, `ftp_proxy` and/or `no_proxy`
@@ -1602,7 +1672,7 @@ Homebrew Documentation: <https://docs.brew.sh>
 
 Homebrew API: <https://rubydoc.brew.sh>
 
-`brew-cask`(1), `git`(1), `git-log`(1)
+`git`(1), `git-log`(1)
 
 ## AUTHORS
 
@@ -1628,6 +1698,9 @@ See our issues on GitHub:
   * **Homebrew/homebrew-core**:
     <https://github.com/Homebrew/homebrew-core/issues>
 
+  * **Homebrew/homebrew-cask**:
+    <https://github.com/Homebrew/homebrew-cask/issues>
+
 [SYNOPSIS]: #SYNOPSIS "SYNOPSIS"
 [DESCRIPTION]: #DESCRIPTION "DESCRIPTION"
 [ESSENTIAL COMMANDS]: #ESSENTIAL-COMMANDS "ESSENTIAL COMMANDS"
@@ -1637,6 +1710,7 @@ See our issues on GitHub:
 [OFFICIAL EXTERNAL COMMANDS]: #OFFICIAL-EXTERNAL-COMMANDS "OFFICIAL EXTERNAL COMMANDS"
 [CUSTOM EXTERNAL COMMANDS]: #CUSTOM-EXTERNAL-COMMANDS "CUSTOM EXTERNAL COMMANDS"
 [SPECIFYING FORMULAE]: #SPECIFYING-FORMULAE "SPECIFYING FORMULAE"
+[SPECIFYING CASKS]: #SPECIFYING-CASKS "SPECIFYING CASKS"
 [ENVIRONMENT]: #ENVIRONMENT "ENVIRONMENT"
 [USING HOMEBREW BEHIND A PROXY]: #USING-HOMEBREW-BEHIND-A-PROXY "USING HOMEBREW BEHIND A PROXY"
 [SEE ALSO]: #SEE-ALSO "SEE ALSO"
diff --git a/manpages/brew-cask.1 b/manpages/brew-cask.1
deleted file mode 100644
index f35a505d79ef8fa05bb8e5554bacb1752e57887c..0000000000000000000000000000000000000000
--- a/manpages/brew-cask.1
+++ /dev/null
@@ -1,316 +0,0 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "BREW\-CASK" "1" "August 2020" "Homebrew" "brew-cask"
-.
-.SH "NAME"
-\fBbrew\-cask\fR \- a friendly binary installer for macOS
-.
-.SH "SYNOPSIS"
-\fBbrew cask\fR command [options] [ \fItoken\fR \.\.\. ]
-.
-.SH "DESCRIPTION"
-Homebrew Cask is a tool for installing precompiled macOS binaries (such as Applications) from the command line\. The user is never required to use the graphical user interface\.
-.
-.SH "FREQUENTLY USED COMMANDS"
-.
-.TP
-\fBinstall\fR [\-\-force] [\-\-skip\-cask\-deps] [\-\-require\-sha] [\-\-no\-quarantine] [\-\-language=\fIiso\-language\fR[,\fIiso\-language\fR \.\.\. ]] \fItoken\fR [ \fItoken\fR \.\.\. ]
-Install Cask identified by \fItoken\fR\.
-.
-.TP
-\fBuninstall\fR [\-\-force] \fItoken\fR [ \fItoken\fR \.\.\. ]
-Uninstall Cask identified by \fItoken\fR\.
-.
-.SH "COMMANDS"
-.
-.TP
-\fB\-\-cache\fR \fItoken\fR [ \fItoken\fR \.\.\. ]
-Display the file used to cache the Cask identified by \fItoken\fR\.
-.
-.TP
-\fBaudit\fR [\-\-language=\fIiso\-language\fR[,\fIiso\-language\fR \.\.\. ]] [ \fItoken\fR \.\.\. ]
-Check the given Casks for installability\. If no tokens are given on the command line, all Casks are audited\.
-.
-.TP
-\fBcat\fR \fItoken\fR [ \fItoken\fR \.\.\. ]
-Dump the given Cask definition file to the standard output\.
-.
-.TP
-\fBcreate\fR \fItoken\fR
-Generate a Cask definition file for the Cask identified by \fItoken\fR and open a template for it in your favorite editor\.
-.
-.TP
-\fBdoctor\fR or \fBdr\fR
-Check for configuration issues\. Can be useful to upload as a gist for developers along with a bug report\.
-.
-.TP
-\fBedit\fR \fItoken\fR
-Open the given Cask definition file for editing\.
-.
-.TP
-\fBfetch\fR [\-\-force] [\-\-no\-quarantine] \fItoken\fR [ \fItoken\fR \.\.\. ]
-Download remote application files for the given Cask to the local cache\. With \fB\-\-force\fR, force re\-download even if the files are already cached\. \fB\-\-no\-quarantine\fR will prevent Gatekeeper from enforcing its security restrictions on the Cask\.
-.
-.TP
-\fBhome\fR or \fBhomepage\fR [ \fItoken\fR \.\.\. ]
-Display the homepage associated with a given Cask in a browser\.
-.
-.IP
-With no arguments, display the project page \fIhttps://brew\.sh/\fR\.
-.
-.TP
-\fBinfo\fR or \fBabv\fR \fItoken\fR [ \fItoken\fR \.\.\. ]
-Display information about the given Cask\.
-.
-.TP
-\fBinstall\fR [\-\-force] [\-\-skip\-cask\-deps] [\-\-require\-sha] [\-\-no\-quarantine] \fItoken\fR [ \fItoken\fR \.\.\. ]
-Install the given Cask\. With \fB\-\-force\fR, re\-install even if the Cask appears to be already present\. With \fB\-\-skip\-cask\-deps\fR, skip any Cask dependencies\. \fB\-\-require\-sha\fR will abort installation if the Cask does not have a checksum defined\. \fB\-\-no\-quarantine\fR will prevent Gatekeeper from enforcing its security restrictions on the Cask\.
-.
-.IP
-\fItoken\fR is usually the ID of a Cask, but see \fIOTHER WAYS TO SPECIFY A CASK\fR for variations\.
-.
-.TP
-\fBlist\fR or \fBls\fR [\-1] [\-\-versions] [ \fItoken\fR \.\.\. ]
-Without any arguments, list all installed Casks\. With \fB\-1\fR, always format the output in a single column\. With \fB\-\-versions\fR, show all installed versions\.
-.
-.IP
-If \fItoken\fR is given, summarize the staged files associated with the given Cask\.
-.
-.TP
-\fBoutdated\fR [\-\-greedy] [\-\-verbose|\-\-quiet] [ \fItoken\fR \.\.\. ]
-Without token arguments, display all the installed Casks that have newer versions available in the tap; otherwise check only the tokens given in the command line\. If \fB\-\-greedy\fR is given then also include in the output the Casks having \fBauto_updates true\fR or \fBversion :latest\fR\. Otherwise they are skipped because there is no reliable way to know when updates are available for them\.
-.
-.br
-\fB\-\-verbose\fR forces the display of the outdated and latest version\.
-.
-.br
-\fB\-\-quiet\fR suppresses the display of versions\.
-.
-.TP
-\fBreinstall\fR [\-\-no\-quarantine] \fItoken\fR [ \fItoken\fR \.\.\. ]
-Reinstall the given Cask\.
-.
-.TP
-\fBstyle\fR [\-\-fix] [ \fItoken\fR \.\.\. ]
-Check the given Casks for correct style using RuboCop (with custom Cask cops)\. If no tokens are given on the command line, all Casks are checked\. With \fB\-\-fix\fR, auto\-correct any style errors if possible\.
-.
-.TP
-\fBuninstall\fR or \fBrm\fR or \fBremove\fR [\-\-force] \fItoken\fR [ \fItoken\fR \.\.\. ]
-Uninstall the given Cask\. With \fB\-\-force\fR, uninstall even if the Cask does not appear to be present\.
-.
-.TP
-\fBupgrade\fR [\-\-force] [\-\-greedy] [\-\-dry\-run] \fItoken\fR [ \fItoken\fR \.\.\. ]
-Without token arguments, upgrade all the installed Casks that have newer versions available in the tap; otherwise update the tokens given in the command line\. If \fB\-\-greedy\fR is given then also upgrade the Casks having \fBauto_updates true\fR or \fBversion :latest\fR\.
-.
-.IP
-If \fB\-\-dry\-run\fR is given, show what would be upgraded, but do not actually upgrade anything\.
-.
-.TP
-\fBzap\fR [\-\-force] \fItoken\fR [ \fItoken\fR \.\.\. ]
-Unconditionally remove \fIall\fR files associated with the given Cask\. With \fB\-\-force\fR, zap even if the Cask does not appear to be currently installed\.
-.
-.IP
-Implicitly performs all actions associated with \fBuninstall\fR\.
-.
-.IP
-Removes all staged versions of the Cask distribution found under \fB<Caskroom_path>/\fR\fItoken\fR\.
-.
-.IP
-If the Cask definition contains a \fBzap\fR stanza, performs additional \fBzap\fR actions as defined there, such as removing local preference files\. \fBzap\fR actions are variable, depending on the level of detail defined by the Cask author\.
-.
-.IP
-\fB\fBzap\fR may remove files which are shared between applications\.\fR
-.
-.SH "INTERNAL COMMANDS"
-.
-.TP
-\fB_stanza\fR \fIstanza_name\fR [ \-\-table | \-\-yaml | \-\-inspect | \-\-quiet ] [ \fItoken\fR \.\.\. ]
-Given a \fIstanza_name\fR and a \fItoken\fR, returns the current stanza for a given Cask\. If no \fItoken\fR is given, then data for all Casks is returned\.
-.
-.SH "OPTIONS"
-To make these options persistent, see the \fIENVIRONMENT\fR section, below\.
-.
-.P
-Some of these (such as \fB\-\-prefpanedir\fR) may be subject to removal in a future version\.
-.
-.TP
-\fB\-\-force\fR
-Force an install to proceed even when a previously\-existing install is detected\.
-.
-.TP
-\fB\-\-skip\-cask\-deps\fR
-Skip Cask dependencies when installing\.
-.
-.TP
-\fB\-\-require\-sha\fR
-Abort Cask installation if the Cask does not have a checksum defined\.
-.
-.TP
-\fB\-\-no\-quarantine\fR
-Prevent Gatekeeper from enforcing its security restrictions on the Cask\. This will let you run it straightaway\.
-.
-.TP
-\fB\-\-verbose\fR
-Give additional feedback during installation\.
-.
-.TP
-\fB\-\-appdir=<path>\fR
-Target location for Applications\. The default value is \fB/Applications\fR\.
-.
-.TP
-\fB\-\-language=<iso\-language>[,<iso\-language> \.\.\. ]]\fR
-Set language of the Cask to install\. The first matching language is used, otherwise the default language on the Cask\. The default value is the \fBlanguage of your system\fR\.
-.
-.TP
-\fB\-\-colorpickerdir=<path>\fR
-Target location for Color Pickers\. The default value is \fB~/Library/ColorPickers\fR\.
-.
-.TP
-\fB\-\-prefpanedir=<path>\fR
-Target location for Preference Panes\. The default value is \fB~/Library/PreferencePanes\fR\.
-.
-.TP
-\fB\-\-qlplugindir=<path>\fR
-Target location for QuickLook Plugins\. The default value is \fB~/Library/QuickLook\fR\.
-.
-.TP
-\fB\-\-dictionarydir=<path>\fR
-Target location for Dictionaries\. The default value is \fB~/Library/Dictionaries\fR\.
-.
-.TP
-\fB\-\-fontdir=<path>\fR
-Target location for Fonts\. The default value is \fB~/Library/Fonts\fR\.
-.
-.TP
-\fB\-\-servicedir=<path>\fR
-Target location for Services\. The default value is \fB~/Library/Services\fR\.
-.
-.TP
-\fB\-\-input_methoddir=<path>\fR
-Target location for Input Methods\. The default value is \fB~/Library/Input Methods\fR\.
-.
-.TP
-\fB\-\-internet_plugindir=<path>\fR
-Target location for Internet Plugins\. The default value is \fB~/Library/Internet Plug\-Ins\fR\.
-.
-.TP
-\fB\-\-audio_unit_plugindir=<path>\fR
-Target location for Audio Unit Plugins\. The default value is \fB~/Library/Audio/Plug\-Ins/Components\fR\.
-.
-.TP
-\fB\-\-vst_plugindir=<path>\fR
-Target location for VST Plugins\. The default value is \fB~/Library/Audio/Plug\-Ins/VST\fR\.
-.
-.TP
-\fB\-\-vst3_plugindir=<path>\fR
-Target location for VST3 Plugins\. The default value is \fB~/Library/Audio/Plug\-Ins/VST3\fR\.
-.
-.TP
-\fB\-\-screen_saverdir=<path>\fR
-Target location for Screen Savers\. The default value is \fB~/Library/Screen Savers\fR\.
-.
-.TP
-\fB\-\-no\-binaries\fR
-Do not link "helper" executables to \fB/usr/local/bin\fR\.
-.
-.TP
-\fB\-\-debug\fR
-Output debugging information of use to Cask authors and developers\.
-.
-.SH "INTERACTION WITH HOMEBREW"
-Homebrew Cask is implemented as a external command for Homebrew\. That means this project is entirely built upon the Homebrew infrastructure\. For example, upgrades to the Homebrew Cask tool are received through Homebrew:
-.
-.IP "" 4
-.
-.nf
-
-brew update; brew cask upgrade; brew cleanup
-.
-.fi
-.
-.IP "" 0
-.
-.P
-And updates to individual Cask definitions are received whenever you issue the Homebrew command:
-.
-.IP "" 4
-.
-.nf
-
-brew update
-.
-.fi
-.
-.IP "" 0
-.
-.SH "OTHER WAYS TO SPECIFY A CASK"
-Most Homebrew Cask commands can accept a Cask token as an argument\. As described above, the argument can take the form of:
-.
-.IP "\(bu" 4
-A simple token, e\.g\. \fBgoogle\-chrome\fR
-.
-.IP "" 0
-.
-.P
-Homebrew Cask also accepts three other forms in place of plain tokens:
-.
-.IP "\(bu" 4
-A fully\-qualified token which includes the Tap name, e\.g\. \fBhomebrew/cask\-fonts/font\-symbola\fR
-.
-.IP "\(bu" 4
-A fully\-qualified pathname to a Cask file, e\.g\. \fB/usr/local/Library/Taps/homebrew/homebrew\-cask/Casks/google\-chrome\.rb\fR
-.
-.IP "\(bu" 4
-A \fBcurl\fR\-retrievable URI to a Cask file, e\.g\. \fBhttps://raw\.githubusercontent\.com/Homebrew/homebrew\-cask/f25b6babcd398abf48e33af3d887b2d00de1d661/Casks/google\-chrome\.rb\fR
-.
-.IP "" 0
-.
-.SH "ENVIRONMENT"
-Homebrew Cask respects many of the environment variables used by the parent command \fBbrew\fR\. Please refer to the \fBbrew\fR(1) man page for more information\.
-.
-.P
-Environment variables specific to Homebrew Cask:
-.
-.TP
-\fBHOMEBREW_CASK_OPTS\fR
-This variable may contain any arguments normally used as options on the command\-line\. This is particularly useful to make options persistent\. For example, you might add to your ~/\.profile, ~/\.bash_profile, or ~/\.zshenv something like:
-.
-.IP "" 4
-.
-.nf
-
-       export HOMEBREW_CASK_OPTS=\'\-\-appdir=~/Applications \-\-fontdir=/Library/Fonts\'
-.
-.fi
-.
-.IP "" 0
-
-.
-.P
-Other environment variables:
-.
-.TP
-\fBSUDO_ASKPASS\fR
-When this variable is set, Homebrew Cask will call \fBsudo\fR(8) with the \fB\-A\fR option\.
-.
-.SH "SEE ALSO"
-The Homebrew home page: \fIhttps://brew\.sh/\fR
-.
-.P
-The Homebrew Cask GitHub page: \fIhttps://github\.com/Homebrew/homebrew\-cask\fR
-.
-.P
-\fBbrew\fR(1), \fBcurl\fR(1)
-.
-.SH "AUTHORS"
-Paul Hinze and Contributors\.
-.
-.P
-Man page format based on \fBbrew\.1\.md\fR from Homebrew\.
-.
-.SH "BUGS"
-We still have bugs \- and we are busy fixing them! If you have a problem, don\'t be shy about reporting it on our GitHub issues page \fIhttps://github\.com/Homebrew/homebrew\-cask/issues?state=open\fR\.
-.
-.P
-When reporting bugs, remember that Homebrew Cask is an separate repository within Homebrew\. Do your best to direct bug reports to the appropriate repository\. If your command\-line started with \fBbrew cask\fR, bring the bug to us first!
diff --git a/manpages/brew.1 b/manpages/brew.1
index 2006676c16b7c981729e506c9b6086ceb8393fb8..9b11825ae0a7dd5140a53d9dfc3967323dc65ee9 100644
--- a/manpages/brew.1
+++ b/manpages/brew.1
@@ -53,6 +53,185 @@ Control Homebrew\'s anonymous aggregate user behaviour analytics\. Read more at
 \fBbrew analytics regenerate\-uuid\fR
     Regenerate the UUID used for Homebrew\'s analytics\.
 .
+.SS "\fBcask\fR \fIcommand\fR [\fIoptions\fR] [\fIcask\fR]"
+Homebrew Cask provides a friendly CLI workflow for the administration of macOS applications distributed as binaries\.
+.
+.P
+Commands:
+.
+.IP "\(bu" 4
+\fB\-\-cache\fR
+.
+.br
+Display the file used to cache a \fIcask\fR
+.
+.IP "\(bu" 4
+\fBaudit\fR
+.
+.br
+Check \fIcask\fR for Homebrew coding style violations
+.
+.IP "\(bu" 4
+\fBcat\fR
+.
+.br
+Dump raw source of a \fIcask\fR to the standard output
+.
+.IP "\(bu" 4
+\fBcreate\fR
+.
+.br
+Creates the given \fIcask\fR and opens it in an editor
+.
+.IP "\(bu" 4
+\fBdoctor\fR
+.
+.br
+Checks for configuration issues
+.
+.IP "\(bu" 4
+\fBedit\fR
+.
+.br
+Open the given \fIcask\fR for editing
+.
+.IP "\(bu" 4
+\fBfetch\fR
+.
+.br
+Downloads remote application files to local cache
+.
+.IP "\(bu" 4
+\fBhelp\fR
+.
+.br
+Print help for \fBcask\fR commands
+.
+.IP "\(bu" 4
+\fBhome\fR
+.
+.br
+Opens the homepage of the given \fIcask\fR
+.
+.IP "\(bu" 4
+\fBinfo\fR
+.
+.br
+Displays information about the given \fIcask\fR
+.
+.IP "\(bu" 4
+\fBinstall\fR
+.
+.br
+Installs the given \fIcask\fR
+.
+.IP "\(bu" 4
+\fBlist\fR
+.
+.br
+Lists installed casks or the casks provided in the arguments
+.
+.IP "\(bu" 4
+\fBoutdated\fR
+.
+.br
+List the outdated installed casks
+.
+.IP "\(bu" 4
+\fBreinstall\fR
+.
+.br
+Reinstalls the given \fIcask\fR
+.
+.IP "\(bu" 4
+\fBstyle\fR
+.
+.br
+Checks style of the given \fIcask\fR using RuboCop
+.
+.IP "\(bu" 4
+\fBuninstall\fR
+.
+.br
+Uninstalls the given \fIcask\fR
+.
+.IP "\(bu" 4
+\fBupgrade\fR
+.
+.br
+Upgrades all outdated casks or the specified casks
+.
+.IP "\(bu" 4
+\fBzap\fR
+.
+.br
+Zaps all files associated with the given \fIcask\fR
+.
+.IP "" 0
+.
+.P
+See also: \fBman brew\fR
+.
+.TP
+\fB\-\-appdir\fR
+Target location for Applications\. Default: \fB/Applications\fR
+.
+.TP
+\fB\-\-colorpickerdir\fR
+Target location for Color Pickers\. Default: \fB~/Library/ColorPickers\fR
+.
+.TP
+\fB\-\-prefpanedir\fR
+Target location for Preference Panes\. Default: \fB~/Library/PreferencePanes\fR
+.
+.TP
+\fB\-\-qlplugindir\fR
+Target location for QuickLook Plugins\. Default: \fB~/Library/QuickLook\fR
+.
+.TP
+\fB\-\-mdimporterdir\fR
+Target location for Spotlight Plugins\. Default: \fB~/Library/Spotlight\fR
+.
+.TP
+\fB\-\-dictionarydir\fR
+Target location for Dictionaries\. Default: \fB~/Library/Dictionaries\fR
+.
+.TP
+\fB\-\-fontdir\fR
+Target location for Fonts\. Default: \fB~/Library/Fonts\fR
+.
+.TP
+\fB\-\-servicedir\fR
+Target location for Services\. Default: \fB~/Library/Services\fR
+.
+.TP
+\fB\-\-input_methoddir\fR
+Target location for Input Methods\. Default: \fB~/Library/Input Methods\fR
+.
+.TP
+\fB\-\-internet_plugindir\fR
+Target location for Internet Plugins\. Default: \fB~/Library/Internet Plug\-Ins\fR
+.
+.TP
+\fB\-\-audio_unit_plugindir\fR
+Target location for Audio Unit Plugins\. Default: \fB~/Library/Audio/Plug\-Ins/Components\fR
+.
+.TP
+\fB\-\-vst_plugindir\fR
+Target location for VST Plugins\. Default: \fB~/Library/Audio/Plug\-Ins/VST\fR
+.
+.TP
+\fB\-\-vst3_plugindir\fR
+Target location for VST3 Plugins\. Default: \fB~/Library/Audio/Plug\-Ins/VST3\fR
+.
+.TP
+\fB\-\-screen_saverdir\fR
+Target location for Screen Savers\. Default: \fB~/Library/Screen Savers\fR
+.
+.TP
+\fB\-\-language\fR
+Set language of the Cask to install\. The first matching language is used, otherwise the default language on the Cask\. The default value is the \fBlanguage of your system\fR
+.
 .SS "\fBcleanup\fR [\fIoptions\fR] [\fIformula\fR|\fIcask\fR]"
 Remove stale lock files and outdated downloads for all formulae and casks, and remove old versions of installed formulae\. If arguments are specified, only do this for the given formulae and casks\. Removes all downloads more than 120 days old\. This can be adjusted with \fBHOMEBREW_CLEANUP_MAX_AGE_DAYS\fR\.
 .
@@ -1038,7 +1217,7 @@ Specify the new git commit \fIrevision\fR corresponding to the specified \fItag\
 \fB\-f\fR, \fB\-\-force\fR
 Ignore duplicate open PRs\. Remove all mirrors if \-\-mirror= was not specified\.
 .
-.SS "\fBbump\-revision\fR [\fIoptions\fR] \fIformula\fR"
+.SS "\fBbump\-revision\fR [\fIoptions\fR] \fIformula\fR [\fIformula\fR \.\.\.]"
 Create a commit to increment the revision of \fIformula\fR\. If no revision is present, "revision 1" will be added\.
 .
 .TP
@@ -1252,6 +1431,10 @@ Print what would be done rather than doing it\.
 Do not amend the commits from pull requests\.
 .
 .TP
+\fB\-\-keep\-old\fR
+If the formula specifies a rebuild version, attempt to preserve its value in the generated DSL\.
+.
+.TP
 \fB\-\-branch\-okay\fR
 Do not warn if pulling to a branch besides master (useful for testing)\.
 .
@@ -1498,6 +1681,10 @@ Install and commit Homebrew\'s vendored gems\.
 These options are applicable across multiple subcommands\.
 .
 .TP
+\fB\-d\fR, \fB\-\-debug\fR
+Display any debugging information\.
+.
+.TP
 \fB\-q\fR, \fB\-\-quiet\fR
 Suppress any warnings\.
 .
@@ -1506,18 +1693,11 @@ Suppress any warnings\.
 Make some output more verbose\.
 .
 .TP
-\fB\-d\fR, \fB\-\-debug\fR
-Display any debugging information\.
+\fB\-h\fR, \fB\-\-help\fR
+Show this message\.
 .
 .SH "OFFICIAL EXTERNAL COMMANDS"
 .
-.SS "\fBcask\fR \fIsubcommand\fR"
-Install macOS applications distributed as binaries\. See \fBbrew\-cask\fR(1)\.
-.
-.P
-\fBHomebrew/homebrew\-cask\fR
-    \fIhttps://github\.com/Homebrew/homebrew\-cask\fR
-.
 .SS "\fBbundle\fR [\fIsubcommand\fR]"
 Bundler for non\-Ruby dependencies from Homebrew, Homebrew Cask, Mac App Store and Whalebrew\.
 .
@@ -1760,6 +1940,9 @@ Sometimes a formula from a tapped repository may conflict with one in \fBhomebre
 An arbitrary file
 Homebrew can install formulae from a local path\. It can point to either a formula file or a bottle\.
 .
+.SH "SPECIFYING CASKS"
+Many Homebrew Cask commands accept one or more \fIcask\fR arguments\. These can be specified the same way as the \fIformula\fR arguments described in \fBSPECIFYING FORMULAE\fR above\.
+.
 .SH "ENVIRONMENT"
 Note that environment variables must have a value set to be detected\. For example, run \fBexport HOMEBREW_NO_INSECURE_REDIRECT=1\fR rather than just \fBexport HOMEBREW_NO_INSECURE_REDIRECT\fR\.
 .
@@ -1830,7 +2013,10 @@ Use the specified directory as the download cache\.
 .
 .TP
 \fBHOMEBREW_CASK_OPTS\fR
-Options which should be used for all \fBcask\fR commands\.
+Options which should be used for all \fBcask\fR commands\. All \fB\-\-*dir\fR options, \fB\-\-language\fR, \fB\-\-require\-sha\fR, \fB\-\-no\-quarantine\fR and \fB\-\-no\-binaries\fR are supported\. For example, you might add something like the following to your ~/\.profile, ~/\.bash_profile, or ~/\.zshenv:
+.
+.P
+\fBexport HOMEBREW_CASK_OPTS=\'\-\-appdir=~/Applications \-\-fontdir=/Library/Fonts\'\fR
 .
 .TP
 \fBHOMEBREW_CLEANUP_MAX_AGE_DAYS\fR
@@ -2064,6 +2250,10 @@ Use this HTTPS proxy for \fBcurl\fR(1), \fBgit\fR(1) and \fBsvn\fR(1) when downl
 \fBno_proxy\fR
 A comma\-separated list of hostnames and domain names excluded from proxying by \fBcurl\fR(1), \fBgit\fR(1) and \fBsvn\fR(1) when downloading through Homebrew\.
 .
+.TP
+\fBSUDO_ASKPASS\fR
+When this variable is set, the \fB\-A\fR option is passed when calling \fBsudo\fR(8)
+.
 .SH "USING HOMEBREW BEHIND A PROXY"
 Set the \fBhttp_proxy\fR, \fBhttps_proxy\fR, \fBall_proxy\fR, \fBftp_proxy\fR and/or \fBno_proxy\fR environment variables documented above\.
 .
@@ -2102,7 +2292,7 @@ Homebrew Documentation: \fIhttps://docs\.brew\.sh\fR
 Homebrew API: \fIhttps://rubydoc\.brew\.sh\fR
 .
 .P
-\fBbrew\-cask\fR(1), \fBgit\fR(1), \fBgit\-log\fR(1)
+\fBgit\fR(1), \fBgit\-log\fR(1)
 .
 .SH "AUTHORS"
 Homebrew\'s Project Leader is Mike McQuaid\.
@@ -2132,4 +2322,8 @@ See our issues on GitHub:
 .TP
 \fBHomebrew/homebrew\-core\fR
 \fIhttps://github\.com/Homebrew/homebrew\-core/issues\fR
+.
+.TP
+\fBHomebrew/homebrew\-cask\fR
+\fIhttps://github\.com/Homebrew/homebrew\-cask/issues\fR