I would like to include --help
and --version
long options without the -h
and -V
short options. Is this possible?
I'm using clap with yaml. The closest I've been able to come up with is to use hidden (unused) args that mask the short options.
# main.rs
use clap::{load_yaml, App};
fn main() {
let y = load_yaml!("cli.yaml");
let m = App::from_yaml(y).get_matches();
println!("_help {}", m.is_present("_help"));
println!("_version {}", m.is_present("_version"));
}
# Cargo.toml
[package]
name = "app"
version = "0.0.1"
edition = "2018"
[dependencies]
clap = {version = "~2.33.0", features = ["yaml"]}
# cli.yaml
name: app
version: 0.0.1
args:
- opt: { short: "o", long: "opt" }
- _help: { short: "h", hidden: true }
- _version: { short: "V", hidden: true }
$ cargo -q run -- --help
app 0.0.1
USAGE:
app [FLAGS]
FLAGS:
--help Prints help information
-o, --opt
--version Prints version information
$ cargo -q run -- -h
_help true
_version false
$ cargo -q run -- -o
_help false
_version false
$ cargo -q run -- -V
_help false
_version true
$ cargo -q run -- -x
error: Found argument '-x' which wasn't expected, or isn't valid in this context
USAGE:
app [FLAGS]
For more information try --help
This doesn't feel like a very clean approach. Is there another/better way?
Clap is designed more towards creating an args parser. So there aren't really that much functionality for getting and removing existing arguments.
If you simply want to rename "-h"
to e.g. "-?"
, then you can do that with help_short("-?")
(see also version_short()
.)
However, there are ways to work around it.
Assuming you're using e.g. clap = "2.33"
. Then similarly to what you're already doing, you can override/replace the help
and version
args, and in that way "remove" the short versions. (For brevity, I'll only include examples for help
.)
You can of course keep it in cli.yaml
if you want, but I'll add it to main.rs
. In short, you want to add a new "help"
arg and only give it a long
version. It's important that you include help("Prints help information")
as this is replacing the existing help
arg, so if you don't it won't have the default help message for --help
.
The downside to overring "help"
is that you'd need to handle print_help()
yourself.
use clap::{load_yaml, App, Arg};
fn main() {
let y = load_yaml!("cli.yaml");
let mut app = App::from_yaml(y)
.arg(
Arg::with_name("help")
.long("help")
.help("Prints help information"),
);
let m = app.clone().get_matches();
if m.is_present("help") {
app.print_help().unwrap();
// std::process::exit(0);
// or just
return;
}
}
However, if you're using clap = "3.0.0-beta.2"
then that simplifies things, with the introduction of mut_arg()
. Because that allows us to mutate the argument. Thereby, we no longer need to call print_help()
ourselves.
use clap::{load_yaml, App, Arg};
fn main() {
let y = load_yaml!("cli.yaml");
let m = App::from(y)
.mut_arg("help", |h| {
Arg::new("help")
.long("help")
.about("Prints help information")
})
.get_matches();
}
Note that App::from_yaml()
is now App::from()
, while Arg::with_name()
has become Arg::new()
, and help()
is now about()
.