mirror of
https://github.com/rust-lang/cargo
synced 2024-08-28 11:50:23 +00:00
Update to semver 1.0.0-rc
This commit is contained in:
parent
e931e4796b
commit
3b62e466ec
|
@ -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"] }
|
||||
|
|
|
@ -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};
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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" => "*",
|
||||
_ => {
|
||||
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,
|
||||
|
@ -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)?;
|
||||
req,
|
||||
inside.name(),
|
||||
inside.version(),
|
||||
corrected,
|
||||
);
|
||||
|
||||
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),
|
||||
}
|
||||
config.shell().warn(&msg)?;
|
||||
|
||||
Ok(VersionReq::parse(corrected).unwrap())
|
||||
}
|
||||
|
||||
impl ser::Serialize for DepKind {
|
||||
|
@ -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),
|
||||
};
|
||||
|
||||
let mut ret = Dependency::new_override(name, source_id);
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -228,7 +232,7 @@ impl Dependency {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn version_req(&self) -> &VersionReq {
|
||||
pub fn version_req(&self) -> &OptVersionReq {
|
||||
&self.inner.req
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 _};
|
||||
|
|
|
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -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";
|
||||
|
@ -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)?
|
||||
|
|
|
@ -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::{
|
||||
|
@ -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;
|
||||
|
|
76
src/cargo/util/semver_ext.rs
Normal file
76
src/cargo/util/semver_ext.rs
Normal file
|
@ -0,0 +1,76 @@
|
|||
use semver::{Comparator, Op, Version, VersionReq};
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
|
||||
pub enum OptVersionReq {
|
||||
Any,
|
||||
Req(VersionReq),
|
||||
}
|
||||
|
||||
pub trait VersionExt {
|
||||
fn is_prerelease(&self) -> bool;
|
||||
}
|
||||
|
||||
pub trait VersionReqExt {
|
||||
fn exact(version: &Version) -> Self;
|
||||
}
|
||||
|
||||
impl VersionExt for Version {
|
||||
fn is_prerelease(&self) -> bool {
|
||||
!self.pre.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl VersionReqExt for VersionReq {
|
||||
fn exact(version: &Version) -> Self {
|
||||
VersionReq {
|
||||
comparators: vec![Comparator {
|
||||
op: Op::Exact,
|
||||
major: version.major,
|
||||
minor: Some(version.minor),
|
||||
patch: Some(version.patch),
|
||||
pre: version.pre.clone(),
|
||||
}],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl OptVersionReq {
|
||||
pub fn exact(version: &Version) -> Self {
|
||||
OptVersionReq::Req(VersionReq::exact(version))
|
||||
}
|
||||
|
||||
pub fn is_exact(&self) -> bool {
|
||||
match self {
|
||||
OptVersionReq::Any => false,
|
||||
OptVersionReq::Req(req) => {
|
||||
req.comparators.len() == 1 && {
|
||||
let cmp = &req.comparators[0];
|
||||
cmp.op == Op::Exact && cmp.minor.is_some() && cmp.patch.is_some()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn matches(&self, version: &Version) -> bool {
|
||||
match self {
|
||||
OptVersionReq::Any => true,
|
||||
OptVersionReq::Req(req) => req.matches(version),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for OptVersionReq {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
OptVersionReq::Any => formatter.write_str("*"),
|
||||
OptVersionReq::Req(req) => Display::fmt(req, formatter),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VersionReq> for OptVersionReq {
|
||||
fn from(req: VersionReq) -> Self {
|
||||
OptVersionReq::Req(req)
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@ impl ToSemver for Version {
|
|||
|
||||
impl<'a> ToSemver for &'a str {
|
||||
fn to_semver(self) -> CargoResult<Version> {
|
||||
match Version::parse(self) {
|
||||
match Version::parse(self.trim()) {
|
||||
Ok(v) => Ok(v),
|
||||
Err(..) => Err(anyhow::format_err!("cannot parse '{}' as a semver", self)),
|
||||
}
|
||||
|
|
|
@ -25,7 +25,9 @@ use crate::core::{GitReference, PackageIdSpec, SourceId, WorkspaceConfig, Worksp
|
|||
use crate::sources::{CRATES_IO_INDEX, CRATES_IO_REGISTRY};
|
||||
use crate::util::errors::{CargoResult, ManifestError};
|
||||
use crate::util::interning::InternedString;
|
||||
use crate::util::{self, config::ConfigRelativePath, validate_package_name, Config, IntoUrl};
|
||||
use crate::util::{
|
||||
self, config::ConfigRelativePath, validate_package_name, Config, IntoUrl, VersionReqExt,
|
||||
};
|
||||
|
||||
mod targets;
|
||||
use self::targets::targets;
|
||||
|
@ -778,6 +780,30 @@ impl<'de> de::Deserialize<'de> for VecStringOrBool {
|
|||
}
|
||||
}
|
||||
|
||||
fn version_trim_whitespace<'de, D>(deserializer: D) -> Result<semver::Version, D::Error>
|
||||
where
|
||||
D: de::Deserializer<'de>,
|
||||
{
|
||||
struct Visitor;
|
||||
|
||||
impl<'de> de::Visitor<'de> for Visitor {
|
||||
type Value = semver::Version;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
formatter.write_str("SemVer version")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, string: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
string.trim().parse().map_err(de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_str(Visitor)
|
||||
}
|
||||
|
||||
/// Represents the `package`/`project` sections of a `Cargo.toml`.
|
||||
///
|
||||
/// Note that the order of the fields matters, since this is the order they
|
||||
|
@ -790,6 +816,7 @@ pub struct TomlProject {
|
|||
edition: Option<String>,
|
||||
rust_version: Option<String>,
|
||||
name: InternedString,
|
||||
#[serde(deserialize_with = "version_trim_whitespace")]
|
||||
version: semver::Version,
|
||||
authors: Option<Vec<String>>,
|
||||
build: Option<StringOrBool>,
|
||||
|
|
|
@ -269,7 +269,7 @@ fn cargo_compile_with_invalid_version() {
|
|||
[ERROR] failed to parse manifest at `[..]`
|
||||
|
||||
Caused by:
|
||||
Expected dot for key `package.version`
|
||||
unexpected end of input while parsing minor version number for key `package.version`
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
@ -544,7 +544,7 @@ Caused by:
|
|||
failed to parse the version requirement `y` for dependency `crossbeam`
|
||||
|
||||
Caused by:
|
||||
the given version requirement is invalid
|
||||
unexpected character 'y' while parsing major version number
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
|
Loading…
Reference in a new issue