fix(derive): Don't duplicate subcommand aliases

When an anonymous struct is inside of an enum, we end up applying the
App methods twice, once for the `augment_args` and once for variant.

This consolidates those calls.

Fixes #2898
This commit is contained in:
Ed Page 2021-10-25 16:28:23 -05:00
parent 07fcaa9597
commit d05622d015
2 changed files with 47 additions and 8 deletions

View file

@ -240,14 +240,24 @@ fn gen_augment(
_ => {
let subcommand_var = Ident::new("__clap_subcommand", Span::call_site());
let arg_block = match variant.fields {
let sub_augment = match variant.fields {
Named(ref fields) => {
// Defer to `gen_augment` for adding app methods
args::gen_augment(&fields.named, &subcommand_var, &attrs, override_required)
}
Unit => quote!( #subcommand_var ),
Unit => {
let arg_block = quote!( #subcommand_var );
let initial_app_methods = attrs.initial_top_level_methods();
let final_from_attrs = attrs.final_top_level_methods();
quote! {
let #subcommand_var = #subcommand_var #initial_app_methods;
let #subcommand_var = #arg_block;
#subcommand_var #final_from_attrs
}
},
Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
let ty = &unnamed[0];
if override_required {
let arg_block = if override_required {
quote_spanned! { ty.span()=>
{
<#ty as clap::Args>::augment_args_for_update(#subcommand_var)
@ -259,6 +269,13 @@ fn gen_augment(
<#ty as clap::Args>::augment_args(#subcommand_var)
}
}
};
let initial_app_methods = attrs.initial_top_level_methods();
let final_from_attrs = attrs.final_top_level_methods();
quote! {
let #subcommand_var = #subcommand_var #initial_app_methods;
let #subcommand_var = #arg_block;
#subcommand_var #final_from_attrs
}
}
Unnamed(..) => {
@ -267,14 +284,10 @@ fn gen_augment(
};
let name = attrs.cased_name();
let initial_app_methods = attrs.initial_top_level_methods();
let final_from_attrs = attrs.final_top_level_methods();
let subcommand = quote! {
let #app_var = #app_var.subcommand({
let #subcommand_var = clap::App::new(#name);
let #subcommand_var = #subcommand_var #initial_app_methods;
let #subcommand_var = #arg_block;
#subcommand_var #final_from_attrs
#sub_augment
});
};
Some(subcommand)

View file

@ -75,6 +75,32 @@ fn issue_324() {
assert!(help.contains("MY_VERSION"));
}
#[test]
fn issue_418() {
#[derive(Debug, Parser)]
struct Opts {
#[clap(subcommand)]
/// The command to run
command: Command,
}
#[derive(Debug, Subcommand)]
enum Command {
/// Reticulate the splines
#[clap(visible_alias = "ret")]
Reticulate {
/// How many splines
num_splines: u8,
},
/// Frobnicate the rest
#[clap(visible_alias = "frob")]
Frobnicate,
}
let help = get_long_help::<Opts>();
assert!(help.contains("Reticulate the splines [aliases: ret]"));
}
#[test]
fn issue_490() {
use clap::Parser;