Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow references to casks when running uninstall and reinstall #7853

Merged
merged 23 commits into from
Jul 6, 2020
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
cbfea6c
args: Add field for kegs and unknowns
whoiswillma Jun 24, 2020
90c26da
uninstall: Add ability to reference casks from brew uninstall
whoiswillma Jun 24, 2020
16f16f3
uninstall: Add test for uninstalling cask
whoiswillma Jun 24, 2020
5900263
args: Add resolved_formulae_and_unknowns
whoiswillma Jun 24, 2020
d1004c8
reinstall: Add ability to reference casks from brew reinstall
whoiswillma Jun 24, 2020
e733fa1
uninstall: Refactor to use AbstractCommand instead of declaring a cla…
whoiswillma Jun 24, 2020
f03336b
uninstall: Clean up cask-appdir after tests
whoiswillma Jun 25, 2020
1044cb9
Merge branch 'master' into integrate-uninstall-reinstall
whoiswillma Jun 26, 2020
4dc2df6
uninstall: Run cask uninstall tests only on macos
whoiswillma Jun 29, 2020
8a05b52
args: Refactor to load casks directly
whoiswillma Jun 30, 2020
dff61c9
style: Fix style issues
whoiswillma Jun 30, 2020
f3ae2fd
reinstall: Replace with more specific imports
whoiswillma Jun 30, 2020
bb93932
Merge branch 'master' into integrate-uninstall-reinstall
whoiswillma Jun 30, 2020
72dcbd6
style: Dedent cask uninstall block
whoiswillma Jun 30, 2020
ac5f0c1
style: Dedent some autoformatted code in uninstall test case
whoiswillma Jun 30, 2020
26d7dd7
uninstall: remove tests
whoiswillma Jul 2, 2020
3459931
Merge branch 'master' into integrate-uninstall-reinstall
whoiswillma Jul 2, 2020
eb1ea00
uninstall: Refactor when using --force
whoiswillma Jul 2, 2020
1826be8
style: Replace Hash.new with {}
whoiswillma Jul 2, 2020
1ae38fb
Delete IDE files (oops)
whoiswillma Jul 3, 2020
525d1ac
Fix PR issues
whoiswillma Jul 3, 2020
6e8f5d0
Modify MultipleVersionsInstalledError to have a generic message
whoiswillma Jul 3, 2020
df8d22a
Remove debugging markers (oops)
whoiswillma Jul 3, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
105 changes: 69 additions & 36 deletions Library/Homebrew/cli/args.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ def freeze_named_args!(named_args)
# Reset cache values reliant on named_args
@formulae = nil
@resolved_formulae = nil
@resolved_formulae_and_unknowns = nil
@formulae_paths = nil
@casks = nil
@kegs = nil
@kegs_and_unknowns = nil

self[:named_args] = named_args
self[:named_args].freeze
Expand Down Expand Up @@ -96,6 +98,19 @@ def resolved_formulae
end.uniq(&:name).freeze
end

def resolved_formulae_and_unknowns
return @resolved_formulae_and_unknowns if @resolved_formulae_and_unknowns

whoiswillma marked this conversation as resolved.
Show resolved Hide resolved
resolved_formulae = []
unknowns = []
downcased_unique_named.each do |name|
resolved_formulae << Formulary.resolve(name, spec: spec(nil))
rescue FormulaUnavailableError
unknowns << name
end
@resolved_formulae_and_unknowns = [resolved_formulae.freeze, unknowns.freeze].freeze
end

def formulae_paths
@formulae_paths ||= (downcased_unique_named - casks).map do |name|
Formulary.path(name)
Expand All @@ -108,55 +123,73 @@ def casks
end

def kegs
@kegs ||= downcased_unique_named.map do |name|
resolve_keg name
rescue NoSuchKegError => e
if (reason = Homebrew::MissingFormula.suggest_command(name, "uninstall"))
$stderr.puts reason
end
raise e
end.freeze
end

def kegs_and_unknowns
return @kegs_and_unknowns if @kegs_and_unknowns

kegs = []
unknowns = []
downcased_unique_named.each do |name|
kegs << resolve_keg(name)
rescue NoSuchKegError
unknowns << name
end

@kegs_and_unknowns = [kegs.freeze, unknowns.freeze].freeze
end

def resolve_keg(name)
whoiswillma marked this conversation as resolved.
Show resolved Hide resolved
require "keg"
require "formula"
require "missing_formula"

@kegs ||= downcased_unique_named.map do |name|
raise UsageError if name.empty?
raise UsageError if name.empty?

rack = Formulary.to_rack(name.downcase)
rack = Formulary.to_rack(name.downcase)

dirs = rack.directory? ? rack.subdirs : []
dirs = rack.directory? ? rack.subdirs : []

if dirs.empty?
if (reason = Homebrew::MissingFormula.suggest_command(name, "uninstall"))
$stderr.puts reason
end
raise NoSuchKegError, rack.basename
end
raise NoSuchKegError, rack.basename if dirs.empty?

linked_keg_ref = HOMEBREW_LINKED_KEGS/rack.basename
opt_prefix = HOMEBREW_PREFIX/"opt/#{rack.basename}"
linked_keg_ref = HOMEBREW_LINKED_KEGS/rack.basename
opt_prefix = HOMEBREW_PREFIX/"opt/#{rack.basename}"

begin
if opt_prefix.symlink? && opt_prefix.directory?
Keg.new(opt_prefix.resolved_path)
elsif linked_keg_ref.symlink? && linked_keg_ref.directory?
Keg.new(linked_keg_ref.resolved_path)
elsif dirs.length == 1
Keg.new(dirs.first)
begin
if opt_prefix.symlink? && opt_prefix.directory?
Keg.new(opt_prefix.resolved_path)
elsif linked_keg_ref.symlink? && linked_keg_ref.directory?
Keg.new(linked_keg_ref.resolved_path)
elsif dirs.length == 1
Keg.new(dirs.first)
else
f = if name.include?("/") || File.exist?(name)
Formulary.factory(name)
else
f = if name.include?("/") || File.exist?(name)
Formulary.factory(name)
else
Formulary.from_rack(rack)
end

unless (prefix = f.installed_prefix).directory?
raise MultipleVersionsInstalledError, rack.basename
end
Formulary.from_rack(rack)
end

Keg.new(prefix)
unless (prefix = f.installed_prefix).directory?
raise MultipleVersionsInstalledError, rack.basename
end
rescue FormulaUnavailableError
raise <<~EOS
Multiple kegs installed to #{rack}
However we don't know which one you refer to.
Please delete (with rm -rf!) all but one and then try again.
EOS

Keg.new(prefix)
end
end.freeze
rescue FormulaUnavailableError
raise <<~EOS
Multiple kegs installed to #{rack}
However we don't know which one you refer to.
Please delete (with rm -rf!) all but one and then try again.
EOS
end
end

def build_stable?
Expand Down
13 changes: 12 additions & 1 deletion Library/Homebrew/cmd/reinstall.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require "reinstall"
require "cli/parser"
require "cleanup"
require "cask/all"
whoiswillma marked this conversation as resolved.
Show resolved Hide resolved

module Homebrew
module_function
Expand Down Expand Up @@ -56,7 +57,8 @@ def reinstall

Install.perform_preinstall_checks

args.resolved_formulae.each do |f|
resolved_formulae, possible_casks = args.resolved_formulae_and_unknowns
whoiswillma marked this conversation as resolved.
Show resolved Hide resolved
resolved_formulae.each do |f|
if f.pinned?
onoe "#{f.full_name} is pinned. You must unpin it to reinstall."
next
Expand All @@ -66,5 +68,14 @@ def reinstall
Cleanup.install_formula_clean!(f)
end
Homebrew.messages.display_messages

possible_casks.each do |name|
reinstall_cmd = Cask::Cmd::Reinstall.new(name)
reinstall_cmd.verbose = args.verbose?
reinstall_cmd.force = args.force?
reinstall_cmd.run
rescue Cask::CaskUnavailableError
ofail "No installed keg or cask with the name \"#{name}\""
end
end
end
26 changes: 22 additions & 4 deletions Library/Homebrew/cmd/uninstall.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
require "diagnostic"
require "migrator"
require "cli/parser"
require "cask/all"
require "cask/cmd"
require "cask/cask_loader"

module Homebrew
module_function
Expand All @@ -29,15 +32,21 @@ def uninstall_args
def uninstall
uninstall_args.parse

kegs_by_rack = if args.force?
Hash[args.named.map do |name|
if args.force?
possible_casks = []
whoiswillma marked this conversation as resolved.
Show resolved Hide resolved
kegs_by_rack = Hash[args.named.map do |name|
whoiswillma marked this conversation as resolved.
Show resolved Hide resolved
rack = Formulary.to_rack(name)
next unless rack.directory?

unless rack.directory?
possible_casks << name
next
end

[rack, rack.subdirs.map { |d| Keg.new(d) }]
end]
else
args.kegs.group_by(&:rack)
kegs_, possible_casks = args.kegs_and_unknowns
kegs_by_rack = kegs_.group_by(&:rack)
end

handle_unsatisfied_dependents(kegs_by_rack)
Expand Down Expand Up @@ -108,6 +117,15 @@ def uninstall
end
end
end

possible_casks.each do |name|
cmd = Cask::Cmd::Uninstall.new(name)
cmd.force = args.force?
cmd.verbose = args.verbose?
cmd.run
rescue Cask::CaskUnavailableError
ofail "No installed keg or cask with the name \"#{name}\""
end
rescue MultipleVersionsInstalledError => e
ofail e
puts "Run `brew uninstall --force #{e.name}` to remove all versions."
Expand Down
35 changes: 35 additions & 0 deletions Library/Homebrew/test/cmd/uninstall_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,41 @@
end
end

describe "brew uninstall cask", :integration_test, :needs_macos do
whoiswillma marked this conversation as resolved.
Show resolved Hide resolved
it "uninstalls a given Cask" do
caffeine = Cask::CaskLoader.load(cask_path("local-caffeine"))
Cask::Installer.new(caffeine).install

expect { brew "uninstall", "local-caffeine" }
.to output(/Uninstalling Cask local-caffeine/).to_stdout
.and not_to_output.to_stderr
.and be_a_success

expect(caffeine).not_to be_installed

rm_r(TEST_TMPDIR + "/cask-appdir")
end

it "uninstalls given Formulae and Casks" do
install_test_formula "testball"

caffeine = Cask::CaskLoader.load(cask_path("local-caffeine"))
Cask::Installer.new(caffeine).install

expect { brew "uninstall", "testball", "local-caffeine" }
.to output(%r{
Uninstalling\s#{TEST_TMPDIR}/cellar/testball/.*\n
==>\sUninstalling\sCask\slocal-caffeine
}x).to_stdout
.and not_to_output.to_stderr
.and be_a_success

expect(caffeine).not_to be_installed

rm_r(TEST_TMPDIR + "/cask-appdir")
end
end

describe Homebrew do
let(:dependency) { formula("dependency") { url "f-1" } }
let(:dependent) do
Expand Down