Skip to content

Commit b90f770

Browse files
committed
Auto merge of #13261 - hi-rustin:rustin-patch-not_inherit_workspace_package_table_if_not_members, r=epage
fix: only inherit workspace package table if the new package is a member
2 parents 8859998 + db4ed03 commit b90f770

File tree

8 files changed

+108
-93
lines changed

8 files changed

+108
-93
lines changed

src/cargo/ops/cargo_new.rs

Lines changed: 81 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -816,35 +816,39 @@ fn mk(config: &Config, opts: &MkOptions<'_>) -> CargoResult<()> {
816816
// This should not block the creation of the new project. It is only a best effort to
817817
// inherit the workspace package keys.
818818
if let Ok(mut workspace_document) = root_manifest.parse::<toml_edit::Document>() {
819-
if let Some(workspace_package_keys) = workspace_document
820-
.get("workspace")
821-
.and_then(|workspace| workspace.get("package"))
822-
.and_then(|package| package.as_table())
823-
{
824-
update_manifest_with_inherited_workspace_package_keys(
825-
opts,
826-
&mut manifest,
827-
workspace_package_keys,
828-
)
829-
}
819+
let display_path = get_display_path(&root_manifest_path, &path)?;
820+
let can_be_a_member = can_be_workspace_member(&display_path, &workspace_document)?;
821+
// Only try to inherit the workspace stuff if the new package can be a member of the workspace.
822+
if can_be_a_member {
823+
if let Some(workspace_package_keys) = workspace_document
824+
.get("workspace")
825+
.and_then(|workspace| workspace.get("package"))
826+
.and_then(|package| package.as_table())
827+
{
828+
update_manifest_with_inherited_workspace_package_keys(
829+
opts,
830+
&mut manifest,
831+
workspace_package_keys,
832+
)
833+
}
834+
// Try to inherit the workspace lints key if it exists.
835+
if workspace_document
836+
.get("workspace")
837+
.and_then(|workspace| workspace.get("lints"))
838+
.is_some()
839+
{
840+
let mut table = toml_edit::Table::new();
841+
table["workspace"] = toml_edit::value(true);
842+
manifest["lints"] = toml_edit::Item::Table(table);
843+
}
830844

831-
// Try to inherit the workspace lints key if it exists.
832-
if workspace_document
833-
.get("workspace")
834-
.and_then(|workspace| workspace.get("lints"))
835-
.is_some()
836-
{
837-
let mut table = toml_edit::Table::new();
838-
table["workspace"] = toml_edit::value(true);
839-
manifest["lints"] = toml_edit::Item::Table(table);
845+
// Try to add the new package to the workspace members.
846+
update_manifest_with_new_member(
847+
&root_manifest_path,
848+
&mut workspace_document,
849+
&display_path,
850+
)?;
840851
}
841-
842-
// Try to add the new package to the workspace members.
843-
update_manifest_with_new_member(
844-
&root_manifest_path,
845-
&mut workspace_document,
846-
opts.path,
847-
)?;
848852
}
849853
}
850854

@@ -955,8 +959,48 @@ fn update_manifest_with_inherited_workspace_package_keys(
955959
fn update_manifest_with_new_member(
956960
root_manifest_path: &Path,
957961
workspace_document: &mut toml_edit::Document,
958-
package_path: &Path,
962+
display_path: &str,
959963
) -> CargoResult<()> {
964+
// If the members element already exist, check if one of the patterns
965+
// in the array already includes the new package's relative path.
966+
// - Add the relative path if the members don't match the new package's path.
967+
// - Create a new members array if there are no members element in the workspace yet.
968+
if let Some(members) = workspace_document
969+
.get_mut("workspace")
970+
.and_then(|workspace| workspace.get_mut("members"))
971+
.and_then(|members| members.as_array_mut())
972+
{
973+
for member in members.iter() {
974+
let pat = member
975+
.as_str()
976+
.with_context(|| format!("invalid non-string member `{}`", member))?;
977+
let pattern = glob::Pattern::new(pat)
978+
.with_context(|| format!("cannot build glob pattern from `{}`", pat))?;
979+
980+
if pattern.matches(&display_path) {
981+
return Ok(());
982+
}
983+
}
984+
985+
let was_sorted = is_sorted(members.iter().map(Value::as_str));
986+
members.push(display_path);
987+
if was_sorted {
988+
members.sort_by(|lhs, rhs| lhs.as_str().cmp(&rhs.as_str()));
989+
}
990+
} else {
991+
let mut array = Array::new();
992+
array.push(display_path);
993+
994+
workspace_document["workspace"]["members"] = toml_edit::value(array);
995+
}
996+
997+
write_atomic(
998+
&root_manifest_path,
999+
workspace_document.to_string().to_string().as_bytes(),
1000+
)
1001+
}
1002+
1003+
fn get_display_path(root_manifest_path: &Path, package_path: &Path) -> CargoResult<String> {
9601004
// Find the relative path for the package from the workspace root directory.
9611005
let workspace_root = root_manifest_path.parent().with_context(|| {
9621006
format!(
@@ -980,9 +1024,14 @@ fn update_manifest_with_new_member(
9801024
components.push(comp);
9811025
}
9821026
let display_path = components.join("/");
1027+
Ok(display_path)
1028+
}
9831029

984-
// Don't add the new package to the workspace's members
985-
// if there is an exclusion match for it.
1030+
// Check if the package can be a member of the workspace.
1031+
fn can_be_workspace_member(
1032+
display_path: &str,
1033+
workspace_document: &toml_edit::Document,
1034+
) -> CargoResult<bool> {
9861035
if let Some(exclude) = workspace_document
9871036
.get("workspace")
9881037
.and_then(|workspace| workspace.get("exclude"))
@@ -993,46 +1042,9 @@ fn update_manifest_with_new_member(
9931042
.as_str()
9941043
.with_context(|| format!("invalid non-string exclude path `{}`", member))?;
9951044
if pat == display_path {
996-
return Ok(());
1045+
return Ok(false);
9971046
}
9981047
}
9991048
}
1000-
1001-
// If the members element already exist, check if one of the patterns
1002-
// in the array already includes the new package's relative path.
1003-
// - Add the relative path if the members don't match the new package's path.
1004-
// - Create a new members array if there are no members element in the workspace yet.
1005-
if let Some(members) = workspace_document
1006-
.get_mut("workspace")
1007-
.and_then(|workspace| workspace.get_mut("members"))
1008-
.and_then(|members| members.as_array_mut())
1009-
{
1010-
for member in members.iter() {
1011-
let pat = member
1012-
.as_str()
1013-
.with_context(|| format!("invalid non-string member `{}`", member))?;
1014-
let pattern = glob::Pattern::new(pat)
1015-
.with_context(|| format!("cannot build glob pattern from `{}`", pat))?;
1016-
1017-
if pattern.matches(&display_path) {
1018-
return Ok(());
1019-
}
1020-
}
1021-
1022-
let was_sorted = is_sorted(members.iter().map(Value::as_str));
1023-
members.push(&display_path);
1024-
if was_sorted {
1025-
members.sort_by(|lhs, rhs| lhs.as_str().cmp(&rhs.as_str()));
1026-
}
1027-
} else {
1028-
let mut array = Array::new();
1029-
array.push(&display_path);
1030-
1031-
workspace_document["workspace"]["members"] = toml_edit::value(array);
1032-
}
1033-
1034-
write_atomic(
1035-
&root_manifest_path,
1036-
workspace_document.to_string().to_string().as_bytes(),
1037-
)
1049+
Ok(true)
10381050
}

tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/in/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
[workspace]
2+
exclude = ["bar"]
13
[workspace.package]
24
authors = ["Rustaceans"]
35
description = "foo"
@@ -13,3 +15,10 @@ include = ["foo"]
1315
license = "MIT OR Apache-2.0"
1416
publish = false
1517
repository = "foo"
18+
[workspace.lints.rust]
19+
unsafe_code = "forbid"
20+
21+
[package]
22+
name = "foo"
23+
version = "0.1.0"
24+
edition = "2018"

tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fn case() {
1111

1212
snapbox::cmd::Command::cargo_ui()
1313
.arg("new")
14-
.args(["foo"])
14+
.args(["bar"])
1515
.current_dir(cwd)
1616
.assert()
1717
.success()

tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/out/Cargo.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[workspace]
2-
members = ["foo"]
2+
exclude = ["bar"]
33
[workspace.package]
44
authors = ["Rustaceans"]
55
description = "foo"
@@ -15,3 +15,10 @@ include = ["foo"]
1515
license = "MIT OR Apache-2.0"
1616
publish = false
1717
repository = "foo"
18+
[workspace.lints.rust]
19+
unsafe_code = "forbid"
20+
21+
[package]
22+
name = "foo"
23+
version = "0.1.0"
24+
edition = "2018"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "bar"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]

tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/out/foo/Cargo.toml

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Created binary (application) `foo` package
1+
Created binary (application) `bar` package

0 commit comments

Comments
 (0)