Skip to content

Commit 47f4b75

Browse files
committed
fix: only inherit workspace package table if the new package is a member
Signed-off-by: hi-rustin <[email protected]>
1 parent 87345a1 commit 47f4b75

File tree

4 files changed

+85
-91
lines changed

4 files changed

+85
-91
lines changed

src/cargo/ops/cargo_new.rs

Lines changed: 81 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -816,35 +816,42 @@ 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-
}
830-
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);
840-
}
841-
842-
// Try to add the new package to the workspace members.
843-
update_manifest_with_new_member(
819+
let (display_path, can_be_a_member) = get_display_path_and_check_membership(
844820
&root_manifest_path,
845-
&mut workspace_document,
846-
opts.path,
821+
&path,
822+
&workspace_document,
847823
)?;
824+
// Only try to inherit the workspace stuff if the new package can be a member of the workspace.
825+
if can_be_a_member {
826+
if let Some(workspace_package_keys) = workspace_document
827+
.get("workspace")
828+
.and_then(|workspace| workspace.get("package"))
829+
.and_then(|package| package.as_table())
830+
{
831+
update_manifest_with_inherited_workspace_package_keys(
832+
opts,
833+
&mut manifest,
834+
workspace_package_keys,
835+
)
836+
}
837+
// Try to inherit the workspace lints key if it exists.
838+
if workspace_document
839+
.get("workspace")
840+
.and_then(|workspace| workspace.get("lints"))
841+
.is_some()
842+
{
843+
let mut table = toml_edit::Table::new();
844+
table["workspace"] = toml_edit::value(true);
845+
manifest["lints"] = toml_edit::Item::Table(table);
846+
}
847+
848+
// Try to add the new package to the workspace members.
849+
update_manifest_with_new_member(
850+
&root_manifest_path,
851+
&mut workspace_document,
852+
&display_path,
853+
)?;
854+
}
848855
}
849856
}
850857

@@ -955,8 +962,52 @@ fn update_manifest_with_inherited_workspace_package_keys(
955962
fn update_manifest_with_new_member(
956963
root_manifest_path: &Path,
957964
workspace_document: &mut toml_edit::Document,
958-
package_path: &Path,
965+
display_path: &str,
959966
) -> CargoResult<()> {
967+
// If the members element already exist, check if one of the patterns
968+
// in the array already includes the new package's relative path.
969+
// - Add the relative path if the members don't match the new package's path.
970+
// - Create a new members array if there are no members element in the workspace yet.
971+
if let Some(members) = workspace_document
972+
.get_mut("workspace")
973+
.and_then(|workspace| workspace.get_mut("members"))
974+
.and_then(|members| members.as_array_mut())
975+
{
976+
for member in members.iter() {
977+
let pat = member
978+
.as_str()
979+
.with_context(|| format!("invalid non-string member `{}`", member))?;
980+
let pattern = glob::Pattern::new(pat)
981+
.with_context(|| format!("cannot build glob pattern from `{}`", pat))?;
982+
983+
if pattern.matches(&display_path) {
984+
return Ok(());
985+
}
986+
}
987+
988+
let was_sorted = is_sorted(members.iter().map(Value::as_str));
989+
members.push(display_path);
990+
if was_sorted {
991+
members.sort_by(|lhs, rhs| lhs.as_str().cmp(&rhs.as_str()));
992+
}
993+
} else {
994+
let mut array = Array::new();
995+
array.push(display_path);
996+
997+
workspace_document["workspace"]["members"] = toml_edit::value(array);
998+
}
999+
1000+
write_atomic(
1001+
&root_manifest_path,
1002+
workspace_document.to_string().to_string().as_bytes(),
1003+
)
1004+
}
1005+
1006+
fn get_display_path_and_check_membership(
1007+
root_manifest_path: &Path,
1008+
package_path: &Path,
1009+
workspace_document: &toml_edit::Document,
1010+
) -> CargoResult<(String, bool)> {
9601011
// Find the relative path for the package from the workspace root directory.
9611012
let workspace_root = root_manifest_path.parent().with_context(|| {
9621013
format!(
@@ -981,8 +1032,6 @@ fn update_manifest_with_new_member(
9811032
}
9821033
let display_path = components.join("/");
9831034

984-
// Don't add the new package to the workspace's members
985-
// if there is an exclusion match for it.
9861035
if let Some(exclude) = workspace_document
9871036
.get("workspace")
9881037
.and_then(|workspace| workspace.get("exclude"))
@@ -993,46 +1042,10 @@ 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((display_path, false));
9971046
}
9981047
}
9991048
}
10001049

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-
)
1050+
Ok((display_path, true))
10381051
}

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

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,7 @@
11
[package]
22
name = "bar"
33
version = "0.1.0"
4-
authors.workspace = true
5-
description.workspace = true
6-
edition.workspace = true
7-
homepage.workspace = true
8-
keywords.workspace = true
9-
readme.workspace = true
10-
rust-version.workspace = true
11-
categories.workspace = true
12-
documentation.workspace = true
13-
exclude.workspace = true
14-
include.workspace = true
15-
license.workspace = true
16-
publish.workspace = true
17-
repository.workspace = true
4+
edition = "2021"
185

196
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
207

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
println!("Hello, world!");
3+
}
Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1 @@
1-
warning: compiling this new package may not work due to invalid workspace configuration
2-
3-
failed to parse manifest at `[ROOT]/case/bar/Cargo.toml`
4-
5-
Caused by:
6-
error inheriting `edition` from workspace root manifest's `workspace.package.edition`
7-
8-
Caused by:
9-
failed to find a workspace root
101
Created binary (application) `bar` package

0 commit comments

Comments
 (0)