Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.0-rc.2", 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
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
90 changes: 47 additions & 43 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::{Config, 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 @@ -104,14 +102,32 @@ fn parse_req_with_deprecated(
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!(
"\
let err = match VersionReq::parse(req) {
Ok(req) => return Ok(req),
Err(err) => err,
};

let (inside, config) = match extra {
Some(pair) => pair,
None => return Err(err.into()),
};

let corrected = match req {
".*" => "*",
"0.1.0." => "0.1.0",
"0.3.1.3" => "0.3.13",
"0.2*" => "0.2.*",
"*.0" => "*",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are copied from dtolnay/semver#93.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for keeping the compat here! That being said the warning below says that it will soon become a hard error, and that was added 5 years ago in #3154. I think it's probably fine to just delete all this at this point (and I'm glad you moved this logic to Cargo from the semver crate itself!)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call 😛 I've deleted the compatibility code in 396bdd3.

_ => {
return Err(anyhow::Error::new(err).context(format!(
"failed to parse the version requirement `{}` for dependency `{}`",
req, name,
)));
}
};

let msg = format!(
"\
parsed version requirement `{}` is no longer valid

Previous versions of Cargo accepted this malformed requirement,
Expand All @@ -122,27 +138,15 @@ 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),
}
req,
inside.name(),
inside.version(),
corrected,
);

config.shell().warn(&msg)?;

Ok(VersionReq::parse(corrected).unwrap())
}

impl ser::Serialize for DepKind {
Expand Down Expand Up @@ -171,8 +175,8 @@ impl 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()),
Some(v) => (true, parse_req_with_deprecated(name, v, arg)?.into()),
None => (false, OptVersionReq::Any),
Copy link
Member Author

@dtolnay dtolnay May 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Any" is not considered a VersionReq, because there is no semver syntax that literally matches any version. * is not that, because of how https://github.com/semver/semver/blob/efcff2c838c9945f79bfd21c1df0073271bcc29c/ranges.md suggests handling pre-release versions:

  • SemVer Versions containing PRERELEASE identifiers MUST NOT be included by a SemVer Comparator Set unless they are included by all of the Comparators in the Comparator Set, and one or more of the following conditions are met:

    • The implementation has provided the user with an option to explicitly include PRERELEASE versions, and the user has set this option. This SHOULD NOT be the default behavior when resolving software dependencies.

    • One or more of the Comparators in the Comparator Set have the same MAJOR, MINOR, and PATCH version as the SemVer Version string being considered, and has a PRERELEASE version, and would normally include the SemVer Version string by virtue of precedence comparison.

      For example, the Range >=1.0.0-alpha would include the Version 1.0.0-beta but not the Version 1.0.1-beta.

In previous versions of the semver crate, VersionReq::any() would literally mean any, which is different from *, and it would match any version. But upon roundtrip through a string, it would decay to *, because again there is no semver syntax that means "any".

Instead I'm suggesting that Cargo use something effectively like Option<VersionReq> with an absent VersionReq meaning "any", and the equivalent of .map_or(true, |req| req.matches(version)) for matching.

};

let mut ret = Dependency::new_override(name, source_id);
Expand All @@ -193,8 +197,8 @@ impl Dependency {
) -> 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) => (true, parse_req_with_deprecated(name, v, None)?.into()),
None => (false, OptVersionReq::Any),
};

let mut ret = Dependency::new_override(name, source_id);
Expand All @@ -214,7 +218,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 +232,7 @@ impl Dependency {
}
}

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

Expand Down Expand Up @@ -365,7 +369,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 +398,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
2 changes: 1 addition & 1 deletion 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
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
6 changes: 3 additions & 3 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 @@ -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
2 changes: 2 additions & 0 deletions src/cargo/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub use self::progress::{Progress, ProgressStyle};
pub use self::queue::Queue;
pub use self::restricted_names::validate_package_name;
pub use self::rustc::Rustc;
pub use self::semver_ext::{OptVersionReq, VersionExt, VersionReqExt};
pub use self::to_semver::ToSemver;
pub use self::vcs::{existing_vcs_repo, FossilRepo, GitRepo, HgRepo, PijulRepo};
pub use self::workspace::{
Expand Down Expand Up @@ -53,6 +54,7 @@ mod progress;
mod queue;
pub mod restricted_names;
pub mod rustc;
mod semver_ext;
pub mod to_semver;
pub mod toml;
mod vcs;
Expand Down
Loading