-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Port cargo to clap3 #10265
Port cargo to clap3 #10265
Changes from 1 commit
f17ecaf
88a122c
5435b26
f3ec865
2aa4e9f
f9b28cf
aed0312
5cd062e
0ab4d0c
24f301b
6e08a30
92fa72d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- One parser change found by `cargo_config::includes` is that clap 2 would ignore any values after a `=` for flags. `cargo config --show-origin` is a flag but the test passed `--show-origin=yes` which happens to give the desired result for that test but is the same as `--show-origin=no` or `--show-origin=alien-invasion`. - The parser now panics when accessing an undefined attribute but clap takes advantage of that for sharing code across commands that have different subsets of arguments defined. I've extended clap so we can "look before you leap" and put the checks at the argument calls to start off with so its very clear what is tenuously shared. This allows us to go in either direction in the future, either addressing how we are sharing between commands or by moving this down into the extension methods and pretending this clap feature doesn't exist - On that topic, a test found clap-rs/clap#3263. For now, there is a hack in clap. Depending on how we fix that in clap for clap 4.0, we might need to re-address things in cargo. - `value_of_os` now requires setting `allow_invalid_utf8`, otherwise it asserts. To help catch this, I updated the argument definitions associated with lookups reported by: - `rg 'values?_os' src/` - `rg 'values?_of_os' src/` - clap now reports `2` for usage errors, so we had to bypass clap's `exit` call to keep the same exit code. BREAKING CHANGE: API now uses clap3
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,8 +35,8 @@ pub fn main(config: &mut Config) -> CliResult { | |
Err(e) => { | ||
if e.kind == clap::ErrorKind::UnrecognizedSubcommand { | ||
// An unrecognized subcommand might be an external subcommand. | ||
let cmd = &e.info.as_ref().unwrap()[0].to_owned(); | ||
return super::execute_external_subcommand(config, cmd, &[cmd, "--help"]) | ||
let cmd = e.info[0].clone(); | ||
return super::execute_external_subcommand(config, &cmd, &[&cmd, "--help"]) | ||
.map_err(|_| e.into()); | ||
} else { | ||
return Err(e.into()); | ||
|
@@ -152,7 +152,7 @@ Run with 'cargo -Z [FLAG] [SUBCOMMAND]'", | |
} | ||
|
||
let (cmd, subcommand_args) = match expanded_args.subcommand() { | ||
(cmd, Some(args)) => (cmd, args), | ||
Some((cmd, args)) => (cmd, args), | ||
_ => { | ||
// No subcommand provided. | ||
cli().print_help()?; | ||
|
@@ -236,10 +236,10 @@ fn add_ssl(version_string: &mut String) { | |
|
||
fn expand_aliases( | ||
config: &mut Config, | ||
args: ArgMatches<'static>, | ||
args: ArgMatches, | ||
mut already_expanded: Vec<String>, | ||
) -> Result<(ArgMatches<'static>, GlobalArgs), CliError> { | ||
if let (cmd, Some(args)) = args.subcommand() { | ||
) -> Result<(ArgMatches, GlobalArgs), CliError> { | ||
if let Some((cmd, args)) = args.subcommand() { | ||
match ( | ||
commands::builtin_exec(cmd), | ||
super::aliased_command(config, cmd)?, | ||
|
@@ -292,7 +292,7 @@ For more information, see issue #10049 <https://github.com/rust-lang/cargo/issue | |
.setting(AppSettings::NoBinaryName) | ||
.get_matches_from_safe(alias)?; | ||
|
||
let (new_cmd, _) = new_args.subcommand(); | ||
let new_cmd = new_args.subcommand_name().expect("subcommand is required"); | ||
already_expanded.push(cmd.to_string()); | ||
if already_expanded.contains(&new_cmd.to_string()) { | ||
// Crash if the aliases are corecursive / unresolvable | ||
|
@@ -316,16 +316,20 @@ For more information, see issue #10049 <https://github.com/rust-lang/cargo/issue | |
|
||
fn config_configure( | ||
config: &mut Config, | ||
args: &ArgMatches<'_>, | ||
subcommand_args: &ArgMatches<'_>, | ||
args: &ArgMatches, | ||
subcommand_args: &ArgMatches, | ||
global_args: GlobalArgs, | ||
) -> CliResult { | ||
let arg_target_dir = &subcommand_args.value_of_path("target-dir", config); | ||
let arg_target_dir = &subcommand_args | ||
._is_valid_arg("target-dir") | ||
.then(|| subcommand_args.value_of_path("target-dir", config)) | ||
.flatten(); | ||
let verbose = global_args.verbose + args.occurrences_of("verbose") as u32; | ||
// quiet is unusual because it is redefined in some subcommands in order | ||
// to provide custom help text. | ||
let quiet = | ||
args.is_present("quiet") || subcommand_args.is_present("quiet") || global_args.quiet; | ||
let quiet = args.is_present("quiet") | ||
|| subcommand_args.is_valid_and_present("quiet") | ||
|| global_args.quiet; | ||
let global_color = global_args.color; // Extract so it can take reference. | ||
let color = args.value_of("color").or_else(|| global_color.as_deref()); | ||
let frozen = args.is_present("frozen") || global_args.frozen; | ||
|
@@ -353,11 +357,7 @@ fn config_configure( | |
Ok(()) | ||
} | ||
|
||
fn execute_subcommand( | ||
config: &mut Config, | ||
cmd: &str, | ||
subcommand_args: &ArgMatches<'_>, | ||
) -> CliResult { | ||
fn execute_subcommand(config: &mut Config, cmd: &str, subcommand_args: &ArgMatches) -> CliResult { | ||
if let Some(exec) = commands::builtin_exec(cmd) { | ||
return exec(config, subcommand_args); | ||
} | ||
|
@@ -380,7 +380,7 @@ struct GlobalArgs { | |
} | ||
|
||
impl GlobalArgs { | ||
fn new(args: &ArgMatches<'_>) -> GlobalArgs { | ||
fn new(args: &ArgMatches) -> GlobalArgs { | ||
GlobalArgs { | ||
verbose: args.occurrences_of("verbose") as u32, | ||
quiet: args.is_present("quiet"), | ||
|
@@ -411,9 +411,12 @@ fn cli() -> App { | |
.settings(&[ | ||
AppSettings::UnifiedHelpMessage, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
AppSettings::DeriveDisplayOrder, | ||
AppSettings::VersionlessSubcommands, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
AppSettings::AllowExternalSubcommands, | ||
AppSettings::NoAutoVersion, | ||
]) | ||
// Doesn't mix well with our list of common cargo commands. See clap-rs/clap#3108 for | ||
// opening clap up to allow us to style our help template | ||
.global_setting(AppSettings::DisableColoredHelp) | ||
.usage(usage) | ||
.template( | ||
"\ | ||
|
@@ -423,7 +426,7 @@ USAGE: | |
{usage} | ||
|
||
OPTIONS: | ||
{unified} | ||
{options} | ||
|
||
Some common cargo commands are (see all commands with --list): | ||
build, b Compile the current package | ||
|
@@ -443,16 +446,16 @@ Some common cargo commands are (see all commands with --list): | |
|
||
See 'cargo help <command>' for more information on a specific command.\n", | ||
) | ||
.arg(opt("version", "Print version info and exit").short("V")) | ||
.arg(opt("version", "Print version info and exit").short('V')) | ||
.arg(opt("list", "List installed commands")) | ||
.arg(opt("explain", "Run `rustc --explain CODE`").value_name("CODE")) | ||
.arg( | ||
opt( | ||
"verbose", | ||
"Use verbose output (-vv very verbose/build.rs output)", | ||
) | ||
.short("v") | ||
.multiple(true) | ||
.short('v') | ||
.multiple_occurrences(true) | ||
.global(true), | ||
) | ||
.arg_quiet() | ||
|
@@ -475,11 +478,16 @@ See 'cargo help <command>' for more information on a specific command.\n", | |
.arg( | ||
Arg::with_name("unstable-features") | ||
.help("Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details") | ||
.short("Z") | ||
.short('Z') | ||
.value_name("FLAG") | ||
.multiple(true) | ||
.number_of_values(1) | ||
.global(true), | ||
) | ||
.subcommands(commands::builtin()) | ||
} | ||
|
||
#[test] | ||
fn verify_cli() { | ||
cli().debug_assert(); | ||
} | ||
Comment on lines
+488
to
+491
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clap assumes errors are programmer mistakes and reports them through debug_asserrts. It does this lazily, only evaluating the subcommands that the user activates. This test will eagerly run all of the debug asserts, helping to catch problems sooner. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clap2 returned
""
when no subcommand was present but now returnsNone
.