Skip to content
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

disable subcommands / flags, to the tune of hide in derive mode #5251

Open
2 tasks done
abesto opened this issue Dec 7, 2023 · 2 comments
Open
2 tasks done

disable subcommands / flags, to the tune of hide in derive mode #5251

abesto opened this issue Dec 7, 2023 · 2 comments
Labels
C-enhancement Category: Raise on the bar on expectations

Comments

@abesto
Copy link

abesto commented Dec 7, 2023

Please complete the following tasks

Clap Version

4.4.7

Describe your use case

Imagine a CLI shipped to multiple environments (i.e. both development servers and laptops). Some features (i.e. subcommands) only make sense in one or the other environment. I'd like to disable (instead of hide) the irrelevant subcommands. The condition is not (cannot be) const.

Describe the solution you'd like

Instead of

#[derive(Subcommand)]
enum Command {
    ...
    #[clap(hide = is_laptop())]
    SomeSubcommand { ... }
}

I'd love to write

#[derive(Subcommand)]
enum Command {
    ...
    #[clap(disable = is_laptop())]
    SomeSubcommand { ... }
}

Alternatives, if applicable

  • Conditional compilation is not an option because the condition is not const. Even if it was, it'd mean we'd need conditional compilation around both the definition of the enum item, and also every place the enum value is used, which is not great ergonomically.
  • We could maybe split out the conditional parts into a separate struct, maybe use Builder mode, and flatten that into the main subcommands enum? Again, not great ergonomics.

Additional Context

No response

@abesto abesto added the C-enhancement Category: Raise on the bar on expectations label Dec 7, 2023
@epage
Copy link
Member

epage commented Dec 7, 2023

A workaround for this is to conditionally

  • Hide the subcommand
  • Error if the subcommand gets activated

Since its possible to do, is there a reason we need to build this in directly to clap?

We have to weigh

  • Features
  • API overload (API too large to find the feature you need, creating diminishing returns for each feature we add)
  • Build time
  • Binary size

This feels like a less common case such that a native solution might not be justified when balancing out these competing demands.

That said, I think the way I would do this is to instead focus on a CommandAction system like our ArgAction which we've wanted to generalize with user actions. There is less built-in functionality to Commands so it has been a lower priority. With user-provided actions, you could create and action that conditionally errors. I think this would also be true if we made the validation plugin system we've talked about.

@abesto
Copy link
Author

abesto commented Dec 7, 2023

This feels like a less common case such that a native solution might not be justified when balancing out these competing demands.

Yep, I buy that.

With user-provided actions, you could create and action that conditionally errors.

Yeah, that'd lead to neater code than raising failures where the subcommand happens to be handled.

I guess it's possible (now, explicitly; or later, in a custom action / validator) to raise a "no such command" error, such that this case would be mostly indistinguishable from a situation where the subcommand actually didn't exist?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-enhancement Category: Raise on the bar on expectations
Projects
None yet
Development

No branches or pull requests

2 participants