Skip to content

Commit

Permalink
Auto merge of #9508 - dtolnay-contrib:semver, r=ehuss
Browse files Browse the repository at this point in the history
Update to semver 1.0.0

I am working on a 1.0.0 of the `semver` crate some time this week. It would be good to confirm Cargo will be able to use it, beforehand!

It's a from-scratch rewrite, but dtolnay/semver#237 has code to compare against 0.10.0 (currently used by Cargo) how every possible version requirement currently published to crates.io matches against every possible crate version. The differences are all broken syntax like `^0-.11.0` previously parsing with ".11.0" as a pre-release string (which is invalid, because pre-release are not allowed to contain empty dot-separated identifiers) and `~2.0-2.2` previously parsing with "2.2" as a pre-release string, when the user almost certainly meant `>=2.0, <=2.2`. I'm not sure how much of those you want to add code into Cargo to preserve behavior, but I would be happy to do it.
  • Loading branch information
bors committed May 27, 2021
2 parents cc75485 + 7ace447 commit 2f3df16
Show file tree
Hide file tree
Showing 18 changed files with 148 additions and 255 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ num_cpus = "1.0"
opener = "0.4"
percent-encoding = "2.0"
rustfix = "0.5.0"
semver = { version = "0.10", features = ["serde"] }
semver = { version = "1.0", features = ["serde"] }
serde = { version = "1.0.123", features = ["derive"] }
serde_ignored = "0.1.0"
serde_json = { version = "1.0.30", features = ["raw_value"] }
Expand Down
6 changes: 3 additions & 3 deletions crates/resolver-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ pub trait ToDep {

impl ToDep for &'static str {
fn to_dep(self) -> Dependency {
Dependency::parse_no_deprecated(self, Some("1.0.0"), registry_loc()).unwrap()
Dependency::parse(self, Some("1.0.0"), registry_loc()).unwrap()
}
}

Expand Down Expand Up @@ -626,7 +626,7 @@ pub fn dep(name: &str) -> Dependency {
dep_req(name, "*")
}
pub fn dep_req(name: &str, req: &str) -> Dependency {
Dependency::parse_no_deprecated(name, Some(req), registry_loc()).unwrap()
Dependency::parse(name, Some(req), registry_loc()).unwrap()
}
pub fn dep_req_kind(name: &str, req: &str, kind: DepKind, public: bool) -> Dependency {
let mut dep = dep_req(name, req);
Expand All @@ -639,7 +639,7 @@ pub fn dep_loc(name: &str, location: &str) -> Dependency {
let url = location.into_url().unwrap();
let master = GitReference::Branch("master".to_string());
let source_id = SourceId::for_git(&url, master).unwrap();
Dependency::parse_no_deprecated(name, Some("1.0.0"), source_id).unwrap()
Dependency::parse(name, Some("1.0.0"), source_id).unwrap()
}
pub fn dep_kind(name: &str, kind: DepKind) -> Dependency {
dep(name).set_kind(kind).clone()
Expand Down
23 changes: 1 addition & 22 deletions src/cargo/core/compiler/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use std::path::PathBuf;

use cargo_platform::CfgExpr;
use cargo_util::{paths, ProcessBuilder};
use semver::Version;

use super::BuildContext;
use crate::core::compiler::{CompileKind, Metadata, Unit};
Expand Down Expand Up @@ -316,10 +315,7 @@ impl<'cfg> Compilation<'cfg> {
.env("CARGO_PKG_VERSION_MAJOR", &pkg.version().major.to_string())
.env("CARGO_PKG_VERSION_MINOR", &pkg.version().minor.to_string())
.env("CARGO_PKG_VERSION_PATCH", &pkg.version().patch.to_string())
.env(
"CARGO_PKG_VERSION_PRE",
&pre_version_component(pkg.version()),
)
.env("CARGO_PKG_VERSION_PRE", pkg.version().pre.as_str())
.env("CARGO_PKG_VERSION", &pkg.version().to_string())
.env("CARGO_PKG_NAME", &*pkg.name())
.env(
Expand Down Expand Up @@ -368,23 +364,6 @@ fn fill_rustc_tool_env(mut cmd: ProcessBuilder, unit: &Unit) -> ProcessBuilder {
cmd
}

fn pre_version_component(v: &Version) -> String {
if v.pre.is_empty() {
return String::new();
}

let mut ret = String::new();

for (i, x) in v.pre.iter().enumerate() {
if i != 0 {
ret.push('.')
};
ret.push_str(&x.to_string());
}

ret
}

fn target_runner(
bcx: &BuildContext<'_, '_>,
kind: CompileKind,
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/compiler/context/compilation_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ fn hash_rustc_version(bcx: &BuildContext<'_, '_>, hasher: &mut StableHasher) {
//
// This assumes that the first segment is the important bit ("nightly",
// "beta", "dev", etc.). Skip other parts like the `.3` in `-beta.3`.
vers.pre[0].hash(hasher);
vers.pre.split('.').next().hash(hasher);
// Keep "host" since some people switch hosts to implicitly change
// targets, (like gnu vs musl or gnu vs msvc). In the future, we may want
// to consider hashing `unit.kind.short_name()` instead.
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/compiler/standard_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub fn resolve_std<'cfg>(
.iter()
.map(|&name| {
let source_path = SourceId::for_path(&src_path.join("library").join(name))?;
let dep = Dependency::parse_no_deprecated(name, None, source_path)?;
let dep = Dependency::parse(name, None, source_path)?;
Ok(dep)
})
.collect::<CargoResult<Vec<_>>>()?;
Expand Down
101 changes: 18 additions & 83 deletions src/cargo/core/dependency.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use anyhow::Context as _;
use cargo_platform::Platform;
use log::trace;
use semver::ReqParseError;
use semver::VersionReq;
use serde::ser;
use serde::Serialize;
Expand All @@ -11,17 +9,17 @@ use std::rc::Rc;
use crate::core::{PackageId, SourceId, Summary};
use crate::util::errors::CargoResult;
use crate::util::interning::InternedString;
use crate::util::Config;
use crate::util::OptVersionReq;

/// Information about a dependency requested by a Cargo manifest.
/// Cheap to copy.
#[derive(PartialEq, Eq, Hash, Ord, PartialOrd, Clone, Debug)]
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
pub struct Dependency {
inner: Rc<Inner>,
}

/// The data underlying a `Dependency`.
#[derive(PartialEq, Eq, Hash, Ord, PartialOrd, Clone, Debug)]
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
struct Inner {
name: InternedString,
source_id: SourceId,
Expand All @@ -32,7 +30,7 @@ struct Inner {
/// `registry` is specified. Or in the case of a crates.io dependency,
/// `source_id` will be crates.io and this will be None.
registry_id: Option<SourceId>,
req: VersionReq,
req: OptVersionReq,
specified_req: bool,
kind: DepKind,
only_match_name: bool,
Expand Down Expand Up @@ -99,52 +97,6 @@ pub enum DepKind {
Build,
}

fn parse_req_with_deprecated(
name: InternedString,
req: &str,
extra: Option<(PackageId, &Config)>,
) -> CargoResult<VersionReq> {
match VersionReq::parse(req) {
Err(ReqParseError::DeprecatedVersionRequirement(requirement)) => {
let (inside, config) = match extra {
Some(pair) => pair,
None => return Err(ReqParseError::DeprecatedVersionRequirement(requirement).into()),
};
let msg = format!(
"\
parsed version requirement `{}` is no longer valid
Previous versions of Cargo accepted this malformed requirement,
but it is being deprecated. This was found when parsing the manifest
of {} {}, and the correct version requirement is `{}`.
This will soon become a hard error, so it's either recommended to
update to a fixed version or contact the upstream maintainer about
this warning.
",
req,
inside.name(),
inside.version(),
requirement
);
config.shell().warn(&msg)?;

Ok(requirement)
}
Err(e) => {
let err: CargoResult<VersionReq> = Err(e.into());
let v: VersionReq = err.with_context(|| {
format!(
"failed to parse the version requirement `{}` for dependency `{}`",
req, name
)
})?;
Ok(v)
}
Ok(v) => Ok(v),
}
}

impl ser::Serialize for DepKind {
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
where
Expand All @@ -165,36 +117,19 @@ impl Dependency {
name: impl Into<InternedString>,
version: Option<&str>,
source_id: SourceId,
inside: PackageId,
config: &Config,
) -> CargoResult<Dependency> {
let name = name.into();
let arg = Some((inside, config));
let (specified_req, version_req) = match version {
Some(v) => (true, parse_req_with_deprecated(name, v, arg)?),
None => (false, VersionReq::any()),
};

let mut ret = Dependency::new_override(name, source_id);
{
let ptr = Rc::make_mut(&mut ret.inner);
ptr.only_match_name = false;
ptr.req = version_req;
ptr.specified_req = specified_req;
}
Ok(ret)
}

/// Attempt to create a `Dependency` from an entry in the manifest.
pub fn parse_no_deprecated(
name: impl Into<InternedString>,
version: Option<&str>,
source_id: SourceId,
) -> CargoResult<Dependency> {
let name = name.into();
let (specified_req, version_req) = match version {
Some(v) => (true, parse_req_with_deprecated(name, v, None)?),
None => (false, VersionReq::any()),
Some(v) => match VersionReq::parse(v) {
Ok(req) => (true, OptVersionReq::Req(req)),
Err(err) => {
return Err(anyhow::Error::new(err).context(format!(
"failed to parse the version requirement `{}` for dependency `{}`",
v, name,
)))
}
},
None => (false, OptVersionReq::Any),
};

let mut ret = Dependency::new_override(name, source_id);
Expand All @@ -214,7 +149,7 @@ impl Dependency {
name,
source_id,
registry_id: None,
req: VersionReq::any(),
req: OptVersionReq::Any,
kind: DepKind::Normal,
only_match_name: true,
optional: false,
Expand All @@ -228,7 +163,7 @@ impl Dependency {
}
}

pub fn version_req(&self) -> &VersionReq {
pub fn version_req(&self) -> &OptVersionReq {
&self.inner.req
}

Expand Down Expand Up @@ -365,7 +300,7 @@ impl Dependency {

/// Sets the version requirement for this dependency.
pub fn set_version_req(&mut self, req: VersionReq) -> &mut Dependency {
Rc::make_mut(&mut self.inner).req = req;
Rc::make_mut(&mut self.inner).req = OptVersionReq::Req(req);
self
}

Expand Down Expand Up @@ -394,7 +329,7 @@ impl Dependency {
id
);
let me = Rc::make_mut(&mut self.inner);
me.req = VersionReq::exact(id.version());
me.req = OptVersionReq::exact(id.version());

// Only update the `precise` of this source to preserve other
// information about dependency's source which may not otherwise be
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::core::{Dependency, PackageId, Source, SourceId, SourceMap, Summary};
use crate::sources::config::SourceConfigMap;
use crate::util::errors::CargoResult;
use crate::util::interning::InternedString;
use crate::util::{profile, CanonicalUrl, Config};
use crate::util::{profile, CanonicalUrl, Config, VersionReqExt};
use anyhow::{bail, Context as _};
use log::{debug, trace};
use semver::VersionReq;
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/resolver/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fmt;

use crate::core::{Dependency, PackageId, Registry, Summary};
use crate::util::lev_distance::lev_distance;
use crate::util::Config;
use crate::util::{Config, VersionExt};
use anyhow::Error;

use super::context::Context;
Expand Down
1 change: 0 additions & 1 deletion src/cargo/core/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,6 @@ impl<'cfg> Workspace<'cfg> {
.map(|(name, dep)| {
dep.to_dependency_split(
name,
/* pkg_id */ None,
source,
&mut nested_paths,
self.config,
Expand Down
8 changes: 2 additions & 6 deletions src/cargo/ops/cargo_install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::core::{Dependency, Edition, Package, PackageId, Source, SourceId, Wor
use crate::ops::common_for_install_and_uninstall::*;
use crate::sources::{GitSource, PathSource, SourceConfigMap};
use crate::util::errors::CargoResult;
use crate::util::{Config, Filesystem, Rustc, ToSemver};
use crate::util::{Config, Filesystem, Rustc, ToSemver, VersionReqExt};
use crate::{drop_println, ops};

use anyhow::{bail, format_err, Context as _};
Expand Down Expand Up @@ -180,11 +180,7 @@ fn install_one(
} else {
None
};
Some(Dependency::parse_no_deprecated(
krate,
vers.as_deref(),
source_id,
)?)
Some(Dependency::parse(krate, vers.as_deref(), source_id)?)
} else {
None
}
Expand Down
10 changes: 5 additions & 5 deletions src/cargo/sources/registry/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ use crate::core::dependency::Dependency;
use crate::core::{PackageId, SourceId, Summary};
use crate::sources::registry::{RegistryData, RegistryPackage, INDEX_V_MAX};
use crate::util::interning::InternedString;
use crate::util::{internal, CargoResult, Config, Filesystem, ToSemver};
use crate::util::{internal, CargoResult, Config, Filesystem, OptVersionReq, ToSemver};
use anyhow::bail;
use cargo_util::paths;
use log::{debug, info};
use semver::{Version, VersionReq};
use semver::Version;
use std::collections::{HashMap, HashSet};
use std::convert::TryInto;
use std::fs;
Expand Down Expand Up @@ -264,7 +264,7 @@ impl<'cfg> RegistryIndex<'cfg> {

/// Returns the hash listed for a specified `PackageId`.
pub fn hash(&mut self, pkg: PackageId, load: &mut dyn RegistryData) -> CargoResult<&str> {
let req = VersionReq::exact(pkg.version());
let req = OptVersionReq::exact(pkg.version());
let summary = self
.summaries(pkg.name(), &req, load)?
.next()
Expand All @@ -285,7 +285,7 @@ impl<'cfg> RegistryIndex<'cfg> {
pub fn summaries<'a, 'b>(
&'a mut self,
name: InternedString,
req: &'b VersionReq,
req: &'b OptVersionReq,
load: &mut dyn RegistryData,
) -> CargoResult<impl Iterator<Item = &'a IndexSummary> + 'b>
where
Expand Down Expand Up @@ -489,7 +489,7 @@ impl<'cfg> RegistryIndex<'cfg> {
}

pub fn is_yanked(&mut self, pkg: PackageId, load: &mut dyn RegistryData) -> CargoResult<bool> {
let req = VersionReq::exact(pkg.version());
let req = OptVersionReq::exact(pkg.version());
let found = self
.summaries(pkg.name(), &req, load)?
.any(|summary| summary.yanked);
Expand Down
8 changes: 4 additions & 4 deletions src/cargo/sources/registry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ use std::path::{Path, PathBuf};
use anyhow::Context as _;
use flate2::read::GzDecoder;
use log::debug;
use semver::{Version, VersionReq};
use semver::Version;
use serde::Deserialize;
use tar::Archive;

Expand All @@ -179,7 +179,7 @@ use crate::sources::PathSource;
use crate::util::hex;
use crate::util::interning::InternedString;
use crate::util::into_url::IntoUrl;
use crate::util::{restricted_names, CargoResult, Config, Filesystem};
use crate::util::{restricted_names, CargoResult, Config, Filesystem, OptVersionReq};

const PACKAGE_SOURCE_LOCK: &str = ".cargo-ok";
pub const CRATES_IO_INDEX: &str = "https://github.com/rust-lang/crates.io-index";
Expand Down Expand Up @@ -373,7 +373,7 @@ impl<'a> RegistryDependency<'a> {
default
};

let mut dep = Dependency::parse_no_deprecated(package.unwrap_or(name), Some(&req), id)?;
let mut dep = Dependency::parse(package.unwrap_or(name), Some(&req), id)?;
if package.is_some() {
dep.set_explicit_name_in_toml(name);
}
Expand Down Expand Up @@ -671,7 +671,7 @@ impl<'cfg> RegistrySource<'cfg> {

// After we've loaded the package configure its summary's `checksum`
// field with the checksum we know for this `PackageId`.
let req = VersionReq::exact(package.version());
let req = OptVersionReq::exact(package.version());
let summary_with_cksum = self
.index
.summaries(package.name(), &req, &mut *self.ops)?
Expand Down
Loading

0 comments on commit 2f3df16

Please sign in to comment.