Add brew zap command.
This commit is contained in:
parent
181baaafb0
commit
f4b4fdac98
@ -32,6 +32,15 @@ module Cask
|
|||||||
|
|
||||||
sig { void }
|
sig { void }
|
||||||
def run
|
def run
|
||||||
|
self.class.zap_casks(*casks, verbose: args.verbose?, force: args.force?)
|
||||||
|
end
|
||||||
|
|
||||||
|
sig { params(casks: Cask, force: T.nilable(T::Boolean), verbose: T.nilable(T::Boolean)).void }
|
||||||
|
def self.zap_casks(
|
||||||
|
*casks,
|
||||||
|
force: nil,
|
||||||
|
verbose: nil
|
||||||
|
)
|
||||||
require "cask/installer"
|
require "cask/installer"
|
||||||
|
|
||||||
casks.each do |cask|
|
casks.each do |cask|
|
||||||
@ -43,10 +52,10 @@ module Cask
|
|||||||
cask = CaskLoader.load(installed_caskfile)
|
cask = CaskLoader.load(installed_caskfile)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise CaskNotInstalledError, cask unless args.force?
|
raise CaskNotInstalledError, cask unless force
|
||||||
end
|
end
|
||||||
|
|
||||||
Installer.new(cask, verbose: args.verbose?, force: args.force?).zap
|
Installer.new(cask, verbose: verbose, force: force).zap
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -35,10 +35,10 @@ module Homebrew
|
|||||||
@to_formulae ||= to_formulae_and_casks(only: :formula).freeze
|
@to_formulae ||= to_formulae_and_casks(only: :formula).freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_formulae_and_casks(only: nil, method: nil)
|
def to_formulae_and_casks(only: nil, ignore_unavailable: nil, method: nil)
|
||||||
@to_formulae_and_casks ||= {}
|
@to_formulae_and_casks ||= {}
|
||||||
@to_formulae_and_casks[only] ||= begin
|
@to_formulae_and_casks[only] ||= begin
|
||||||
to_objects(only: only, method: method).reject { |o| o.is_a?(Tap) }.freeze
|
to_objects(only: only, ignore_unavailable: ignore_unavailable, method: method).freeze
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -58,6 +58,10 @@ module Homebrew
|
|||||||
end.uniq.freeze
|
end.uniq.freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig do
|
||||||
|
params(name: String, only: T.nilable(Symbol), method: T.nilable(Symbol))
|
||||||
|
.returns(T.any(Formula, Cask::Cask, Keg, T::Array[Keg]))
|
||||||
|
end
|
||||||
def load_formula_or_cask(name, only: nil, method: nil)
|
def load_formula_or_cask(name, only: nil, method: nil)
|
||||||
if only != :cask
|
if only != :cask
|
||||||
begin
|
begin
|
||||||
@ -68,6 +72,9 @@ module Homebrew
|
|||||||
resolve_formula(name)
|
resolve_formula(name)
|
||||||
when :keg
|
when :keg
|
||||||
resolve_keg(name)
|
resolve_keg(name)
|
||||||
|
when :kegs
|
||||||
|
rack = Formulary.to_rack(name)
|
||||||
|
rack.directory? ? rack.subdirs.map { |d| Keg.new(d) } : []
|
||||||
else
|
else
|
||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
@ -108,10 +115,12 @@ module Homebrew
|
|||||||
# Convert named arguments to {Formula} or {Cask} objects.
|
# Convert named arguments to {Formula} or {Cask} objects.
|
||||||
# If both a formula and cask exist with the same name, returns the
|
# If both a formula and cask exist with the same name, returns the
|
||||||
# formula and prints a warning unless `only` is specified.
|
# formula and prints a warning unless `only` is specified.
|
||||||
def to_objects(only: nil, method: nil)
|
def to_objects(only: nil, ignore_unavailable: nil, method: nil)
|
||||||
@to_objects ||= {}
|
@to_objects ||= {}
|
||||||
@to_objects[only] ||= downcased_unique_named.map do |name|
|
@to_objects[only] ||= downcased_unique_named.flat_map do |name|
|
||||||
load_formula_or_cask(name, only: only, method: method)
|
load_formula_or_cask(name, only: only, method: method)
|
||||||
|
rescue NoSuchKegError, FormulaUnavailableError, Cask::CaskUnavailableError
|
||||||
|
ignore_unavailable ? [] : raise
|
||||||
end.uniq.freeze
|
end.uniq.freeze
|
||||||
end
|
end
|
||||||
private :to_objects
|
private :to_objects
|
||||||
@ -159,9 +168,15 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(only: T.nilable(Symbol)).returns([T::Array[Keg], T::Array[Cask::Cask]]) }
|
sig do
|
||||||
def to_kegs_to_casks(only: nil)
|
params(only: T.nilable(Symbol), ignore_unavailable: T.nilable(T::Boolean), all_kegs: T.nilable(T::Boolean))
|
||||||
@to_kegs_to_casks ||= to_formulae_and_casks(only: only, method: :keg)
|
.returns([T::Array[Keg], T::Array[Cask::Cask]])
|
||||||
|
end
|
||||||
|
def to_kegs_to_casks(only: nil, ignore_unavailable: nil, all_kegs: nil)
|
||||||
|
method = all_kegs ? :kegs : :keg
|
||||||
|
@to_kegs_to_casks ||= {}
|
||||||
|
@to_kegs_to_casks[method] ||=
|
||||||
|
to_formulae_and_casks(only: only, ignore_unavailable: ignore_unavailable, method: method)
|
||||||
.partition { |o| o.is_a?(Keg) }
|
.partition { |o| o.is_a?(Keg) }
|
||||||
.map(&:freeze).freeze
|
.map(&:freeze).freeze
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# typed: false
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "keg"
|
require "keg"
|
||||||
@ -19,12 +19,13 @@ module Homebrew
|
|||||||
def uninstall_args
|
def uninstall_args
|
||||||
Homebrew::CLI::Parser.new do
|
Homebrew::CLI::Parser.new do
|
||||||
usage_banner <<~EOS
|
usage_banner <<~EOS
|
||||||
`uninstall`, `rm`, `remove` [<options>] <formula>
|
`uninstall`, `rm`, `remove` [<options>] <formula>|<cask>
|
||||||
|
|
||||||
Uninstall <formula>.
|
Uninstall a <formula> or <cask>.
|
||||||
EOS
|
EOS
|
||||||
switch "-f", "--force",
|
switch "-f", "--force",
|
||||||
description: "Delete all installed versions of <formula>."
|
description: "Delete all installed versions of <formula>. Uninstall even if <cask> is not " \
|
||||||
|
"installed, overwrite existing files and ignore errors when removing files."
|
||||||
switch "--ignore-dependencies",
|
switch "--ignore-dependencies",
|
||||||
description: "Don't fail uninstall, even if <formula> is a dependency of any installed "\
|
description: "Don't fail uninstall, even if <formula> is a dependency of any installed "\
|
||||||
"formulae."
|
"formulae."
|
||||||
@ -35,7 +36,7 @@ module Homebrew
|
|||||||
description: "Treat all named arguments as casks."
|
description: "Treat all named arguments as casks."
|
||||||
conflicts "--formula", "--cask"
|
conflicts "--formula", "--cask"
|
||||||
|
|
||||||
min_named :formula
|
min_named :formula_or_cask
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -45,35 +46,15 @@ module Homebrew
|
|||||||
only = :formula if args.formula? && !args.cask?
|
only = :formula if args.formula? && !args.cask?
|
||||||
only = :cask if args.cask? && !args.formula?
|
only = :cask if args.cask? && !args.formula?
|
||||||
|
|
||||||
if args.force?
|
all_kegs, casks = args.named.to_kegs_to_casks(only: only, ignore_unavailable: args.force?, all_kegs: args.force?)
|
||||||
casks = []
|
|
||||||
kegs_by_rack = {}
|
|
||||||
|
|
||||||
args.named.each do |name|
|
|
||||||
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(only: only)
|
|
||||||
kegs_by_rack = all_kegs.group_by(&:rack)
|
kegs_by_rack = all_kegs.group_by(&:rack)
|
||||||
end
|
|
||||||
|
|
||||||
Uninstall.uninstall_kegs(kegs_by_rack,
|
Uninstall.uninstall_kegs(
|
||||||
|
kegs_by_rack,
|
||||||
force: args.force?,
|
force: args.force?,
|
||||||
ignore_dependencies: args.ignore_dependencies?,
|
ignore_dependencies: args.ignore_dependencies?,
|
||||||
named_args: args.named)
|
named_args: args.named,
|
||||||
|
)
|
||||||
return if casks.blank?
|
|
||||||
|
|
||||||
Cask::Cmd::Uninstall.uninstall_casks(
|
Cask::Cmd::Uninstall.uninstall_casks(
|
||||||
*casks,
|
*casks,
|
||||||
@ -81,15 +62,5 @@ module Homebrew
|
|||||||
verbose: args.verbose?,
|
verbose: args.verbose?,
|
||||||
force: args.force?,
|
force: args.force?,
|
||||||
)
|
)
|
||||||
rescue MultipleVersionsInstalledError => e
|
|
||||||
ofail e
|
|
||||||
ensure
|
|
||||||
# If we delete Cellar/newname, then Cellar/oldname symlink
|
|
||||||
# can become broken and we have to remove it.
|
|
||||||
if HOMEBREW_CELLAR.directory?
|
|
||||||
HOMEBREW_CELLAR.children.each do |rack|
|
|
||||||
rack.unlink if rack.symlink? && !rack.resolved_path_exists?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
64
Library/Homebrew/cmd/zap.rb
Normal file
64
Library/Homebrew/cmd/zap.rb
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# typed: true
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "cask/cmd"
|
||||||
|
require "cask/cask_loader"
|
||||||
|
require "uninstall"
|
||||||
|
|
||||||
|
module Homebrew
|
||||||
|
extend T::Sig
|
||||||
|
|
||||||
|
module_function
|
||||||
|
|
||||||
|
sig { returns(CLI::Parser) }
|
||||||
|
def zap_args
|
||||||
|
Homebrew::CLI::Parser.new do
|
||||||
|
usage_banner <<~EOS
|
||||||
|
`zap` [<options>] <formula>|<cask>
|
||||||
|
|
||||||
|
Remove all files associated with the given <formula> or <cask>.
|
||||||
|
Implicitly also performs all actions associated with `uninstall`.
|
||||||
|
|
||||||
|
*May remove files which are shared between applications.*
|
||||||
|
EOS
|
||||||
|
switch "-f", "--force",
|
||||||
|
description: "Delete all installed versions of <formula>. Uninstall even if <cask> is not " \
|
||||||
|
"installed, overwrite existing files and ignore errors when removing files."
|
||||||
|
switch "--ignore-dependencies",
|
||||||
|
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_or_cask
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def zap
|
||||||
|
args = zap_args.parse
|
||||||
|
|
||||||
|
only = :formula if args.formula? && !args.cask?
|
||||||
|
only = :cask if args.cask? && !args.formula?
|
||||||
|
|
||||||
|
all_kegs, casks = args.named.to_kegs_to_casks(only: only, ignore_unavailable: args.force?, all_kegs: args.force?)
|
||||||
|
kegs_by_rack = all_kegs.group_by(&:rack)
|
||||||
|
|
||||||
|
Uninstall.uninstall_kegs(
|
||||||
|
kegs_by_rack,
|
||||||
|
force: args.force?,
|
||||||
|
ignore_dependencies: args.ignore_dependencies?,
|
||||||
|
named_args: args.named,
|
||||||
|
)
|
||||||
|
|
||||||
|
Cask::Cmd::Zap.zap_casks(
|
||||||
|
*casks,
|
||||||
|
binaries: EnvConfig.cask_opts_binaries?,
|
||||||
|
verbose: args.verbose?,
|
||||||
|
force: args.force?,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -75,7 +75,7 @@ describe Cask::Cmd::Style, :cask do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "tries to find paths for all tokens" do
|
it "tries to find paths for all tokens" do
|
||||||
expect(Cask::CaskLoader).to receive(:load).twice.and_return(double("cask", sourcefile_path: nil))
|
expect(Cask::CaskLoader).to receive(:load).twice.and_return(instance_double(Cask::Cask, sourcefile_path: nil))
|
||||||
subject
|
subject
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -82,6 +82,16 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
rescue MultipleVersionsInstalledError => e
|
||||||
|
ofail e
|
||||||
|
ensure
|
||||||
|
# If we delete Cellar/newname, then Cellar/oldname symlink
|
||||||
|
# can become broken and we have to remove it.
|
||||||
|
if HOMEBREW_CELLAR.directory?
|
||||||
|
HOMEBREW_CELLAR.children.each do |rack|
|
||||||
|
rack.unlink if rack.symlink? && !rack.resolved_path_exists?
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_unsatisfied_dependents(kegs_by_rack, ignore_dependencies: false, named_args: [])
|
def handle_unsatisfied_dependents(kegs_by_rack, ignore_dependencies: false, named_args: [])
|
||||||
|
|||||||
@ -104,3 +104,4 @@ upgrade
|
|||||||
uses
|
uses
|
||||||
vendor-gems
|
vendor-gems
|
||||||
vendor-install
|
vendor-install
|
||||||
|
zap
|
||||||
|
|||||||
@ -563,12 +563,12 @@ If no *`tap`* names are provided, display brief statistics for all installed tap
|
|||||||
* `--json`:
|
* `--json`:
|
||||||
Print a JSON representation of *`tap`*. Currently the default and only accepted value for *`version`* is `v1`. See the docs for examples of using the JSON output: <https://docs.brew.sh/Querying-Brew>
|
Print a JSON representation of *`tap`*. Currently the default and only accepted value for *`version`* is `v1`. See the docs for examples of using the JSON output: <https://docs.brew.sh/Querying-Brew>
|
||||||
|
|
||||||
### `uninstall`, `rm`, `remove` [*`options`*] *`formula`*
|
### `uninstall`, `rm`, `remove` [*`options`*] *`formula`*|*`cask`*
|
||||||
|
|
||||||
Uninstall *`formula`*.
|
Uninstall a *`formula`* or *`cask`*.
|
||||||
|
|
||||||
* `-f`, `--force`:
|
* `-f`, `--force`:
|
||||||
Delete all installed versions of *`formula`*.
|
Delete all installed versions of *`formula`*. Uninstall even if *`cask`* is not installed, overwrite existing files and ignore errors when removing files.
|
||||||
* `--ignore-dependencies`:
|
* `--ignore-dependencies`:
|
||||||
Don't fail uninstall, even if *`formula`* is a dependency of any installed formulae.
|
Don't fail uninstall, even if *`formula`* is a dependency of any installed formulae.
|
||||||
* `--formula`:
|
* `--formula`:
|
||||||
@ -677,6 +677,22 @@ specify *`formula`* as a required or recommended dependency for their stable bui
|
|||||||
* `--skip-recommended`:
|
* `--skip-recommended`:
|
||||||
Skip all formulae that specify *`formula`* as `:recommended` type dependency.
|
Skip all formulae that specify *`formula`* as `:recommended` type dependency.
|
||||||
|
|
||||||
|
### `zap` [*`options`*] *`formula`*|*`cask`*
|
||||||
|
|
||||||
|
Remove all files associated with the given *`formula`* or *`cask`*.
|
||||||
|
Implicitly also performs all actions associated with `uninstall`.
|
||||||
|
|
||||||
|
*May remove files which are shared between applications.*
|
||||||
|
|
||||||
|
* `-f`, `--force`:
|
||||||
|
Delete all installed versions of *`formula`*. Uninstall even if *`cask`* is not installed, overwrite existing files and ignore errors when removing files.
|
||||||
|
* `--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.
|
||||||
|
|
||||||
### `--cache` [*`options`*] [*`formula`*|*`cask`*]
|
### `--cache` [*`options`*] [*`formula`*|*`cask`*]
|
||||||
|
|
||||||
Display Homebrew's download cache. See also `HOMEBREW_CACHE`.
|
Display Homebrew's download cache. See also `HOMEBREW_CACHE`.
|
||||||
|
|||||||
@ -782,12 +782,12 @@ Show information on each installed tap\.
|
|||||||
\fB\-\-json\fR
|
\fB\-\-json\fR
|
||||||
Print a JSON representation of \fItap\fR\. Currently the default and only accepted value for \fIversion\fR is \fBv1\fR\. See the docs for examples of using the JSON output: \fIhttps://docs\.brew\.sh/Querying\-Brew\fR
|
Print a JSON representation of \fItap\fR\. Currently the default and only accepted value for \fIversion\fR is \fBv1\fR\. See the docs for examples of using the JSON output: \fIhttps://docs\.brew\.sh/Querying\-Brew\fR
|
||||||
.
|
.
|
||||||
.SS "\fBuninstall\fR, \fBrm\fR, \fBremove\fR [\fIoptions\fR] \fIformula\fR"
|
.SS "\fBuninstall\fR, \fBrm\fR, \fBremove\fR [\fIoptions\fR] \fIformula\fR|\fIcask\fR"
|
||||||
Uninstall \fIformula\fR\.
|
Uninstall a \fIformula\fR or \fIcask\fR\.
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-f\fR, \fB\-\-force\fR
|
\fB\-f\fR, \fB\-\-force\fR
|
||||||
Delete all installed versions of \fIformula\fR\.
|
Delete all installed versions of \fIformula\fR\. Uninstall even if \fIcask\fR is not installed, overwrite existing files and ignore errors when removing files\.
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-ignore\-dependencies\fR
|
\fB\-\-ignore\-dependencies\fR
|
||||||
@ -940,6 +940,28 @@ Include all formulae that specify \fIformula\fR as \fB:optional\fR type dependen
|
|||||||
\fB\-\-skip\-recommended\fR
|
\fB\-\-skip\-recommended\fR
|
||||||
Skip all formulae that specify \fIformula\fR as \fB:recommended\fR type dependency\.
|
Skip all formulae that specify \fIformula\fR as \fB:recommended\fR type dependency\.
|
||||||
.
|
.
|
||||||
|
.SS "\fBzap\fR [\fIoptions\fR] \fIformula\fR|\fIcask\fR"
|
||||||
|
Remove all files associated with the given \fIformula\fR or \fIcask\fR\. Implicitly also performs all actions associated with \fBuninstall\fR\.
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
\fIMay remove files which are shared between applications\.\fR
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-f\fR, \fB\-\-force\fR
|
||||||
|
Delete all installed versions of \fIformula\fR\. Uninstall even if \fIcask\fR is not installed, overwrite existing files and ignore errors when removing files\.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\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 "\fB\-\-cache\fR [\fIoptions\fR] [\fIformula\fR|\fIcask\fR]"
|
.SS "\fB\-\-cache\fR [\fIoptions\fR] [\fIformula\fR|\fIcask\fR]"
|
||||||
Display Homebrew\'s download cache\. See also \fBHOMEBREW_CACHE\fR\.
|
Display Homebrew\'s download cache\. See also \fBHOMEBREW_CACHE\fR\.
|
||||||
.
|
.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user