Skip to content

Commit f38cd4b

Browse files
committed
Convert bundle subcommands
- `brew bundle` needs each action to own its options and usage. - Keep shared Brewfile, type and install context in one place. - Move existing behaviour into command-shaped subcommand classes.
1 parent eb6acfe commit f38cd4b

42 files changed

Lines changed: 2333 additions & 1030 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Library/Homebrew/bundle/commands/add.rb

Lines changed: 0 additions & 20 deletions
This file was deleted.

Library/Homebrew/bundle/commands/check.rb

Lines changed: 0 additions & 53 deletions
This file was deleted.

Library/Homebrew/bundle/commands/dump.rb

Lines changed: 0 additions & 23 deletions
This file was deleted.

Library/Homebrew/bundle/commands/install.rb

Lines changed: 0 additions & 46 deletions
This file was deleted.

Library/Homebrew/bundle/commands/list.rb

Lines changed: 0 additions & 24 deletions
This file was deleted.

Library/Homebrew/bundle/commands/remove.rb

Lines changed: 0 additions & 17 deletions
This file was deleted.
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# typed: strict
2+
# frozen_string_literal: true
3+
4+
require "abstract_subcommand"
5+
require "bundle/extensions/extension"
6+
require "cli/parser"
7+
require "etc"
8+
require "bundle/subcommand_context"
9+
require "utils/output"
10+
11+
Dir["#{__dir__}/subcommand/*.rb"].each do |subcommand|
12+
require "bundle/subcommand/#{File.basename(subcommand, ".rb")}"
13+
end
14+
15+
module Homebrew
16+
module Cmd
17+
class Bundle < Homebrew::AbstractCommand
18+
extend Utils::Output::Mixin
19+
20+
class << self
21+
sig {
22+
params(
23+
args: T.untyped,
24+
extensions: T::Array[T.class_of(Homebrew::Bundle::Extension)],
25+
).void
26+
}
27+
def dispatch(args, extensions:)
28+
# Don't want to ask for input in Bundle
29+
ENV["HOMEBREW_ASK"] = nil
30+
31+
if !args.describe? && (dump_describe = ENV["HOMEBREW_BUNDLE_DUMP_DESCRIBE"].presence)
32+
opoo "`HOMEBREW_BUNDLE_DUMP_DESCRIBE` is deprecated. Use `HOMEBREW_BUNDLE_DESCRIBE` instead."
33+
# odeprecated "HOMEBREW_BUNDLE_DUMP_DESCRIBE", "HOMEBREW_BUNDLE_DESCRIBE"
34+
ENV["HOMEBREW_BUNDLE_DESCRIBE"] = dump_describe
35+
end
36+
37+
context = context(args, extensions:)
38+
Homebrew::Bundle.upgrade_formulae = args.upgrade_formulae
39+
40+
if args.install?
41+
redirect_stdout($stderr) do
42+
InstallSubcommand.new(args, context:, quiet: true, cleanup: false).run
43+
end
44+
end
45+
46+
subcommand_class = Homebrew::AbstractSubcommand.subcommands_for(Homebrew::Cmd::Bundle).find do |candidate|
47+
candidate.subcommand_name == context.subcommand
48+
end
49+
raise UsageError, "Unknown subcommand: #{context.subcommand}" unless subcommand_class
50+
51+
subcommand_class.new(args, context:).run
52+
end
53+
54+
sig {
55+
params(
56+
args: T.untyped,
57+
extensions: T::Array[T.class_of(Homebrew::Bundle::Extension)],
58+
).returns(SubcommandContext)
59+
}
60+
def context(args, extensions:)
61+
subcommand = T.let(args.subcommand || "install", String)
62+
jobs_arg = args.jobs || ENV.fetch("HOMEBREW_BUNDLE_JOBS", nil)
63+
jobs = if jobs_arg == "auto"
64+
[Etc.nprocessors, 4].min
65+
else
66+
jobs_arg&.to_i || 1
67+
end
68+
no_upgrade = if args.upgrade? || subcommand == "upgrade"
69+
false
70+
else
71+
args.no_upgrade?.present?
72+
end
73+
74+
SubcommandContext.new(
75+
subcommand:,
76+
global: args.global?,
77+
file: args.file,
78+
no_upgrade:,
79+
verbose: args.verbose?,
80+
force: args.force?,
81+
jobs: [jobs, 1].max,
82+
zap: args.zap?,
83+
no_type_args: no_type_args?(args, extensions:),
84+
extensions:,
85+
)
86+
end
87+
88+
sig {
89+
params(
90+
args: T.untyped,
91+
extensions: T::Array[T.class_of(Homebrew::Bundle::Extension)],
92+
).returns(T::Boolean)
93+
}
94+
def no_type_args?(args, extensions:)
95+
([args.formulae?, args.casks?, args.taps?] +
96+
extensions.map { |extension| args.public_send(extension.predicate_method) }).none?
97+
end
98+
end
99+
end
100+
end
101+
end
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# typed: strict
2+
# frozen_string_literal: true
3+
4+
require "abstract_subcommand"
5+
require "bundle/extensions/extension"
6+
7+
require "bundle/adder"
8+
module Homebrew
9+
module Cmd
10+
class Bundle < Homebrew::AbstractCommand
11+
class AddSubcommand < Homebrew::AbstractSubcommand
12+
subcommand_args do
13+
extensions = Homebrew::Bundle.extensions
14+
usage_banner <<~EOS
15+
`brew bundle add` <name> [...]:
16+
Add entries to your `Brewfile`. Adds formulae by default. Use #{["`--cask`", "`--tap`", *extensions.select(&:add_supported?).map { |extension| "`--#{extension.flag}`" }].to_sentence} to add the corresponding entry instead.
17+
EOS
18+
named_args min: 1
19+
switch "--install",
20+
description: "Run `install` before continuing to other operations, e.g. `exec`."
21+
switch "--formula", "--formulae", "--brews",
22+
description: "Add Homebrew formula entries."
23+
switch "--cask", "--casks",
24+
description: "Add Homebrew cask entries."
25+
switch "--tap", "--taps",
26+
description: "Add Homebrew tap entries."
27+
extensions.select(&:add_supported?).each do |extension|
28+
switch "--#{extension.flag}",
29+
description: extension.switch_description
30+
end
31+
switch "--describe",
32+
description: "`dump` and `add` add a description comment above each line, unless the " \
33+
"dependency does not have a description.",
34+
env: :bundle_describe
35+
end
36+
37+
sig { override.void }
38+
def run
39+
selected_types = context.selected_types(args)
40+
raise UsageError, "`add` supports only one type of entry at a time." if selected_types.count != 1
41+
42+
type = case (t = selected_types.first)
43+
when :none then :brew
44+
when :mas then raise UsageError, "`add` does not support `--mas`."
45+
else t
46+
end
47+
48+
extension = Homebrew::Bundle.extension(type)
49+
if extension && !extension.add_supported?
50+
raise UsageError,
51+
"`add` does not support `--#{extension.flag}`."
52+
end
53+
54+
Homebrew::Bundle::Adder.add(
55+
*args.named,
56+
type:,
57+
global: context.global,
58+
file: context.file,
59+
describe: args.describe?,
60+
)
61+
end
62+
end
63+
end
64+
end
65+
end

0 commit comments

Comments
 (0)