diff --git a/Library/Homebrew/cli/named_args.rb b/Library/Homebrew/cli/named_args.rb index 57c554b629754edefad6481fdd2cf17e8d465c6c..99c76247af01d7e59ed3e90a0e0a4b8fb7ebcceb 100644 --- a/Library/Homebrew/cli/named_args.rb +++ b/Library/Homebrew/cli/named_args.rb @@ -6,6 +6,7 @@ require "delegate" require "cask/cask_loader" require "cli/args" require "formulary" +require "keg" require "missing_formula" module Homebrew @@ -14,6 +15,8 @@ module Homebrew # # @api private class NamedArgs < Array + extend T::Sig + def initialize(*args, parent: Args.new, override_spec: nil, force_bottle: false, flags: []) @args = args @override_spec = override_spec @@ -39,9 +42,9 @@ module Homebrew end end - def to_formulae_to_casks(method: nil, only: nil) + def to_formulae_to_casks(only: nil, method: nil) @to_formulae_to_casks ||= {} - @to_formulae_to_casks[[method, only]] = to_formulae_and_casks(method: method, only: only) + @to_formulae_to_casks[[method, only]] = to_formulae_and_casks(only: only, method: method) .partition { |o| o.is_a?(Formula) } .map(&:freeze).freeze end @@ -62,14 +65,16 @@ module Homebrew when nil, :factory Formulary.factory(name, *spec, force_bottle: @force_bottle, flags: @flags) when :resolve - Formulary.resolve(name, spec: spec, force_bottle: @force_bottle, flags: @flags) + resolve_formula(name) + when :keg + resolve_keg(name) else raise end warn_if_cask_conflicts(name, "formula") unless only == :formula return formula - rescue FormulaUnavailableError => e + rescue NoSuchKegError, FormulaUnavailableError => e raise e if only == :formula end end @@ -97,7 +102,7 @@ module Homebrew end def to_resolved_formulae_to_casks(only: nil) - to_formulae_to_casks(method: :resolve, only: only) + to_formulae_to_casks(only: only, method: :resolve) end # Convert named arguments to {Formula} or {Cask} objects. @@ -105,7 +110,7 @@ module Homebrew # formula and prints a warning unless `only` is specified. def to_objects(only: nil, method: nil) @to_objects ||= {} - @to_objects[only] ||= downcased_unique_named.flat_map do |name| + @to_objects[only] ||= downcased_unique_named.map do |name| load_formula_or_cask(name, only: only, method: method) end.uniq.freeze end @@ -142,44 +147,33 @@ module Homebrew end.uniq.freeze end + sig { returns(T::Array[Keg]) } def to_kegs - @to_kegs ||= downcased_unique_named.map do |name| - resolve_keg name + @to_kegs ||= begin + to_formulae_and_casks(only: :formula, method: :keg).freeze rescue NoSuchKegError => e - if (reason = Homebrew::MissingFormula.suggest_command(name, "uninstall")) + if (reason = Homebrew::MissingFormula.suggest_command(e.name, "uninstall")) $stderr.puts reason end raise e - end.freeze + end end - def to_kegs_to_casks - @to_kegs_to_casks ||= begin - kegs = [] - casks = [] - - downcased_unique_named.each do |name| - kegs << resolve_keg(name) - - warn_if_cask_conflicts(name, "keg") - rescue NoSuchKegError, FormulaUnavailableError - begin - casks << Cask::CaskLoader.load(name, config: Cask::Config.from_args(@parent)) - rescue Cask::CaskUnavailableError - raise "No installed keg or cask with the name \"#{name}\"" - end - end - - [kegs.freeze, casks.freeze].freeze - end + sig { params(only: Symbol).returns([T::Array[Keg], T::Array[Cask::Cask]]) } + def to_kegs_to_casks(only: nil) + @to_kegs_to_casks ||= to_formulae_and_casks(only: only, method: :keg) + .partition { |o| o.is_a?(Keg) } + .map(&:freeze).freeze end + sig { returns(T::Array[String]) } def homebrew_tap_cask_names downcased_unique_named.grep(HOMEBREW_CASK_TAP_CASK_REGEX) end private + sig { returns(T::Array[String]) } def downcased_unique_named # Only lowercase names, not paths, bottle filenames or URLs map do |arg| diff --git a/Library/Homebrew/cmd/uninstall.rb b/Library/Homebrew/cmd/uninstall.rb index ce2b3df3c242fd88a3da91a6d008f53c985c2257..7b787d923efb733b90b2e40d8c8096a3ce8a2f3b 100644 --- a/Library/Homebrew/cmd/uninstall.rb +++ b/Library/Homebrew/cmd/uninstall.rb @@ -29,6 +29,12 @@ module Homebrew description: "Don't fail uninstall, even if <formula> is a dependency of any installed "\ "formulae." + switch "--formula", "--formulae", + description: "Treat all named arguments as formulae." + switch "--cask", "--casks", + description: "Treat all named arguments as casks." + conflicts "--formula", "--cask" + min_named :formula end end @@ -36,25 +42,29 @@ module Homebrew def uninstall args = uninstall_args.parse + only = :formula if args.formula? && !args.cask? + only = :cask if args.cask? && !args.formula? + if args.force? casks = [] kegs_by_rack = {} args.named.each do |name| - rack = Formulary.to_rack(name) - - if rack.directory? - kegs_by_rack[rack] = rack.subdirs.map { |d| Keg.new(d) } - else - begin - casks << Cask::CaskLoader.load(name) - rescue Cask::CaskUnavailableError - # Since the uninstall was forced, ignore any unavailable casks - end + if only != :cask + rack = Formulary.to_rack(name) + kegs_by_rack[rack] = rack.subdirs.map { |d| Keg.new(d) } if rack.directory? + end + + next if only == :formula + + begin + casks << Cask::CaskLoader.load(name) + rescue Cask::CaskUnavailableError + # Since the uninstall was forced, ignore any unavailable casks. end end else - all_kegs, casks = args.named.to_kegs_to_casks + all_kegs, casks = args.named.to_kegs_to_casks(only: only) kegs_by_rack = all_kegs.group_by(&:rack) end diff --git a/docs/Manpage.md b/docs/Manpage.md index 62090c849148cde180cd92e6abe1efb56ba5c2cf..cb9af56786dbae49c09bd4f30b00d89abdcc0341 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -571,6 +571,10 @@ Uninstall *`formula`*. Delete all installed versions of *`formula`*. * `--ignore-dependencies`: Don't fail uninstall, even if *`formula`* is a dependency of any installed formulae. +* `--formula`: + Treat all named arguments as formulae. +* `--cask`: + Treat all named arguments as casks. ### `unlink` [*`options`*] *`formula`* diff --git a/manpages/brew.1 b/manpages/brew.1 index 61427bbc78c8df2130f3847baa626c010fd319b7..5dcb13e59f4e8afecc18d7c41c97ecda9c4c9543 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -793,6 +793,14 @@ Delete all installed versions of \fIformula\fR\. \fB\-\-ignore\-dependencies\fR Don\'t fail uninstall, even if \fIformula\fR is a dependency of any installed formulae\. . +.TP +\fB\-\-formula\fR +Treat all named arguments as formulae\. +. +.TP +\fB\-\-cask\fR +Treat all named arguments as casks\. +. .SS "\fBunlink\fR [\fIoptions\fR] \fIformula\fR" Remove symlinks for \fIformula\fR from Homebrew\'s prefix\. This can be useful for temporarily disabling a formula: \fBbrew unlink\fR \fIformula\fR \fB&&\fR \fIcommands\fR \fB&& brew link\fR \fIformula\fR .