Skip to content

Commit f797978

Browse files
committed
Auto merge of #12553 - epage:version, r=weihanglo
refactor: Pull out cargo-add MSRV code for reuse ### What does this PR try to resolve? #12078 added MSRV code in `cargo add`. Our assumption when writing it is that we'd need to generalize the code before reusing it in other places, like `cargo install`. This PR focused purely on that refactor because I'm hopeful it will be useful for other work I'm doing. Despite not having a user for this yet, I think the `cargo install` case is inevitable and I feel this does a bit to clean up MSRV related code by using a more specific type everywhere. ### How should we test and review this PR? Each commit gradually progresses things along
2 parents e3b3ed8 + 1701b4e commit f797978

File tree

14 files changed

+228
-58
lines changed

14 files changed

+228
-58
lines changed

crates/resolver-tests/src/lib.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use cargo::core::resolver::{self, ResolveOpts, VersionPreferences};
1515
use cargo::core::source::{GitReference, QueryKind, SourceId};
1616
use cargo::core::Resolve;
1717
use cargo::core::{Dependency, PackageId, Registry, Summary};
18-
use cargo::util::{CargoResult, Config, Graph, IntoUrl};
18+
use cargo::util::{CargoResult, Config, Graph, IntoUrl, PartialVersion};
1919

2020
use proptest::collection::{btree_map, vec};
2121
use proptest::prelude::*;
@@ -183,7 +183,7 @@ pub fn resolve_with_config_raw(
183183
deps,
184184
&BTreeMap::new(),
185185
None::<&String>,
186-
None::<&String>,
186+
None::<PartialVersion>,
187187
)
188188
.unwrap();
189189
let opts = ResolveOpts::everything();
@@ -584,7 +584,7 @@ pub fn pkg_dep<T: ToPkgId>(name: T, dep: Vec<Dependency>) -> Summary {
584584
dep,
585585
&BTreeMap::new(),
586586
link,
587-
None::<&String>,
587+
None::<PartialVersion>,
588588
)
589589
.unwrap()
590590
}
@@ -612,7 +612,7 @@ pub fn pkg_loc(name: &str, loc: &str) -> Summary {
612612
Vec::new(),
613613
&BTreeMap::new(),
614614
link,
615-
None::<&String>,
615+
None::<PartialVersion>,
616616
)
617617
.unwrap()
618618
}
@@ -626,7 +626,7 @@ pub fn remove_dep(sum: &Summary, ind: usize) -> Summary {
626626
deps,
627627
&BTreeMap::new(),
628628
sum.links().map(|a| a.as_str()),
629-
None::<&String>,
629+
None::<PartialVersion>,
630630
)
631631
.unwrap()
632632
}

src/cargo/core/compiler/compilation.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ impl<'cfg> Compilation<'cfg> {
312312
// crate properties which might require rebuild upon change
313313
// consider adding the corresponding properties to the hash
314314
// in BuildContext::target_metadata()
315+
let rust_version = pkg.rust_version().as_ref().map(ToString::to_string);
315316
cmd.env("CARGO_MANIFEST_DIR", pkg.root())
316317
.env("CARGO_PKG_VERSION_MAJOR", &pkg.version().major.to_string())
317318
.env("CARGO_PKG_VERSION_MINOR", &pkg.version().minor.to_string())
@@ -342,7 +343,7 @@ impl<'cfg> Compilation<'cfg> {
342343
.env("CARGO_PKG_AUTHORS", &pkg.authors().join(":"))
343344
.env(
344345
"CARGO_PKG_RUST_VERSION",
345-
&pkg.rust_version().unwrap_or(&String::new()),
346+
&rust_version.as_deref().unwrap_or_default(),
346347
)
347348
.env(
348349
"CARGO_PKG_README",

src/cargo/core/manifest.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::core::{Edition, Feature, Features, WorkspaceConfig};
1919
use crate::util::errors::*;
2020
use crate::util::interning::InternedString;
2121
use crate::util::toml::{TomlManifest, TomlProfiles};
22-
use crate::util::{short_hash, Config, Filesystem};
22+
use crate::util::{short_hash, Config, Filesystem, PartialVersion};
2323

2424
pub enum EitherManifest {
2525
Real(Manifest),
@@ -58,7 +58,7 @@ pub struct Manifest {
5858
original: Rc<TomlManifest>,
5959
unstable_features: Features,
6060
edition: Edition,
61-
rust_version: Option<String>,
61+
rust_version: Option<PartialVersion>,
6262
im_a_teapot: Option<bool>,
6363
default_run: Option<String>,
6464
metabuild: Option<Vec<String>>,
@@ -112,7 +112,7 @@ pub struct ManifestMetadata {
112112
pub documentation: Option<String>, // URL
113113
pub badges: BTreeMap<String, BTreeMap<String, String>>,
114114
pub links: Option<String>,
115-
pub rust_version: Option<String>,
115+
pub rust_version: Option<PartialVersion>,
116116
}
117117

118118
#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
@@ -401,7 +401,7 @@ impl Manifest {
401401
workspace: WorkspaceConfig,
402402
unstable_features: Features,
403403
edition: Edition,
404-
rust_version: Option<String>,
404+
rust_version: Option<PartialVersion>,
405405
im_a_teapot: Option<bool>,
406406
default_run: Option<String>,
407407
original: Rc<TomlManifest>,
@@ -570,8 +570,8 @@ impl Manifest {
570570
self.edition
571571
}
572572

573-
pub fn rust_version(&self) -> Option<&str> {
574-
self.rust_version.as_deref()
573+
pub fn rust_version(&self) -> Option<PartialVersion> {
574+
self.rust_version
575575
}
576576

577577
pub fn custom_metadata(&self) -> Option<&toml::Value> {

src/cargo/core/package.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use crate::util::network::http::http_handle_and_timeout;
3131
use crate::util::network::http::HttpTimeout;
3232
use crate::util::network::retry::{Retry, RetryResult};
3333
use crate::util::network::sleep::SleepTracker;
34+
use crate::util::PartialVersion;
3435
use crate::util::{self, internal, Config, Progress, ProgressStyle};
3536

3637
pub const MANIFEST_PREAMBLE: &str = "\
@@ -103,7 +104,7 @@ pub struct SerializedPackage {
103104
#[serde(skip_serializing_if = "Option::is_none")]
104105
metabuild: Option<Vec<String>>,
105106
default_run: Option<String>,
106-
rust_version: Option<String>,
107+
rust_version: Option<PartialVersion>,
107108
}
108109

109110
impl Package {
@@ -177,7 +178,7 @@ impl Package {
177178
self.targets().iter().any(|target| target.proc_macro())
178179
}
179180
/// Gets the package's minimum Rust version.
180-
pub fn rust_version(&self) -> Option<&str> {
181+
pub fn rust_version(&self) -> Option<PartialVersion> {
181182
self.manifest().rust_version()
182183
}
183184

@@ -262,7 +263,7 @@ impl Package {
262263
metabuild: self.manifest().metabuild().cloned(),
263264
publish: self.publish().as_ref().cloned(),
264265
default_run: self.manifest().default_run().map(|s| s.to_owned()),
265-
rust_version: self.rust_version().map(|s| s.to_owned()),
266+
rust_version: self.rust_version(),
266267
}
267268
}
268269
}

src/cargo/core/resolver/version_prefs.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ impl VersionPreferences {
8181
mod test {
8282
use super::*;
8383
use crate::core::SourceId;
84+
use crate::util::PartialVersion;
8485
use std::collections::BTreeMap;
8586

8687
fn pkgid(name: &str, version: &str) -> PackageId {
@@ -103,7 +104,7 @@ mod test {
103104
Vec::new(),
104105
&features,
105106
None::<&String>,
106-
None::<&String>,
107+
None::<PartialVersion>,
107108
)
108109
.unwrap()
109110
}

src/cargo/core/summary.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::core::{Dependency, PackageId, SourceId};
22
use crate::util::interning::InternedString;
33
use crate::util::CargoResult;
4+
use crate::util::PartialVersion;
45
use anyhow::bail;
56
use semver::Version;
67
use std::collections::{BTreeMap, HashMap, HashSet};
@@ -25,7 +26,7 @@ struct Inner {
2526
features: Rc<FeatureMap>,
2627
checksum: Option<String>,
2728
links: Option<InternedString>,
28-
rust_version: Option<InternedString>,
29+
rust_version: Option<PartialVersion>,
2930
}
3031

3132
impl Summary {
@@ -34,7 +35,7 @@ impl Summary {
3435
dependencies: Vec<Dependency>,
3536
features: &BTreeMap<InternedString, Vec<InternedString>>,
3637
links: Option<impl Into<InternedString>>,
37-
rust_version: Option<impl Into<InternedString>>,
38+
rust_version: Option<PartialVersion>,
3839
) -> CargoResult<Summary> {
3940
// ****CAUTION**** If you change anything here that may raise a new
4041
// error, be sure to coordinate that change with either the index
@@ -56,7 +57,7 @@ impl Summary {
5657
features: Rc::new(feature_map),
5758
checksum: None,
5859
links: links.map(|l| l.into()),
59-
rust_version: rust_version.map(|l| l.into()),
60+
rust_version,
6061
}),
6162
})
6263
}
@@ -87,7 +88,7 @@ impl Summary {
8788
self.inner.links
8889
}
8990

90-
pub fn rust_version(&self) -> Option<InternedString> {
91+
pub fn rust_version(&self) -> Option<PartialVersion> {
9192
self.inner.rust_version
9293
}
9394

src/cargo/ops/cargo_add/mod.rs

+3-11
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use crate::util::toml_mut::dependency::Source;
3434
use crate::util::toml_mut::dependency::WorkspaceSource;
3535
use crate::util::toml_mut::manifest::DepTable;
3636
use crate::util::toml_mut::manifest::LocalManifest;
37+
use crate::util::PartialVersion;
3738
use crate::CargoResult;
3839
use crate::Config;
3940
use crate_spec::CrateSpec;
@@ -567,16 +568,7 @@ fn get_latest_dependency(
567568
})?;
568569

569570
if config.cli_unstable().msrv_policy && honor_rust_version {
570-
fn parse_msrv(rust_version: impl AsRef<str>) -> (u64, u64, u64) {
571-
// HACK: `rust-version` is a subset of the `VersionReq` syntax that only ever
572-
// has one comparator with a required minor and optional patch, and uses no
573-
// other features. If in the future this syntax is expanded, this code will need
574-
// to be updated.
575-
let version_req = semver::VersionReq::parse(rust_version.as_ref()).unwrap();
576-
assert!(version_req.comparators.len() == 1);
577-
let comp = &version_req.comparators[0];
578-
assert_eq!(comp.op, semver::Op::Caret);
579-
assert_eq!(comp.pre, semver::Prerelease::EMPTY);
571+
fn parse_msrv(comp: PartialVersion) -> (u64, u64, u64) {
580572
(comp.major, comp.minor.unwrap_or(0), comp.patch.unwrap_or(0))
581573
}
582574

@@ -636,7 +628,7 @@ fn get_latest_dependency(
636628

637629
fn rust_version_incompat_error(
638630
dep: &str,
639-
rust_version: &str,
631+
rust_version: PartialVersion,
640632
lowest_rust_version: Option<&Summary>,
641633
) -> anyhow::Error {
642634
let mut error_msg = format!(

src/cargo/ops/cargo_compile/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ pub fn create_bcx<'a, 'cfg>(
492492
None => continue,
493493
};
494494

495-
let req = semver::VersionReq::parse(version).unwrap();
495+
let req = version.caret_req();
496496
if req.matches(&untagged_version) {
497497
continue;
498498
}

src/cargo/ops/registry/publish.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@ fn transmit(
383383
ref links,
384384
ref rust_version,
385385
} = *manifest.metadata();
386+
let rust_version = rust_version.as_ref().map(ToString::to_string);
386387
let readme_content = readme
387388
.as_ref()
388389
.map(|readme| {
@@ -435,7 +436,7 @@ fn transmit(
435436
license_file: license_file.clone(),
436437
badges: badges.clone(),
437438
links: links.clone(),
438-
rust_version: rust_version.clone(),
439+
rust_version,
439440
},
440441
tarball,
441442
)

src/cargo/sources/registry/index.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ use crate::core::{PackageId, SourceId, Summary};
9191
use crate::sources::registry::{LoadResponse, RegistryData};
9292
use crate::util::interning::InternedString;
9393
use crate::util::IntoUrl;
94-
use crate::util::{internal, CargoResult, Config, Filesystem, OptVersionReq, ToSemver};
94+
use crate::util::{
95+
internal, CargoResult, Config, Filesystem, OptVersionReq, PartialVersion, ToSemver,
96+
};
9597
use anyhow::bail;
9698
use cargo_util::{paths, registry::make_dep_path};
9799
use semver::Version;
@@ -305,7 +307,7 @@ pub struct IndexPackage<'a> {
305307
///
306308
/// Added in 2023 (see <https://github.com/rust-lang/crates.io/pull/6267>),
307309
/// can be `None` if published before then or if not set in the manifest.
308-
rust_version: Option<InternedString>,
310+
rust_version: Option<PartialVersion>,
309311
/// The schema version for this entry.
310312
///
311313
/// If this is None, it defaults to version `1`. Entries with unknown

src/cargo/util/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub use self::progress::{Progress, ProgressStyle};
2222
pub use self::queue::Queue;
2323
pub use self::restricted_names::validate_package_name;
2424
pub use self::rustc::Rustc;
25-
pub use self::semver_ext::{OptVersionReq, VersionExt, VersionReqExt};
25+
pub use self::semver_ext::{OptVersionReq, PartialVersion, VersionExt, VersionReqExt};
2626
pub use self::to_semver::ToSemver;
2727
pub use self::vcs::{existing_vcs_repo, FossilRepo, GitRepo, HgRepo, PijulRepo};
2828
pub use self::workspace::{

0 commit comments

Comments
 (0)