Repository: pacak/bpaf (rust)

Issue:
Broken command aliases
Command aliases fail to parse (or I'm using them wrong?):

```rust
fn main() {
    groups().run();
}

#[derive(Debug, Bpaf, Clone)]
enum Groups {
    #[bpaf(command("top"), long("top-alias"))]
    Command(),
}
```

```
✅ $ cargo run -- top
💢 $ cargo run -- top-alias 
Error: expected `COMMAND ...`, got `top-alias`. Pass `--help` for usage information
```

Pull request description:
bpaf_derive: fix command aliases for enum members
Fixes #278 

Patch:
diff --git a/bpaf_derive/src/top.rs b/bpaf_derive/src/top.rs
index 9a166b4..c09bc5a 100644
--- a/bpaf_derive/src/top.rs
+++ b/bpaf_derive/src/top.rs
@@ -380,7 +380,11 @@ impl ParsedEnumBranch {
                     attrs.push(EAttr::NamedCommand(ident_to_long(&branch.ident)));
                 }
 
-                EAttr::CommandShort(_) | EAttr::CommandLong(_) => branch.set_command(),
+                EAttr::CommandShort(_) | EAttr::CommandLong(_) => {
+                    // TODO should probably be a bit more careful here,
+                    // new_derive macro addresses that though
+                    attrs.push(attr);
+                }
 
                 EAttr::UnitShort(n) => branch.set_unit_name(StrictName::Short {
                     name: n.unwrap_or_else(|| ident_to_short(&branch.ident)),


Test patch:
diff --git a/bpaf_derive/src/top_tests.rs b/bpaf_derive/src/top_tests.rs
index a8a92b5..02e6691 100644
--- a/bpaf_derive/src/top_tests.rs
+++ b/bpaf_derive/src/top_tests.rs
@@ -546,7 +546,7 @@ fn generate_command() {
 }
 
 #[test]
-fn command_with_aliases() {
+fn command_with_aliases_struct() {
     let top: Top = parse_quote! {
         #[bpaf(command, short('c'), long("long"), long("long2"))]
         /// help
@@ -574,6 +574,37 @@ fn command_with_aliases() {
     assert_eq!(top.to_token_stream().to_string(), expected.to_string());
 }
 
+#[test]
+fn command_with_aliases_enum() {
+    let top: Top = parse_quote! {
+        enum Options {
+            #[bpaf(command("command"), short('c'), long("long"), long("long2"))]
+            /// help
+            Command {
+                i: bool,
+            }
+        }
+    };
+
+    let expected = quote! {
+        fn options() -> impl ::bpaf::Parser<Options> {
+            #[allow(unused_imports)]
+            use ::bpaf::Parser;
+            {
+                let i = ::bpaf::short('i').switch();
+                ::bpaf::construct!(Options::Command { i, })
+            }
+            .to_options()
+            .descr("help")
+            .command("command")
+            .short('c')
+            .long("long")
+            .long("long2")
+        }
+    };
+    assert_eq!(top.to_token_stream().to_string(), expected.to_string());
+}
+
 #[test]
 fn version_with_commands_with_cargo_helper() {
     let top: Top = parse_quote! {
diff --git a/tests/params.rs b/tests/params.rs
index 008d54b..b527147 100644
--- a/tests/params.rs
+++ b/tests/params.rs
@@ -102,3 +102,16 @@ fn squashed_short_names() {
     let r = parser.run_inner(&["-a", "-bfoo"]).unwrap();
     assert_eq!(r.1, "foo");
 }
+
+#[test]
+fn command_alias() {
+    #[derive(Debug, Bpaf, Clone)]
+    #[bpaf(options)]
+    enum Groups {
+        #[bpaf(command("top"), long("top-alias"))]
+        Command,
+    }
+
+    groups().run_inner(&["top"]).unwrap();
+    groups().run_inner(&["top-alias"]).unwrap();
+}