diff --git a/src/cargo/ops/cargo_install.rs b/src/cargo/ops/cargo_install.rs index 21de0997b..d726eafc0 100644 --- a/src/cargo/ops/cargo_install.rs +++ b/src/cargo/ops/cargo_install.rs @@ -14,6 +14,7 @@ use crate::{drop_println, ops}; use anyhow::{bail, format_err, Context as _}; use cargo_util::paths; +use itertools::Itertools; use semver::VersionReq; use tempfile::Builder as TempFileBuilder; @@ -360,10 +361,33 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> { // // Note that we know at this point that _if_ bins or examples is set to `::Just`, // they're `::Just([])`, which is `FilterRule::none()`. - if self.pkg.targets().iter().any(|t| t.is_executable()) { - self.config - .shell() - .warn("none of the package's binaries are available for install using the selected features")?; + let binaries: Vec<_> = self.pkg.targets().iter().filter(|t| t.is_bin()).collect(); + if !binaries.is_empty() { + let target_features_message = binaries + .iter() + .map(|b| { + let name = b.name(); + let features = b + .required_features() + .unwrap_or(&Vec::new()) + .iter() + .map(|f| format!("`{f}`")) + .join(", "); + format!(" Target `{name}` requires the features: {features}") + }) + .join("\n"); + let example_features = binaries[0] + .required_features() + .map(|f| f.join(" ")) + .unwrap_or_else(|| String::new()); + let consider_enabling_message = format!("Consider enabling some of them by passing, e.g., `--features=\"{example_features}\"`"); + let message = format!( + "\ +none of the package's binaries are available for install using the selected features +{target_features_message} +{consider_enabling_message}" + ); + self.config.shell().warn(message)?; } return Ok(false); diff --git a/tests/testsuite/required_features.rs b/tests/testsuite/required_features.rs index 340a138ca..92a7b3d13 100644 --- a/tests/testsuite/required_features.rs +++ b/tests/testsuite/required_features.rs @@ -640,6 +640,8 @@ fn install_default_features() { [INSTALLING] foo v0.0.1 ([..]) [FINISHED] release [optimized] target(s) in [..] [WARNING] none of the package's binaries are available for install using the selected features + Target `foo` requires the features: `a` +Consider enabling some of them by passing, e.g., `--features=\"a\"` ", ) .run(); @@ -792,6 +794,9 @@ fn install_multiple_required_features() { [INSTALLING] foo v0.0.1 ([..]) [FINISHED] release [optimized] target(s) in [..] [WARNING] none of the package's binaries are available for install using the selected features + Target `foo_1` requires the features: `b`, `c` + Target `foo_2` requires the features: `a` +Consider enabling some of them by passing, e.g., `--features=\"b c\"` ", ) .run(); @@ -802,6 +807,9 @@ fn install_multiple_required_features() { [WARNING] Target filter `bins` specified, but no targets matched. This is a no-op [FINISHED] release [optimized] target(s) in [..] [WARNING] none of the package's binaries are available for install using the selected features + Target `foo_1` requires the features: `b`, `c` + Target `foo_2` requires the features: `a` +Consider enabling some of them by passing, e.g., `--features=\"b c\"` ", ) .run(); @@ -812,6 +820,9 @@ fn install_multiple_required_features() { [WARNING] Target filter `examples` specified, but no targets matched. This is a no-op [FINISHED] release [optimized] target(s) in [..] [WARNING] none of the package's binaries are available for install using the selected features + Target `foo_1` requires the features: `b`, `c` + Target `foo_2` requires the features: `a` +Consider enabling some of them by passing, e.g., `--features=\"b c\"` ", ) .run(); @@ -822,6 +833,9 @@ fn install_multiple_required_features() { [WARNING] Target filters `bins`, `examples` specified, but no targets matched. This is a no-op [FINISHED] release [optimized] target(s) in [..] [WARNING] none of the package's binaries are available for install using the selected features + Target `foo_1` requires the features: `b`, `c` + Target `foo_2` requires the features: `a` +Consider enabling some of them by passing, e.g., `--features=\"b c\"` ", ) .run(); @@ -1080,6 +1094,8 @@ Consider enabling them by passing, e.g., `--features=\"bar/a\"` [INSTALLING] foo v0.0.1 ([..]) [FINISHED] release [optimized] target(s) in [..] [WARNING] none of the package's binaries are available for install using the selected features + Target `foo` requires the features: `bar/a` +Consider enabling some of them by passing, e.g., `--features=\"bar/a\"` ", ) .run();