Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement support for rust-version field in project metadata #8037

Merged
merged 2 commits into from
Jan 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions crates/cargo-test-support/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
33 changes: 31 additions & 2 deletions crates/cargo-test-support/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -247,6 +249,8 @@ impl Package {
invalid_json: false,
proc_macro: false,
links: None,
rust_version: None,
cargo_features: Vec::new(),
}
}

Expand Down Expand Up @@ -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());
djc marked this conversation as resolved.
Show resolved Hide resolved
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 {
Expand All @@ -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
Expand Down Expand Up @@ -502,15 +517,29 @@ 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 = "{}"
version = "{}"
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(),
Expand Down
1 change: 1 addition & 0 deletions src/bin/cargo/commands/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions src/bin/cargo/commands/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
1 change: 1 addition & 0 deletions src/bin/cargo/commands/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
1 change: 1 addition & 0 deletions src/bin/cargo/commands/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand Down
1 change: 1 addition & 0 deletions src/bin/cargo/commands/fix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}

Expand Down
1 change: 1 addition & 0 deletions src/bin/cargo/commands/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}

Expand Down
1 change: 1 addition & 0 deletions src/bin/cargo/commands/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}

Expand Down
1 change: 1 addition & 0 deletions src/bin/cargo/commands/rustdoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}

Expand Down
1 change: 1 addition & 0 deletions src/bin/cargo/commands/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
4 changes: 2 additions & 2 deletions src/cargo/core/compiler/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
self.prepare_units()?;
self.prepare()?;
custom_build::build_map(&mut self)?;
self.check_collistions()?;
self.check_collisions()?;
djc marked this conversation as resolved.
Show resolved Hide resolved

for unit in &self.bcx.roots {
// Build up a list of pending jobs, each of which represent
Expand Down Expand Up @@ -398,7 +398,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
Ok(inputs.into_iter().collect())
}

fn check_collistions(&self) -> CargoResult<()> {
fn check_collisions(&self) -> CargoResult<()> {
let mut output_collisions = HashMap::new();
let describe_collision = |unit: &Unit, other_unit: &Unit, path: &PathBuf| -> String {
format!(
Expand Down
14 changes: 14 additions & 0 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/cargo/core/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>>,
Expand Down Expand Up @@ -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>,
Expand All @@ -401,6 +403,7 @@ impl Manifest {
workspace,
unstable_features,
edition,
rust_version,
original,
im_a_teapot,
default_run,
Expand Down Expand Up @@ -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()
}
Expand Down
4 changes: 4 additions & 0 deletions src/cargo/core/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
35 changes: 35 additions & 0 deletions src/cargo/ops/cargo_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -95,6 +98,7 @@ impl<'a> CompileOptions {
target_rustc_args: None,
local_rustdoc_args: None,
rustdoc_document_private_items: false,
honor_rust_version: true,
})
}
}
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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(
djc marked this conversation as resolved.
Show resolved Hide resolved
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,
Expand Down
1 change: 1 addition & 0 deletions src/cargo/ops/cargo_package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)?;
Expand Down
17 changes: 17 additions & 0 deletions src/cargo/util/command_prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
djc marked this conversation as resolved.
Show resolved Hide resolved
self._arg(
opt(
"ignore-rust-version",
"Ignore `rust-version` specification in packages",
)
.hidden(true), // nightly only (`rust-version` feature)
)
}
}

impl AppExt for App {
Expand Down Expand Up @@ -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"),
djc marked this conversation as resolved.
Show resolved Hide resolved
};

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") {
Expand Down
Loading