Skip to content

Commit

Permalink
make unknown features on cargo add more discoverable
Browse files Browse the repository at this point in the history
  • Loading branch information
Emilgardis committed Sep 19, 2022
1 parent d924a25 commit baee4cb
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 24 deletions.
59 changes: 57 additions & 2 deletions src/cargo/ops/cargo_add/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::path::Path;
use anyhow::Context as _;
use cargo_util::paths;
use indexmap::IndexSet;
use itertools::Itertools;
use termcolor::Color::Green;
use termcolor::Color::Red;
use termcolor::ColorSpec;
Expand Down Expand Up @@ -101,7 +102,6 @@ pub fn add(workspace: &Workspace<'_>, options: &AddOptions<'_>) -> CargoResult<(
});
for dep in deps {
print_action_msg(&mut options.config.shell(), &dep, &dep_table)?;
print_dep_table_msg(&mut options.config.shell(), &dep)?;
if let Some(Source::Path(src)) = dep.source() {
if src.path == manifest.path.parent().unwrap_or_else(|| Path::new("")) {
anyhow::bail!(
Expand All @@ -126,11 +126,66 @@ pub fn add(workspace: &Workspace<'_>, options: &AddOptions<'_>) -> CargoResult<(
inherited_features.iter().map(|s| s.as_str()).collect();
unknown_features.extend(inherited_features.difference(&available_features).copied());
}

unknown_features.sort();

if !unknown_features.is_empty() {
anyhow::bail!("unrecognized features: {unknown_features:?}");
let (activated, deactivated) = dep.features();
let deactivated = deactivated
.iter()
.filter(|f| !unknown_features.contains(f))
.collect::<Vec<_>>();
let activated = activated
.iter()
.filter(|f| !unknown_features.contains(f))
.collect::<Vec<_>>();
let mut message = format!(
"unrecognized feature{} for crate {}: {}\n",
if unknown_features.len() == 1 { "" } else { "s" },
dep.name,
unknown_features.iter().format(", "),
);
if activated.is_empty() && deactivated.is_empty() {
write!(message, "no features available for crate {}", dep.name)?;
} else {
if !deactivated.is_empty() {
writeln!(
message,
"disabled features:\n {}",
deactivated
.iter()
.map(|s| s.to_string())
.coalesce(|x, y| if x.len() + y.len() < 78 {
Ok(format!("{x}, {y}"))
} else {
Err((x, y))
})
.into_iter()
.format("\n ")
)?
}
if !activated.is_empty() {
writeln!(
message,
"enabled features:\n {}",
activated
.iter()
.map(|s| s.to_string())
.coalesce(|x, y| if x.len() + y.len() < 78 {
Ok(format!("{x}, {y}"))
} else {
Err((x, y))
})
.into_iter()
.format("\n ")
)?
}
}
anyhow::bail!(message.trim().to_owned());
}

print_dep_table_msg(&mut options.config.shell(), &dep)?;

manifest.insert_into_table(&dep_table, &dep)?;
manifest.gc_dep(dep.toml_key());
}
Expand Down
19 changes: 19 additions & 0 deletions tests/testsuite/cargo_add/features_unknown/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,22 @@ fn features_unknown() {

assert_ui().subset_matches(curr_dir!().join("out"), &project_root);
}

#[cargo_test]
fn features_unknown_empty() {
init_registry();
let project = Project::from_template(curr_dir!().join("in"));
let project_root = project.root();
let cwd = &project_root;

snapbox::cmd::Command::cargo_ui()
.arg("add")
.arg_line("my-package --features noze")
.current_dir(cwd)
.assert()
.code(101)
.stdout_matches_path(curr_dir!().join("stdout_no_features.log"))
.stderr_matches_path(curr_dir!().join("stderr_no_features.log"));

assert_ui().subset_matches(curr_dir!().join("out"), &project_root);
}
10 changes: 3 additions & 7 deletions tests/testsuite/cargo_add/features_unknown/stderr.log
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
Updating `dummy-registry` index
Adding your-face v99999.0.0 to dependencies.
Features:
+ noze
- ears
- eyes
- mouth
- nose
error: unrecognized features: ["noze"]
error: unrecognized feature for crate your-face: noze
disabled features:
ears, eyes, mouth, nose
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Updating `dummy-registry` index
Adding my-package v99999.0.0 to dependencies.
error: unrecognized feature for crate my-package: noze
no features available for crate my-package
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ version = "0.0.0"
default-base = []
default-test-base = []
default-merge-base = []
default = ["default-base", "default-test-base", "default-merge-base"]
long-feature-name-because-of-formatting-reasons = []
default = [
"default-base",
"default-test-base",
"default-merge-base",
"long-feature-name-because-of-formatting-reasons",
]
test-base = []
test = ["test-base", "default-test-base"]
merge-base = []
merge = ["merge-base", "default-merge-base"]
unrelated = []
unrelated = []
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ version = "0.0.0"
default-base = []
default-test-base = []
default-merge-base = []
default = ["default-base", "default-test-base", "default-merge-base"]
long-feature-name-because-of-formatting-reasons = []
default = [
"default-base",
"default-test-base",
"default-merge-base",
"long-feature-name-because-of-formatting-reasons",
]
test-base = []
test = ["test-base", "default-test-base"]
merge-base = []
merge = ["merge-base", "default-merge-base"]
unrelated = []
unrelated = []
17 changes: 6 additions & 11 deletions tests/testsuite/cargo_add/unknown_inherited_feature/stderr.log
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
Adding foo (workspace) to dependencies.
Features as of v0.0.0:
+ default-base
+ default-merge-base
+ default-test-base
+ not_recognized
+ test
+ test-base
- merge
- merge-base
- unrelated
error: unrecognized features: ["not_recognized"]
error: unrecognized feature for crate foo: not_recognized
disabled features:
merge, merge-base, unrelated
enabled features:
default-base, default-merge-base, default-test-base
long-feature-name-because-of-formatting-reasons, test, test-base

0 comments on commit baee4cb

Please sign in to comment.