-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
If there's a version in the lock file only use that exact version #12772
Conversation
r? @epage (rustbot has picked a reviewer for you, use r? to override) |
src/cargo/sources/registry/index.rs
Outdated
@@ -437,11 +437,13 @@ impl<'cfg> RegistryIndex<'cfg> { | |||
/// checking the integrity of a downloaded package matching the checksum in | |||
/// the index file, aka [`IndexSummary`]. | |||
pub fn hash(&mut self, pkg: PackageId, load: &mut dyn RegistryData) -> Poll<CargoResult<&str>> { | |||
let req = OptVersionReq::exact(pkg.version()); | |||
let mut req = OptVersionReq::exact(pkg.version()); | |||
// Since crates.io allows crate versions to differ only by build metadata, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because of rust-lang/crates.io#6518, should we change this to "Since some registries may allow"?
Or should we go a step further and make this a requirement on all registries? If not, should we at least document it as a best practice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am open to wordsmithing the comment.
I'm pretty sure we already documented it. If not we should.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In light of everything, maybe this should be "Since some registries may incorrectly allow ..."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(plus the other comment)
src/cargo/sources/registry/index.rs
Outdated
let mut req = OptVersionReq::exact(pkg.version()); | ||
|
||
// Since crates.io allows crate versions to differ only by build metadata, | ||
// a query using OptVersionReq::exact + next() can return nondeterministic results. | ||
// So we `lock_to` the exact version were interested in | ||
req.lock_to(pkg.version()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: exact
+ lock_to
seems like a weird dance. Should we have a new constructor for this purpose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Sounds good.
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn locked_has_the_same_with_exact() { | ||
fn test_versions(target_ver: &str, vers: &[&str]) { | ||
let ver = Version::parse(target_ver).unwrap(); | ||
let exact = OptVersionReq::exact(&ver); | ||
let mut locked = exact.clone(); | ||
locked.lock_to(&ver); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we keep this test but change it so it requires metadata to be the same?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that's testing an implementation detail. If we want to add a test for this, we could extend the test added in #11447, to ensure that if we have a lock file we get the version specified in the lock file. I may give that a try.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have expanded the test to make sure that the version from a lock file is used even if there other versions available from the registry. Confusingly, it passes on head. I am trying to determine what's going on.
While attempting to implement the requested test I discovered that this PR does not change behavior. We apparently already had code that ensured that if a lock file was insufficient to uniquely identify a solution the resolver would prefer versions from the lockfile. Here. With that in place, a lock file containing semver build metadata will be respected through a somewhat circuitous route.
So we seem to have redundant mechanisms to ensure lock files are respected. Specifically, we have a mechanism that tell the resolver to prefer the versions from lock file AND we have a mechanism that locks dependencies to the version from lock file. The former is more elegant and simpler, but is not (yet?) capable of enforcing In the meantime this PR makes the implementation of "locking a dependency to a version" actually match its description, while not changing any user facing behavior. |
2961584
to
48c6775
Compare
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
fix(replace): Partial-version spec support ### What does this PR try to resolve? #12614 changed package ID specs to allow fields in the version number to be optional. This earliest branch with this change is `rust-1.74.0` (beta). While `@Eh2406` was investigating version metadata issues in #12772, problems with the partial version change were found - `replace`s that specify version metadata were ignored **(fixed with this PR)** - This also extends out to any other place a PackageIDSpec may show up, like `cargo check -p <name>`@<spec>`` - We explicitly kept the same semantics of version requirements that pre-releases require opt-in. If nothing else, this gives us more room to change semantics in the future if we ever fix the semantics for pre-release. - `replace`s that don't specify version metadata when the `Cargo.lock` contained a version metadata, it would previously be ignored (with a warning) but now match **(unchanged with this PR)** - When the version metadata in `Cargo.lock` differed from the overriding `Cargo.toml`, cargo would panic **(now an error in this PR)** With this PR, we are acknowledging that we changed behavior in taking ignored replaces (because of differences with version metadata) and applying them. Seeing as version metadata is relatively rare, replaces are relatively rare, and differences in it for registries is unsupported, the impact seems very small. The questions before us are - Do we revert #12614 in `master` and `rust-1.74.0` or merge this PR into `master` - If we merge this PR into `master`, do we cherry-pick this into `rust-1.74.0` or revert #12614, giving ourselves more time to find problems ### How should we test and review this PR? The initial commit adds tests that pass as of #12614. Prior to #12614, these tests would have warned that the `replace` was unused and failed because `bar::bar` didn't exist. Each commit then changes the behavior (or not) and updates the corresponding test. ### Additional information
I think the core of the problem is that rust-lang@725420e was a mistake. Before that PR we used `=` constraints to imply that it came from lock file so when we saw a `=` constraints being constructed for a replace it should use the new system for marking something as coming from lock file. But I don't think that is the semantics that an `=` constraint implies in this context.
48c6775
to
98766fb
Compare
This is unblocked, rebased, and ready for review. I dealt with the issue of the new "locked means locked" semantics are not the ones we want for "replace" by not "locking" the replace dependencies. The plane |
@bors r+ |
☀️ Test successful - checks-actions |
Update cargo 22 commits in 8eb8acbb116e7923ea2ce33a50109933ed5ab375..d2f6a048529eb8e9ebc55d793abd63456c98fac2 2023-10-17 11:55:04 +0000 to 2023-10-20 18:25:30 +0000 - chore(deps): bump rustix from 0.38.18 to 0.38.19 (rust-lang/cargo#12851) - refactor: centralize logic of getting max resolve version (rust-lang/cargo#12860) - If there's a version in the lock file only use that exact version (rust-lang/cargo#12772) - Make the precise field of a source an Enum (rust-lang/cargo#12849) - fix(cli): Provide next steps for bad -Z flag (rust-lang/cargo#12857) - fix(remove): Preserve feature comments (rust-lang/cargo#12837) - docs: fix typo (rust-lang/cargo#12844) - chore(triagebot): auto label when PR review state changes (rust-lang/cargo#12856) - fix(add): Preserve more comments (rust-lang/cargo#12838) - ci: big⚠️ to ensure the CNAME file is always there (rust-lang/cargo#12853) - docs(cargo-bench): `--bench` is passed in unconditionally to bench harnesses (rust-lang/cargo#12850) - docs(contrib): generate redirection HTML pages in CI (rust-lang/cargo#12846) - docs: remove review capacity notice (rust-lang/cargo#12842) - fix(help):Clarify install's positional (rust-lang/cargo#12841) - Adjust `-Zcheck-cfg` for new rustc syntax and behavior (rust-lang/cargo#12845) - fix(replace): Partial-version spec support (rust-lang/cargo#12806) - Print environment variables for build script executions with `-vv` (rust-lang/cargo#12829) - fix(cli): Suggest cargo-search on bad commands (rust-lang/cargo#12840) - docs(contrib): Policy on manifest editing (rust-lang/cargo#12836) - ci/contrib: use separate concurrency group (rust-lang/cargo#12835) - ci/contrib: do not fail on missing gh-pages (rust-lang/cargo#12834) - Clarify flag behavior in `cargo remove --help` (rust-lang/cargo#12823) r? ghost
Update cargo 22 commits in 8eb8acbb116e7923ea2ce33a50109933ed5ab375..d2f6a048529eb8e9ebc55d793abd63456c98fac2 2023-10-17 11:55:04 +0000 to 2023-10-20 18:25:30 +0000 - chore(deps): bump rustix from 0.38.18 to 0.38.19 (rust-lang/cargo#12851) - refactor: centralize logic of getting max resolve version (rust-lang/cargo#12860) - If there's a version in the lock file only use that exact version (rust-lang/cargo#12772) - Make the precise field of a source an Enum (rust-lang/cargo#12849) - fix(cli): Provide next steps for bad -Z flag (rust-lang/cargo#12857) - fix(remove): Preserve feature comments (rust-lang/cargo#12837) - docs: fix typo (rust-lang/cargo#12844) - chore(triagebot): auto label when PR review state changes (rust-lang/cargo#12856) - fix(add): Preserve more comments (rust-lang/cargo#12838) - ci: big⚠️ to ensure the CNAME file is always there (rust-lang/cargo#12853) - docs(cargo-bench): `--bench` is passed in unconditionally to bench harnesses (rust-lang/cargo#12850) - docs(contrib): generate redirection HTML pages in CI (rust-lang/cargo#12846) - docs: remove review capacity notice (rust-lang/cargo#12842) - fix(help):Clarify install's positional (rust-lang/cargo#12841) - Adjust `-Zcheck-cfg` for new rustc syntax and behavior (rust-lang/cargo#12845) - fix(replace): Partial-version spec support (rust-lang/cargo#12806) - Print environment variables for build script executions with `-vv` (rust-lang/cargo#12829) - fix(cli): Suggest cargo-search on bad commands (rust-lang/cargo#12840) - docs(contrib): Policy on manifest editing (rust-lang/cargo#12836) - ci/contrib: use separate concurrency group (rust-lang/cargo#12835) - ci/contrib: do not fail on missing gh-pages (rust-lang/cargo#12834) - Clarify flag behavior in `cargo remove --help` (rust-lang/cargo#12823) r? ghost
Update cargo 22 commits in 8eb8acbb116e7923ea2ce33a50109933ed5ab375..d2f6a048529eb8e9ebc55d793abd63456c98fac2 2023-10-17 11:55:04 +0000 to 2023-10-20 18:25:30 +0000 - chore(deps): bump rustix from 0.38.18 to 0.38.19 (rust-lang/cargo#12851) - refactor: centralize logic of getting max resolve version (rust-lang/cargo#12860) - If there's a version in the lock file only use that exact version (rust-lang/cargo#12772) - Make the precise field of a source an Enum (rust-lang/cargo#12849) - fix(cli): Provide next steps for bad -Z flag (rust-lang/cargo#12857) - fix(remove): Preserve feature comments (rust-lang/cargo#12837) - docs: fix typo (rust-lang/cargo#12844) - chore(triagebot): auto label when PR review state changes (rust-lang/cargo#12856) - fix(add): Preserve more comments (rust-lang/cargo#12838) - ci: big⚠️ to ensure the CNAME file is always there (rust-lang/cargo#12853) - docs(cargo-bench): `--bench` is passed in unconditionally to bench harnesses (rust-lang/cargo#12850) - docs(contrib): generate redirection HTML pages in CI (rust-lang/cargo#12846) - docs: remove review capacity notice (rust-lang/cargo#12842) - fix(help):Clarify install's positional (rust-lang/cargo#12841) - Adjust `-Zcheck-cfg` for new rustc syntax and behavior (rust-lang/cargo#12845) - fix(replace): Partial-version spec support (rust-lang/cargo#12806) - Print environment variables for build script executions with `-vv` (rust-lang/cargo#12829) - fix(cli): Suggest cargo-search on bad commands (rust-lang/cargo#12840) - docs(contrib): Policy on manifest editing (rust-lang/cargo#12836) - ci/contrib: use separate concurrency group (rust-lang/cargo#12835) - ci/contrib: do not fail on missing gh-pages (rust-lang/cargo#12834) - Clarify flag behavior in `cargo remove --help` (rust-lang/cargo#12823) r? ghost
Update cargo 22 commits in 8eb8acbb116e7923ea2ce33a50109933ed5ab375..d2f6a048529eb8e9ebc55d793abd63456c98fac2 2023-10-17 11:55:04 +0000 to 2023-10-20 18:25:30 +0000 - chore(deps): bump rustix from 0.38.18 to 0.38.19 (rust-lang/cargo#12851) - refactor: centralize logic of getting max resolve version (rust-lang/cargo#12860) - If there's a version in the lock file only use that exact version (rust-lang/cargo#12772) - Make the precise field of a source an Enum (rust-lang/cargo#12849) - fix(cli): Provide next steps for bad -Z flag (rust-lang/cargo#12857) - fix(remove): Preserve feature comments (rust-lang/cargo#12837) - docs: fix typo (rust-lang/cargo#12844) - chore(triagebot): auto label when PR review state changes (rust-lang/cargo#12856) - fix(add): Preserve more comments (rust-lang/cargo#12838) - ci: big⚠️ to ensure the CNAME file is always there (rust-lang/cargo#12853) - docs(cargo-bench): `--bench` is passed in unconditionally to bench harnesses (rust-lang/cargo#12850) - docs(contrib): generate redirection HTML pages in CI (rust-lang/cargo#12846) - docs: remove review capacity notice (rust-lang/cargo#12842) - fix(help):Clarify install's positional (rust-lang/cargo#12841) - Adjust `-Zcheck-cfg` for new rustc syntax and behavior (rust-lang/cargo#12845) - fix(replace): Partial-version spec support (rust-lang/cargo#12806) - Print environment variables for build script executions with `-vv` (rust-lang/cargo#12829) - fix(cli): Suggest cargo-search on bad commands (rust-lang/cargo#12840) - docs(contrib): Policy on manifest editing (rust-lang/cargo#12836) - ci/contrib: use separate concurrency group (rust-lang/cargo#12835) - ci/contrib: do not fail on missing gh-pages (rust-lang/cargo#12834) - Clarify flag behavior in `cargo remove --help` (rust-lang/cargo#12823) r? ghost
Update cargo 22 commits in 8eb8acbb116e7923ea2ce33a50109933ed5ab375..d2f6a048529eb8e9ebc55d793abd63456c98fac2 2023-10-17 11:55:04 +0000 to 2023-10-20 18:25:30 +0000 - chore(deps): bump rustix from 0.38.18 to 0.38.19 (rust-lang/cargo#12851) - refactor: centralize logic of getting max resolve version (rust-lang/cargo#12860) - If there's a version in the lock file only use that exact version (rust-lang/cargo#12772) - Make the precise field of a source an Enum (rust-lang/cargo#12849) - fix(cli): Provide next steps for bad -Z flag (rust-lang/cargo#12857) - fix(remove): Preserve feature comments (rust-lang/cargo#12837) - docs: fix typo (rust-lang/cargo#12844) - chore(triagebot): auto label when PR review state changes (rust-lang/cargo#12856) - fix(add): Preserve more comments (rust-lang/cargo#12838) - ci: big⚠️ to ensure the CNAME file is always there (rust-lang/cargo#12853) - docs(cargo-bench): `--bench` is passed in unconditionally to bench harnesses (rust-lang/cargo#12850) - docs(contrib): generate redirection HTML pages in CI (rust-lang/cargo#12846) - docs: remove review capacity notice (rust-lang/cargo#12842) - fix(help):Clarify install's positional (rust-lang/cargo#12841) - Adjust `-Zcheck-cfg` for new rustc syntax and behavior (rust-lang/cargo#12845) - fix(replace): Partial-version spec support (rust-lang/cargo#12806) - Print environment variables for build script executions with `-vv` (rust-lang/cargo#12829) - fix(cli): Suggest cargo-search on bad commands (rust-lang/cargo#12840) - docs(contrib): Policy on manifest editing (rust-lang/cargo#12836) - ci/contrib: use separate concurrency group (rust-lang/cargo#12835) - ci/contrib: do not fail on missing gh-pages (rust-lang/cargo#12834) - Clarify flag behavior in `cargo remove --help` (rust-lang/cargo#12823) r? ghost
Update cargo 22 commits in 8eb8acbb116e7923ea2ce33a50109933ed5ab375..d2f6a048529eb8e9ebc55d793abd63456c98fac2 2023-10-17 11:55:04 +0000 to 2023-10-20 18:25:30 +0000 - chore(deps): bump rustix from 0.38.18 to 0.38.19 (rust-lang/cargo#12851) - refactor: centralize logic of getting max resolve version (rust-lang/cargo#12860) - If there's a version in the lock file only use that exact version (rust-lang/cargo#12772) - Make the precise field of a source an Enum (rust-lang/cargo#12849) - fix(cli): Provide next steps for bad -Z flag (rust-lang/cargo#12857) - fix(remove): Preserve feature comments (rust-lang/cargo#12837) - docs: fix typo (rust-lang/cargo#12844) - chore(triagebot): auto label when PR review state changes (rust-lang/cargo#12856) - fix(add): Preserve more comments (rust-lang/cargo#12838) - ci: big⚠️ to ensure the CNAME file is always there (rust-lang/cargo#12853) - docs(cargo-bench): `--bench` is passed in unconditionally to bench harnesses (rust-lang/cargo#12850) - docs(contrib): generate redirection HTML pages in CI (rust-lang/cargo#12846) - docs: remove review capacity notice (rust-lang/cargo#12842) - fix(help):Clarify install's positional (rust-lang/cargo#12841) - Adjust `-Zcheck-cfg` for new rustc syntax and behavior (rust-lang/cargo#12845) - fix(replace): Partial-version spec support (rust-lang/cargo#12806) - Print environment variables for build script executions with `-vv` (rust-lang/cargo#12829) - fix(cli): Suggest cargo-search on bad commands (rust-lang/cargo#12840) - docs(contrib): Policy on manifest editing (rust-lang/cargo#12836) - ci/contrib: use separate concurrency group (rust-lang/cargo#12835) - ci/contrib: do not fail on missing gh-pages (rust-lang/cargo#12834) - Clarify flag behavior in `cargo remove --help` (rust-lang/cargo#12823) r? ghost
What does this PR try to resolve?
Generally, cargo is of the opinion that semver metadata should be ignored.
It's is relevant to dependency resolution as any other description of the version, just like the description field in cargo.toml.
If your registry has two versions that only differing metadata you get the bugs you deserve.
We implement functionality to make it easier for our users or for us to maintain.
So let's use==
because it's less code to write and test.We also believe that lock files should ensure reproducibility
and protect against mutations from the registry.
In this circumstance these two goals are in conflict, and this PR picks reproducibility.
If the lock file tells us that there is a version called
1.0.0+bar
thenwe should not silently use
1.0.0+foo
even though they have the same version.This is one of the alternatives/follow-ups discussed in #11447.
It was separated from #12749, to allow for separate discussion and because I was being too clever by half.
How should we test and review this PR?
All tests still pass except for the ones that were removed. The removed tests were only added to verify the on intuitive behavior of the older implementation in #9847.