Skip to content

Support subcommands in Homebrew::CLI::Parser #19639

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

Open
1 task done
MikeMcQuaid opened this issue Mar 28, 2025 · 9 comments
Open
1 task done

Support subcommands in Homebrew::CLI::Parser #19639

MikeMcQuaid opened this issue Mar 28, 2025 · 9 comments
Labels
help wanted We want help addressing this

Comments

@MikeMcQuaid
Copy link
Member

Verification

Provide a detailed description of the proposed feature

We have brew bundle and brew services commands that both provide "subcommands" i.e. brew bundle install, brew bundle exec, etc.

These both have some fairly messy and repetitive argument handling, don't do decent generation of e.g. manpages/completions/etc. and don't handle switches well e.g. those that only apply to one subcommand and not others.

#19638 is an example of a slightly messy workaround for brew services that doesn't get e.g. brew services info <tab> to work nicely.

What is the motivation for the feature?

  • Improved user experience using subcommands
  • Improved APIs for developers creating subcommands

How will the feature be relevant to at least 90% of Homebrew users?

Improved user experience using subcommands

What alternatives to the feature have been considered?

Migrating all subcommands to e.g. brew bundle-exec instead of brew bundle exec. This would require some workflow changes for users but would result in less code being needed.

@MikeMcQuaid MikeMcQuaid added the help wanted We want help addressing this label Mar 28, 2025
@botantony
Copy link
Contributor

My question is how do we specify flags, switches, named args, etc. for these subcommands? Do we just assume each of the options works with all subcommands? In this case, the implementation is fairly trivial but does not reflect the actual usage (autocomplete would suggest dummy parameters to the user). Or do we allow specifying which subcommands accept the flag/option? I think it is not good either (almost all flags in brew bundle work only with a few subcommands).

IMHO, the best solution would be to split the bundle and services commands into separate small commands and create default aliases for all users (f.e. bundle install aliased to bundle-install). This way, it is possible to list only useful flags for a subcommand and keep backward compatibility.

@MikeMcQuaid
Copy link
Member Author

My question is how do we specify flags, switches, named args, etc. for these subcommands?

Using cmd_args (or similar) like other commands currently do.

Do we just assume each of the options works with all subcommands?

No, that's what we have today and would be god to avoid.

IMHO, the best solution would be to split the bundle and services commands into separate small commands and create default aliases for all users

That's an option if we don't want to have the minimal code changes for this, sure.

We'd likely also want/need to adjust the manpage generation to ensure those commands remain grouped nicely as they are today.

@NeimadTL
Copy link
Contributor

NeimadTL commented Apr 2, 2025

Hey @MikeMcQuaid, @botantony , I'd to tackle this one. What would be the first step in your opinion please?

@MikeMcQuaid
Copy link
Member Author

@NeimadTL You're welcome to give it a go but I'm afraid I think:

  • if the above isn't enough to get started, I don't think you'll be able to complete this work
  • this is likely too hard a lift for anyone who isn't a Homebrew maintainer

@NeimadTL
Copy link
Contributor

NeimadTL commented Apr 2, 2025

Understood. I'll try to at least understand and if I can't move forward, I'll get into another one (any suggestion another issue you may have will be appreciated). Thank you @MikeMcQuaid.

@raghavtan
Copy link

If it is alright i would like to take this @MikeMcQuaid / @botantony

For implementation i have the following though going forward

  • Create a SubcommandFramework module that provides a consistent way to handle subcommands in Homebrew.

    • handle argument parsing, documentation, shell completion, and routing for subcommands
    • generate proper shell completions for bash, zsh, and fish
  • Corresponding command classes to use the new framework:

    • Cmd::Bundle now routes to SubcommandBundle
    • Cmd::Services now routes to SubcommandServices
  • Update the CompletionsGenerator to detect and use completions from the new subcommand framework

@MikeMcQuaid
Copy link
Member Author

Given the demand here: we're not going to "assign" it to anyone in particular but we'll happily review a PR from anyone.

  • Create a SubcommandFramework module that provides a consistent way to handle subcommands in Homebrew.

I don't think we need a dedicated module for Subcommands unless this otherwise excessively bloats the other modules that need changed.

Otherwise: makes sense so far.

@Bo98
Copy link
Member

Bo98 commented Apr 3, 2025

Simplest model is probably something like:

  • cmd/bundle.rb - specifies cmd_args with the top-level description and a new DSL subcommand or something to specify the list of subcommands, and potentially flags/switches that are applicable on a global level (if any - there might be none here). Probably want a default: true or something for the subcommand to run if none are specified. run method can probably remain abstract.
  • cmd/bundle/*.rb - for each subcommand. Should use the CLI::Parser in the same way as any other command does.

@MikeMcQuaid
Copy link
Member Author

Yeh, this makes sense to me @Bo98 👍🏻

The hard bit here won't be splitting out the commands as much as:

  • providing a DSL for each subcommand to be able to specify different switches/flags/etc.
  • generating the manpage and completions correctly for these subcommands so that the manpage looks similar to today and the completions allow e.g. auto-completing on formula names

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted We want help addressing this
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants