Skip to content
This repository has been archived by the owner on Jan 1, 2022. It is now read-only.

Allow end users to indicate that specific arguments may be ignored if not recognized #179

Open
2 tasks done
epage opened this issue Dec 6, 2021 · 3 comments
Open
2 tasks done

Comments

@epage
Copy link
Owner

epage commented Dec 6, 2021

Issue by wchargin
Saturday Feb 20, 2021 at 02:46 GMT
Originally opened as clap-rs/clap#2354


Make sure you completed the following tasks

  • Searched the discussions
    • Relevant: #2314 opened by @josvisser66. That discussion has one
      request to file it as an issue, and one request for more info.
      Here, then, is an issue with more info.
  • Searched the closed issues: for unrecognized arguments

Describe your use case

My team distributes two binaries; one written in Python, and one in Rust
with Clap. The Python binary invokes the Rust binary. As we add new
options to the Rust binary, we can’t immediately teach the Python
binary to pass them
, because the most recently released version of
the Rust binary would fail with an “unrecognized option” error.

Another use case, as discussed in #2314, involves rolling deployments.
You have a binary at v1.0.0 running in production. You add a flag to it,
but you can’t teach your your prod configs to pass the new flag, because
v1.0.0 will choke if given that flag. Instead, you can change the
configs to pass --undefok=bar --bar=1. On v1.0.0, this will do
nothing; once v1.1.0 is rolled out, the flag value will be honored.

If a project of yours is blocked on this feature, please, mention it explicitly.

Kind of: this would make developing my team’s project (TensorBoard)
notably easier, as noted in the above link, but we have workarounds.

Describe the solution you'd like

The Google flags system has a feature called undefok (read as
“undefined OK”). If your binary myprog uses gflags, and you run

myprog --undefok=bar --foo=1 --bar=2

then:

  • if myprog knows about the --bar option, it will interpret the
    option as usual;
  • but if myprog does not know about the --bar option, then it will
    be ignored. (Without --undefok=bar, this would be an error that
    there is no known flag by the name bar.)

Note that supporting or passing --undefok=bar does not mean that you
can pass arbitrary unrecognized arguments: --wat=3 would still be an
error.

I imagine that this could be implemented either as a new AppSettings:

let m = App::new("myprog")
    .setting(AppSettings::AllowUndefok)
    .arg(Arg::with_name("foo").long("foo").takes_value(true))
    .get_matches_from(vec![
        "myprog", "--undefok=bar", "--foo=1", "--bar=2",
    ]);

assert_eq!(m.value_of("foo"), Some("1"));
assert_eq!(m.value_of("baz"), None); // arg just ignored

…or as an ArgSettings to allow customizing the magic name undefok:

let m = App::new("myprog")
    .arg(Arg::with_name("foo").long("foo").takes_value(true))
    .arg(Arg::with_name("undefok").long("my-undef-ok").undefok(true))
    .get_matches_from(vec![
        "myprog", "--my-undef-ok=bar", "--foo=1", "--bar=2",
    ]);

assert_eq!(m.value_of("foo"), Some("1"));
assert_eq!(m.value_of("bar"), None); // arg just ignored

Alternatives, if applicable

One heavyweight alternative is to provide a mode in which arbitrary
unrecognized flags are permitted. But this carries too high a cost:
users who make a typo in an option name should be alerted, not have
their inputs silently ignored.

Additional context

IMHO, it’s okay if we need to require that --undefok precede the
undefined arguments on the command line:

--undefok=bar --bar=2  # should be accepted and ignored
--bar=2 --undefok=bar  # it's okay with me if this is rejected

I also imagine that there might be issues distinguishing flags from
options. It’s okay with me if we need to require that any undefok
options use the “stuck” form:

--undefok=bar --bar=2  # should be accepted and ignored
--undefok=bar --bar 2  # it's okay with me if this is rejected
@epage
Copy link
Owner Author

epage commented Dec 6, 2021

Comment by tmplt
Thursday Jul 29, 2021 at 22:33 GMT


provide a mode in which arbitrary unrecognized flags are permitted.

This would be useful in programs that extend cargo build. For example, in cargo-flash and cargo-rtic-scope we want to forward unknown arguments to cargo build. At present this is possible with AppSettings:TrailingVarArgs | Appsettings::AllowLeadingHyphens, but it requires cargo options to be passed as the last options. E.g. cargo flash --bin foobar --release [cargo-flash options...] would be invalid whereas cargo flash [cargo-flash options...] --bin foobar --release would be correct, but not immidiately obvious for the end-user.

@epage
Copy link
Owner Author

epage commented Dec 6, 2021

Comment by epage
Friday Jul 30, 2021 at 00:44 GMT


@tmplt another related issue is clap-rs/clap#1880

@epage
Copy link
Owner Author

epage commented Dec 6, 2021

Comment by tmplt
Friday Jul 30, 2021 at 00:55 GMT


@epage, thanks. The minimal viable solution proposed within would help my case, but it seems that IgnoreErrors has been deprecated.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant