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

structopt-derive 0.3.6 breaks structopt <=0.3.5 #315

Closed
timotree3 opened this issue Dec 22, 2019 · 8 comments · Fixed by #316
Closed

structopt-derive 0.3.6 breaks structopt <=0.3.5 #315

timotree3 opened this issue Dec 22, 2019 · 8 comments · Fixed by #316

Comments

@timotree3
Copy link

structopt-derive v0.3.6 relies on internal details of structopt v0.3.6. However, older versions of structopt than v0.3.6 have their dependencies set up so that they can depend on structopt-derive v0.3.6. This leads to a compilation failure after someone who has a dependency such as structopt = "=0.3.5" runs cargo update.

Steps to reproduce

  1. Create a new library package foo (cargo new --lib foo)
  2. Edit foo/Cargo.toml to include
[dependencies]
structopt = "=0.3.5"
  1. Edit foo/src/lib.rs to include
#[derive(structopt::StructOpt)]
struct Bar { }
  1. Run cargo check
  2. You should see a nonsense error, caused by the wrong derive macro being run.

Possible solution

  1. Yank structopt-derive v0.3.6 and structopt v0.3.6
  2. In their place release structopt-derive v 0.4.0 and release an equivalent structopt v0.3.7 that depends on this new minor version of structopt-derive

Future mitigation

Only release versions of structopt that have an = dependency on structopt-derive. For example if structopt v0.3.5 had been released with the dependency structopt-derive = "=0.3.5" then it wouldn't have been susceptible to this breakage.

@CreepySkeleton
Copy link
Collaborator

0.3.6 is yanked. Sorry for the inconvenience

@CreepySkeleton
Copy link
Collaborator

@TeXitoi

I propose the following steps to mitigate this issue:

  • Release this version as 0.4.0 (both structopt and structopt-derive). structopt 0.4.0 uses strict dependency on structopt-derive = "=0.4.0". All the future versions will have been being released as 0.4.x`.
  • Release structopt 0.3.7 (not structopt-derive!) which depends on the newly released =0.4.0. This way, our users will be able to use new features without bumping the minor version.
  • From that moment on, we use only strict dependencies!
  • Future versions will be released as 0.4.x. Also, each such a release will be accompanied with the corresponding 0.3.x structopt version (not structopt-derive!) so the users who had to stay on 0.3.x channel - or didn't bother to switch to 0.4.x- could have the new features.
  • Should we decide to release a really breaking change, we can release 0.5.0

What do you think?

@TeXitoi
Copy link
Owner

TeXitoi commented Dec 23, 2019

It will be a lot of work. Why having structopt 0.4? as it add nothing, simpler to just update structopt-derive to 0.4 and using strict version dependency.

@CreepySkeleton
Copy link
Collaborator

Why having structopt 0.4? as it add nothing, simpler to just update structopt-derive to 0.4 and using strict version dependency.

You are right. Any other concerns?

@bkchr
Copy link

bkchr commented Dec 23, 2019

Why not release 0.4 to add the function to the StructOpt trait? I don't understand the reason against 0.4.

@CreepySkeleton
Copy link
Collaborator

add the function

What function are you talking about? augment_clap?

@TeXitoi
Copy link
Owner

TeXitoi commented Dec 23, 2019

0.4 will be used only if you decide to upgrade. The modifications are not a breaking change, it will only panic if the structopt traits are manually implemented (but this rely on implementing undocumented internals, thus not guaranteed to work).

@CreepySkeleton
Copy link
Collaborator

CreepySkeleton commented Dec 23, 2019

Please note that this issue is not about the StructOpt trait and its methods, it's just we fucked up our versioning.

Actually, it has been fucked for years and just happened to work because nobody have made attempt to radically rework the internal machinery. Now, when we tried to extend our trait with internal methods, it went sought.

structopt used to depend on structopt-derive like structopt-derive = "x.y.z" where x.y.z is the exact version of the release of structopt. The dependency is not strict. This was supposed to be OK since at the time of structopt x.y.z release there is only one structopt-derive x.y.z version, and yes, this is true.

Let's imagine someone has a strict dependency on structopt, like structopt = "=0.3.5" (possibly transitive). They run cargo update which happily bumps structopt-derive (since this dependency is not strict) but not structopt (since this dependency is strict).

Bingo! The code generated by structopt-derive 0.3.6 is not compatible with structopt 0.3.5 trait and it's not supposed to be. That is the problem.

The proposed solution here is to release the next structopt-derive as 0.4.0 - so cargo update wouldn't pull it for old 0.3.x versions - and the new structopt 0.3.7 will strictly depend on structopt-derive = "=0.4.0". All the future releases will use strict dependencies so the problem will not arise again.

Everything's works, everybody's happy, angels sing, and a light suddenly fills the room.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants