Skip to content

Commit ddb51cb

Browse files
michiel-de-muynckTeXitoi
authored andcommitted
Fix duplication of aliases in subcommands
This commit fixes the issue where all top level methods were duplicated for subcommands with fields (see issue #418). For some attributes, such as aliases, this resulted in duplicate output.
1 parent 701d6dd commit ddb51cb

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

structopt-derive/src/lib.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -520,9 +520,14 @@ fn gen_augment_clap_enum(
520520

521521
_ => {
522522
let app_var = Ident::new("subcommand", Span::call_site());
523+
let from_attrs = attrs.top_level_methods();
524+
let version = attrs.version();
525+
523526
let arg_block = match variant.fields {
527+
// If the variant is named, then gen_augmentation already generates the
528+
// top level methods (#from_attrs) and version.
524529
Named(ref fields) => gen_augmentation(&fields.named, &app_var, &attrs),
525-
Unit => quote!( #app_var ),
530+
Unit => quote!( #app_var#from_attrs#version ),
526531
Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
527532
let ty = &unnamed[0];
528533
quote_spanned! { ty.span()=>
@@ -536,21 +541,18 @@ fn gen_augment_clap_enum(
536541
)
537542
} else {
538543
#app_var
539-
}
544+
}#from_attrs#version
540545
}
541546
}
542547
}
543548
Unnamed(..) => abort!(variant, "non single-typed tuple enums are not supported"),
544549
};
545550

546551
let name = attrs.cased_name();
547-
let from_attrs = attrs.top_level_methods();
548-
let version = attrs.version();
549552
Some(quote! {
550553
let app = app.subcommand({
551554
let #app_var = ::structopt::clap::SubCommand::with_name(#name);
552-
let #app_var = #arg_block;
553-
#app_var#from_attrs#version
555+
#arg_block
554556
});
555557
})
556558
},

tests/issues.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,34 @@ fn issue_359() {
116116
);
117117
}
118118

119+
#[test]
120+
fn issue_418() {
121+
use structopt::StructOpt;
122+
123+
#[derive(Debug, StructOpt)]
124+
struct Opts {
125+
#[structopt(subcommand)]
126+
/// The command to run
127+
command: Command,
128+
}
129+
130+
#[derive(Debug, StructOpt)]
131+
enum Command {
132+
/// Reticulate the splines
133+
#[structopt(visible_alias = "ret")]
134+
Reticulate {
135+
/// How many splines
136+
num_splines: u8,
137+
},
138+
/// Frobnicate the rest
139+
#[structopt(visible_alias = "frob")]
140+
Frobnicate,
141+
}
142+
143+
let help = get_long_help::<Opts>();
144+
assert!(help.contains("Reticulate the splines [aliases: ret]"));
145+
}
146+
119147
#[test]
120148
fn issue_490() {
121149
use std::iter::FromIterator;

0 commit comments

Comments
 (0)