]> git.proxmox.com Git - cargo.git/commitdiff
Rework cargo-features a little.
authorEric Huss <eric@huss.org>
Thu, 21 Jan 2021 04:08:52 +0000 (20:08 -0800)
committerEric Huss <eric@huss.org>
Thu, 21 Jan 2021 20:16:35 +0000 (12:16 -0800)
* Add `removed` support.
* Include the version where it is stabilized.
* Include a links to the documentation in the error/warning messages.

src/cargo/core/features.rs
tests/testsuite/cargo_features.rs
tests/testsuite/pub_priv.rs
tests/testsuite/publish_lockfile.rs

index 0a4ce2a2831a8187ca1504f9a18fdc07ff1cfa9f..70b3fd43259d3665a648d34b6313664d4c376c2d 100644 (file)
@@ -116,13 +116,12 @@ impl FromStr for Edition {
 enum Status {
     Stable,
     Unstable,
+    Removed,
 }
 
 macro_rules! features {
     (
-        pub struct Features {
-            $([$stab:ident] $feature:ident: bool,)*
-        }
+        $(($stab:ident, $feature:ident, $version:expr, $docs:expr),)*
     ) => (
         #[derive(Default, Clone, Debug)]
         pub struct Features {
@@ -138,6 +137,9 @@ macro_rules! features {
                     }
                     static FEAT: Feature = Feature {
                         name: stringify!($feature),
+                        stability: stab!($stab),
+                        version: $version,
+                        docs: $docs,
                         get,
                     };
                     &FEAT
@@ -150,14 +152,14 @@ macro_rules! features {
         }
 
         impl Features {
-            fn status(&mut self, feature: &str) -> Option<(&mut bool, Status)> {
+            fn status(&mut self, feature: &str) -> Option<(&mut bool, &'static Feature)> {
                 if feature.contains("_") {
                     return None
                 }
                 let feature = feature.replace("-", "_");
                 $(
                     if feature == stringify!($feature) {
-                        return Some((&mut self.$feature, stab!($stab)))
+                        return Some((&mut self.$feature, Feature::$feature()))
                     }
                 )*
                 None
@@ -173,6 +175,9 @@ macro_rules! stab {
     (unstable) => {
         Status::Unstable
     };
+    (removed) => {
+        Status::Removed
+    };
 }
 
 // A listing of all features in Cargo.
@@ -187,57 +192,64 @@ macro_rules! stab {
 // character is translated to `-` when specified in the `cargo-features`
 // manifest entry in `Cargo.toml`.
 features! {
-    pub struct Features {
-
-        // A dummy feature that doesn't actually gate anything, but it's used in
-        // testing to ensure that we can enable stable features.
-        [stable] test_dummy_stable: bool,
+    // A dummy feature that doesn't actually gate anything, but it's used in
+    // testing to ensure that we can enable stable features.
+    (stable, test_dummy_stable, "1.0", ""),
 
-        // A dummy feature that gates the usage of the `im-a-teapot` manifest
-        // entry. This is basically just intended for tests.
-        [unstable] test_dummy_unstable: bool,
+    // A dummy feature that gates the usage of the `im-a-teapot` manifest
+    // entry. This is basically just intended for tests.
+    (unstable, test_dummy_unstable, "", "reference/unstable.html"),
 
-        // Downloading packages from alternative registry indexes.
-        [stable] alternative_registries: bool,
+    // Downloading packages from alternative registry indexes.
+    (stable, alternative_registries, "1.34", "reference/registries.html"),
 
-        // Using editions
-        [stable] edition: bool,
+    // Using editions
+    (stable, edition, "1.31", "reference/manifest.html#the-edition-field"),
 
-        // Renaming a package in the manifest via the `package` key
-        [stable] rename_dependency: bool,
+    // Renaming a package in the manifest via the `package` key
+    (stable, rename_dependency, "1.31", "reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml"),
 
-        // Whether a lock file is published with this crate
-        // This is deprecated, and will likely be removed in a future version.
-        [unstable] publish_lockfile: bool,
+    // Whether a lock file is published with this crate
+    (removed, publish_lockfile, "", PUBLISH_LOCKFILE_REMOVED),
 
-        // Overriding profiles for dependencies.
-        [stable] profile_overrides: bool,
+    // Overriding profiles for dependencies.
+    (stable, profile_overrides, "1.41", "reference/profiles.html#overrides"),
 
-        // "default-run" manifest option,
-        [stable] default_run: bool,
+    // "default-run" manifest option,
+    (stable, default_run, "1.37", "reference/manifest.html#the-default-run-field"),
 
-        // Declarative build scripts.
-        [unstable] metabuild: bool,
+    // Declarative build scripts.
+    (unstable, metabuild, "", "reference/unstable.html#metabuild"),
 
-        // Specifying the 'public' attribute on dependencies
-        [unstable] public_dependency: bool,
+    // Specifying the 'public' attribute on dependencies
+    (unstable, public_dependency, "", "reference/unstable.html#public-dependency"),
 
-        // Allow to specify profiles other than 'dev', 'release', 'test', etc.
-        [unstable] named_profiles: bool,
+    // Allow to specify profiles other than 'dev', 'release', 'test', etc.
+    (unstable, named_profiles, "", "reference/unstable.html#custom-named-profiles"),
 
-        // Opt-in new-resolver behavior.
-        [stable] resolver: bool,
+    // Opt-in new-resolver behavior.
+    (stable, resolver, "1.51", "reference/resolver.html#resolver-versions"),
 
-        // Allow to specify whether binaries should be stripped.
-        [unstable] strip: bool,
+    // Allow to specify whether binaries should be stripped.
+    (unstable, strip, "", "reference/unstable.html#profile-strip-option"),
 
-        // Specifying a minimal 'rust-version' attribute for crates
-        [unstable] rust_version: bool,
-    }
+    // Specifying a minimal 'rust-version' attribute for crates
+    (unstable, rust_version, "", "reference/unstable.html#rust-version"),
 }
 
+const PUBLISH_LOCKFILE_REMOVED: &str = "The publish-lockfile key in Cargo.toml \
+    has been removed. The Cargo.lock file is always included when a package is \
+    published if the package contains a binary target. `cargo install` requires \
+    the `--locked` flag to use the Cargo.lock file.\n\
+    See https://doc.rust-lang.org/cargo/commands/cargo-package.html and \
+    https://doc.rust-lang.org/cargo/commands/cargo-install.html for more \
+    information.";
+
 pub struct Feature {
     name: &'static str,
+    stability: Status,
+    version: &'static str,
+    docs: &'static str,
     get: fn(&Features) -> bool,
 }
 
@@ -251,35 +263,61 @@ impl Features {
         Ok(ret)
     }
 
-    fn add(&mut self, feature: &str, warnings: &mut Vec<String>) -> CargoResult<()> {
-        let (slot, status) = match self.status(feature) {
+    fn add(&mut self, feature_name: &str, warnings: &mut Vec<String>) -> CargoResult<()> {
+        let (slot, feature) = match self.status(feature_name) {
             Some(p) => p,
-            None => bail!("unknown cargo feature `{}`", feature),
+            None => bail!("unknown cargo feature `{}`", feature_name),
         };
 
         if *slot {
-            bail!("the cargo feature `{}` has already been activated", feature);
+            bail!(
+                "the cargo feature `{}` has already been activated",
+                feature_name
+            );
         }
 
-        match status {
+        let see_docs = || {
+            let url_channel = match channel().as_str() {
+                "dev" | "nightly" => "nightly/",
+                "beta" => "beta/",
+                _ => "",
+            };
+            format!(
+                "See https://doc.rust-lang.org/{}cargo/{} for more information \
+                about using this feature.",
+                url_channel, feature.docs
+            )
+        };
+
+        match feature.stability {
             Status::Stable => {
                 let warning = format!(
-                    "the cargo feature `{}` is now stable \
-                     and is no longer necessary to be listed \
-                     in the manifest",
-                    feature
+                    "the cargo feature `{}` has been stabilized in the {} \
+                     release and is no longer necessary to be listed in the \
+                     manifest\n  {}",
+                    feature_name,
+                    feature.version,
+                    see_docs()
                 );
                 warnings.push(warning);
             }
             Status::Unstable if !nightly_features_allowed() => bail!(
                 "the cargo feature `{}` requires a nightly version of \
                  Cargo, but this is the `{}` channel\n\
-                 {}",
-                feature,
+                 {}\n{}",
+                feature_name,
                 channel(),
-                SEE_CHANNELS
+                SEE_CHANNELS,
+                see_docs()
             ),
             Status::Unstable => {}
+            Status::Removed => bail!(
+                "the cargo feature `{}` has been removed\n\
+                Remove the feature from Cargo.toml to remove this error.\n\
+                {}",
+                feature_name,
+                feature.docs
+            ),
         }
 
         *slot = true;
index 0d8aa242ae170bb3f490d57d0ec84a1ecb2becf5..806fc4195c9666f7905191a86436703eb63c3dbe 100644 (file)
@@ -103,8 +103,9 @@ fn stable_feature_warns() {
     p.cargo("build")
         .with_stderr(
             "\
-warning: the cargo feature `test-dummy-stable` is now stable and is no longer \
-necessary to be listed in the manifest
+warning: the cargo feature `test-dummy-stable` has been stabilized in the 1.0 \
+release and is no longer necessary to be listed in the manifest
+  See https://doc.rust-lang.org/[..]cargo/ for more information about using this feature.
 [COMPILING] a [..]
 [FINISHED] [..]
 ",
@@ -149,6 +150,8 @@ Caused by:
   the cargo feature `test-dummy-unstable` requires a nightly version of Cargo, \
   but this is the `stable` channel
   See [..]
+  See https://doc.rust-lang.org/[..]cargo/reference/unstable.html for more \
+  information about using this feature.
 ",
         )
         .run();
@@ -214,6 +217,8 @@ Caused by:
   the cargo feature `test-dummy-unstable` requires a nightly version of Cargo, \
   but this is the `stable` channel
   See [..]
+  See https://doc.rust-lang.org/[..]cargo/reference/unstable.html for more \
+  information about using this feature.
 ",
         )
         .run();
@@ -256,6 +261,8 @@ Caused by:
   the cargo feature `test-dummy-unstable` requires a nightly version of Cargo, \
   but this is the `stable` channel
   See [..]
+  See https://doc.rust-lang.org/[..]cargo/reference/unstable.html for more \
+  information about using this feature.
 ",
         )
         .run();
index a10cb1ef0efc5958b1069e88f464789f58c4a5ca..ba77e7f4a68b84d43557bf49bcef16df610b7820 100644 (file)
@@ -115,6 +115,7 @@ error: failed to parse manifest at `[..]`
 Caused by:
   the cargo feature `public-dependency` requires a nightly version of Cargo, but this is the `stable` channel
   See https://doc.rust-lang.org/book/appendix-07-nightly-rust.html for more information about Rust release channels.
+  See https://doc.rust-lang.org/[..]cargo/reference/unstable.html#public-dependency for more information about using this feature.
 "
         )
         .run()
index 9355de07b1d20812d5ac13caee93ed64db912402..7be995545f8446dfe7cddc5c691ab50cde0d2a87 100644 (file)
@@ -48,12 +48,16 @@ fn deprecated() {
         .build();
     p.cargo("package")
         .masquerade_as_nightly_cargo()
+        .with_status(101)
         .with_stderr(
             "\
-[PACKAGING] foo v0.1.0 ([..])
-[VERIFYING] foo v0.1.0 ([..])
-[COMPILING] foo v0.1.0 ([..])
-[FINISHED] dev [..]
+[ERROR] failed to parse manifest at [..]
+
+Caused by:
+  the cargo feature `publish-lockfile` has been removed
+  Remove the feature from Cargo.toml to remove this error.
+  The publish-lockfile key [..]
+  See [..]
 ",
         )
         .run();