mirror of
https://github.com/rust-lang/cargo
synced 2024-08-28 03:39:31 +00:00
Auto merge of #12796 - dtolnay-contrib:switching, r=epage
Do not call it "Downgrading" when difference is only build metadata ### What does this PR try to resolve? When a `cargo update --precise` changes a dependency between 2 versions which differ only in build metadata, Cargo prints a log referring to it as "Updating" or "Downgrading" the dependency, depending on a comparison between the build metadatas. This is usually not meaningful, given that build metadata is often stuff like git commit hashes, which are not meaningfully ordered. ```console Updating crates.io index Downgrading foo v0.0.1+43ef4fe -> v0.0.1+2c65d16 Updating bar v0.0.2+bc17664 -> v0.0.2+c144a98 ``` ~~This PR changes to the word "Switching" when the version major, minor, patch, and pre-release value are not being changed.~~ This PR uses the word "Updating" when the version major, minor, patch, and pre-release value are unchanged, regardless of whether the build metadata is going up or down. ### How should we test and review this PR? - `cargo test` - `cargo build --release` - `/path/to/cargo/target/release/cargo add tonic_datastore_v1` - `/path/to/cargo/target/release/cargo update -p tonic_datastore_v1 --precise 0.1.0+3562b6cb3` - `/path/to/cargo/target/release/cargo update -p tonic_datastore_v1 --precise 0.1.0+ee9e8e4e6` Before: <img src="https://github.com/rust-lang/cargo/assets/1940490/93e377e7-928e-4cec-aff6-451166ef7c81" width="500"> ~~After:~~ <img src="https://github.com/rust-lang/cargo/assets/1940490/bb71459e-469a-4e09-bb8a-4083f34bce79" width="500"> After: <img src="https://github.com/rust-lang/cargo/assets/1940490/8804e2fe-d0de-4c9e-b463-a5742daf9446" width="500">
This commit is contained in:
commit
90fb62fc65
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -2886,9 +2886,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.19"
|
version = "1.0.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0"
|
checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
|
@ -76,7 +76,7 @@ rand = "0.8.5"
|
||||||
rustfix = "0.6.1"
|
rustfix = "0.6.1"
|
||||||
same-file = "1.0.6"
|
same-file = "1.0.6"
|
||||||
security-framework = "2.9.2"
|
security-framework = "2.9.2"
|
||||||
semver = { version = "1.0.19", features = ["serde"] }
|
semver = { version = "1.0.20", features = ["serde"] }
|
||||||
serde = "1.0.188"
|
serde = "1.0.188"
|
||||||
serde-untagged = "0.1.1"
|
serde-untagged = "0.1.1"
|
||||||
serde-value = "0.7.0"
|
serde-value = "0.7.0"
|
||||||
|
|
|
@ -29,8 +29,7 @@ struct PackageIdInner {
|
||||||
source_id: SourceId,
|
source_id: SourceId,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom equality that uses full equality of SourceId, rather than its custom equality,
|
// Custom equality that uses full equality of SourceId, rather than its custom equality.
|
||||||
// and Version, which usually ignores `build` metadata.
|
|
||||||
//
|
//
|
||||||
// The `build` part of the version is usually ignored (like a "comment").
|
// The `build` part of the version is usually ignored (like a "comment").
|
||||||
// However, there are some cases where it is important. The download path from
|
// However, there are some cases where it is important. The download path from
|
||||||
|
@ -40,11 +39,7 @@ struct PackageIdInner {
|
||||||
impl PartialEq for PackageIdInner {
|
impl PartialEq for PackageIdInner {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.name == other.name
|
self.name == other.name
|
||||||
&& self.version.major == other.version.major
|
&& self.version == other.version
|
||||||
&& self.version.minor == other.version.minor
|
|
||||||
&& self.version.patch == other.version.patch
|
|
||||||
&& self.version.pre == other.version.pre
|
|
||||||
&& self.version.build == other.version.build
|
|
||||||
&& self.source_id.full_eq(other.source_id)
|
&& self.source_id.full_eq(other.source_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,11 +48,7 @@ impl PartialEq for PackageIdInner {
|
||||||
impl Hash for PackageIdInner {
|
impl Hash for PackageIdInner {
|
||||||
fn hash<S: hash::Hasher>(&self, into: &mut S) {
|
fn hash<S: hash::Hasher>(&self, into: &mut S) {
|
||||||
self.name.hash(into);
|
self.name.hash(into);
|
||||||
self.version.major.hash(into);
|
self.version.hash(into);
|
||||||
self.version.minor.hash(into);
|
|
||||||
self.version.patch.hash(into);
|
|
||||||
self.version.pre.hash(into);
|
|
||||||
self.version.build.hash(into);
|
|
||||||
self.source_id.full_hash(into);
|
self.source_id.full_hash(into);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -237,6 +228,16 @@ impl fmt::Debug for PackageId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for PackageIdInner {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
f.debug_struct("PackageIdInner")
|
||||||
|
.field("name", &self.name)
|
||||||
|
.field("version", &self.version.to_string())
|
||||||
|
.field("source", &self.source_id.to_string())
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::PackageId;
|
use super::PackageId;
|
||||||
|
@ -261,4 +262,14 @@ mod tests {
|
||||||
let pkg_id = PackageId::new("foo", "1.0.0", SourceId::for_registry(&loc).unwrap()).unwrap();
|
let pkg_id = PackageId::new("foo", "1.0.0", SourceId::for_registry(&loc).unwrap()).unwrap();
|
||||||
assert_eq!("foo v1.0.0", pkg_id.to_string());
|
assert_eq!("foo v1.0.0", pkg_id.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn unequal_build_metadata() {
|
||||||
|
let loc = CRATES_IO_INDEX.into_url().unwrap();
|
||||||
|
let repo = SourceId::for_registry(&loc).unwrap();
|
||||||
|
let first = PackageId::new("foo", "0.0.1+first", repo).unwrap();
|
||||||
|
let second = PackageId::new("foo", "0.0.1+second", repo).unwrap();
|
||||||
|
assert_ne!(first, second);
|
||||||
|
assert_ne!(first.inner, second.inner);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ use crate::util::config::Config;
|
||||||
use crate::util::style;
|
use crate::util::style;
|
||||||
use crate::util::CargoResult;
|
use crate::util::CargoResult;
|
||||||
use anstyle::Style;
|
use anstyle::Style;
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::collections::{BTreeMap, HashSet};
|
use std::collections::{BTreeMap, HashSet};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
|
@ -152,7 +153,11 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
|
||||||
format!("{} -> v{}", removed[0], added[0].version())
|
format!("{} -> v{}", removed[0], added[0].version())
|
||||||
};
|
};
|
||||||
|
|
||||||
if removed[0].version() > added[0].version() {
|
// If versions differ only in build metadata, we call it an "update"
|
||||||
|
// regardless of whether the build metadata has gone up or down.
|
||||||
|
// This metadata is often stuff like git commit hashes, which are
|
||||||
|
// not meaningfully ordered.
|
||||||
|
if removed[0].version().cmp_precedence(added[0].version()) == Ordering::Greater {
|
||||||
print_change("Downgrading", msg, &style::WARN)?;
|
print_change("Downgrading", msg, &style::WARN)?;
|
||||||
} else {
|
} else {
|
||||||
print_change("Updating", msg, &style::GOOD)?;
|
print_change("Updating", msg, &style::GOOD)?;
|
||||||
|
|
|
@ -98,6 +98,7 @@ use cargo_util::{paths, registry::make_dep_path};
|
||||||
use semver::Version;
|
use semver::Version;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
@ -674,11 +675,8 @@ impl<'cfg> RegistryIndex<'cfg> {
|
||||||
(true, true) => s_vers == requested,
|
(true, true) => s_vers == requested,
|
||||||
(true, false) => false,
|
(true, false) => false,
|
||||||
(false, true) => {
|
(false, true) => {
|
||||||
// Strip out the metadata.
|
// Compare disregarding the metadata.
|
||||||
s_vers.major == requested.major
|
s_vers.cmp_precedence(requested) == Ordering::Equal
|
||||||
&& s_vers.minor == requested.minor
|
|
||||||
&& s_vers.patch == requested.patch
|
|
||||||
&& s_vers.pre == requested.pre
|
|
||||||
}
|
}
|
||||||
(false, false) => s_vers == requested,
|
(false, false) => s_vers == requested,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use semver::{Comparator, Op, Version, VersionReq};
|
use semver::{Comparator, Op, Version, VersionReq};
|
||||||
use serde_untagged::UntaggedEnumVisitor;
|
use serde_untagged::UntaggedEnumVisitor;
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
|
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
|
||||||
|
@ -83,12 +84,7 @@ impl OptVersionReq {
|
||||||
match self {
|
match self {
|
||||||
OptVersionReq::Any => true,
|
OptVersionReq::Any => true,
|
||||||
OptVersionReq::Req(req) => req.matches(version),
|
OptVersionReq::Req(req) => req.matches(version),
|
||||||
OptVersionReq::Locked(v, _) => {
|
OptVersionReq::Locked(v, _) => v.cmp_precedence(version) == Ordering::Equal,
|
||||||
v.major == version.major
|
|
||||||
&& v.minor == version.minor
|
|
||||||
&& v.patch == version.patch
|
|
||||||
&& v.pre == version.pre
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -391,6 +391,50 @@ fn update_precise() {
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cargo_test]
|
||||||
|
fn update_precise_build_metadata() {
|
||||||
|
Package::new("serde", "0.0.1+first").publish();
|
||||||
|
Package::new("serde", "0.0.1+second").publish();
|
||||||
|
|
||||||
|
let p = project()
|
||||||
|
.file(
|
||||||
|
"Cargo.toml",
|
||||||
|
r#"
|
||||||
|
[package]
|
||||||
|
name = "foo"
|
||||||
|
version = "0.0.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = "0.0.1"
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file("src/lib.rs", "")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
p.cargo("generate-lockfile").run();
|
||||||
|
p.cargo("update serde --precise 0.0.1+first").run();
|
||||||
|
|
||||||
|
p.cargo("update serde --precise 0.0.1+second")
|
||||||
|
.with_stderr(
|
||||||
|
"\
|
||||||
|
[UPDATING] `[..]` index
|
||||||
|
[UPDATING] serde v0.0.1+first -> v0.0.1+second
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.run();
|
||||||
|
|
||||||
|
// This is not considered "Downgrading". Build metadata are not assumed to
|
||||||
|
// be ordered.
|
||||||
|
p.cargo("update serde --precise 0.0.1+first")
|
||||||
|
.with_stderr(
|
||||||
|
"\
|
||||||
|
[UPDATING] `[..]` index
|
||||||
|
[UPDATING] serde v0.0.1+second -> v0.0.1+first
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
#[cargo_test]
|
#[cargo_test]
|
||||||
fn update_precise_do_not_force_update_deps() {
|
fn update_precise_do_not_force_update_deps() {
|
||||||
Package::new("log", "0.1.0").publish();
|
Package::new("log", "0.1.0").publish();
|
||||||
|
|
Loading…
Reference in a new issue