Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions Library/Homebrew/abstract_subcommand.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@ def define(parser)
parser_block = @parser_block
raise TypeError, "subcommand arguments have not been defined" if parser_block.nil?

parser.subcommand(subcommand_name, aliases: @aliases || [], default: @default || false) do
parser.subcommand(
subcommand_name,
aliases: @aliases || [],
alias_options: @alias_options || {},
default: @default || false,
) do
instance_eval(&parser_block)
end
end
Expand All @@ -58,9 +63,17 @@ def define(parser)
# The description and arguments of the subcommand should be defined within this block.
#
# @api public
sig { params(aliases: T::Array[String], default: T::Boolean, block: T.proc.bind(CLI::Parser).void).void }
def subcommand_args(aliases: [], default: false, &block)
sig {
params(
aliases: T::Array[String],
alias_options: T::Hash[String, String],
default: T::Boolean,
block: T.proc.bind(CLI::Parser).void,
).void
}
def subcommand_args(aliases: [], alias_options: {}, default: false, &block)
@aliases = T.let(aliases, T.nilable(T::Array[String]))
@alias_options = T.let(alias_options, T.nilable(T::Hash[String, String]))
@default = T.let(default, T.nilable(T::Boolean))
@parser_block = T.let(block, T.nilable(T.proc.void))
end
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/bundle/subcommand.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def context(args, extensions:)
else
jobs_arg&.to_i || 1
end
no_upgrade = if args.upgrade? || subcommand == "upgrade"
no_upgrade = if args.upgrade?
false
else
args.no_upgrade?.present?
Expand Down
6 changes: 4 additions & 2 deletions Library/Homebrew/bundle/subcommand/install.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ module Homebrew
module Cmd
class Bundle < Homebrew::AbstractCommand
class InstallSubcommand < Homebrew::AbstractSubcommand
subcommand_args default: true do
subcommand_args alias_options: { "upgrade" => "--upgrade" }, default: true do
usage_banner <<~EOS
`brew bundle` [`install`]:
`brew bundle` [`install`|`upgrade`]:
Install and upgrade (by default) all dependencies from the `Brewfile`.

Use this to restore a recorded installed state from a `Brewfile`.

`brew bundle upgrade` is shorthand for `brew bundle install --upgrade`.

You can specify the `Brewfile` location using `--file` or by setting the `$HOMEBREW_BUNDLE_FILE` environment variable.

You can skip the installation of dependencies by adding space-separated values to one or more of the following environment variables: `$HOMEBREW_BUNDLE_BREW_SKIP`, `$HOMEBREW_BUNDLE_CASK_SKIP`, `$HOMEBREW_BUNDLE_MAS_SKIP`, `$HOMEBREW_BUNDLE_TAP_SKIP`.
Expand Down
35 changes: 0 additions & 35 deletions Library/Homebrew/bundle/subcommand/upgrade.rb

This file was deleted.

23 changes: 16 additions & 7 deletions Library/Homebrew/cli/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Parser
class Subcommand < T::Struct
const :name, String
const :aliases, T::Array[String], default: []
const :alias_options, T::Hash[String, String], default: {}
prop :description, T.nilable(String), default: nil
prop :usage_banner, T.nilable(String), default: nil
const :default, T::Boolean, default: false
Expand Down Expand Up @@ -490,6 +491,12 @@ def parse(argv = ARGV.freeze, ignore_invalid_options: false)
end

unless ignore_invalid_options
if @subcommands.present? && named_args.present?
subcommand_arg = named_args.fetch(0)
if (subcommand = subcommand_for_name(subcommand_arg)) && subcommand.alias_options.key?(subcommand_arg)
set_switch(subcommand.alias_options.fetch(subcommand_arg), value: true, from: :args)
end
end
unless @is_dev_cmd
set_default_options
validate_options
Expand Down Expand Up @@ -652,19 +659,21 @@ def hide_from_man_page!

sig {
params(
name: String,
aliases: T::Array[String],
description: T.nilable(String),
default: T::Boolean,
block: T.nilable(T.proc.bind(Parser).void),
name: String,
aliases: T::Array[String],
alias_options: T::Hash[String, String],
description: T.nilable(String),
default: T::Boolean,
block: T.nilable(T.proc.bind(Parser).void),
).void
}
def subcommand(name, aliases: [], description: nil, default: false, &block)
def subcommand(name, aliases: [], alias_options: {}, description: nil, default: false, &block)
previous_subcommands = @current_subcommands

@subcommands << Subcommand.new(
name:,
aliases:,
aliases: aliases | alias_options.keys,
alias_options:,
description:,
default:,
)
Expand Down
17 changes: 17 additions & 0 deletions Library/Homebrew/test/cli/parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,23 @@ def subcommand_parser
expect(args.global?).to be(true)
end

it "applies implied options from subcommand aliases", :aggregate_failures do
parser = described_class.new(Cmd) do
subcommand "install", alias_options: { "upgrade" => "--upgrade" } do
switch "--upgrade"
switch "--force"
named_args :none
end
end

args = parser.parse(%w[upgrade --force])

expect(parser.subcommands.first.aliases).to eq(["upgrade"])
expect(args.subcommand).to eq("install")
expect(args.upgrade?).to be(true)
expect(args.force?).to be(true)
end

it "returns options for a specific subcommand" do
parser = subcommand_parser

Expand Down
15 changes: 15 additions & 0 deletions Library/Homebrew/test/cmd/bundle_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@
.to raise_error(UsageError, /`exec` subcommand does not accept the `--jobs` flag/)
end

it "treats upgrade as install --upgrade", :aggregate_failures do
with_env("HOMEBREW_BUNDLE_NO_UPGRADE" => "1") do
args = described_class.new(%w[upgrade -fq]).args
context = described_class.context(args, extensions: described_class::BUNDLE_EXTENSIONS)

expect(args.subcommand).to eq("install")
expect(args.upgrade?).to be(true)
expect(args.force?).to be(true)
expect(args.quiet?).to be(true)
expect(context.subcommand).to eq("install")
expect(context.no_upgrade).to be(false)
end
end

it "uses subcommand-specific option descriptions", :aggregate_failures do
subcommand_options = ->(subcommand) { Commands.command_options("bundle", subcommand:).to_h }

Expand All @@ -32,6 +46,7 @@
.to eq("Add entries for VSCode (and forks/variants) extensions.")
expect(subcommand_options.call("remove")["--vscode"])
.to eq("Remove entries for VSCode (and forks/variants) extensions.")
expect(subcommand_options.call("upgrade")["--force"]).to eq("Run with `--force`/`--overwrite`.")
end

it "uses subcommand-specific descriptions in help output", :aggregate_failures do
Expand Down
19 changes: 2 additions & 17 deletions completions/bash/brew
Original file line number Diff line number Diff line change
Expand Up @@ -729,11 +729,10 @@ _brew_bundle() {
for (( i = 2; i < COMP_CWORD; i++ ))
do
case "${COMP_WORDS[i]}" in
upgrade) subcommand="upgrade"; break ;;
sh) subcommand="sh"; break ;;
remove) subcommand="remove"; break ;;
list) subcommand="list"; break ;;
install) subcommand="install"; break ;;
install|upgrade) subcommand="install"; break ;;
exec) subcommand="exec"; break ;;
env) subcommand="env"; break ;;
edit) subcommand="edit"; break ;;
Expand All @@ -758,20 +757,6 @@ _brew_bundle() {
"
return
;;
upgrade)
__brewcomp "
--debug
--file
--global
--help
--jobs
--quiet
--upgrade
--upgrade-formulae
--verbose
"
return
;;
sh)
__brewcomp "
--check
Expand Down Expand Up @@ -992,7 +977,7 @@ add)
esac
case "${subcommand}" in
"")
__brewcomp "upgrade sh remove list install exec env edit dump cleanup check add"
__brewcomp "sh remove list install upgrade exec env edit dump cleanup check add"
;;
exec)
__brew_complete_commands
Expand Down
37 changes: 14 additions & 23 deletions completions/fish/brew.fish
Original file line number Diff line number Diff line change
Expand Up @@ -521,11 +521,11 @@ __fish_brew_complete_arg 'bump-unversioned-casks' -a '(__fish_brew_suggest_taps_


__fish_brew_complete_cmd 'bundle' 'Bundler for non-Ruby dependencies from Homebrew, Homebrew Cask, Mac App Store dependencies, VSCode (and forks/variants) extensions, Go packages, Cargo packages, uv tools, Flatpak packages, Krew plugins and npm packages'
__fish_brew_complete_sub_cmd 'bundle' 'upgrade' 'Shorthand for `brew bundle install --upgrade`'
__fish_brew_complete_sub_cmd 'bundle' 'sh' 'Run your shell in a `brew bundle exec` environment'
__fish_brew_complete_sub_cmd 'bundle' 'remove' 'Remove entries that match `name` from your `Brewfile`. Use `--formula`, `--cask`, `--tap`, `--mas`, `--vscode`, `--go`, `--cargo`, `--uv`, `--flatpak`, `--krew` and `--npm` to remove only entries of the corresponding type. Passing `--formula` also removes matches against formula aliases and old formula names'
__fish_brew_complete_sub_cmd 'bundle' 'list' 'By default, only Homebrew formula dependencies are listed'
__fish_brew_complete_sub_cmd 'bundle' 'install' 'Use this to restore a recorded installed state from a `Brewfile`'
__fish_brew_complete_sub_cmd 'bundle' 'upgrade' 'Use this to restore a recorded installed state from a `Brewfile`'
__fish_brew_complete_sub_cmd 'bundle' 'exec' 'This sanitized build environment ignores unrequested dependencies, which makes sure that things you didn\'t specify in your `Brewfile` won\'t get picked up by commands like `bundle install`, `npm install`, etc. It will also add compiler flags which will help with finding keg-only dependencies like `openssl`, `icu4c`, etc'
__fish_brew_complete_sub_cmd 'bundle' 'env' 'Print the environment variables that would be set in a `brew bundle exec` environment'
__fish_brew_complete_sub_cmd 'bundle' 'edit' 'Edit the `Brewfile` in your editor'
Expand All @@ -539,15 +539,6 @@ __fish_brew_complete_arg 'bundle; and [ (count (__fish_brew_args)) = 1 ]' -l glo
__fish_brew_complete_arg 'bundle; and [ (count (__fish_brew_args)) = 1 ]' -l help -d 'Show this message'
__fish_brew_complete_arg 'bundle; and [ (count (__fish_brew_args)) = 1 ]' -l quiet -d 'Make some output more quiet'
__fish_brew_complete_arg 'bundle; and [ (count (__fish_brew_args)) = 1 ]' -l verbose -d 'Make some output more verbose'
__fish_brew_complete_sub_arg 'bundle' 'upgrade' -l debug -d 'Display any debugging information'
__fish_brew_complete_sub_arg 'bundle' 'upgrade' -l file -d 'Read from or write to the `Brewfile` from this location. Use `--file=-` to pipe to stdin/stdout'
__fish_brew_complete_sub_arg 'bundle' 'upgrade' -l global -d 'Read from or write to the `Brewfile` from `$HOMEBREW_BUNDLE_FILE_GLOBAL` (if set), `${XDG_CONFIG_HOME}/homebrew/Brewfile` (if `$XDG_CONFIG_HOME` is set), `~/.homebrew/Brewfile` or `~/.Brewfile` otherwise'
__fish_brew_complete_sub_arg 'bundle' 'upgrade' -l help -d 'Show this message'
__fish_brew_complete_sub_arg 'bundle' 'upgrade' -l jobs -d 'Run up to this many formula installations in parallel. Defaults to 1 (sequential). Use `auto` for the number of CPU cores (max 4)'
__fish_brew_complete_sub_arg 'bundle' 'upgrade' -l quiet -d 'Make some output more quiet'
__fish_brew_complete_sub_arg 'bundle' 'upgrade' -l upgrade -d 'Run `brew upgrade` on outdated dependencies, even if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set'
__fish_brew_complete_sub_arg 'bundle' 'upgrade' -l upgrade-formulae -d 'Run `brew upgrade` on any of these comma-separated formulae, even if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set'
__fish_brew_complete_sub_arg 'bundle' 'upgrade' -l verbose -d 'Make some output more verbose'
__fish_brew_complete_sub_arg 'bundle' 'sh' -l check -d 'Check that all dependencies in the Brewfile are installed before starting the shell. Enabled by default if `$HOMEBREW_BUNDLE_CHECK` is set'
__fish_brew_complete_sub_arg 'bundle' 'sh' -l debug -d 'Display any debugging information'
__fish_brew_complete_sub_arg 'bundle' 'sh' -l file -d 'Read from or write to the `Brewfile` from this location. Use `--file=-` to pipe to stdin/stdout'
Expand Down Expand Up @@ -595,19 +586,19 @@ __fish_brew_complete_sub_arg 'bundle' 'list' -l tap -d 'List Homebrew tap depend
__fish_brew_complete_sub_arg 'bundle' 'list' -l uv -d 'List uv tools'
__fish_brew_complete_sub_arg 'bundle' 'list' -l verbose -d 'Make some output more verbose'
__fish_brew_complete_sub_arg 'bundle' 'list' -l vscode -d 'List VSCode (and forks/variants) extensions'
__fish_brew_complete_sub_arg 'bundle' 'install' -l cleanup -d 'Perform cleanup after installing dependencies, same as running `cleanup --force`. Enabled by default if `$HOMEBREW_BUNDLE_INSTALL_CLEANUP` is set and `--global` is passed'
__fish_brew_complete_sub_arg 'bundle' 'install' -l debug -d 'Display any debugging information'
__fish_brew_complete_sub_arg 'bundle' 'install' -l file -d 'Read from or write to the `Brewfile` from this location. Use `--file=-` to pipe to stdin/stdout'
__fish_brew_complete_sub_arg 'bundle' 'install' -l force -d 'Run with `--force`/`--overwrite`'
__fish_brew_complete_sub_arg 'bundle' 'install' -l global -d 'Read from or write to the `Brewfile` from `$HOMEBREW_BUNDLE_FILE_GLOBAL` (if set), `${XDG_CONFIG_HOME}/homebrew/Brewfile` (if `$XDG_CONFIG_HOME` is set), `~/.homebrew/Brewfile` or `~/.Brewfile` otherwise'
__fish_brew_complete_sub_arg 'bundle' 'install' -l help -d 'Show this message'
__fish_brew_complete_sub_arg 'bundle' 'install' -l jobs -d 'Run up to this many formula installations in parallel. Defaults to 1 (sequential). Use `auto` for the number of CPU cores (max 4)'
__fish_brew_complete_sub_arg 'bundle' 'install' -l no-upgrade -d 'Do not run `brew upgrade` on outdated dependencies. Note they may still be upgraded by `brew install` if needed. Enabled by default if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set'
__fish_brew_complete_sub_arg 'bundle' 'install' -l quiet -d 'Make some output more quiet'
__fish_brew_complete_sub_arg 'bundle' 'install' -l upgrade -d 'Run `brew upgrade` on outdated dependencies, even if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set'
__fish_brew_complete_sub_arg 'bundle' 'install' -l upgrade-formulae -d 'Run `brew upgrade` on any of these comma-separated formulae, even if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set'
__fish_brew_complete_sub_arg 'bundle' 'install' -l verbose -d 'Print output from commands as they are run'
__fish_brew_complete_sub_arg 'bundle' 'install' -l zap -d 'Use `zap` instead of `uninstall` when cleaning up casks after installing dependencies'
__fish_brew_complete_sub_arg 'bundle' 'install upgrade' -l cleanup -d 'Perform cleanup after installing dependencies, same as running `cleanup --force`. Enabled by default if `$HOMEBREW_BUNDLE_INSTALL_CLEANUP` is set and `--global` is passed'
__fish_brew_complete_sub_arg 'bundle' 'install upgrade' -l debug -d 'Display any debugging information'
__fish_brew_complete_sub_arg 'bundle' 'install upgrade' -l file -d 'Read from or write to the `Brewfile` from this location. Use `--file=-` to pipe to stdin/stdout'
__fish_brew_complete_sub_arg 'bundle' 'install upgrade' -l force -d 'Run with `--force`/`--overwrite`'
__fish_brew_complete_sub_arg 'bundle' 'install upgrade' -l global -d 'Read from or write to the `Brewfile` from `$HOMEBREW_BUNDLE_FILE_GLOBAL` (if set), `${XDG_CONFIG_HOME}/homebrew/Brewfile` (if `$XDG_CONFIG_HOME` is set), `~/.homebrew/Brewfile` or `~/.Brewfile` otherwise'
__fish_brew_complete_sub_arg 'bundle' 'install upgrade' -l help -d 'Show this message'
__fish_brew_complete_sub_arg 'bundle' 'install upgrade' -l jobs -d 'Run up to this many formula installations in parallel. Defaults to 1 (sequential). Use `auto` for the number of CPU cores (max 4)'
__fish_brew_complete_sub_arg 'bundle' 'install upgrade' -l no-upgrade -d 'Do not run `brew upgrade` on outdated dependencies. Note they may still be upgraded by `brew install` if needed. Enabled by default if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set'
__fish_brew_complete_sub_arg 'bundle' 'install upgrade' -l quiet -d 'Make some output more quiet'
__fish_brew_complete_sub_arg 'bundle' 'install upgrade' -l upgrade -d 'Run `brew upgrade` on outdated dependencies, even if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set'
__fish_brew_complete_sub_arg 'bundle' 'install upgrade' -l upgrade-formulae -d 'Run `brew upgrade` on any of these comma-separated formulae, even if `$HOMEBREW_BUNDLE_NO_UPGRADE` is set'
__fish_brew_complete_sub_arg 'bundle' 'install upgrade' -l verbose -d 'Print output from commands as they are run'
__fish_brew_complete_sub_arg 'bundle' 'install upgrade' -l zap -d 'Use `zap` instead of `uninstall` when cleaning up casks after installing dependencies'
__fish_brew_complete_sub_arg 'bundle' 'exec' -l check -d 'Check that all dependencies in the Brewfile are installed before executing the command. Enabled by default if `$HOMEBREW_BUNDLE_CHECK` is set'
__fish_brew_complete_sub_arg 'bundle' 'exec' -l debug -d 'Display any debugging information'
__fish_brew_complete_sub_arg 'bundle' 'exec' -l file -d 'Read from or write to the `Brewfile` from this location. Use `--file=-` to pipe to stdin/stdout'
Expand Down
Loading
Loading