Skip to content

Commit

Permalink
Auto merge of #9369 - PicoJr:fix-9350, r=ehuss
Browse files Browse the repository at this point in the history
Fix #9350 (cargo build -Z help is missing options)

> Do not merge yet, some options are still undocumented.

Fix #9350 (cargo build -Z help is missing options)

Add a procedural macro to declare `CliUnstable` struct and provide help messages instead of hard-coding help in `src/bin/cargo/cli.rs`

> Flags documentation: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html

Feedback welcome
  • Loading branch information
bors committed Apr 20, 2021
2 parents eb5476b + 05d37ae commit a18936b
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 63 deletions.
42 changes: 28 additions & 14 deletions src/bin/cargo/cli.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use cargo::core::features;
use cargo::core::{features, CliUnstable};
use cargo::{self, drop_print, drop_println, CliResult, Config};
use clap::{AppSettings, Arg, ArgMatches};

use super::commands;
use super::list_commands;
use crate::command_prelude::*;
use cargo::core::features::HIDDEN;

pub fn main(config: &mut Config) -> CliResult {
// CAUTION: Be careful with using `config` until it is configured below.
Expand All @@ -30,25 +31,38 @@ pub fn main(config: &mut Config) -> CliResult {
};

if args.value_of("unstable-features") == Some("help") {
let options = CliUnstable::help();
let non_hidden_options: Vec<(String, String)> = options
.iter()
.filter(|(_, help_message)| *help_message != HIDDEN)
.map(|(name, help)| (name.to_string(), help.to_string()))
.collect();
let longest_option = non_hidden_options
.iter()
.map(|(option_name, _)| option_name.len())
.max()
.unwrap_or(0);
let help_lines: Vec<String> = non_hidden_options
.iter()
.map(|(option_name, option_help_message)| {
let option_name_kebab_case = option_name.replace("_", "-");
let padding = " ".repeat(longest_option - option_name.len()); // safe to substract
format!(
" -Z {}{} -- {}",
option_name_kebab_case, padding, option_help_message
)
})
.collect();
let joined = help_lines.join("\n");
drop_println!(
config,
"
Available unstable (nightly-only) flags:
-Z allow-features -- Allow *only* the listed unstable features
-Z avoid-dev-deps -- Avoid installing dev-dependencies if possible
-Z extra-link-arg -- Allow `cargo:rustc-link-arg` in build scripts
-Z minimal-versions -- Install minimal dependency versions instead of maximum
-Z no-index-update -- Do not update the registry, avoids a network request for benchmarking
-Z unstable-options -- Allow the usage of unstable options
-Z timings -- Display concurrency information
-Z doctest-xcompile -- Compile and run doctests for non-host target using runner config
-Z terminal-width -- Provide a terminal width to rustc for error truncation
-Z namespaced-features -- Allow features with `dep:` prefix
-Z weak-dep-features -- Allow `dep_name?/feature` feature syntax
-Z patch-in-config -- Allow `[patch]` sections in .cargo/config.toml files
{}
Run with 'cargo -Z [FLAG] [SUBCOMMAND]'"
Run with 'cargo -Z [FLAG] [SUBCOMMAND]'",
joined
);
if !config.nightly_features_allowed {
drop_println!(
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/compiler/job_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,7 @@ impl<'cfg> DrainState<'cfg> {
}

fn emit_future_incompat(&mut self, cx: &mut Context<'_, '_>) {
if cx.bcx.config.cli_unstable().enable_future_incompat_feature {
if cx.bcx.config.cli_unstable().future_incompat_report {
if self.per_crate_future_incompat_reports.is_empty() {
drop(
cx.bcx
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,7 @@ fn build_base_args(
.env("RUSTC_BOOTSTRAP", "1");
}

if bcx.config.cli_unstable().enable_future_incompat_feature {
if bcx.config.cli_unstable().future_incompat_report {
cmd.arg("-Z").arg("emit-future-incompat-report");
}

Expand Down
112 changes: 67 additions & 45 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
//! get an instance of `CliUnstable` and check if the option has been
//! enabled on the `CliUnstable` instance. Nightly gating is already
//! handled, so no need to worry about that.
//! 4. Update the `-Z help` documentation in the `main` function.
//!
//! ## Stabilization
//!
Expand All @@ -83,9 +82,9 @@
//! 2. `-Z unstable-options`: Find the call to `fail_if_stable_opt` and
//! remove it. Be sure to update the man pages if necessary.
//! 3. `-Z` flag: Change the parsing code in [`CliUnstable::add`] to call
//! `stabilized_warn` or `stabilized_err`. Remove it from the `-Z help`
//! docs in the `main` function. Remove the `(unstable)` note in the
//! clap help text if necessary.
//! `stabilized_warn` or `stabilized_err` and remove the field from
//! `CliUnstable. Remove the `(unstable)` note in the clap help text if
//! necessary.
//! 2. Remove `masquerade_as_nightly_cargo` from any tests, and remove
//! `cargo-features` from `Cargo.toml` test files if any.
//! 3. Remove the docs from unstable.md and update the redirect at the bottom
Expand All @@ -105,6 +104,7 @@ use crate::util::errors::CargoResult;
use crate::util::{indented_lines, iter_join};
use crate::Config;

pub const HIDDEN: &str = "";
pub const SEE_CHANNELS: &str =
"See https://doc.rust-lang.org/book/appendix-07-nightly-rust.html for more information \
about Rust release channels.";
Expand Down Expand Up @@ -538,51 +538,73 @@ impl Features {
}
}

/// A parsed representation of all unstable flags that Cargo accepts.
///
/// Cargo, like `rustc`, accepts a suite of `-Z` flags which are intended for
/// gating unstable functionality to Cargo. These flags are only available on
/// the nightly channel of Cargo.
#[derive(Default, Debug, Deserialize)]
#[serde(default, rename_all = "kebab-case")]
pub struct CliUnstable {
macro_rules! unstable_cli_options {
(
$(
$(#[$meta:meta])?
$element: ident: $ty: ty = ($help: expr )
),*
) => {
/// A parsed representation of all unstable flags that Cargo accepts.
///
/// Cargo, like `rustc`, accepts a suite of `-Z` flags which are intended for
/// gating unstable functionality to Cargo. These flags are only available on
/// the nightly channel of Cargo.
#[derive(Default, Debug, Deserialize)]
#[serde(default, rename_all = "kebab-case")]
pub struct CliUnstable {
$(
$(#[$meta])?
pub $element: $ty
),*
}
impl CliUnstable {
pub fn help() -> Vec<(&'static str, &'static str)> {
let fields = vec![$((stringify!($element), $help)),*];
fields
}
}
}
}

unstable_cli_options!(
// Permanently unstable features:
pub allow_features: Option<BTreeSet<String>>,
pub print_im_a_teapot: bool,
allow_features: Option<BTreeSet<String>> = ("Allow *only* the listed unstable features"),
print_im_a_teapot: bool= (HIDDEN),

// All other unstable features.
// Please keep this list lexiographically ordered.
pub advanced_env: bool,
pub avoid_dev_deps: bool,
pub binary_dep_depinfo: bool,
advanced_env: bool = (HIDDEN),
avoid_dev_deps: bool = ("Avoid installing dev-dependencies if possible"),
binary_dep_depinfo: bool = ("Track changes to dependency artifacts"),
#[serde(deserialize_with = "deserialize_build_std")]
pub build_std: Option<Vec<String>>,
pub build_std_features: Option<Vec<String>>,
pub config_include: bool,
pub configurable_env: bool,
pub credential_process: bool,
pub doctest_in_workspace: bool,
pub doctest_xcompile: bool,
pub dual_proc_macros: bool,
pub enable_future_incompat_feature: bool,
pub extra_link_arg: bool,
pub features: Option<Vec<String>>,
pub jobserver_per_rustc: bool,
pub minimal_versions: bool,
pub mtime_on_use: bool,
pub multitarget: bool,
pub named_profiles: bool,
pub namespaced_features: bool,
pub no_index_update: bool,
pub panic_abort_tests: bool,
pub patch_in_config: bool,
pub rustdoc_map: bool,
pub separate_nightlies: bool,
pub terminal_width: Option<Option<usize>>,
pub timings: Option<Vec<String>>,
pub unstable_options: bool,
pub weak_dep_features: bool,
}
build_std: Option<Vec<String>> = ("Enable Cargo to compile the standard library itself as part of a crate graph compilation"),
build_std_features: Option<Vec<String>> = ("Configure features enabled for the standard library itself when building the standard library"),
config_include: bool = ("Enable the `include` key in config files"),
configurable_env: bool = ("Enable the [env] section in the .cargo/config.toml file"),
credential_process: bool = ("Add a config setting to fetch registry authentication tokens by calling an external process"),
doctest_in_workspace: bool = ("Compile doctests with paths relative to the workspace root"),
doctest_xcompile: bool = ("Compile and run doctests for non-host target using runner config"),
dual_proc_macros: bool = ("Build proc-macros for both the host and the target"),
future_incompat_report: bool = ("Enable creation of a future-incompat report for all dependencies"),
extra_link_arg: bool = ("Allow `cargo:rustc-link-arg` in build scripts"),
features: Option<Vec<String>> = (HIDDEN),
jobserver_per_rustc: bool = (HIDDEN),
minimal_versions: bool = ("Resolve minimal dependency versions instead of maximum"),
mtime_on_use: bool = ("Configure Cargo to update the mtime of used files"),
multitarget: bool = ("Allow passing multiple `--target` flags to the cargo subcommand selected"),
named_profiles: bool = ("Allow defining custom profiles"),
namespaced_features: bool = ("Allow features with `dep:` prefix"),
no_index_update: bool = ("Do not update the registry index even if the cache is outdated"),
panic_abort_tests: bool = ("Enable support to run tests with -Cpanic=abort"),
patch_in_config: bool = ("Allow `[patch]` sections in .cargo/config.toml files"),
rustdoc_map: bool = ("Allow passing external documentation mappings to rustdoc"),
separate_nightlies: bool = (HIDDEN),
terminal_width: Option<Option<usize>> = ("Provide a terminal width to rustc for error truncation"),
timings: Option<Vec<String>> = ("Display concurrency information"),
unstable_options: bool = ("Allow the usage of unstable options"),
weak_dep_features: bool = ("Allow `dep_name?/feature` feature syntax")
);

const STABILIZED_COMPILE_PROGRESS: &str = "The progress bar is now always \
enabled when used on an interactive console.\n\
Expand Down Expand Up @@ -798,7 +820,7 @@ impl CliUnstable {
"config-profile" => stabilized_warn(k, "1.43", STABILIZED_CONFIG_PROFILE),
"crate-versions" => stabilized_warn(k, "1.47", STABILIZED_CRATE_VERSIONS),
"package-features" => stabilized_warn(k, "1.51", STABILIZED_PACKAGE_FEATURES),
"future-incompat-report" => self.enable_future_incompat_feature = parse_empty(k, v)?,
"future-incompat-report" => self.future_incompat_report = parse_empty(k, v)?,
_ => bail!("unknown `-Z` flag specified: {}", k),
}

Expand Down
2 changes: 1 addition & 1 deletion src/cargo/util/command_prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ pub trait ArgMatchesExt {
// TODO: Tracking issue
.fail_if_stable_opt("--future-incompat-report", 9241)?;

if !config.cli_unstable().enable_future_incompat_feature {
if !config.cli_unstable().future_incompat_report {
anyhow::bail!(
"Usage of `--future-incompat-report` requires `-Z future-incompat-report`"
)
Expand Down
4 changes: 3 additions & 1 deletion tests/testsuite/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ fn z_flags_help() {
// Test that the output of `cargo -Z help` shows a different help screen with
// all the `-Z` flags.
cargo_process("-Z help")
.with_stdout_contains(" -Z unstable-options -- Allow the usage of unstable options")
.with_stdout_contains(
" -Z allow-features[..]-- Allow *only* the listed unstable features",
)
.run();
}

Expand Down

0 comments on commit a18936b

Please sign in to comment.