diff --git a/src/cargo/util/toml_mut/manifest.rs b/src/cargo/util/toml_mut/manifest.rs index f3fc150e12a..5529b802958 100644 --- a/src/cargo/util/toml_mut/manifest.rs +++ b/src/cargo/util/toml_mut/manifest.rs @@ -496,6 +496,11 @@ fn fix_feature_activations( for idx in remove_list.iter().rev() { feature_values.remove(*idx); } + if !remove_list.is_empty() { + // HACK: Instead of cleaning up the users formatting from having removed a feature, we just + // re-format the whole feature list + feature_values.fmt(); + } if status == DependencyStatus::Required { for value in feature_values.iter_mut() { @@ -511,13 +516,13 @@ fn fix_feature_activations( } = parsed_value { if dep_name == dep_key && weak { - *value = format!("{dep_name}/{dep_feature}").into(); + let mut new_value = toml_edit::Value::from(format!("{dep_name}/{dep_feature}")); + *new_value.decor_mut() = value.decor().clone(); + *value = new_value; } } } } - - feature_values.fmt(); } pub fn str_or_1_len_table(item: &toml_edit::Item) -> bool { diff --git a/tests/testsuite/cargo_add/mod.rs b/tests/testsuite/cargo_add/mod.rs index d62964e8805..4a03220dde0 100644 --- a/tests/testsuite/cargo_add/mod.rs +++ b/tests/testsuite/cargo_add/mod.rs @@ -95,6 +95,7 @@ mod path_dev; mod path_inferred_name; mod path_inferred_name_conflicts_full_feature; mod path_normalized_name; +mod preserve_features_table; mod preserve_sorted; mod preserve_unsorted; mod quiet; diff --git a/tests/testsuite/cargo_add/preserve_features_table/in/Cargo.toml b/tests/testsuite/cargo_add/preserve_features_table/in/Cargo.toml new file mode 100644 index 00000000000..d32f5eb82b4 --- /dev/null +++ b/tests/testsuite/cargo_add/preserve_features_table/in/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "xxx" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +your-face = { version = "99999.0.0", optional = true } + +[features] +default = [ + "a", + "b", + "c", +] +a = [ + "your-face?/nose", # but not the mouth and nose +] +b = [] +c = [] diff --git a/tests/testsuite/cargo_add/preserve_features_table/in/src/lib.rs b/tests/testsuite/cargo_add/preserve_features_table/in/src/lib.rs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/testsuite/cargo_add/preserve_features_table/mod.rs b/tests/testsuite/cargo_add/preserve_features_table/mod.rs new file mode 100644 index 00000000000..1998fa7420e --- /dev/null +++ b/tests/testsuite/cargo_add/preserve_features_table/mod.rs @@ -0,0 +1,31 @@ +use cargo_test_support::compare::assert_ui; +use cargo_test_support::prelude::*; +use cargo_test_support::Project; + +use cargo_test_support::curr_dir; + +#[cargo_test] +fn case() { + cargo_test_support::registry::init(); + cargo_test_support::registry::Package::new("your-face", "99999.0.0+my-package") + .feature("nose", &[]) + .feature("mouth", &[]) + .feature("eyes", &[]) + .feature("ears", &[]) + .publish(); + + 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("your-face --no-optional") + .current_dir(cwd) + .assert() + .success() + .stdout_matches_path(curr_dir!().join("stdout.log")) + .stderr_matches_path(curr_dir!().join("stderr.log")); + + assert_ui().subset_matches(curr_dir!().join("out"), &project_root); +} diff --git a/tests/testsuite/cargo_add/preserve_features_table/out/Cargo.toml b/tests/testsuite/cargo_add/preserve_features_table/out/Cargo.toml new file mode 100644 index 00000000000..39acd101601 --- /dev/null +++ b/tests/testsuite/cargo_add/preserve_features_table/out/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "xxx" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +your-face = { version = "99999.0.0" } + +[features] +default = [ + "a", + "b", + "c", +] +a = [ + "your-face/nose", # but not the mouth and nose +] +b = [] +c = [] diff --git a/tests/testsuite/cargo_add/preserve_features_table/stderr.log b/tests/testsuite/cargo_add/preserve_features_table/stderr.log new file mode 100644 index 00000000000..796b9601b4d --- /dev/null +++ b/tests/testsuite/cargo_add/preserve_features_table/stderr.log @@ -0,0 +1,7 @@ + Updating `dummy-registry` index + Adding your-face v99999.0.0 to dependencies. + Features: + - ears + - eyes + - mouth + - nose diff --git a/tests/testsuite/cargo_add/preserve_features_table/stdout.log b/tests/testsuite/cargo_add/preserve_features_table/stdout.log new file mode 100644 index 00000000000..e69de29bb2d