mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
Implement support for rust-version field in project metadata
This commit is contained in:
parent
50cc40bc89
commit
c221fec911
@ -19,4 +19,5 @@ lazy_static = "1.0"
|
||||
remove_dir_all = "0.5"
|
||||
serde_json = "1.0"
|
||||
tar = { version = "0.4.18", default-features = false }
|
||||
toml = "0.5.7"
|
||||
url = "2.0"
|
||||
|
@ -146,6 +146,8 @@ pub struct Package {
|
||||
invalid_json: bool,
|
||||
proc_macro: bool,
|
||||
links: Option<String>,
|
||||
rust_version: Option<String>,
|
||||
cargo_features: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -247,6 +249,8 @@ impl Package {
|
||||
invalid_json: false,
|
||||
proc_macro: false,
|
||||
links: None,
|
||||
rust_version: None,
|
||||
cargo_features: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,6 +367,12 @@ impl Package {
|
||||
self
|
||||
}
|
||||
|
||||
/// Specify a minimal Rust version.
|
||||
pub fn rust_version(&mut self, rust_version: &str) -> &mut Package {
|
||||
self.rust_version = Some(rust_version.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Causes the JSON line emitted in the index to be invalid, presumably
|
||||
/// causing Cargo to skip over this version.
|
||||
pub fn invalid_json(&mut self, invalid: bool) -> &mut Package {
|
||||
@ -375,6 +385,11 @@ impl Package {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn cargo_feature(&mut self, feature: &str) -> &mut Package {
|
||||
self.cargo_features.push(feature.to_owned());
|
||||
self
|
||||
}
|
||||
|
||||
/// Creates the package and place it in the registry.
|
||||
///
|
||||
/// This does not actually use Cargo's publishing system, but instead
|
||||
@ -502,7 +517,16 @@ impl Package {
|
||||
}
|
||||
|
||||
fn append_manifest<W: Write>(&self, ar: &mut Builder<W>) {
|
||||
let mut manifest = format!(
|
||||
let mut manifest = String::new();
|
||||
|
||||
if !self.cargo_features.is_empty() {
|
||||
manifest.push_str(&format!(
|
||||
"cargo-features = {}\n\n",
|
||||
toml::to_string(&self.cargo_features).unwrap()
|
||||
));
|
||||
}
|
||||
|
||||
manifest.push_str(&format!(
|
||||
r#"
|
||||
[package]
|
||||
name = "{}"
|
||||
@ -510,7 +534,12 @@ impl Package {
|
||||
authors = []
|
||||
"#,
|
||||
self.name, self.vers
|
||||
);
|
||||
));
|
||||
|
||||
if let Some(version) = &self.rust_version {
|
||||
manifest.push_str(&format!("rust-version = \"{}\"", version));
|
||||
}
|
||||
|
||||
for dep in self.deps.iter() {
|
||||
let target = match dep.target {
|
||||
None => String::new(),
|
||||
|
@ -39,6 +39,7 @@ pub fn cli() -> App {
|
||||
.arg_target_triple("Build for the target triple")
|
||||
.arg_target_dir()
|
||||
.arg_manifest_path()
|
||||
.arg_ignore_rust_version()
|
||||
.arg_message_format()
|
||||
.arg(opt(
|
||||
"no-fail-fast",
|
||||
|
@ -39,6 +39,7 @@ pub fn cli() -> App {
|
||||
.value_name("PATH"),
|
||||
)
|
||||
.arg_manifest_path()
|
||||
.arg_ignore_rust_version()
|
||||
.arg_message_format()
|
||||
.arg_build_plan()
|
||||
.arg_unit_graph()
|
||||
|
@ -32,6 +32,7 @@ pub fn cli() -> App {
|
||||
.arg_target_triple("Check for the target triple")
|
||||
.arg_target_dir()
|
||||
.arg_manifest_path()
|
||||
.arg_ignore_rust_version()
|
||||
.arg_message_format()
|
||||
.arg_unit_graph()
|
||||
.after_help("Run `cargo help check` for more detailed information.\n")
|
||||
|
@ -30,6 +30,7 @@ pub fn cli() -> App {
|
||||
.arg_target_dir()
|
||||
.arg_manifest_path()
|
||||
.arg_message_format()
|
||||
.arg_ignore_rust_version()
|
||||
.arg_unit_graph()
|
||||
.after_help("Run `cargo help doc` for more detailed information.\n")
|
||||
}
|
||||
|
@ -72,6 +72,7 @@ pub fn cli() -> App {
|
||||
.long("allow-staged")
|
||||
.help("Fix code even if the working directory has staged changes"),
|
||||
)
|
||||
.arg_ignore_rust_version()
|
||||
.after_help("Run `cargo help fix` for more detailed information.\n")
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ pub fn cli() -> App {
|
||||
.arg_manifest_path()
|
||||
.arg_message_format()
|
||||
.arg_unit_graph()
|
||||
.arg_ignore_rust_version()
|
||||
.after_help("Run `cargo help run` for more detailed information.\n")
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ pub fn cli() -> App {
|
||||
.arg_manifest_path()
|
||||
.arg_message_format()
|
||||
.arg_unit_graph()
|
||||
.arg_ignore_rust_version()
|
||||
.after_help("Run `cargo help rustc` for more detailed information.\n")
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ pub fn cli() -> App {
|
||||
.arg_manifest_path()
|
||||
.arg_message_format()
|
||||
.arg_unit_graph()
|
||||
.arg_ignore_rust_version()
|
||||
.after_help("Run `cargo help rustdoc` for more detailed information.\n")
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,7 @@ pub fn cli() -> App {
|
||||
.arg_target_triple("Build for the target triple")
|
||||
.arg_target_dir()
|
||||
.arg_manifest_path()
|
||||
.arg_ignore_rust_version()
|
||||
.arg_message_format()
|
||||
.arg_unit_graph()
|
||||
.after_help("Run `cargo help test` for more detailed information.\n")
|
||||
|
@ -70,6 +70,17 @@ pub enum Edition {
|
||||
Edition2021,
|
||||
}
|
||||
|
||||
impl Edition {
|
||||
pub(crate) fn first_version(&self) -> Option<semver::Version> {
|
||||
use Edition::*;
|
||||
match self {
|
||||
Edition2015 => None,
|
||||
Edition2018 => Some(semver::Version::new(1, 31, 0)),
|
||||
Edition2021 => Some(semver::Version::new(1, 62, 0)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Edition {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
@ -218,6 +229,9 @@ features! {
|
||||
|
||||
// Allow to specify whether binaries should be stripped.
|
||||
[unstable] strip: bool,
|
||||
|
||||
// Specifying a minimal 'rust-version' attribute for crates
|
||||
[unstable] rust_version: bool,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ pub struct Manifest {
|
||||
original: Rc<TomlManifest>,
|
||||
unstable_features: Features,
|
||||
edition: Edition,
|
||||
rust_version: Option<String>,
|
||||
im_a_teapot: Option<bool>,
|
||||
default_run: Option<String>,
|
||||
metabuild: Option<Vec<String>>,
|
||||
@ -379,6 +380,7 @@ impl Manifest {
|
||||
workspace: WorkspaceConfig,
|
||||
unstable_features: Features,
|
||||
edition: Edition,
|
||||
rust_version: Option<String>,
|
||||
im_a_teapot: Option<bool>,
|
||||
default_run: Option<String>,
|
||||
original: Rc<TomlManifest>,
|
||||
@ -401,6 +403,7 @@ impl Manifest {
|
||||
workspace,
|
||||
unstable_features,
|
||||
edition,
|
||||
rust_version,
|
||||
original,
|
||||
im_a_teapot,
|
||||
default_run,
|
||||
@ -520,6 +523,10 @@ impl Manifest {
|
||||
self.edition
|
||||
}
|
||||
|
||||
pub fn rust_version(&self) -> Option<&str> {
|
||||
self.rust_version.as_deref()
|
||||
}
|
||||
|
||||
pub fn custom_metadata(&self) -> Option<&toml::Value> {
|
||||
self.custom_metadata.as_ref()
|
||||
}
|
||||
|
@ -170,6 +170,10 @@ impl Package {
|
||||
pub fn proc_macro(&self) -> bool {
|
||||
self.targets().iter().any(|target| target.proc_macro())
|
||||
}
|
||||
/// Gets the package's minimum Rust version.
|
||||
pub fn rust_version(&self) -> Option<&str> {
|
||||
self.manifest().rust_version()
|
||||
}
|
||||
|
||||
/// Returns `true` if the package uses a custom build script for any target.
|
||||
pub fn has_custom_build(&self) -> bool {
|
||||
|
@ -78,6 +78,9 @@ pub struct CompileOptions {
|
||||
/// Whether the `--document-private-items` flags was specified and should
|
||||
/// be forwarded to `rustdoc`.
|
||||
pub rustdoc_document_private_items: bool,
|
||||
/// Whether the build process should check the minimum Rust version
|
||||
/// defined in the cargo metadata for a crate.
|
||||
pub honor_rust_version: bool,
|
||||
}
|
||||
|
||||
impl<'a> CompileOptions {
|
||||
@ -95,6 +98,7 @@ impl<'a> CompileOptions {
|
||||
target_rustc_args: None,
|
||||
local_rustdoc_args: None,
|
||||
rustdoc_document_private_items: false,
|
||||
honor_rust_version: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -306,6 +310,7 @@ pub fn create_bcx<'a, 'cfg>(
|
||||
ref target_rustc_args,
|
||||
ref local_rustdoc_args,
|
||||
rustdoc_document_private_items,
|
||||
honor_rust_version,
|
||||
} = *options;
|
||||
let config = ws.config();
|
||||
|
||||
@ -551,6 +556,36 @@ pub fn create_bcx<'a, 'cfg>(
|
||||
}
|
||||
}
|
||||
|
||||
if honor_rust_version {
|
||||
// Remove any pre-release identifiers for easier comparison
|
||||
let current_version = &target_data.rustc.version;
|
||||
let untagged_version = semver::Version::new(
|
||||
current_version.major,
|
||||
current_version.minor,
|
||||
current_version.patch,
|
||||
);
|
||||
|
||||
for unit in unit_graph.keys() {
|
||||
let version = match unit.pkg.rust_version() {
|
||||
Some(v) => v,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let req = semver::VersionReq::parse(version).unwrap();
|
||||
if req.matches(&untagged_version) {
|
||||
continue;
|
||||
}
|
||||
|
||||
anyhow::bail!(
|
||||
"package `{}` cannot be built because it requires rustc {} or newer, \
|
||||
while the currently active rustc version is {}",
|
||||
unit.pkg,
|
||||
version,
|
||||
current_version,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let bcx = BuildContext::new(
|
||||
ws,
|
||||
pkg_set,
|
||||
|
@ -701,6 +701,7 @@ fn run_verify(ws: &Workspace<'_>, tar: &FileLock, opts: &PackageOpts<'_>) -> Car
|
||||
target_rustc_args: rustc_args,
|
||||
local_rustdoc_args: None,
|
||||
rustdoc_document_private_items: false,
|
||||
honor_rust_version: true,
|
||||
},
|
||||
&exec,
|
||||
)?;
|
||||
|
@ -212,6 +212,16 @@ pub trait AppExt: Sized {
|
||||
fn arg_dry_run(self, dry_run: &'static str) -> Self {
|
||||
self._arg(opt("dry-run", dry_run))
|
||||
}
|
||||
|
||||
fn arg_ignore_rust_version(self) -> Self {
|
||||
self._arg(
|
||||
opt(
|
||||
"ignore-rust-version",
|
||||
"Ignore `rust-version` specification in packages",
|
||||
)
|
||||
.hidden(true), // nightly only (`rust-version` feature)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl AppExt for App {
|
||||
@ -488,8 +498,15 @@ pub trait ArgMatchesExt {
|
||||
target_rustc_args: None,
|
||||
local_rustdoc_args: None,
|
||||
rustdoc_document_private_items: false,
|
||||
honor_rust_version: !self._is_present("ignore-rust-version"),
|
||||
};
|
||||
|
||||
if !opts.honor_rust_version {
|
||||
config
|
||||
.cli_unstable()
|
||||
.fail_if_stable_opt("--ignore-rust-version", 8072)?;
|
||||
}
|
||||
|
||||
if let Some(ws) = workspace {
|
||||
self.check_optional_opts(ws, &opts)?;
|
||||
} else if self.is_present_with_zero_values("package") {
|
||||
|
@ -15,6 +15,7 @@ use url::Url;
|
||||
|
||||
use crate::core::dependency::DepKind;
|
||||
use crate::core::manifest::{ManifestMetadata, TargetSourcePath, Warnings};
|
||||
use crate::core::nightly_features_allowed;
|
||||
use crate::core::profiles::Strip;
|
||||
use crate::core::resolver::ResolveBehavior;
|
||||
use crate::core::{Dependency, Manifest, PackageId, Summary, Target};
|
||||
@ -800,8 +801,10 @@ impl<'de> de::Deserialize<'de> for VecStringOrBool {
|
||||
/// the field `metadata`, since it is a table and values cannot appear after
|
||||
/// tables.
|
||||
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct TomlProject {
|
||||
edition: Option<String>,
|
||||
rust_version: Option<String>,
|
||||
name: InternedString,
|
||||
version: semver::Version,
|
||||
authors: Option<Vec<String>>,
|
||||
@ -811,16 +814,13 @@ pub struct TomlProject {
|
||||
exclude: Option<Vec<String>>,
|
||||
include: Option<Vec<String>>,
|
||||
publish: Option<VecStringOrBool>,
|
||||
#[serde(rename = "publish-lockfile")]
|
||||
publish_lockfile: Option<bool>,
|
||||
workspace: Option<String>,
|
||||
#[serde(rename = "im-a-teapot")]
|
||||
im_a_teapot: Option<bool>,
|
||||
autobins: Option<bool>,
|
||||
autoexamples: Option<bool>,
|
||||
autotests: Option<bool>,
|
||||
autobenches: Option<bool>,
|
||||
#[serde(rename = "default-run")]
|
||||
default_run: Option<String>,
|
||||
|
||||
// Package metadata.
|
||||
@ -831,7 +831,6 @@ pub struct TomlProject {
|
||||
keywords: Option<Vec<String>>,
|
||||
categories: Option<Vec<String>>,
|
||||
license: Option<String>,
|
||||
#[serde(rename = "license-file")]
|
||||
license_file: Option<String>,
|
||||
repository: Option<String>,
|
||||
metadata: Option<toml::Value>,
|
||||
@ -1049,6 +1048,48 @@ impl TomlManifest {
|
||||
Edition::Edition2015
|
||||
};
|
||||
|
||||
if let Some(rust_version) = &project.rust_version {
|
||||
if features.require(Feature::rust_version()).is_err() {
|
||||
let mut msg =
|
||||
"`rust-version` is not supported on this version of Cargo and will be ignored"
|
||||
.to_string();
|
||||
if nightly_features_allowed() {
|
||||
msg.push_str(
|
||||
"\n\n\
|
||||
consider adding `cargo-features = [\"rust-version\"]` to the manifest",
|
||||
);
|
||||
} else {
|
||||
msg.push_str(
|
||||
"\n\n\
|
||||
this Cargo does not support nightly features, but if you\n\
|
||||
switch to nightly channel you can add\n\
|
||||
`cargo-features = [\"rust-version\"]` to enable this feature",
|
||||
);
|
||||
}
|
||||
warnings.push(msg);
|
||||
}
|
||||
|
||||
let req = match semver::VersionReq::parse(rust_version) {
|
||||
// Exclude semver operators like `^` and pre-release identifiers
|
||||
Ok(req) if rust_version.chars().all(|c| c.is_ascii_digit() || c == '.') => req,
|
||||
_ => bail!("`rust-version` must be a value like \"1.32\""),
|
||||
};
|
||||
|
||||
if let Some(first_version) = edition.first_version() {
|
||||
let unsupported =
|
||||
semver::Version::new(first_version.major, first_version.minor - 1, 9999);
|
||||
if req.matches(&unsupported) {
|
||||
bail!(
|
||||
"rust-version {} is older than first version ({}) required by \
|
||||
the specified edition ({})",
|
||||
rust_version,
|
||||
first_version,
|
||||
edition,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if project.metabuild.is_some() {
|
||||
features.require(Feature::metabuild())?;
|
||||
}
|
||||
@ -1302,6 +1343,7 @@ impl TomlManifest {
|
||||
workspace_config,
|
||||
features,
|
||||
edition,
|
||||
project.rust_version.clone(),
|
||||
project.im_a_teapot,
|
||||
project.default_run.clone(),
|
||||
Rc::clone(me),
|
||||
|
@ -1003,3 +1003,22 @@ cargo logout -Z credential-process`
|
||||
[`credentials` file]: config.md#credentials
|
||||
[crates.io]: https://crates.io/
|
||||
[config file]: config.md
|
||||
|
||||
### rust-version
|
||||
* RFC: [#2495](https://github.com/rust-lang/rfcs/blob/master/text/2495-min-rust-version.md)
|
||||
* rustc Tracking Issue: [#65262](https://github.com/rust-lang/rust/issues/65262)
|
||||
|
||||
The `-Z rust-version` flag enables the reading the `rust-version` field in the
|
||||
Cargo manifest `package` section. This can be used by a package to state a minimal
|
||||
version of the compiler required to build the package. An error is generated if
|
||||
the version of rustc is older than the stated `rust-version`. The
|
||||
`--ignore-rust-version` flag can be used to override the check.
|
||||
|
||||
```toml
|
||||
cargo-features = ["rust-version"]
|
||||
|
||||
[package]
|
||||
name = "mypackage"
|
||||
version = "0.0.1"
|
||||
rust-version = "1.42"
|
||||
```
|
||||
|
@ -103,6 +103,7 @@ mod rename_deps;
|
||||
mod replace;
|
||||
mod required_features;
|
||||
mod run;
|
||||
mod rust_version;
|
||||
mod rustc;
|
||||
mod rustc_info_cache;
|
||||
mod rustdoc;
|
||||
|
260
tests/testsuite/rust_version.rs
Normal file
260
tests/testsuite/rust_version.rs
Normal file
@ -0,0 +1,260 @@
|
||||
//! Tests for targets with `rust-version`.
|
||||
|
||||
use cargo_test_support::{project, registry::Package};
|
||||
|
||||
#[cargo_test]
|
||||
fn rust_version_gated() {
|
||||
project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
rust-version = "1.17"
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.build()
|
||||
.cargo("build")
|
||||
.masquerade_as_nightly_cargo()
|
||||
.with_stderr_contains(
|
||||
"warning: `rust-version` is not supported on this version of Cargo and will be ignored\
|
||||
\n\nconsider adding `cargo-features = [\"rust-version\"]` to the manifest",
|
||||
)
|
||||
.run();
|
||||
|
||||
project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
rust-version = "1.17"
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.build()
|
||||
.cargo("build")
|
||||
.with_stderr_contains(
|
||||
"warning: `rust-version` is not supported on this version of Cargo and will be ignored\
|
||||
\n\nthis Cargo does not support nightly features, but if you\n\
|
||||
switch to nightly channel you can add\n\
|
||||
`cargo-features = [\"rust-version\"]` to enable this feature",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn rust_version_satisfied() {
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["rust-version"]
|
||||
|
||||
[project]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
rust-version = "1.1.1"
|
||||
[[bin]]
|
||||
name = "foo"
|
||||
"#,
|
||||
)
|
||||
.file("src/main.rs", "fn main() {}")
|
||||
.build();
|
||||
|
||||
p.cargo("build").masquerade_as_nightly_cargo().run();
|
||||
p.cargo("build --ignore-rust-version -Zunstable-options")
|
||||
.masquerade_as_nightly_cargo()
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn rust_version_bad_caret() {
|
||||
project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["rust-version"]
|
||||
|
||||
[project]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
rust-version = "^1.43"
|
||||
[[bin]]
|
||||
name = "foo"
|
||||
"#,
|
||||
)
|
||||
.file("src/main.rs", "fn main() {}")
|
||||
.build()
|
||||
.cargo("build")
|
||||
.masquerade_as_nightly_cargo()
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"error: failed to parse manifest at `[..]`\n\n\
|
||||
Caused by:\n `rust-version` must be a value like \"1.32\"",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn rust_version_bad_pre_release() {
|
||||
project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["rust-version"]
|
||||
|
||||
[project]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
rust-version = "1.43-beta.1"
|
||||
[[bin]]
|
||||
name = "foo"
|
||||
"#,
|
||||
)
|
||||
.file("src/main.rs", "fn main() {}")
|
||||
.build()
|
||||
.cargo("build")
|
||||
.masquerade_as_nightly_cargo()
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"error: failed to parse manifest at `[..]`\n\n\
|
||||
Caused by:\n `rust-version` must be a value like \"1.32\"",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn rust_version_bad_nonsense() {
|
||||
project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["rust-version"]
|
||||
|
||||
[project]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
rust-version = "foodaddle"
|
||||
[[bin]]
|
||||
name = "foo"
|
||||
"#,
|
||||
)
|
||||
.file("src/main.rs", "fn main() {}")
|
||||
.build()
|
||||
.cargo("build")
|
||||
.masquerade_as_nightly_cargo()
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"error: failed to parse manifest at `[..]`\n\n\
|
||||
Caused by:\n `rust-version` must be a value like \"1.32\"",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn rust_version_too_high() {
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["rust-version"]
|
||||
|
||||
[project]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
rust-version = "1.9876.0"
|
||||
[[bin]]
|
||||
name = "foo"
|
||||
"#,
|
||||
)
|
||||
.file("src/main.rs", "fn main() {}")
|
||||
.build();
|
||||
|
||||
p.cargo("build")
|
||||
.masquerade_as_nightly_cargo()
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"error: package `foo v0.0.1 ([..])` cannot be built because it requires \
|
||||
rustc 1.9876.0 or newer, while the currently active rustc version is [..]",
|
||||
)
|
||||
.run();
|
||||
p.cargo("build --ignore-rust-version -Zunstable-options")
|
||||
.masquerade_as_nightly_cargo()
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn rust_version_dependency_fails() {
|
||||
Package::new("bar", "0.0.1")
|
||||
.cargo_feature("rust-version")
|
||||
.rust_version("1.2345.0")
|
||||
.file("src/lib.rs", "fn other_stuff() {}")
|
||||
.publish();
|
||||
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
[dependencies]
|
||||
bar = "0.0.1"
|
||||
"#,
|
||||
)
|
||||
.file("src/main.rs", "fn main(){}")
|
||||
.build();
|
||||
|
||||
p.cargo("build")
|
||||
.masquerade_as_nightly_cargo()
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
" Updating `[..]` index\n \
|
||||
Downloading crates ...\n \
|
||||
Downloaded bar v0.0.1 (registry `[..]`)\n\
|
||||
error: package `bar v0.0.1` cannot be built because it requires \
|
||||
rustc 1.2345.0 or newer, while the currently active rustc version is [..]",
|
||||
)
|
||||
.run();
|
||||
p.cargo("build --ignore-rust-version -Zunstable-options")
|
||||
.masquerade_as_nightly_cargo()
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn rust_version_older_than_edition() {
|
||||
project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["rust-version"]
|
||||
|
||||
[project]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
rust-version = "1.1"
|
||||
edition = "2018"
|
||||
[[bin]]
|
||||
name = "foo"
|
||||
"#,
|
||||
)
|
||||
.file("src/main.rs", "fn main() {}")
|
||||
.build()
|
||||
.cargo("build")
|
||||
.masquerade_as_nightly_cargo()
|
||||
.with_status(101)
|
||||
.with_stderr_contains(" rust-version 1.1 is older than first version (1.31.0) required by the specified edition (2018)",
|
||||
)
|
||||
.run();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user