`cargo update -p bar` where `bar` is patched can partially unpatch `bar`
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 15.5k
- Forks
- 3k
- Avg merge
- 23h 30m
- Merged PRs (30d)
- 51
Description
Problem
If there is a [patch] for something at version 0.1.0, and you need to update the [patch] to version 0.1.1, but there is also a 0.1.2 available in the registry, cargo update is too aggressive and will pick 0.1.2. This can lead to a somewhat corrupt state where there are two different semver compatible versions in the lockfile.
See https://github.com/rust-lang/rust/pull/73238#issuecomment-643060741 for a real-life example.
Note: This isn't specific to cargo update. Implicit updates from cargo build also cause this.
Steps
Repro as a cargo test:
#[cargo_test]
fn update_patch_when_newer_available() {
// `cargo update` when there is a patch, and there is a *newer*
// version available on crates.io.
Package::new("bar", "0.1.0").publish();
let p = project()
.file(
"Cargo.toml",
r#"
[workspace]
members = ["foo", "bar"]
[patch.crates-io]
bar = { path = "bar" }
"#,
)
.file(
"foo/Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
bar = "0.1"
"#,
)
.file("foo/src/lib.rs", "")
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "")
.build();
// Establish an initial Cargo.lock.
p.cargo("tree")
.with_stdout(
"\
bar v0.1.0 ([ROOT]/foo/bar)
foo v0.1.0 ([ROOT]/foo/foo)
└── bar v0.1.0 ([ROOT]/foo/bar)
",
)
.run();
Package::new("bar", "0.1.1").publish();
Package::new("bar", "0.1.2").publish();
p.change_file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"));
// Ideally this would just work, and pick 0.1.1 from the workspace.
// Unfortunately it picks 0.1.2.
// p.cargo("update -p bar").run();
// This doesn't work either (it picks 0.1.2).
// p.cargo("update -p bar --precise 0.1.1").run();
// Currently, the only solution is to do:
// cargo update -p bar
// cargo update -p bar:0.1.2 --precise 0.1.1
//
// where the second command downgrades and reverses the damage from the first command.
}
Notes
cargo 1.45.0-nightly (40ebd5220 2020-06-01)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the supplied cargo test case, update_patch_when_newer_available, and inspect how cargo update and implicit cargo build resolution handle the [patch] entry. Done means the patched workspace version 0.1.1 is selected without introducing the newer registry version 0.1.2 or duplicate compatible versions in Cargo.lock.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100