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

Support multiple arguments writing to the same destination #3146

Open
2 tasks done
epage opened this issue Dec 10, 2021 · 5 comments
Open
2 tasks done

Support multiple arguments writing to the same destination #3146

epage opened this issue Dec 10, 2021 · 5 comments
Labels
A-builder Area: Builder API A-parsing Area: Parser's logic and needs it changed somehow. A-validators Area: ArgMatches validation logi C-enhancement Category: Raise on the bar on expectations S-experimental Status: Ongoing experiment that does not require reviewing and won't be merged in its current state.

Comments

@epage
Copy link
Member

epage commented Dec 10, 2021

Please complete the following tasks

  • I have searched the discussions
  • I have searched the existing issues

Clap Version

3.0.0-rc.0

Describe your use case

Related issues

Describe the solution you'd like

In Python's argparse, you can assign the dest (for us, name) for an argument in the Namespace (for us, ArgMatches). This gives a lot of power. One example is #1820 with migrating flags. The thing I used this most frequently for was negations (#815).

The code would look something like

parser.add_argument("--flag", dest="flag", action="store_true")
parser.add_argument("--no-flag", dest="flag", action="store_false")
... some line about setting the default

This makes it easy to define and handle and gives good semantics (last writer wins)

For now, I'm doing stuff like

fn resolve_bool_arg(yes: bool, no: bool) -> Option<bool> {
    match (yes, no) {
        (true, false) => Some(true),
        (false, true) => Some(false),
        (false, false) => None,
        (_, _) => unreachable!("StructOpt should make this impossible"),
    }
}

https://github.com/epage/git-stack/blob/main/src/bin/git-stack/args.rs#L105

and haven't played with overrides_with to see what a last-writer-wins would look like with clap.

Alternatives, if applicable

No response

Additional Context

See #1820 which has several concerns over doing this. I especially expect problems with

  • Interaction with global(true)
  • Validation rules (they have to be aware of and operate on the dest)
  • Derives reading the right dest
  • Derives dealing with multiple "arguments" pointing to the same dest

See #3119 for more use cases

@epage epage added C-enhancement Category: Raise on the bar on expectations A-builder Area: Builder API A-parsing Area: Parser's logic and needs it changed somehow. A-validators Area: ArgMatches validation logi S-experimental Status: Ongoing experiment that does not require reviewing and won't be merged in its current state. labels Dec 10, 2021
@tmccombs
Copy link
Contributor

Is there a good workaround for this? I have a lot of options that are negatable (mostly using no- prefixed options), and it would be really nice to avoid having duplicate boolean fields for all of them that I have to check both of.

@ducaale
Copy link
Contributor

ducaale commented Jun 27, 2022

@tmccombs would a workaround like this work for your use case?

@tmccombs
Copy link
Contributor

Maybe. In my case I only want these options for a few of the options, and in some cases I the man option starts with --no- and the negating option doesn't have the prefix (or in other words, the option without the --no prefix is the default).

I'm also not really sure what the best way to do that when using the derive api would be.

@epage
Copy link
Member Author

epage commented Jun 28, 2022

@tmccombs if your interest is in negation flags, be sure to watch the more specific #815. In it, I do bring up a more unusual solution using ArgAction so there is room for solutions outside of this issue.

@tmccombs
Copy link
Contributor

tmccombs commented Jul 1, 2022

Some other use cases for this:

  • having an option that is a shortcut for passing a specific value to another option. For example -1 as an alias for --max-results=1
  • Allowing an argument to be passed either as a positional argument or an option
  • Options that take the same value, but with different meanings. for example --include and --exclude might feed into a single list of filters, where relative order matters, and the difference is just which variant of an enum is used (or maybe one type is prefixed with some delimiter like "!").

vimpostor added a commit to vimpostor/wezterm that referenced this issue Oct 26, 2022
Right now wezterm already allows to pass a cmdline to execute (instead
of the shell) by calling "wezterm start" with trailing arguments, e.g.
wezterm start -- bash

However, most other terminals implement this via a "-e" option. This
seems to be adopted widely in the wild, such that some third-party
frameworks just blindly expect the user's terminal to use the "-e"
option for this.

One such notable framework is kio from KDE Plasma, that calls the user's
terminal in that way when launching a desktop file that uses
Terminal=true. [1]

To solve this problem, we add a compatibility layer by adding a dummy
"-e" option. This will then consume the "-e" leaving the remaining
arguments as trailing arguments, which will later be consumed by our
existing implementation in the "prog" option.

Given that clap does not really support multiple arguments writing to
the same destination [2], this seems like the most sane implementation,
even if it is a hack.

It seems to work reliable, even for edge cases where we pass wezterm
options as trailing arguments, e.g. the following will just work and do
the expected outcome (and will **not** parse "--position" as a wezterm
argument):
wezterm start -e echo --position 10,10

Fixes wez#2622

[1] https://bugs.kde.org/show_bug.cgi?id=459616
[2] clap-rs/clap#3146
vimpostor added a commit to vimpostor/wezterm that referenced this issue Nov 2, 2022
Right now wezterm already allows to pass a cmdline to execute (instead
of the shell) by calling "wezterm start" with trailing arguments, e.g.
wezterm start -- bash

However, most other terminals implement this via a "-e" option. This
seems to be adopted widely in the wild, such that some third-party
frameworks just blindly expect the user's terminal to use the "-e"
option for this.

One such notable framework is kio from KDE Plasma, that calls the user's
terminal in that way when launching a desktop file that uses
Terminal=true. [1]

To solve this problem, we add a compatibility layer by adding a dummy
"-e" option. This will then consume the "-e" leaving the remaining
arguments as trailing arguments, which will later be consumed by our
existing implementation in the "prog" option.

Given that clap does not really support multiple arguments writing to
the same destination [2], this seems like the most sane implementation,
even if it is a hack.

It seems to work reliable, even for edge cases where we pass wezterm
options as trailing arguments, e.g. the following will just work and do
the expected outcome (and will **not** parse "--position" as a wezterm
argument):
wezterm start -e echo --position 10,10

Fixes wez#2622

[1] https://bugs.kde.org/show_bug.cgi?id=459616
[2] clap-rs/clap#3146
wez pushed a commit to wez/wezterm that referenced this issue Nov 4, 2022
Right now wezterm already allows to pass a cmdline to execute (instead
of the shell) by calling "wezterm start" with trailing arguments, e.g.
wezterm start -- bash

However, most other terminals implement this via a "-e" option. This
seems to be adopted widely in the wild, such that some third-party
frameworks just blindly expect the user's terminal to use the "-e"
option for this.

One such notable framework is kio from KDE Plasma, that calls the user's
terminal in that way when launching a desktop file that uses
Terminal=true. [1]

To solve this problem, we add a compatibility layer by adding a dummy
"-e" option. This will then consume the "-e" leaving the remaining
arguments as trailing arguments, which will later be consumed by our
existing implementation in the "prog" option.

Given that clap does not really support multiple arguments writing to
the same destination [2], this seems like the most sane implementation,
even if it is a hack.

It seems to work reliable, even for edge cases where we pass wezterm
options as trailing arguments, e.g. the following will just work and do
the expected outcome (and will **not** parse "--position" as a wezterm
argument):
wezterm start -e echo --position 10,10

Fixes #2622

[1] https://bugs.kde.org/show_bug.cgi?id=459616
[2] clap-rs/clap#3146
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-builder Area: Builder API A-parsing Area: Parser's logic and needs it changed somehow. A-validators Area: ArgMatches validation logi C-enhancement Category: Raise on the bar on expectations S-experimental Status: Ongoing experiment that does not require reviewing and won't be merged in its current state.
Projects
None yet
Development

No branches or pull requests

3 participants