I would love to have a way to pass arguments to subcommands, to build CLIs like this:
foo bar <argument>
(I removed the template because no section applied to my problem). I'm not sure whether I told you this before... but a short google search and github search did not bring up anything useful...
@panicbit said on IRC that I should write "positional arguments". :smile:
This actually seems to work already. Oddly I remember it not working though. Was this added recently?
Maybe it was subcommands and positional args being mutually exclusive?
Anyways, here is an example:
extern crate clap;
use clap::{Arg, App, SubCommand};
fn main() {
let matches = App::new("My Super Program")
.subcommand(SubCommand::with_name("foo")
.arg(Arg::with_name("BAR")
.index(1)
.required(true)
)
)
.get_matches();
}
Which yields the following with foo --help:
clapper-foo
USAGE:
clapper foo <BAR>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
ARGS:
<BAR>
@panicbit Thanks!
@matthiasbeyer yep, they aleady work exactly like that. Subcommands are actually just aliases for Apps. So anything App can do, so can a SubCommand. I know it's somewhat confusing so I'm actually just considering going to Cmd for both the App and SubCommand since're identical.
The reasoning behind going through two different names was they originally didn't have the same functionality. And it allowed you "switch mental contexts" between what you were doing.
Edit: Here's the docs page, which I think could be worded a little better to reduce confusion.
Was this added recently? Maybe it was subcommands and positional args being mutually exclusive?
It's been in for quite a while. There may have been a bug at the time you tried it? Also there are some oddities like trying to use a value for a positional argument which happens to be the same as one of your subcommands (i.e. trying to use $ prog foo for $ prog <positional> when prog foo is a valid subcommand as well...but this is super rare in reality, and would just require to use $ prog -- foo to solve it which is also conventional.). Recently added (as of last night) there is also a new setting to combat that issue, if it ever comes up (such as designing a CLI where you'd like some positional values to be the same your subcommands), see AppSettings::ArgsNegateSubcommands for details (sorry it's not on docs.rs yet as I haven't put out the new version yet!)
Sorry, I had some other stuff to do.
I just replicated my scenario and minified it:
App::new("App")
.arg(Arg::with_name("foo")
.required_unless("bar")
)
.subcommand(SubCommand::with_name("quux"))
.get_matches()
Results in:
App
USAGE:
super <foo> [SUBCOMMAND]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
ARGS:
<foo>
SUBCOMMANDS:
bar
help Prints this message or the help of the given subcommand(s)
I guess this is not a bug because of the .required_unless.
But you can't specify subcommands in required_unless and co, which is an issue.
@panicbit you can use AppSettings:: SubcommandsNegateReqs which does what you're looking for.
Cool, thanks!