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

Support workspace-level crate version denylist / local yanking #13856

Open
demurgos opened this issue May 3, 2024 · 2 comments
Open

Support workspace-level crate version denylist / local yanking #13856

demurgos opened this issue May 3, 2024 · 2 comments
Labels
A-dependency-resolution Area: dependency resolution and the resolver A-patch Area: [patch] table override C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` S-needs-info Status: Needs more info, such as a reproduction or more background for a feature request.

Comments

@demurgos
Copy link
Contributor

demurgos commented May 3, 2024

Problem

Occasionally, crates release a semver-violating version that causes breakage when consumed.

Cargo currently has two main features to address this issue:

  1. Crate authors can mark the offending crate as "yanked"
  2. Crate consumers can use a lock file with a pinned working version

The first approach is the best one, but it requires active intervention of the crate authors which may sometime take a few days. The second approach works great if the dependency was already used through a good version, however it's not easy to use when we want start using this dependency. This dependency can be deep in the chain so applying requirements locally in the workspace may not work. There are also solutions involving forking the crate or pointing to some other source (such as the Git repo), but these feel more complex than needed since the working version already exists in the registry, cargo resolution should be able to resolve it.

The scenario is the following:

  1. foo has a private dependency on clumsy ^1.0.0
  2. bar has a private dependency on clumsy ^2.0.0
  3. myproject depends on foo only
  4. clumsy releases 2.0.1 which contains a semver violation
  5. myproject wants to add a dependency on bar, but by doing so cargo pulls the broken clumsy 2.0.1 instead of the working clumsy 2.0.0

myproject now needs to wait for an upstream fix or manually edit the lock file to add foo and clumsy 2.0.0, which is pretty tedious.

Proposed Solution

The solution for me would be to help resolution / updating the lock file in presence of semver violations without expecting coordination from third-party libraries, In the problem description, the fix could also be applied in bar, but in all cases myproject has to wait for a fix upstream instead of fixing it itself locally and moving on. I expect the solution to be applied locally at the workspace level and not be used when publishing the top crate to the registry.

  1. The restricted solution for this issue of semver violations would be to have a way to mark at the workspace level that a crate version should be treated as yanked. When cargo performs resolution, a crate version is treated as yanked if it is marked as such either on the registry or in the workspace manifest (for example in the patch section). Resolution proceeds with regular yanking semantics. With this solution, myproject would flag clumsy@2.0.1 as yanked and cargo resolution would select clumsy@2.0.0.

  2. A more general solution would be to allow patching dependency requirements. myproject could patch bar to depend on clumsy =2.0.0 instead of clumsy ^2.0.0.

  3. Another general solution would be support for version substitution when patching the registry. Right now patch.crates-io.clumsy can swap it to a path or git dependency, but it could also support swapping for a different version from the registry.

Notes

Despite being currently affected by the scenario above, I prefer to avoid sharing exact details of the crates involved as general improvements to occasional semver violations feel more important than blaming specific instances which should be fixed eventually anyway. It's not the first time that I encounter a semver violation, nor the last and it would be nice to have an escape hatch. EDIT: The violation that prompted me to fill this issue was fixed through yanking after 3 days.

Also related:

@demurgos demurgos added C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` S-triage Status: This issue is waiting on initial triage. labels May 3, 2024
@epage epage added A-dependency-resolution Area: dependency resolution and the resolver A-patch Area: [patch] table override labels May 3, 2024
@demurgos demurgos changed the title Support workspace crate version denylist / local yanking Support workspace-level crate version denylist / local yanking May 3, 2024
@mladedav
Copy link

mladedav commented May 5, 2024

You currently also have other options:

  • Downgrade the package without manually editing the lock file. You can run `cargo update -p clumsy@2.0.1 --precise 2.0.0 to downgrade
  • Pin the version in your Cargo.toml with something like bar = "=2.0.0". This has the drawback of missing potential upgrades after the broken version, but then again, if the crate broke semver you might want to check the future 2.0.2 manually first and not allow automatic updates. You would have to add the dependency directly in one of your projects though to pin the version.

Are those solutions good enough for you?

@weihanglo
Copy link
Member

Thanks for the report. I love the amount of details you filled in!

I wonder if we could consolidate similar feature requests into one location, so people don't need to jump between issues to get the full picture. Personally I favor #5286 and close this. Does that sound good to you?

@weihanglo weihanglo added S-needs-info Status: Needs more info, such as a reproduction or more background for a feature request. and removed S-triage Status: This issue is waiting on initial triage. labels May 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-dependency-resolution Area: dependency resolution and the resolver A-patch Area: [patch] table override C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` S-needs-info Status: Needs more info, such as a reproduction or more background for a feature request.
Projects
None yet
Development

No branches or pull requests

4 participants