mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
Merge pull request #1082 from alyssais/uninstall_dependancy_error
uninstall: refuse when dependents still installed
This commit is contained in:
commit
2ce17a1137
@ -1,6 +1,9 @@
|
|||||||
#: * `missing` [<formulae>]:
|
#: * `missing` [`--hide=`<hidden>] [<formulae>]:
|
||||||
#: Check the given <formulae> for missing dependencies. If no <formulae> are
|
#: Check the given <formulae> for missing dependencies. If no <formulae> are
|
||||||
#: given, check all installed brews.
|
#: given, check all installed brews.
|
||||||
|
#:
|
||||||
|
#: If `--hide=`<hidden> is passed, act as if none of <hidden> are installed.
|
||||||
|
#: <hidden> should be a comma-separated list of formulae.
|
||||||
|
|
||||||
require "formula"
|
require "formula"
|
||||||
require "tab"
|
require "tab"
|
||||||
@ -18,8 +21,11 @@ module Homebrew
|
|||||||
ARGV.resolved_formulae
|
ARGV.resolved_formulae
|
||||||
end
|
end
|
||||||
|
|
||||||
Diagnostic.missing_deps(ff) do |name, missing|
|
ff.each do |f|
|
||||||
print "#{name}: " if ff.size > 1
|
missing = f.missing_dependencies(hide: ARGV.values("hide"))
|
||||||
|
next if missing.empty?
|
||||||
|
|
||||||
|
print "#{f}: " if ff.size > 1
|
||||||
puts missing.join(" ")
|
puts missing.join(" ")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
#: * `uninstall`, `rm`, `remove` [`--force`] <formula>:
|
#: * `uninstall`, `rm`, `remove` [`--force`] [`--ignore-dependencies`] <formula>:
|
||||||
#: Uninstall <formula>.
|
#: Uninstall <formula>.
|
||||||
#:
|
#:
|
||||||
#: If `--force` is passed, and there are multiple versions of <formula>
|
#: If `--force` is passed, and there are multiple versions of <formula>
|
||||||
#: installed, delete all installed versions.
|
#: installed, delete all installed versions.
|
||||||
|
#:
|
||||||
|
#: If `--ignore-dependencies` is passed, uninstalling won't fail, even if
|
||||||
|
#: formulae depending on <formula> would still be installed.
|
||||||
|
|
||||||
require "keg"
|
require "keg"
|
||||||
require "formula"
|
require "formula"
|
||||||
|
require "diagnostic"
|
||||||
require "migrator"
|
require "migrator"
|
||||||
|
|
||||||
module Homebrew
|
module Homebrew
|
||||||
@ -14,38 +18,50 @@ module Homebrew
|
|||||||
def uninstall
|
def uninstall
|
||||||
raise KegUnspecifiedError if ARGV.named.empty?
|
raise KegUnspecifiedError if ARGV.named.empty?
|
||||||
|
|
||||||
if !ARGV.force?
|
kegs_by_rack = if ARGV.force?
|
||||||
ARGV.kegs.each do |keg|
|
Hash[ARGV.named.map do |name|
|
||||||
keg.lock do
|
|
||||||
puts "Uninstalling #{keg}... (#{keg.abv})"
|
|
||||||
keg.unlink
|
|
||||||
keg.uninstall
|
|
||||||
rack = keg.rack
|
|
||||||
rm_pin rack
|
|
||||||
|
|
||||||
if rack.directory?
|
|
||||||
versions = rack.subdirs.map(&:basename)
|
|
||||||
verb = versions.length == 1 ? "is" : "are"
|
|
||||||
puts "#{keg.name} #{versions.join(", ")} #{verb} still installed."
|
|
||||||
puts "Remove all versions with `brew uninstall --force #{keg.name}`."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
ARGV.named.each do |name|
|
|
||||||
rack = Formulary.to_rack(name)
|
rack = Formulary.to_rack(name)
|
||||||
|
[rack, rack.subdirs.map { |d| Keg.new(d) }]
|
||||||
|
end]
|
||||||
|
else
|
||||||
|
ARGV.kegs.group_by(&:rack)
|
||||||
|
end
|
||||||
|
|
||||||
|
if should_check_for_dependents?
|
||||||
|
all_kegs = kegs_by_rack.values.flatten(1)
|
||||||
|
return if check_for_dependents all_kegs
|
||||||
|
end
|
||||||
|
|
||||||
|
kegs_by_rack.each do |rack, kegs|
|
||||||
|
if ARGV.force?
|
||||||
name = rack.basename
|
name = rack.basename
|
||||||
|
|
||||||
if rack.directory?
|
if rack.directory?
|
||||||
puts "Uninstalling #{name}... (#{rack.abv})"
|
puts "Uninstalling #{name}... (#{rack.abv})"
|
||||||
rack.subdirs.each do |d|
|
kegs.each do |keg|
|
||||||
keg = Keg.new(d)
|
|
||||||
keg.unlink
|
keg.unlink
|
||||||
keg.uninstall
|
keg.uninstall
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
rm_pin rack
|
rm_pin rack
|
||||||
|
else
|
||||||
|
kegs.each do |keg|
|
||||||
|
keg.lock do
|
||||||
|
puts "Uninstalling #{keg}... (#{keg.abv})"
|
||||||
|
keg.unlink
|
||||||
|
keg.uninstall
|
||||||
|
rack = keg.rack
|
||||||
|
rm_pin rack
|
||||||
|
|
||||||
|
if rack.directory?
|
||||||
|
versions = rack.subdirs.map(&:basename)
|
||||||
|
verb = versions.length == 1 ? "is" : "are"
|
||||||
|
puts "#{keg.name} #{versions.join(", ")} #{verb} still installed."
|
||||||
|
puts "Remove all versions with `brew uninstall --force #{keg.name}`."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rescue MultipleVersionsInstalledError => e
|
rescue MultipleVersionsInstalledError => e
|
||||||
@ -61,6 +77,30 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def should_check_for_dependents?
|
||||||
|
# --ignore-dependencies, to be consistent with install
|
||||||
|
return false if ARGV.include?("--ignore-dependencies")
|
||||||
|
return false if ARGV.homebrew_developer?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_for_dependents(kegs)
|
||||||
|
return false unless result = Keg.find_some_installed_dependents(kegs)
|
||||||
|
|
||||||
|
requireds, dependents = result
|
||||||
|
|
||||||
|
msg = "Refusing to uninstall #{requireds.join(", ")} because "
|
||||||
|
msg << (requireds.count == 1 ? "it is" : "they are")
|
||||||
|
msg << " required by #{dependents.join(", ")}, which "
|
||||||
|
msg << (dependents.count == 1 ? "is" : "are")
|
||||||
|
msg << " currently installed."
|
||||||
|
ofail msg
|
||||||
|
print "You can override this and force removal with "
|
||||||
|
puts "`brew uninstall --ignore-dependencies #{requireds.map(&:name).join(" ")}`."
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
def rm_pin(rack)
|
def rm_pin(rack)
|
||||||
Formulary.from_rack(rack).unpin
|
Formulary.from_rack(rack).unpin
|
||||||
rescue
|
rescue
|
||||||
|
@ -7,24 +7,14 @@ require "utils/shell"
|
|||||||
|
|
||||||
module Homebrew
|
module Homebrew
|
||||||
module Diagnostic
|
module Diagnostic
|
||||||
def self.missing_deps(ff)
|
def self.missing_deps(ff, hide = nil)
|
||||||
missing = {}
|
missing = {}
|
||||||
ff.each do |f|
|
ff.each do |f|
|
||||||
missing_deps = f.recursive_dependencies do |dependent, dep|
|
missing_dependencies = f.missing_dependencies(hide: hide)
|
||||||
if dep.optional? || dep.recommended?
|
|
||||||
tab = Tab.for_formula(dependent)
|
|
||||||
Dependency.prune unless tab.with?(dep)
|
|
||||||
elsif dep.build?
|
|
||||||
Dependency.prune
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
missing_deps.map!(&:to_formula)
|
unless missing_dependencies.empty?
|
||||||
missing_deps.reject! { |d| d.installed_prefixes.any? }
|
yield f.full_name, missing_dependencies if block_given?
|
||||||
|
missing[f.full_name] = missing_dependencies
|
||||||
unless missing_deps.empty?
|
|
||||||
yield f.full_name, missing_deps if block_given?
|
|
||||||
missing[f.full_name] = missing_deps
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
missing
|
missing
|
||||||
|
@ -121,6 +121,13 @@ module HomebrewArgvExtension
|
|||||||
flag_with_value.strip_prefix(arg_prefix) if flag_with_value
|
flag_with_value.strip_prefix(arg_prefix) if flag_with_value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns an array of values that were given as a comma-seperated list.
|
||||||
|
# @see value
|
||||||
|
def values(name)
|
||||||
|
return unless val = value(name)
|
||||||
|
val.split(",")
|
||||||
|
end
|
||||||
|
|
||||||
def force?
|
def force?
|
||||||
flag? "--force"
|
flag? "--force"
|
||||||
end
|
end
|
||||||
|
@ -1337,6 +1337,13 @@ class Formula
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Clear caches of .racks and .installed.
|
||||||
|
# @private
|
||||||
|
def self.clear_cache
|
||||||
|
@racks = nil
|
||||||
|
@installed = nil
|
||||||
|
end
|
||||||
|
|
||||||
# An array of all racks currently installed.
|
# An array of all racks currently installed.
|
||||||
# @private
|
# @private
|
||||||
def self.racks
|
def self.racks
|
||||||
@ -1459,6 +1466,26 @@ class Formula
|
|||||||
recursive_dependencies.reject(&:build?)
|
recursive_dependencies.reject(&:build?)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns a list of formulae depended on by this formula that aren't
|
||||||
|
# installed
|
||||||
|
def missing_dependencies(hide: nil)
|
||||||
|
hide ||= []
|
||||||
|
missing_dependencies = recursive_dependencies do |dependent, dep|
|
||||||
|
if dep.optional? || dep.recommended?
|
||||||
|
tab = Tab.for_formula(dependent)
|
||||||
|
Dependency.prune unless tab.with?(dep)
|
||||||
|
elsif dep.build?
|
||||||
|
Dependency.prune
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
missing_dependencies.map!(&:to_formula)
|
||||||
|
missing_dependencies.select! do |d|
|
||||||
|
hide.include?(d.name) || d.installed_prefixes.empty?
|
||||||
|
end
|
||||||
|
missing_dependencies
|
||||||
|
end
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
def to_hash
|
def to_hash
|
||||||
hsh = {
|
hsh = {
|
||||||
|
@ -87,6 +87,41 @@ class Keg
|
|||||||
mime-info pixmaps sounds postgresql
|
mime-info pixmaps sounds postgresql
|
||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
|
# Will return some kegs, and some dependencies, if they're present.
|
||||||
|
# For efficiency, we don't bother trying to get complete data.
|
||||||
|
def self.find_some_installed_dependents(kegs)
|
||||||
|
# First, check in the tabs of installed Formulae.
|
||||||
|
kegs.each do |keg|
|
||||||
|
dependents = keg.installed_dependents - kegs
|
||||||
|
dependents.map! { |d| "#{d.name} #{d.version}" }
|
||||||
|
return [keg], dependents if dependents.any?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Some kegs won't have modern Tabs with the dependencies listed.
|
||||||
|
# In this case, fall back to Formula#missing_dependencies.
|
||||||
|
|
||||||
|
# Find formulae that didn't have dependencies saved in all of their kegs,
|
||||||
|
# so need them to be calculated now.
|
||||||
|
#
|
||||||
|
# This happens after the initial dependency check because it's sloooow.
|
||||||
|
remaining_formulae = Formula.installed.select do |f|
|
||||||
|
f.installed_kegs.any? { |k| Tab.for_keg(k).runtime_dependencies.nil? }
|
||||||
|
end
|
||||||
|
|
||||||
|
keg_names = kegs.map(&:name)
|
||||||
|
kegs_by_name = kegs.group_by(&:to_formula)
|
||||||
|
remaining_formulae.each do |dependent|
|
||||||
|
required = dependent.missing_dependencies(hide: keg_names)
|
||||||
|
required.select! { |f| kegs_by_name.key?(f) }
|
||||||
|
next unless required.any?
|
||||||
|
|
||||||
|
required_kegs = required.map { |f| kegs_by_name[f].sort_by(&:version).last }
|
||||||
|
return required_kegs, [dependent.to_s]
|
||||||
|
end
|
||||||
|
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
# if path is a file in a keg then this will return the containing Keg object
|
# if path is a file in a keg then this will return the containing Keg object
|
||||||
def self.for(path)
|
def self.for(path)
|
||||||
path = path.realpath
|
path = path.realpath
|
||||||
@ -292,6 +327,23 @@ class Keg
|
|||||||
PkgVersion.parse(path.basename.to_s)
|
PkgVersion.parse(path.basename.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_formula
|
||||||
|
Formulary.from_keg(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def installed_dependents
|
||||||
|
Formula.installed.flat_map(&:installed_kegs).select do |keg|
|
||||||
|
tab = Tab.for_keg(keg)
|
||||||
|
next if tab.runtime_dependencies.nil? # no dependency information saved.
|
||||||
|
tab.runtime_dependencies.any? do |dep|
|
||||||
|
# Resolve formula rather than directly comparing names
|
||||||
|
# in case of conflicts between formulae from different taps.
|
||||||
|
dep_formula = Formulary.factory(dep["full_name"])
|
||||||
|
dep_formula == to_formula && dep["version"] == version.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def find(*args, &block)
|
def find(*args, &block)
|
||||||
path.find(*args, &block)
|
path.find(*args, &block)
|
||||||
end
|
end
|
||||||
|
@ -73,10 +73,12 @@ class IntegrationCommandTestCase < Homebrew::TestCase
|
|||||||
cmd_args << "-rintegration_mocks"
|
cmd_args << "-rintegration_mocks"
|
||||||
cmd_args << (HOMEBREW_LIBRARY_PATH/"brew.rb").resolved_path.to_s
|
cmd_args << (HOMEBREW_LIBRARY_PATH/"brew.rb").resolved_path.to_s
|
||||||
cmd_args += args
|
cmd_args += args
|
||||||
|
developer = ENV["HOMEBREW_DEVELOPER"]
|
||||||
Bundler.with_original_env do
|
Bundler.with_original_env do
|
||||||
ENV["HOMEBREW_BREW_FILE"] = HOMEBREW_PREFIX/"bin/brew"
|
ENV["HOMEBREW_BREW_FILE"] = HOMEBREW_PREFIX/"bin/brew"
|
||||||
ENV["HOMEBREW_INTEGRATION_TEST"] = cmd_id_from_args(args)
|
ENV["HOMEBREW_INTEGRATION_TEST"] = cmd_id_from_args(args)
|
||||||
ENV["HOMEBREW_TEST_TMPDIR"] = TEST_TMPDIR
|
ENV["HOMEBREW_TEST_TMPDIR"] = TEST_TMPDIR
|
||||||
|
ENV["HOMEBREW_DEVELOPER"] = developer
|
||||||
env.each_pair do |k, v|
|
env.each_pair do |k, v|
|
||||||
ENV[k] = v
|
ENV[k] = v
|
||||||
end
|
end
|
||||||
@ -127,7 +129,6 @@ class IntegrationCommandTestCase < Homebrew::TestCase
|
|||||||
sha256 "#{TESTBALL_SHA256}"
|
sha256 "#{TESTBALL_SHA256}"
|
||||||
|
|
||||||
option "with-foo", "Build with foo"
|
option "with-foo", "Build with foo"
|
||||||
#{content}
|
|
||||||
|
|
||||||
def install
|
def install
|
||||||
(prefix/"foo"/"test").write("test") if build.with? "foo"
|
(prefix/"foo"/"test").write("test") if build.with? "foo"
|
||||||
@ -138,6 +139,8 @@ class IntegrationCommandTestCase < Homebrew::TestCase
|
|||||||
system ENV.cc, "test.c", "-o", bin/"test"
|
system ENV.cc, "test.c", "-o", bin/"test"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#{content}
|
||||||
|
|
||||||
# something here
|
# something here
|
||||||
EOS
|
EOS
|
||||||
when "foo"
|
when "foo"
|
||||||
|
@ -62,4 +62,19 @@ class ArgvExtensionTests < Homebrew::TestCase
|
|||||||
assert !@argv.flag?("--frotz")
|
assert !@argv.flag?("--frotz")
|
||||||
assert !@argv.flag?("--debug")
|
assert !@argv.flag?("--debug")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_value
|
||||||
|
@argv << "--foo=" << "--bar=ab"
|
||||||
|
assert_equal "", @argv.value("foo")
|
||||||
|
assert_equal "ab", @argv.value("bar")
|
||||||
|
assert_nil @argv.value("baz")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_values
|
||||||
|
@argv << "--foo=" << "--bar=a" << "--baz=b,c"
|
||||||
|
assert_equal [], @argv.values("foo")
|
||||||
|
assert_equal ["a"], @argv.values("bar")
|
||||||
|
assert_equal ["b", "c"], @argv.values("baz")
|
||||||
|
assert_nil @argv.values("qux")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -5,15 +5,22 @@ require "stringio"
|
|||||||
class LinkTests < Homebrew::TestCase
|
class LinkTests < Homebrew::TestCase
|
||||||
include FileUtils
|
include FileUtils
|
||||||
|
|
||||||
def setup
|
def setup_test_keg(name, version)
|
||||||
keg = HOMEBREW_CELLAR.join("foo", "1.0")
|
path = HOMEBREW_CELLAR.join(name, version)
|
||||||
keg.join("bin").mkpath
|
path.join("bin").mkpath
|
||||||
|
|
||||||
%w[hiworld helloworld goodbye_cruel_world].each do |file|
|
%w[hiworld helloworld goodbye_cruel_world].each do |file|
|
||||||
touch keg.join("bin", file)
|
touch path.join("bin", file)
|
||||||
end
|
end
|
||||||
|
|
||||||
@keg = Keg.new(keg)
|
keg = Keg.new(path)
|
||||||
|
@kegs ||= []
|
||||||
|
@kegs << keg
|
||||||
|
keg
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@keg = setup_test_keg("foo", "1.0")
|
||||||
@dst = HOMEBREW_PREFIX.join("bin", "helloworld")
|
@dst = HOMEBREW_PREFIX.join("bin", "helloworld")
|
||||||
@nonexistent = Pathname.new("/some/nonexistent/path")
|
@nonexistent = Pathname.new("/some/nonexistent/path")
|
||||||
|
|
||||||
@ -27,8 +34,10 @@ class LinkTests < Homebrew::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
def teardown
|
def teardown
|
||||||
@keg.unlink
|
@kegs.each do |keg|
|
||||||
@keg.uninstall
|
keg.unlink
|
||||||
|
keg.uninstall
|
||||||
|
end
|
||||||
|
|
||||||
$stdout = @old_stdout
|
$stdout = @old_stdout
|
||||||
|
|
||||||
@ -305,3 +314,72 @@ class LinkTests < Homebrew::TestCase
|
|||||||
keg.uninstall
|
keg.uninstall
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class InstalledDependantsTests < LinkTests
|
||||||
|
def stub_formula_name(name)
|
||||||
|
stub_formula_loader formula(name) { url "foo-1.0" }
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup_test_keg(name, version)
|
||||||
|
stub_formula_name(name)
|
||||||
|
keg = super
|
||||||
|
Formula.clear_cache
|
||||||
|
keg
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup
|
||||||
|
super
|
||||||
|
@dependent = setup_test_keg("bar", "1.0")
|
||||||
|
end
|
||||||
|
|
||||||
|
def alter_tab(keg = @dependent)
|
||||||
|
tab = Tab.for_keg(keg)
|
||||||
|
yield tab
|
||||||
|
tab.write
|
||||||
|
end
|
||||||
|
|
||||||
|
def dependencies(deps)
|
||||||
|
alter_tab do |tab|
|
||||||
|
tab.tabfile = @dependent.join("INSTALL_RECEIPT.json")
|
||||||
|
tab.runtime_dependencies = deps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_no_dependencies_anywhere
|
||||||
|
dependencies nil
|
||||||
|
assert_empty @keg.installed_dependents
|
||||||
|
assert_nil Keg.find_some_installed_dependents([@keg])
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_missing_formula_dependency
|
||||||
|
dependencies nil
|
||||||
|
Formula["bar"].class.depends_on "foo"
|
||||||
|
assert_empty @keg.installed_dependents
|
||||||
|
assert_equal [[@keg], ["bar"]], Keg.find_some_installed_dependents([@keg])
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_empty_dependencies_in_tab
|
||||||
|
dependencies []
|
||||||
|
assert_empty @keg.installed_dependents
|
||||||
|
assert_nil Keg.find_some_installed_dependents([@keg])
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_same_name_different_version_in_tab
|
||||||
|
dependencies [{ "full_name" => "foo", "version" => "1.1" }]
|
||||||
|
assert_empty @keg.installed_dependents
|
||||||
|
assert_nil Keg.find_some_installed_dependents([@keg])
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_different_name_same_version_in_tab
|
||||||
|
stub_formula_name("baz")
|
||||||
|
dependencies [{ "full_name" => "baz", "version" => @keg.version.to_s }]
|
||||||
|
assert_empty @keg.installed_dependents
|
||||||
|
assert_nil Keg.find_some_installed_dependents([@keg])
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_same_name_and_version_in_tab
|
||||||
|
dependencies [{ "full_name" => "foo", "version" => "1.0" }]
|
||||||
|
assert_equal [@dependent], @keg.installed_dependents
|
||||||
|
assert_equal [[@keg], ["bar 1.0"]], Keg.find_some_installed_dependents([@keg])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@ -1,11 +1,34 @@
|
|||||||
require "helper/integration_command_test_case"
|
require "helper/integration_command_test_case"
|
||||||
|
|
||||||
class IntegrationCommandTestMissing < IntegrationCommandTestCase
|
class IntegrationCommandTestMissing < IntegrationCommandTestCase
|
||||||
def test_missing
|
def setup
|
||||||
|
super
|
||||||
|
|
||||||
setup_test_formula "foo"
|
setup_test_formula "foo"
|
||||||
setup_test_formula "bar"
|
setup_test_formula "bar"
|
||||||
|
end
|
||||||
|
|
||||||
|
def make_prefix(name)
|
||||||
|
(HOMEBREW_CELLAR/name/"1.0").mkpath
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_missing_missing
|
||||||
|
make_prefix "bar"
|
||||||
|
|
||||||
(HOMEBREW_CELLAR/"bar/1.0").mkpath
|
|
||||||
assert_match "foo", cmd("missing")
|
assert_match "foo", cmd("missing")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_missing_not_missing
|
||||||
|
make_prefix "foo"
|
||||||
|
make_prefix "bar"
|
||||||
|
|
||||||
|
assert_empty cmd("missing")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_missing_hide
|
||||||
|
make_prefix "foo"
|
||||||
|
make_prefix "bar"
|
||||||
|
|
||||||
|
assert_match "foo", cmd("missing", "--hide=foo")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,26 @@
|
|||||||
require "helper/integration_command_test_case"
|
require "helper/integration_command_test_case"
|
||||||
|
require "cmd/uninstall"
|
||||||
|
|
||||||
|
class UninstallTests < Homebrew::TestCase
|
||||||
|
def test_check_for_testball_f2s_when_developer
|
||||||
|
refute_predicate Homebrew, :should_check_for_dependents?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_check_for_dependents_when_not_developer
|
||||||
|
run_as_not_developer do
|
||||||
|
assert_predicate Homebrew, :should_check_for_dependents?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_check_for_dependents_when_ignore_dependencies
|
||||||
|
ARGV << "--ignore-dependencies"
|
||||||
|
run_as_not_developer do
|
||||||
|
refute_predicate Homebrew, :should_check_for_dependents?
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
ARGV.delete("--ignore-dependencies")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class IntegrationCommandTestUninstall < IntegrationCommandTestCase
|
class IntegrationCommandTestUninstall < IntegrationCommandTestCase
|
||||||
def test_uninstall
|
def test_uninstall
|
||||||
|
@ -245,8 +245,11 @@ packages.</p>
|
|||||||
|
|
||||||
<p>If <code>--force</code> is passed, then treat installed <var>formulae</var> and passed <var>formulae</var>
|
<p>If <code>--force</code> is passed, then treat installed <var>formulae</var> and passed <var>formulae</var>
|
||||||
like if they are from same taps and migrate them anyway.</p></dd>
|
like if they are from same taps and migrate them anyway.</p></dd>
|
||||||
<dt><code>missing</code> [<var>formulae</var>]</dt><dd><p>Check the given <var>formulae</var> for missing dependencies. If no <var>formulae</var> are
|
<dt><code>missing</code> [<code>--hide=</code><var>hidden</var>] [<var>formulae</var>]</dt><dd><p>Check the given <var>formulae</var> for missing dependencies. If no <var>formulae</var> are
|
||||||
given, check all installed brews.</p></dd>
|
given, check all installed brews.</p>
|
||||||
|
|
||||||
|
<p>If <code>--hide=</code><var>hidden</var> is passed, act as if none of <var>hidden</var> are installed.
|
||||||
|
<var>hidden</var> should be a comma-separated list of formulae.</p></dd>
|
||||||
<dt><code>options</code> [<code>--compact</code>] (<code>--all</code>|<code>--installed</code>|<var>formulae</var>)</dt><dd><p>Display install options specific to <var>formulae</var>.</p>
|
<dt><code>options</code> [<code>--compact</code>] (<code>--all</code>|<code>--installed</code>|<var>formulae</var>)</dt><dd><p>Display install options specific to <var>formulae</var>.</p>
|
||||||
|
|
||||||
<p>If <code>--compact</code> is passed, show all options on a single line separated by
|
<p>If <code>--compact</code> is passed, show all options on a single line separated by
|
||||||
@ -348,10 +351,13 @@ for <var>version</var> is <code>v1</code>.</p>
|
|||||||
<dt><code>tap-pin</code> <var>tap</var></dt><dd><p>Pin <var>tap</var>, prioritizing its formulae over core when formula names are supplied
|
<dt><code>tap-pin</code> <var>tap</var></dt><dd><p>Pin <var>tap</var>, prioritizing its formulae over core when formula names are supplied
|
||||||
by the user. See also <code>tap-unpin</code>.</p></dd>
|
by the user. See also <code>tap-unpin</code>.</p></dd>
|
||||||
<dt><code>tap-unpin</code> <var>tap</var></dt><dd><p>Unpin <var>tap</var> so its formulae are no longer prioritized. See also <code>tap-pin</code>.</p></dd>
|
<dt><code>tap-unpin</code> <var>tap</var></dt><dd><p>Unpin <var>tap</var> so its formulae are no longer prioritized. See also <code>tap-pin</code>.</p></dd>
|
||||||
<dt><code>uninstall</code>, <code>rm</code>, <code>remove</code> [<code>--force</code>] <var>formula</var></dt><dd><p>Uninstall <var>formula</var>.</p>
|
<dt><code>uninstall</code>, <code>rm</code>, <code>remove</code> [<code>--force</code>] [<code>--ignore-dependencies</code>] <var>formula</var></dt><dd><p>Uninstall <var>formula</var>.</p>
|
||||||
|
|
||||||
<p>If <code>--force</code> is passed, and there are multiple versions of <var>formula</var>
|
<p>If <code>--force</code> is passed, and there are multiple versions of <var>formula</var>
|
||||||
installed, delete all installed versions.</p></dd>
|
installed, delete all installed versions.</p>
|
||||||
|
|
||||||
|
<p>If <code>--ignore-dependencies</code> is passed, uninstalling won't fail, even if
|
||||||
|
formulae depending on <var>formula</var> would still be installed.</p></dd>
|
||||||
<dt><code>unlink</code> [<code>--dry-run</code>] <var>formula</var></dt><dd><p>Remove symlinks for <var>formula</var> from the Homebrew prefix. This can be useful
|
<dt><code>unlink</code> [<code>--dry-run</code>] <var>formula</var></dt><dd><p>Remove symlinks for <var>formula</var> from the Homebrew prefix. This can be useful
|
||||||
for temporarily disabling a formula:
|
for temporarily disabling a formula:
|
||||||
<code>brew unlink foo && commands && brew link foo</code>.</p>
|
<code>brew unlink foo && commands && brew link foo</code>.</p>
|
||||||
|
@ -329,9 +329,12 @@ Migrate renamed packages to new name, where \fIformulae\fR are old names of pack
|
|||||||
If \fB\-\-force\fR is passed, then treat installed \fIformulae\fR and passed \fIformulae\fR like if they are from same taps and migrate them anyway\.
|
If \fB\-\-force\fR is passed, then treat installed \fIformulae\fR and passed \fIformulae\fR like if they are from same taps and migrate them anyway\.
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBmissing\fR [\fIformulae\fR]
|
\fBmissing\fR [\fB\-\-hide=\fR\fIhidden\fR] [\fIformulae\fR]
|
||||||
Check the given \fIformulae\fR for missing dependencies\. If no \fIformulae\fR are given, check all installed brews\.
|
Check the given \fIformulae\fR for missing dependencies\. If no \fIformulae\fR are given, check all installed brews\.
|
||||||
.
|
.
|
||||||
|
.IP
|
||||||
|
If \fB\-\-hide=\fR\fIhidden\fR is passed, act as if none of \fIhidden\fR are installed\. \fIhidden\fR should be a comma\-separated list of formulae\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBoptions\fR [\fB\-\-compact\fR] (\fB\-\-all\fR|\fB\-\-installed\fR|\fIformulae\fR)
|
\fBoptions\fR [\fB\-\-compact\fR] (\fB\-\-all\fR|\fB\-\-installed\fR|\fIformulae\fR)
|
||||||
Display install options specific to \fIformulae\fR\.
|
Display install options specific to \fIformulae\fR\.
|
||||||
@ -484,12 +487,15 @@ Pin \fItap\fR, prioritizing its formulae over core when formula names are suppli
|
|||||||
Unpin \fItap\fR so its formulae are no longer prioritized\. See also \fBtap\-pin\fR\.
|
Unpin \fItap\fR so its formulae are no longer prioritized\. See also \fBtap\-pin\fR\.
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBuninstall\fR, \fBrm\fR, \fBremove\fR [\fB\-\-force\fR] \fIformula\fR
|
\fBuninstall\fR, \fBrm\fR, \fBremove\fR [\fB\-\-force\fR] [\fB\-\-ignore\-dependencies\fR] \fIformula\fR
|
||||||
Uninstall \fIformula\fR\.
|
Uninstall \fIformula\fR\.
|
||||||
.
|
.
|
||||||
.IP
|
.IP
|
||||||
If \fB\-\-force\fR is passed, and there are multiple versions of \fIformula\fR installed, delete all installed versions\.
|
If \fB\-\-force\fR is passed, and there are multiple versions of \fIformula\fR installed, delete all installed versions\.
|
||||||
.
|
.
|
||||||
|
.IP
|
||||||
|
If \fB\-\-ignore\-dependencies\fR is passed, uninstalling won\'t fail, even if formulae depending on \fIformula\fR would still be installed\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBunlink\fR [\fB\-\-dry\-run\fR] \fIformula\fR
|
\fBunlink\fR [\fB\-\-dry\-run\fR] \fIformula\fR
|
||||||
Remove symlinks for \fIformula\fR from the Homebrew prefix\. This can be useful for temporarily disabling a formula: \fBbrew unlink foo && commands && brew link foo\fR\.
|
Remove symlinks for \fIformula\fR from the Homebrew prefix\. This can be useful for temporarily disabling a formula: \fBbrew unlink foo && commands && brew link foo\fR\.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user