Add infrastructure for nightly Cargo flags
authorAlex Crichton <alex@alexcrichton.com>
Thu, 24 Aug 2017 22:04:46 +0000 (15:04 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Fri, 25 Aug 2017 15:58:47 +0000 (08:58 -0700)
33 files changed:
src/bin/bench.rs
src/bin/build.rs
src/bin/cargo.rs
src/bin/check.rs
src/bin/clean.rs
src/bin/doc.rs
src/bin/fetch.rs
src/bin/generate_lockfile.rs
src/bin/git_checkout.rs
src/bin/init.rs
src/bin/install.rs
src/bin/login.rs
src/bin/metadata.rs
src/bin/new.rs
src/bin/owner.rs
src/bin/package.rs
src/bin/pkgid.rs
src/bin/publish.rs
src/bin/run.rs
src/bin/rustc.rs
src/bin/rustdoc.rs
src/bin/search.rs
src/bin/test.rs
src/bin/uninstall.rs
src/bin/update.rs
src/bin/verify_project.rs
src/bin/yank.rs
src/cargo/core/features.rs
src/cargo/core/manifest.rs
src/cargo/core/mod.rs
src/cargo/ops/cargo_compile.rs
src/cargo/util/config.rs
tests/cargo-features.rs

index dcee0049e23f372949e914844b92fe11247ced87..f0921667cbb065b51ca08083786d3c2ecbf6a1d0 100644 (file)
@@ -35,6 +35,8 @@ pub struct Options {
     arg_args: Vec<String>,
     flag_all: bool,
     flag_exclude: Vec<String>,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -72,6 +74,7 @@ Options:
     --no-fail-fast               Run all benchmarks regardless of failure
     --frozen                     Require Cargo.lock and cache are up to date
     --locked                     Require Cargo.lock is up to date
+    -Z FLAG ...                  Unstable (nightly-only) flags to Cargo
 
 All of the trailing arguments are passed to the benchmark binaries generated
 for filtering benchmarks and generally providing options configuring how they
@@ -99,7 +102,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
 
     let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
     let ws = Workspace::new(&root, config)?;
index b0ee43b4ba459e6693b503614a2bc628ba28a262..b4074109294518f69d77e9a2881621ee9143ce27 100644 (file)
@@ -33,6 +33,8 @@ pub struct Options {
     flag_frozen: bool,
     flag_all: bool,
     flag_exclude: Vec<String>,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -69,6 +71,7 @@ Options:
     --message-format FMT         Error format: human, json [default: human]
     --frozen                     Require Cargo.lock and cache are up to date
     --locked                     Require Cargo.lock is up to date
+    -Z FLAG ...                  Unstable (nightly-only) flags to Cargo
 
 If the --package argument is given, then SPEC is a package id specification
 which indicates which package should be built. If it is not given, then the
@@ -91,7 +94,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
 
     let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
     let ws = Workspace::new(&root, config)?;
index c7432905c1520f7bbc6bef7037ba60d02cfd23ad..155d42b63845dd7fc6155c310d56d53644df2775 100644 (file)
@@ -31,6 +31,8 @@ pub struct Flags {
     arg_args: Vec<String>,
     flag_locked: bool,
     flag_frozen: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 const USAGE: &'static str = "
@@ -50,6 +52,7 @@ Options:
     --color WHEN        Coloring: auto, always, never
     --frozen            Require Cargo.lock and cache are up to date
     --locked            Require Cargo.lock is up to date
+    -Z FLAG ...         Unstable (nightly-only) flags to Cargo
 
 Some common cargo commands are (see all commands with --list):
     build       Compile the current project
@@ -149,7 +152,8 @@ fn execute(flags: Flags, config: &Config) -> CliResult {
                    flags.flag_quiet,
                    &flags.flag_color,
                    flags.flag_frozen,
-                   flags.flag_locked)?;
+                   flags.flag_locked,
+                   &flags.flag_z)?;
 
     init_git_transports(config);
     let _token = cargo::util::job::setup();
index 262e4aaf859d8ac3a50a8e3a2ae70ada25a18bb5..a89a3b579b5b20625f37a6b3539bb2022ccf7d9a 100644 (file)
@@ -39,6 +39,7 @@ Options:
     --message-format FMT         Error format: human, json [default: human]
     --frozen                     Require Cargo.lock and cache are up to date
     --locked                     Require Cargo.lock is up to date
+    -Z FLAG ...                  Unstable (nightly-only) flags to Cargo
 
 If the --package argument is given, then SPEC is a package id specification
 which indicates which package should be built. If it is not given, then the
@@ -78,6 +79,8 @@ pub struct Options {
     flag_frozen: bool,
     flag_all: bool,
     flag_exclude: Vec<String>,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub fn execute(options: Options, config: &Config) -> CliResult {
@@ -88,7 +91,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
 
     let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
     let ws = Workspace::new(&root, config)?;
index 661425e9e37f5b884d3f1cc3cf677031e0b20a4b..9e331dd64b9db449ceee32b1f24c404e2329fd97 100644 (file)
@@ -16,6 +16,8 @@ pub struct Options {
     flag_release: bool,
     flag_frozen: bool,
     flag_locked: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -35,6 +37,7 @@ Options:
     --color WHEN                 Coloring: auto, always, never
     --frozen                     Require Cargo.lock and cache are up to date
     --locked                     Require Cargo.lock is up to date
+    -Z FLAG ...                  Unstable (nightly-only) flags to Cargo
 
 If the --package argument is given, then SPEC is a package id specification
 which indicates which package's artifacts should be cleaned out. If it is not
@@ -48,7 +51,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
 
     let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
     let opts = ops::CleanOptions {
index 517d2b6da153c438a53f4564fefc78d53946fe78..ec45feef1d1b098fad1e06d0872d6b1897dba592 100644 (file)
@@ -27,6 +27,8 @@ pub struct Options {
     flag_frozen: bool,
     flag_locked: bool,
     flag_all: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -57,6 +59,7 @@ Options:
     --message-format FMT         Error format: human, json [default: human]
     --frozen                     Require Cargo.lock and cache are up to date
     --locked                     Require Cargo.lock is up to date
+    -Z FLAG ...                  Unstable (nightly-only) flags to Cargo
 
 By default the documentation for the local package and all dependencies is
 built. The output is all placed in `target/doc` in rustdoc's usual format.
@@ -78,7 +81,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
 
     let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
     let ws = Workspace::new(&root, config)?;
index 6b61ba7d6892df0d70d09dd17dbb4c5db94637df..8dce4633fe9ea41e638603683ca62b081d230d24 100644 (file)
@@ -11,6 +11,8 @@ pub struct Options {
     flag_color: Option<String>,
     flag_frozen: bool,
     flag_locked: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -27,6 +29,7 @@ Options:
     --color WHEN             Coloring: auto, always, never
     --frozen                 Require Cargo.lock and cache are up to date
     --locked                 Require Cargo.lock is up to date
+    -Z FLAG ...              Unstable (nightly-only) flags to Cargo
 
 If a lockfile is available, this command will ensure that all of the git
 dependencies and/or registries dependencies are downloaded and locally
@@ -43,7 +46,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
     let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
     let ws = Workspace::new(&root, config)?;
     ops::fetch(&ws)?;
index 60cb6c6566aa2f28c3cf91f19003a5aeabe7c132..f6733768cfb78e2cf3e599135369f1ca1f0e3679 100644 (file)
@@ -13,6 +13,8 @@ pub struct Options {
     flag_color: Option<String>,
     flag_frozen: bool,
     flag_locked: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -29,6 +31,7 @@ Options:
     --color WHEN             Coloring: auto, always, never
     --frozen                 Require Cargo.lock and cache are up to date
     --locked                 Require Cargo.lock is up to date
+    -Z FLAG ...              Unstable (nightly-only) flags to Cargo
 ";
 
 pub fn execute(options: Options, config: &Config) -> CliResult {
@@ -37,7 +40,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
     let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
 
     let ws = Workspace::new(&root, config)?;
index 7dc9c5c9831c14cfabf68ac1b5213f7ffdbf642b..ed020c7eff17046147641bfd5aa1633fa6a3a8c3 100644 (file)
@@ -11,6 +11,8 @@ pub struct Options {
     flag_color: Option<String>,
     flag_frozen: bool,
     flag_locked: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -27,6 +29,7 @@ Options:
     --color WHEN             Coloring: auto, always, never
     --frozen                 Require Cargo.lock and cache are up to date
     --locked                 Require Cargo.lock is up to date
+    -Z FLAG ...              Unstable (nightly-only) flags to Cargo
 ";
 
 pub fn execute(options: Options, config: &Config) -> CliResult {
@@ -34,7 +37,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
     let Options { flag_url: url, flag_reference: reference, .. } = options;
 
     let url = url.to_url()?;
index 50afe9bea828fe82b2731ff091836e6e81c3151d..6d5c37185f62d202dfcc0dbb505cea39de1ea136 100644 (file)
@@ -15,6 +15,8 @@ pub struct Options {
     flag_vcs: Option<ops::VersionControl>,
     flag_frozen: bool,
     flag_locked: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -38,6 +40,7 @@ Options:
     --color WHEN        Coloring: auto, always, never
     --frozen            Require Cargo.lock and cache are up to date
     --locked            Require Cargo.lock is up to date
+    -Z FLAG ...         Unstable (nightly-only) flags to Cargo
 ";
 
 pub fn execute(options: Options, config: &Config) -> CliResult {
@@ -46,7 +49,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
 
     let Options { flag_bin, flag_lib, arg_path, flag_name, flag_vcs, .. } = options;
 
index 10ea2d1259cf59d558a3df6aa752d537c927f799..1e34ece162f21106d546404f0f094e823b7fa839 100644 (file)
@@ -31,6 +31,8 @@ pub struct Options {
     flag_rev: Option<String>,
 
     flag_path: Option<String>,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -66,6 +68,7 @@ Build and install options:
     --color WHEN              Coloring: auto, always, never
     --frozen                  Require Cargo.lock and cache are up to date
     --locked                  Require Cargo.lock is up to date
+    -Z FLAG ...               Unstable (nightly-only) flags to Cargo
 
 This command manages Cargo's local set of installed binary crates. Only packages
 which have [[bin]] targets can be installed, and all binaries are installed into
@@ -103,7 +106,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
 
     let compile_opts = ops::CompileOptions {
         config: config,
index a9d6b1a710ae5b1922cc48376c7ea7c8e3b36274..c41118cc35066d09f7601a51cf47c5c3185aa77e 100644 (file)
@@ -15,6 +15,8 @@ pub struct Options {
     flag_color: Option<String>,
     flag_frozen: bool,
     flag_locked: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -31,6 +33,7 @@ Options:
     --color WHEN             Coloring: auto, always, never
     --frozen                 Require Cargo.lock and cache are up to date
     --locked                 Require Cargo.lock is up to date
+    -Z FLAG ...              Unstable (nightly-only) flags to Cargo
 
 ";
 
@@ -39,7 +42,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
     let token = match options.arg_token.clone() {
         Some(token) => token,
         None => {
index 0811535307bd197296dbed9055f47957274aa510..9d52d610b2194d82eac1026836073d88ca9b1bd6 100644 (file)
@@ -17,6 +17,8 @@ pub struct Options {
     flag_verbose: u32,
     flag_frozen: bool,
     flag_locked: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -41,6 +43,7 @@ Options:
     --color WHEN               Coloring: auto, always, never
     --frozen                   Require Cargo.lock and cache are up to date
     --locked                   Require Cargo.lock is up to date
+    -Z FLAG ...                Unstable (nightly-only) flags to Cargo
 ";
 
 pub fn execute(options: Options, config: &Config) -> CliResult {
@@ -48,7 +51,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
     let manifest = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
 
     if options.flag_format_version.is_none() {
index 7dbb00b9671872a2de1d4e687ee8d436dbb82e95..9b0c97d9561ccd006fc8d3b9ae893ed02f72982b 100644 (file)
@@ -15,6 +15,8 @@ pub struct Options {
     flag_vcs: Option<ops::VersionControl>,
     flag_frozen: bool,
     flag_locked: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -38,6 +40,7 @@ Options:
     --color WHEN        Coloring: auto, always, never
     --frozen            Require Cargo.lock and cache are up to date
     --locked            Require Cargo.lock is up to date
+    -Z FLAG ...         Unstable (nightly-only) flags to Cargo
 ";
 
 pub fn execute(options: Options, config: &Config) -> CliResult {
@@ -46,7 +49,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
 
     let Options { flag_bin, flag_lib, arg_path, flag_name, flag_vcs, .. } = options;
 
index 587a968a6bf05091e2cc94c0e49b372e1ba3415e..438bb109deec64138025e8d93b3771f4680fdebd 100644 (file)
@@ -14,6 +14,8 @@ pub struct Options {
     flag_list: bool,
     flag_frozen: bool,
     flag_locked: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -34,6 +36,7 @@ Options:
     --color WHEN             Coloring: auto, always, never
     --frozen                 Require Cargo.lock and cache are up to date
     --locked                 Require Cargo.lock is up to date
+    -Z FLAG ...              Unstable (nightly-only) flags to Cargo
 
 This command will modify the owners for a package on the specified registry (or
 default). Note that owners of a package can upload new versions, yank old
@@ -49,7 +52,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
     let opts = ops::OwnersOptions {
         krate: options.arg_crate,
         token: options.flag_token,
index e4c4af44968756ac9b3853148f34a2f286241e6d..8b88ba882ea45be11c9ef3af4ef17b04a4399970 100644 (file)
@@ -16,6 +16,8 @@ pub struct Options {
     flag_jobs: Option<u32>,
     flag_frozen: bool,
     flag_locked: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -37,6 +39,7 @@ Options:
     --color WHEN            Coloring: auto, always, never
     --frozen                Require Cargo.lock and cache are up to date
     --locked                Require Cargo.lock is up to date
+    -Z FLAG ...             Unstable (nightly-only) flags to Cargo
 ";
 
 pub fn execute(options: Options, config: &Config) -> CliResult {
@@ -44,7 +47,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
     let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
     let ws = Workspace::new(&root, config)?;
     ops::package(&ws, &ops::PackageOpts {
index f8574139458ebaf2ca5078dd2ae47a85f3c445bd..d69c982df9175fe5e5bc4a36ef6af817f34a2b25 100644 (file)
@@ -13,6 +13,8 @@ pub struct Options {
     flag_locked: bool,
     flag_package: Option<String>,
     arg_spec: Option<String>,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -30,6 +32,7 @@ Options:
     --color WHEN             Coloring: auto, always, never
     --frozen                 Require Cargo.lock and cache are up to date
     --locked                 Require Cargo.lock is up to date
+    -Z FLAG ...              Unstable (nightly-only) flags to Cargo
 
 Given a <spec> argument, print out the fully qualified package id specifier.
 This command will generate an error if <spec> is ambiguous as to which package
@@ -58,7 +61,8 @@ pub fn execute(options: Options,
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
     let root = find_root_manifest_for_wd(options.flag_manifest_path.clone(), config.cwd())?;
     let ws = Workspace::new(&root, config)?;
 
index 507496b46c2973d3c420bda7ac037b6d92f1cf9b..d77957109c35cdbdc505e8ef0edbca9e09fb7149 100644 (file)
@@ -18,6 +18,8 @@ pub struct Options {
     flag_dry_run: bool,
     flag_frozen: bool,
     flag_locked: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -41,6 +43,7 @@ Options:
     --color WHEN             Coloring: auto, always, never
     --frozen                 Require Cargo.lock and cache are up to date
     --locked                 Require Cargo.lock is up to date
+    -Z FLAG ...              Unstable (nightly-only) flags to Cargo
 
 ";
 
@@ -49,9 +52,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
-
-
+                     options.flag_locked,
+                     &options.flag_z)?;
 
     let Options {
         flag_token: token,
index 58012cb3469e68722d3be870a8b25e35a89615a2..64f30877d82b4a1e7ce52ad7f95168fc740d9423 100644 (file)
@@ -24,6 +24,8 @@ pub struct Options {
     flag_frozen: bool,
     flag_locked: bool,
     arg_args: Vec<String>,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -50,6 +52,7 @@ Options:
     --message-format FMT         Error format: human, json [default: human]
     --frozen                     Require Cargo.lock and cache are up to date
     --locked                     Require Cargo.lock is up to date
+    -Z FLAG ...                  Unstable (nightly-only) flags to Cargo
 
 If neither `--bin` nor `--example` are given, then if the project only has one
 bin target it will be run. Otherwise `--bin` specifies the bin target to run,
@@ -66,7 +69,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
 
     let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
 
index 95f6d173b86fea7c8dab9e886b777734bf6cb322..fafa8632dcbdafd69a7e0747c72527dcb9bfd716 100644 (file)
@@ -33,6 +33,8 @@ pub struct Options {
     flag_profile: Option<String>,
     flag_frozen: bool,
     flag_locked: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -68,6 +70,7 @@ Options:
     --message-format FMT     Error format: human, json [default: human]
     --frozen                 Require Cargo.lock and cache are up to date
     --locked                 Require Cargo.lock is up to date
+    -Z FLAG ...              Unstable (nightly-only) flags to Cargo
 
 The specified target for the current package (or package specified by SPEC if
 provided) will be compiled along with all of its dependencies. The specified
@@ -90,7 +93,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
 
     let root = find_root_manifest_for_wd(options.flag_manifest_path,
                                          config.cwd())?;
index 82de14c00f528b188a098b021ab0dc285951d2cf..6ff12689cc32cffa1dc27ad269f35082f25f7479 100644 (file)
@@ -31,6 +31,8 @@ pub struct Options {
     flag_all_targets: bool,
     flag_frozen: bool,
     flag_locked: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -66,6 +68,7 @@ Options:
     --message-format FMT     Error format: human, json [default: human]
     --frozen                 Require Cargo.lock and cache are up to date
     --locked                 Require Cargo.lock is up to date
+    -Z FLAG ...              Unstable (nightly-only) flags to Cargo
 
 The specified target for the current package (or package specified by SPEC if
 provided) will be documented with the specified <opts>... being passed to the
@@ -85,7 +88,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
 
     let root = find_root_manifest_for_wd(options.flag_manifest_path,
                                          config.cwd())?;
index 8a456d124b7f7d983dac8c4856d9111778a4fd44..17b8ed3aa45626fc2d7c2eea6738cc3a8fff8f4f 100644 (file)
@@ -14,6 +14,8 @@ pub struct Options {
     flag_frozen: bool,
     flag_locked: bool,
     arg_query: Vec<String>,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -33,6 +35,7 @@ Options:
     --limit LIMIT            Limit the number of results (default: 10, max: 100)
     --frozen                 Require Cargo.lock and cache are up to date
     --locked                 Require Cargo.lock is up to date
+    -Z FLAG ...              Unstable (nightly-only) flags to Cargo
 ";
 
 pub fn execute(options: Options, config: &Config) -> CliResult {
@@ -40,7 +43,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
     let Options {
         flag_index: index,
         flag_host: host,    // TODO: Depricated, remove
index 39322feb5f912bcba6a13f80bd7d09283ab4d9fd..b27421a2b640e79d4597c7335d4787633395d59f 100644 (file)
@@ -37,6 +37,8 @@ pub struct Options {
     flag_locked: bool,
     flag_all: bool,
     flag_exclude: Vec<String>,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -76,6 +78,7 @@ Options:
     --no-fail-fast               Run all tests regardless of failure
     --frozen                     Require Cargo.lock and cache are up to date
     --locked                     Require Cargo.lock is up to date
+    -Z FLAG ...                  Unstable (nightly-only) flags to Cargo
 
 All of the trailing arguments are passed to the test binaries generated for
 filtering tests and generally providing options configuring how they run. For
@@ -120,7 +123,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
 
     let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
     let ws = Workspace::new(&root, config)?;
index 619b029f511bee7f5d13d39f421ded2ddb35dd5b..69079265e665e2437d0f79b5a41cc89ba0d08755 100644 (file)
@@ -10,6 +10,8 @@ pub struct Options {
     flag_color: Option<String>,
     flag_frozen: bool,
     flag_locked: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 
     arg_spec: String,
 }
@@ -30,6 +32,7 @@ Options:
     --color WHEN              Coloring: auto, always, never
     --frozen                  Require Cargo.lock and cache are up to date
     --locked                  Require Cargo.lock is up to date
+    -Z FLAG ...               Unstable (nightly-only) flags to Cargo
 
 The argument SPEC is a package id specification (see `cargo help pkgid`) to
 specify which crate should be uninstalled. By default all binaries are
@@ -42,7 +45,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
 
     let root = options.flag_root.as_ref().map(|s| &s[..]);
     ops::uninstall(root, &options.arg_spec, &options.flag_bin, config)?;
index 1890ab7cc61b46a4318e33dea4bdca2f7a08030f..a9a57312ee1e524248d9d9309309cea7f67b88fd 100644 (file)
@@ -16,6 +16,8 @@ pub struct Options {
     flag_color: Option<String>,
     flag_frozen: bool,
     flag_locked: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -35,6 +37,7 @@ Options:
     --color WHEN                 Coloring: auto, always, never
     --frozen                     Require Cargo.lock and cache are up to date
     --locked                     Require Cargo.lock is up to date
+    -Z FLAG ...                  Unstable (nightly-only) flags to Cargo
 
 This command requires that a `Cargo.lock` already exists as generated by
 `cargo build` or related commands.
@@ -63,7 +66,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
     let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
 
     let update_opts = ops::UpdateOptions {
index ea03bdd58c4c1830f2f470790413409409ea2eef..00127e1fe076fe685229652f5714356fe72ad1c7 100644 (file)
@@ -17,6 +17,8 @@ pub struct Flags {
     flag_color: Option<String>,
     flag_frozen: bool,
     flag_locked: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub const USAGE: &'static str = "
@@ -34,6 +36,7 @@ Options:
     --color WHEN            Coloring: auto, always, never
     --frozen                Require Cargo.lock and cache are up to date
     --locked                Require Cargo.lock is up to date
+    -Z FLAG ...             Unstable (nightly-only) flags to Cargo
 ";
 
 pub fn execute(args: Flags, config: &Config) -> CliResult {
@@ -41,7 +44,8 @@ pub fn execute(args: Flags, config: &Config) -> CliResult {
                      args.flag_quiet,
                      &args.flag_color,
                      args.flag_frozen,
-                     args.flag_locked)?;
+                     args.flag_locked,
+                     &args.flag_z)?;
 
     let mut contents = String::new();
     let filename = args.flag_manifest_path.unwrap_or("Cargo.toml".into());
index de48639ecff4b8631d55b17ea130e7d71fe55dea..0526c4c4f0ddac9fd6ea83d222f0f3f1a57a2004 100644 (file)
@@ -13,6 +13,8 @@ pub struct Options {
     flag_undo: bool,
     flag_frozen: bool,
     flag_locked: bool,
+    #[serde(rename = "flag_Z")]
+    flag_z: Vec<String>,
 }
 
 pub static USAGE: &'static str = "
@@ -32,6 +34,7 @@ Options:
     --color WHEN        Coloring: auto, always, never
     --frozen            Require Cargo.lock and cache are up to date
     --locked            Require Cargo.lock is up to date
+    -Z FLAG ...         Unstable (nightly-only) flags to Cargo
 
 The yank command removes a previously pushed crate's version from the server's
 index. This command does not delete any data, and the crate will still be
@@ -47,7 +50,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
                      options.flag_quiet,
                      &options.flag_color,
                      options.flag_frozen,
-                     options.flag_locked)?;
+                     options.flag_locked,
+                     &options.flag_z)?;
     ops::yank(config,
               options.arg_crate,
               options.flag_vers,
index 4a24024c1a337efa253692be60a2f64d52f83f9b..51b82076ce9d37a5d7bb5a4b613054602b75d922 100644 (file)
@@ -63,8 +63,8 @@ macro_rules! features {
         impl Feature {
             $(
                 pub fn $feature() -> &'static Feature {
-                    fn get(features: &Features) -> &bool {
-                        &features.$feature
+                    fn get(features: &Features) -> bool {
+                        features.$feature
                     }
                     static FEAT: Feature = Feature {
                         name: stringify!($feature),
@@ -73,6 +73,10 @@ macro_rules! features {
                     &FEAT
                 }
             )*
+
+            fn is_enabled(&self, features: &Features) -> bool {
+                (self.get)(features)
+            }
         }
 
         impl Features {
@@ -123,7 +127,7 @@ features! {
 
 pub struct Feature {
     name: &'static str,
-    get: fn(&Features) -> &bool,
+    get: fn(&Features) -> bool,
 }
 
 impl Features {
@@ -173,7 +177,7 @@ impl Features {
     }
 
     pub fn require(&self, feature: &Feature) -> CargoResult<()> {
-        if *(feature.get)(self) {
+        if feature.is_enabled(self) {
             Ok(())
         } else {
             let feature = feature.name.replace("_", "-");
@@ -196,6 +200,70 @@ impl Features {
     }
 }
 
+/// A parsed represetnation 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.
+///
+/// This struct doesn't have quite the same convenience macro that the features
+/// have above, but the procedure should still be relatively stable for adding a
+/// new unstable flag:
+///
+/// 1. First, add a field to this `CliUnstable` structure. All flags are allowed
+///    to have a value as the `-Z` flags are either of the form `-Z foo` or
+///    `-Z foo=bar`, and it's up to you how to parse `bar`.
+///
+/// 2. Add an arm to the match statement in `CliUnstable::add` below to match on
+///    your new flag. The key (`k`) is what you're matching on and the value is
+///    in `v`.
+///
+/// 3. (optional) Add a new parsing function to parse your datatype. As of now
+///    there's an example for `bool`, but more can be added!
+///
+/// 4. In Cargo use `config.cli_unstable()` to get a reference to this structure
+///    and then test for your flag or your value and act accordingly.
+///
+/// If you have any trouble with this, please let us know!
+#[derive(Default, Debug)]
+pub struct CliUnstable {
+    pub print_im_a_teapot: bool,
+}
+
+impl CliUnstable {
+    pub fn parse(&mut self, flags: &[String]) -> CargoResult<()> {
+        if flags.len() > 0 && !nightly_features_allowed() {
+            bail!("the `-Z` flag is only accepted on the nightly channel of Cargo")
+        }
+        for flag in flags {
+            self.add(flag)?;
+        }
+        Ok(())
+    }
+
+    fn add(&mut self, flag: &str) -> CargoResult<()> {
+        let mut parts = flag.splitn(2, '=');
+        let k = parts.next().unwrap();
+        let v = parts.next();
+
+        fn parse_bool(value: Option<&str>) -> CargoResult<bool> {
+            match value {
+                None |
+                Some("yes") => Ok(true),
+                Some("no") => Ok(false),
+                Some(s) => bail!("expected `no` or `yes`, found: {}", s),
+            }
+        }
+
+        match k {
+            "print-im-a-teapot" => self.print_im_a_teapot = parse_bool(v)?,
+            _ => bail!("unknown `-Z` flag specified: {}", k),
+        }
+
+        Ok(())
+    }
+}
+
 fn channel() -> String {
     env::var("__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS").unwrap_or_else(|_| {
         ::version().cfg_info.map(|c| c.release_channel)
index 908899985b2b78e5eafba8a069e2071ec7ef106c..74187bc9cc4b0326c705cfb8a376edf131fb2a6a 100644 (file)
@@ -9,6 +9,7 @@ use url::Url;
 
 use core::{Dependency, PackageId, Summary, SourceId, PackageIdSpec};
 use core::{WorkspaceConfig, Features, Feature};
+use util::Config;
 use util::toml::TomlManifest;
 use util::errors::*;
 
@@ -321,6 +322,15 @@ impl Manifest {
 
         Ok(())
     }
+
+    // Just a helper function to test out `-Z` flags on Cargo
+    pub fn print_teapot(&self, config: &Config) {
+        if let Some(teapot) = self.im_a_teapot {
+            if config.cli_unstable().print_im_a_teapot {
+                println!("im-a-teapot = {}", teapot);
+            }
+        }
+    }
 }
 
 impl VirtualManifest {
index 2323b6c4033ddc86f800edd19bf2d7d476889c38..2eb0c608b028e6a75e9e26ba5a1c365cfaf36bd3 100644 (file)
@@ -1,5 +1,5 @@
 pub use self::dependency::Dependency;
-pub use self::features::{Features, Feature};
+pub use self::features::{Features, Feature, CliUnstable};
 pub use self::manifest::{EitherManifest, VirtualManifest};
 pub use self::manifest::{Manifest, Target, TargetKind, Profile, LibKind, Profiles};
 pub use self::package::{Package, PackageSet};
index c1931fc0a407960b83466c1d6645e349df711d50..894d2a7a24da5adc14ab95c5519e2133e241b58a 100644 (file)
@@ -232,6 +232,7 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>,
         }
     } else {
         let root_package = ws.current()?;
+        root_package.manifest().print_teapot(ws.config());
         let all_features = resolve_all_features(&resolve_with_overrides,
                                                 root_package.package_id());
         generate_targets(root_package, profiles, mode, filter, &all_features, release)?;
index e86877eae657b84ad345fc7011fee3ed8d781535..359ec01ab9c30103dd12e109d060e6a8ea584135 100644 (file)
@@ -1,4 +1,4 @@
-use std::cell::{RefCell, RefMut, Cell};
+use std::cell::{RefCell, RefMut, Cell, Ref};
 use std::collections::HashSet;
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::collections::hash_map::HashMap;
@@ -12,7 +12,7 @@ use std::path::{Path, PathBuf};
 use std::str::FromStr;
 use std::sync::{Once, ONCE_INIT};
 
-use core::Shell;
+use core::{Shell, CliUnstable};
 use core::shell::Verbosity;
 use jobserver;
 use serde::{Serialize, Serializer};
@@ -39,6 +39,7 @@ pub struct Config {
     frozen: Cell<bool>,
     locked: Cell<bool>,
     jobserver: Option<jobserver::Client>,
+    cli_flags: RefCell<CliUnstable>,
 }
 
 impl Config {
@@ -74,6 +75,7 @@ impl Config {
                     Some((*GLOBAL_JOBSERVER).clone())
                 }
             },
+            cli_flags: RefCell::new(CliUnstable::default()),
         }
     }
 
@@ -371,7 +373,8 @@ impl Config {
                      quiet: Option<bool>,
                      color: &Option<String>,
                      frozen: bool,
-                     locked: bool) -> CargoResult<()> {
+                     locked: bool,
+                     unstable_flags: &[String]) -> CargoResult<()> {
         let extra_verbose = verbose >= 2;
         let verbose = if verbose == 0 {None} else {Some(true)};
 
@@ -410,10 +413,15 @@ impl Config {
         self.extra_verbose.set(extra_verbose);
         self.frozen.set(frozen);
         self.locked.set(locked);
+        self.cli_flags.borrow_mut().parse(unstable_flags)?;
 
         Ok(())
     }
 
+    pub fn cli_unstable(&self) -> Ref<CliUnstable> {
+        self.cli_flags.borrow()
+    }
+
     pub fn extra_verbose(&self) -> bool {
         self.extra_verbose.get()
     }
index 2f88f3867d5c26c17e52545340545782ac5724f4..fde2727d96d55ab1feb9209b412796d806d3f43c 100644 (file)
@@ -122,6 +122,54 @@ Caused by:
 "));
 }
 
+#[test]
+fn nightly_feature_requires_nightly_in_dep() {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "b"
+            version = "0.0.1"
+            authors = []
+
+            [dependencies]
+            a = { path = "a" }
+        "#)
+        .file("src/lib.rs", "")
+        .file("a/Cargo.toml", r#"
+            [package]
+            name = "a"
+            version = "0.0.1"
+            authors = []
+            im-a-teapot = true
+            cargo-features = ["test-dummy-unstable"]
+        "#)
+        .file("a/src/lib.rs", "");
+    assert_that(p.cargo_process("build")
+                 .masquerade_as_nightly_cargo(),
+                execs().with_status(0)
+                       .with_stderr("\
+[COMPILING] a [..]
+[COMPILING] b [..]
+[FINISHED] [..]
+"));
+
+    assert_that(p.cargo("build"),
+                execs().with_status(101)
+                       .with_stderr("\
+error: failed to load source for a dependency on `a`
+
+Caused by:
+  Unable to update [..]
+
+Caused by:
+  failed to parse manifest at `[..]`
+
+Caused by:
+  the cargo feature `test-dummy-unstable` requires a nightly version of Cargo, \
+  but this is the `stable` channel
+"));
+}
+
 #[test]
 fn cant_publish() {
     let p = project("foo")
@@ -152,3 +200,60 @@ Caused by:
   but this is the `stable` channel
 "));
 }
+
+#[test]
+fn z_flags_rejected() {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "a"
+            version = "0.0.1"
+            authors = []
+            im-a-teapot = true
+            cargo-features = ["test-dummy-unstable"]
+        "#)
+        .file("src/lib.rs", "");
+    assert_that(p.cargo_process("build")
+                 .arg("-Zprint-im-a-teapot"),
+                execs().with_status(101)
+                       .with_stderr("\
+error: the `-Z` flag is only accepted on the nightly channel of Cargo
+"));
+
+    assert_that(p.cargo("build")
+                 .masquerade_as_nightly_cargo()
+                 .arg("-Zarg"),
+                execs().with_status(101)
+                       .with_stderr("\
+error: unknown `-Z` flag specified: arg
+"));
+
+    assert_that(p.cargo("build")
+                 .masquerade_as_nightly_cargo()
+                 .arg("-Zprint-im-a-teapot"),
+                execs().with_status(0)
+                       .with_stdout("im-a-teapot = true\n")
+                       .with_stderr("\
+[COMPILING] a [..]
+[FINISHED] [..]
+"));
+}
+
+#[test]
+fn publish_rejected() {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "a"
+            version = "0.0.1"
+            authors = []
+            cargo-features = ["test-dummy-unstable"]
+        "#)
+        .file("src/lib.rs", "");
+    assert_that(p.cargo_process("package")
+                 .masquerade_as_nightly_cargo(),
+                execs().with_status(101)
+                       .with_stderr("\
+error: cannot package or publish crates which activate nightly-only cargo features
+"));
+}