Skip to content
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

version = expr ignored when using subcommands #324

Closed
wez opened this issue Jan 10, 2020 · 13 comments · Fixed by #325
Closed

version = expr ignored when using subcommands #324

wez opened this issue Jan 10, 2020 · 13 comments · Fixed by #325
Assignees
Labels
bug This is a BUG. The fix may be released in a patch version even if considered breaking

Comments

@wez
Copy link

wez commented Jan 10, 2020

This sounds similar to #283 but manifests a little differently.

#[derive(StructOpt)]
#[structopt(version = my_version())]
struct Opt {
    #[structopt(subcommand)]
    cmd: Option<SubCommand>,
}

#[derive(StructOpt)]
struct StartCommand {
}

#[derive(StructOpt)]
enum SubCommand {
   Start(StartCommand),
}

generates code along the lines of:

impl StructOptInternal for Opt {
  fn augment_clap(app) {
      let app = app.version("1.0").version(my_version());
      let app = <SubCommand>::augment_clap(app);
      app
   }
}

impl StructOptInternal for Start {
   fn augment_clap(app) {
      // this overrides the version set on the top level, which is the bug
      let app = app.version("1.0");
      // ...
      app
}

The workaround is to add something like:

#[structopt(no_version, version = my_version())]

on everthing for which the StructOpt derive is used.

@CreepySkeleton CreepySkeleton added the bug This is a BUG. The fix may be released in a patch version even if considered breaking label Jan 10, 2020
@CreepySkeleton
Copy link
Collaborator

I really regret the decision to generate version() automatically when not asked, unlike author and about. It's third bug because of that.

@wez
Copy link
Author

wez commented Jan 10, 2020

I was going to suggest only setting it when explicitly referenced, but I haven't been following the changes since 0.2 closely enough to understand the background.

@CreepySkeleton
Copy link
Collaborator

You mean, generate .version() call only when explicitly requested by #[structopt(version)]? We were considering it in #217 but we ended up with no_version instead, and I wholeheartedly regret this decision. I'll do my best to change in in clap_derive but, for structopt, it would be a breaking change.

@TeXitoi
Copy link
Owner

TeXitoi commented Jan 10, 2020

That's a breaking change.

For the memory: #217

@wez
Copy link
Author

wez commented Jan 10, 2020

My expectation would be that if I didn't explicitly use #[structopt(version)] then I would get a default version for the top level struct only, with the others leaving it unspecified.

I believe that that is the behavior in structopt 0.2 which is what I was attempting to upgrade from; from my perspective 0.2 -> 0.3 is already a breaking change, so I have no problem with a fix being an additional breaking change--it would make it less of a breaking change for me :)

@wez
Copy link
Author

wez commented Jan 10, 2020

FWIW, I'm also totally fine with not setting the default version at all, but that's because I prefer to show versions based off the commit information for executables. So long as overriding the version is not overly laborious, I don't have a strong opinion on what the default behavior is.

@CreepySkeleton
Copy link
Collaborator

My expectation would be that if I didn't explicitly use #[structopt(version)] then I would get a default version for the top level struct only, with the others leaving it unspecified.

The question here, how to detect if the struct is top level or not? StructOpt uses only one trait for all the stuff: top level structs (apps), flattened structs, and subcommands.

It would be much easier to develop and support if they were separate traits, like StructOpt, StructFlatten, StructSubcmd or whatever, and this would also allow us to confidently say "yes, this is top level struct since StructOpt is used only on top level structs". But, unfortunately, this is a breaking change too.

(Not to mention that this would simplify the implementing code significantly).

I'm looking forward to change it in clap_derive, we'll see then.

@TeXitoi
Copy link
Owner

TeXitoi commented Jan 10, 2020

That would be more complicated for the user.

@CreepySkeleton
Copy link
Collaborator

CreepySkeleton commented Jan 10, 2020

I believe that that is the behavior in structopt 0.2 which is what I was attempting to upgrade from

Actually, it was a longstanding bug in 0.2, which was fixed only recently.

The bug in a nutshell - top level attributes (including the auto-generated .version() call) on inner structs (flattened, subcommands) had been ignored up until then.

@CreepySkeleton
Copy link
Collaborator

That would be more complicated for the user.

What's complicated with separate traits? It would be like:

if you want to use the struct with flatten, it must derive StructFlatten.

if you want to use a struct wit subcommand, it must derive StructSubcommand

The top level app must derive StructOpt.

Pretty simple, huh?

@TeXitoi
Copy link
Owner

TeXitoi commented Jan 10, 2020

You'll be surprised by the bug reports that would generate such a change.

@CreepySkeleton
Copy link
Collaborator

Er, I'm not proposing to change structopt, heavens no. I'm just thinking aloud about "what clap_derive should look like".

@TeXitoi
Copy link
Owner

TeXitoi commented Jan 10, 2020

Of course, just don't underestimate the simplicity of your interface, and don't forget that you are biased as a contributor.

@CreepySkeleton CreepySkeleton self-assigned this Jan 11, 2020
CreepySkeleton added a commit that referenced this issue Jan 11, 2020
CreepySkeleton added a commit that referenced this issue Jan 12, 2020
CreepySkeleton added a commit that referenced this issue Jan 13, 2020
CreepySkeleton added a commit to clap-rs/clap that referenced this issue Feb 4, 2020
CreepySkeleton added a commit to clap-rs/clap that referenced this issue Feb 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This is a BUG. The fix may be released in a patch version even if considered breaking
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants