Skip to content
This repository was archived by the owner on Apr 22, 2025. It is now read-only.

Commit 23f3b00

Browse files
authored
Merge pull request #1652 from Homebrew/remove-aliases-oldnames
remover: match against formula aliases and old names when called with `--formula`
2 parents 1125871 + 5593e1b commit 23f3b00

File tree

5 files changed

+96
-7
lines changed

5 files changed

+96
-7
lines changed

cmd/bundle.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class BundleCmd < AbstractCommand
5959
Add entries to your `Brewfile`. Adds formulae by default. Use `--cask`, `--tap`, `--whalebrew` or `--vscode` to add the corresponding entry instead.
6060
6161
`brew bundle remove` <name> [...]:
62-
Remove entries that match `name` from your `Brewfile`. Use `--formula`, `--cask`, `--tap`, `--mas`, `--whalebrew` or `--vscode` to remove only entries of the corresponding type.
62+
Remove entries that match `name` from your `Brewfile`. Use `--formula`, `--cask`, `--tap`, `--mas`, `--whalebrew` or `--vscode` to remove only entries of the corresponding type. Passing `--formula` also removes matches against formula aliases and old formula names.
6363
6464
`brew bundle exec` <command>:
6565
Run an external command in an isolated build environment based on the `Brewfile` dependencies.

lib/bundle/remover.rb

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,39 @@ module Remover
77

88
def remove(*args, type:, global:, file:)
99
brewfile = Brewfile.read(global:, file:)
10-
content = brewfile.input.split("\n")
10+
content = brewfile.input
1111
entry_type = type.to_s if type != :none
12-
escaped_args = args.map { |arg| Regexp.escape(arg) }
13-
content = content.grep_v(/#{entry_type}(\s+|\(\s*)"(#{escaped_args.join("|")})"/)
14-
.join("\n") << "\n"
12+
escaped_args = args.flat_map do |arg|
13+
names = if type == :brew
14+
possible_names(arg)
15+
else
16+
[arg]
17+
end
18+
19+
names.uniq.map { |a| Regexp.escape(a) }
20+
end
21+
22+
new_content = content.split("\n")
23+
.grep_v(/#{entry_type}(\s+|\(\s*)"(#{escaped_args.join("|")})"/)
24+
.join("\n") << "\n"
25+
26+
if content.chomp == new_content.chomp &&
27+
type == :none &&
28+
args.any? { |arg| possible_names(arg, raise_error: false).count > 1 }
29+
opoo "No matching entries found in Brewfile. Try again with `--formula` to match formula " \
30+
"aliases and old formula names."
31+
return
32+
end
33+
1534
path = Dumper.brewfile_path(global:, file:)
35+
Dumper.write_file path, new_content
36+
end
1637

17-
Dumper.write_file path, content
38+
def possible_names(formula_name, raise_error: true)
39+
formula = Formulary.factory(formula_name)
40+
[formula_name, formula.name, formula.full_name, *formula.aliases, *formula.oldnames].compact.uniq
41+
rescue FormulaUnavailableError
42+
raise if raise_error
1843
end
1944
end
2045
end

lib/bundle/remover.rbi

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# typed: true
2+
3+
module Bundle
4+
module Remover
5+
include Kernel
6+
end
7+
end

spec/bundle/commands/remove_command_spec.rb

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
described_class.run(*args, type:, global:, file:)
88
end
99

10-
before { File.write(file, "brew \"hello\"\n") }
10+
before { File.write(file, content) }
1111
after { FileUtils.rm_f file }
1212

1313
let(:global) { false }
@@ -16,10 +16,54 @@
1616
let(:args) { ["hello"] }
1717
let(:type) { :brew }
1818
let(:file) { "/tmp/some_random_brewfile#{Random.rand(2 ** 16)}" }
19+
let(:content) do
20+
<<~BREWFILE
21+
brew "hello"
22+
BREWFILE
23+
end
1924

2025
it "removes entries from the given Brewfile" do
2126
expect { remove }.not_to raise_error
2227
expect(File.read(file)).not_to include("#{type} \"#{args.first}\"")
2328
end
2429
end
30+
31+
context "when called with no type" do
32+
let(:args) { ["foo"] }
33+
let(:type) { :none }
34+
let(:file) { "/tmp/some_random_brewfile#{Random.rand(2 ** 16)}" }
35+
let(:content) do
36+
<<~BREWFILE
37+
tap "someone/tap"
38+
brew "foo"
39+
cask "foo"
40+
BREWFILE
41+
end
42+
43+
it "removes all matching entries from the given Brewfile" do
44+
expect { remove }.not_to raise_error
45+
expect(File.read(file)).not_to include(args.first)
46+
end
47+
48+
context "with arguments that match entries only when considering formula aliases" do
49+
let(:foo) do
50+
instance_double(
51+
Formula,
52+
name: "foo",
53+
full_name: "qux/quuz/foo",
54+
oldnames: ["oldfoo"],
55+
aliases: ["foobar"],
56+
)
57+
end
58+
let(:args) { ["foobar"] }
59+
60+
it "suggests using `--formula` to match against formula aliases" do
61+
expect(Formulary).to receive(:factory).with("foobar").and_return(foo)
62+
expect { remove }.not_to raise_error
63+
expect(File.read(file)).to eq(content)
64+
# FIXME: Why doesn't this work?
65+
# expect { remove }.to output("--formula").to_stderr
66+
end
67+
end
68+
end
2569
end

spec/bundle/remover_spec.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# frozen_string_literal: true
2+
3+
describe Bundle::Remover do
4+
subject(:remover) { described_class }
5+
6+
let(:name) { "foo" }
7+
8+
before { allow(Formulary).to receive(:factory).with(name).and_raise(FormulaUnavailableError) }
9+
10+
it "raises no errors when requested" do
11+
expect { remover.possible_names(name, raise_error: false) }.not_to raise_error
12+
end
13+
end

0 commit comments

Comments
 (0)