-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
TrailingVarArg
doesn't work without --
#1538
Comments
-
-
-
-
TrailingVarArg
doesn't work without --
Do we really want this? |
Yeah, this looks like a bug. |
+ 1 on this one. This is behavior that's quite common seen when using |
This would be very useful for me. Is there a work-around? |
+1 This is a semi-common scenario. I have the same use case as the OP. Any plans to implement this feature? |
The work-around for me right now is just to get rid of the |
I just ported the example code to clap3 and it seems to work for me fn main() {
let m = parser().get_matches();
dbg!(m.is_present("prog-flag"));
dbg!(m
.values_of("EXECUTABLE")
.unwrap_or_default()
.collect::<Vec<_>>());
dbg!(m.values_of("ARGS").unwrap_or_default().collect::<Vec<_>>());
}
fn parser<'a>() -> clap::App<'a> {
clap::App::new("varargs")
.setting(clap::AppSettings::TrailingVarArg)
// boolean
.arg(
clap::Arg::new("prog-flag")
.long("prog-flag")
.takes_value(false),
)
// path to executable
.arg(
clap::Arg::new("EXECUTABLE")
.takes_value(true)
.required(true),
)
// list of arguments to pass to executable
.arg(
clap::Arg::new("ARGS")
.takes_value(true)
.multiple_values(true)
.allow_hyphen_values(true),
)
}
#[test]
fn test_with_delimiter() {
parser()
.try_get_matches_from(vec!["--prog-flag", "executable", "--", "-a", "1"])
.unwrap();
}
#[test]
fn test_without_delimiter() {
parser()
.try_get_matches_from(vec!["--prog-flag", "executable", "-a", "1"])
.unwrap();
} Am I missing something or does it look like this was fixed and we can close it? |
@epage It seems that particular example works, but it still fails if you follow #[test]
fn test_without_delimiter() {
parser()
.try_get_matches_from(vec!["--prog-flag", "executable", "--foo", "1"])
.unwrap();
} |
Thanks for calling out that other case! I was able to reproduce that. I threw together #3389 as part of looking at this. long arguments are missing some of the checks that short arguments have. This PR just copied over one of them. Some more work is needed on it. I'm giving myself some pause to consider how disruptive of a change any of this is. My guess is I'll consider it to not be a breaking change but will want it called out in a compatibility section in the CHANGELOG (like Rust does). I want to reserve those for minor releases (I am preparing for a minor release atm). If anyone wants to pick this up, that'd be a big help. |
@epage Thanks a lot for looking into this. That sounds reasonable, regarding how you treat this change in behaviour. I was just thinking of corner cases, and what stands out is the situation when the first of the multiple positional arguments can be interpreted as a flag. Example: App::new("varargs")
.setting(AppSettings::TrailingVarArg)
.arg(Arg::with_name("prog-flag")
.long("prog-flag")
.takes_value(false))
// Note that `EXECUTABLE` is no longer present.
.arg(Arg::with_name("ARGS")
.takes_value(true)
.multiple(true)
.allow_hyphen_values(true))
Here,
Would the idea be to treat |
Could you create a separate issue for that? I ran into those cases as well though I've still been mulling over my thoughts on what should be done. As for current behavior, It looks like we start processing One of the questions I have for this is if we should check for flags between Another is a concern over backwards compatibility for user applications. If we start |
Just to hopefully clarify things, as I don't think I mentioned this in my bug report, my use case is creating something like The project in question is naftulikay/escalator. As opposed to Examples of usage:
Presently, as can be seen in the docs for |
@epage One issue with some of the test cases listed in this issue: the calls to |
Thanks! Thats easy to overlook |
Did some more comparisons #!/usr/bin/env -S rust-script --debug
//! ```cargo
//! [dependencies]
//! #clap = { path = "../clap" }
//! clap = "3"
//! ```
fn main() {
let all_args: &[&[&str]] = &[
&["cmd", "--prog-flag", "executable", "--apple", "1"],
&["cmd", "--prog-flag", "executable", "--", "--apple", "1"],
&["cmd", "--prog-flag", "executable", "-a", "1"],
&["cmd", "--prog-flag", "executable", "--", "-a", "1"],
];
for args in all_args {
dbg!(args);
let cmd = clap::App::new("varargs")
.setting(clap::AppSettings::TrailingVarArg)
.setting(clap::AppSettings::AllowLeadingHyphen)
// boolean
.arg(
clap::Arg::with_name("prog-flag")
.long("prog-flag")
.takes_value(false),
)
// path to executable
.arg(
clap::Arg::with_name("EXECUTABLE")
.takes_value(true)
.required(true),
)
// list of arguments to pass to executable
.arg(
clap::Arg::with_name("ARGS")
.takes_value(true)
.multiple(true)
.allow_hyphen_values(true),
);
let m = cmd.get_matches_from_safe(*args);
match m {
Ok(m) => {
dbg!(m.is_present("prog-flag"));
dbg!(m
.values_of("EXECUTABLE")
.unwrap_or_default()
.collect::<Vec<_>>());
dbg!(m.values_of("ARGS").unwrap_or_default().collect::<Vec<_>>());
}
Err(err) => {
eprintln!("{}", err);
}
}
}
} clap v2 without setting(clap::AppSettings::AllowLeadingHyphen)
clap v2 with setting(clap::AppSettings::AllowLeadingHyphen)
clap v3 without setting(clap::AppSettings::AllowLeadingHyphen)
clap v3 with setting(clap::AppSettings::AllowLeadingHyphen)
|
The fact that |
As noted in #4039, since
As well, when we resolve this, we should
|
…first pos This makes it match up with `Command::allow_hyphen_values` which was the guiding factor for what the behavior should be. This supersedes clap-rs#4039 Fixes clap-rs#3880 Fixes clap-rs#1538
I'm feeling fairly confident in the behavior in #4187 |
Maintainer's notes
Command::allow_hyphen_values(true)
Rust Version
Stable
Affected Version of clap
Latest
Bug or Feature Request Summary
I am unable to write a program which accepts a variable amount of final args which include flag-like values without using a delimiter.
Expected Behavior Summary
I'd like to be able to have my variable amount of args be of any format, including flag-like options.
Actual Behavior Summary
Parsing fails.
Steps to Reproduce the issue
I have created a playground example which demonstrates the problem directly.
Sample Code or Link to Sample Code
Playground
My exact use-case is that I have a positional argument which is a path to an executable, followed by a list of arguments to pass to that executable.
Example:
Internally, I'm using
--prog-flag
to customize my application's behavior, the executable path to find the binary to execute, and the variable length of args to pass to the program as arguments.I can't seem to find a way to write the above without needing a delimiter (
--
) between executable and the argument list.The text was updated successfully, but these errors were encountered: