Skip to content

Commit

Permalink
Auto merge of #14250 - linyihai:update-breaking-prerelease, r=weihanglo
Browse files Browse the repository at this point in the history
Don't downgrade on prerelease `VersionReq` when update with --breaking.

### What does this PR try to resolve?
Do nothing with prerelease when update with `--breaking`.

Fixes #14178

### How should we test and review this PR?

Previous commit add a test, next commit to fix and update.

### Additional information
  • Loading branch information
bors committed Jul 24, 2024
2 parents 9bda502 + 9e2701a commit a7917fd
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 3 deletions.
49 changes: 46 additions & 3 deletions src/cargo/util/toml_mut/upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ pub(crate) fn upgrade_requirement(
// Empty matches everything, no-change.
Ok(None)
} else {
let comparators: CargoResult<Vec<_>> = raw_req
let comparators: Vec<_> = raw_req
.comparators
.into_iter()
// Don't downgrade if pre-release was used, see https://github.com/rust-lang/cargo/issues/14178 and https://github.com/rust-lang/cargo/issues/13290.
.filter(|p| p.pre.is_empty() || matches_greater(p, version))
.map(|p| set_comparator(p, version))
.collect();
let comparators = comparators?;
.collect::<CargoResult<_>>()?;
if comparators.is_empty() {
return Ok(None);
}
let new_req = semver::VersionReq { comparators };
let mut new_req_text = new_req.to_string();
if new_req_text.starts_with('^') && !req.starts_with('^') {
Expand Down Expand Up @@ -74,6 +78,33 @@ fn set_comparator(
}
}

// See https://github.com/dtolnay/semver/blob/69efd3cc770ead273a06ad1788477b3092996d29/src/eval.rs#L64-L88
fn matches_greater(cmp: &semver::Comparator, ver: &semver::Version) -> bool {
if ver.major != cmp.major {
return ver.major > cmp.major;
}

match cmp.minor {
None => return false,
Some(minor) => {
if ver.minor != minor {
return ver.minor > minor;
}
}
}

match cmp.patch {
None => return false,
Some(patch) => {
if ver.patch != patch {
return ver.patch > patch;
}
}
}

ver.pre > cmp.pre
}

fn assign_partial_req(
version: &semver::Version,
mut pred: semver::Comparator,
Expand Down Expand Up @@ -217,5 +248,17 @@ mod test {
assert_req_bump("1.1.1", "=1.0.0", "=1.1.1");
assert_req_bump("2.0.0", "=1.0.0", "=2.0.0");
}

#[test]
fn greater_prerelease() {
assert_req_bump("1.7.0", "2.0.0-beta.21", None);
assert_req_bump("1.7.0", "=2.0.0-beta.21", None);
assert_req_bump("1.7.0", "~2.0.0-beta.21", None);
assert_req_bump("2.0.0-beta.20", "2.0.0-beta.21", None);
assert_req_bump("2.0.0-beta.21", "2.0.0-beta.21", None);
assert_req_bump("2.0.0-beta.22", "2.0.0-beta.21", "2.0.0-beta.22");
assert_req_bump("2.0.0", "2.0.0-beta.21", "2.0.0");
assert_req_bump("3.0.0", "2.0.0-beta.21", "3.0.0");
}
}
}
91 changes: 91 additions & 0 deletions tests/testsuite/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2619,3 +2619,94 @@ fn update_breaking_mixed_pinning_renaming() {
"#]],
);
}

#[cargo_test]
fn update_breaking_pre_release_downgrade() {
Package::new("bar", "2.0.0-beta.21").publish();

let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
edition = "2015"
authors = []
[dependencies]
bar = "2.0.0-beta.21"
"#,
)
.file("src/lib.rs", "")
.build();

p.cargo("generate-lockfile").run();

// The purpose of this test is
// to demonstrate that `update --breaking` will not try to downgrade to the latest stable version (1.7.0),
// but will rather keep the latest pre-release (2.0.0-beta.21).
Package::new("bar", "1.7.0").publish();
p.cargo("update -Zunstable-options --breaking bar")
.masquerade_as_nightly_cargo(&["update-breaking"])
.with_stderr_data(str![[r#"
[UPDATING] `dummy-registry` index
"#]])
.run();
}

#[cargo_test]
fn update_breaking_pre_release_upgrade() {
Package::new("bar", "2.0.0-beta.21").publish();

let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
edition = "2015"
authors = []
[dependencies]
bar = "2.0.0-beta.21"
"#,
)
.file("src/lib.rs", "")
.build();

p.cargo("generate-lockfile").run();

// TODO: `2.0.0-beta.21` can be upgraded to `2.0.0-beta.22`
Package::new("bar", "2.0.0-beta.22").publish();
p.cargo("update -Zunstable-options --breaking bar")
.masquerade_as_nightly_cargo(&["update-breaking"])
.with_stderr_data(str![[r#"
[UPDATING] `dummy-registry` index
"#]])
.run();
// TODO: `2.0.0-beta.21` can be upgraded to `2.0.0`
Package::new("bar", "2.0.0").publish();
p.cargo("update -Zunstable-options --breaking bar")
.masquerade_as_nightly_cargo(&["update-breaking"])
.with_stderr_data(str![[r#"
[UPDATING] `dummy-registry` index
"#]])
.run();

Package::new("bar", "3.0.0").publish();
p.cargo("update -Zunstable-options --breaking bar")
.masquerade_as_nightly_cargo(&["update-breaking"])
.with_stderr_data(str![[r#"
[UPDATING] `dummy-registry` index
[UPGRADING] bar ^2.0.0-beta.21 -> ^3.0.0
[LOCKING] 1 package to latest compatible version
[UPDATING] bar v2.0.0-beta.21 -> v3.0.0
"#]])
.run();
}

0 comments on commit a7917fd

Please sign in to comment.