Skip to content

Commit e6dae8e

Browse files
committed
Automatically inherit workspace fields when running cargo new
Signed-off-by: hi-rustin <[email protected]>
1 parent f69b46a commit e6dae8e

File tree

1 file changed

+60
-4
lines changed

1 file changed

+60
-4
lines changed

src/cargo/ops/cargo_new.rs

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::core::{Edition, Shell, Workspace};
22
use crate::util::errors::CargoResult;
3+
use crate::util::important_paths::find_root_manifest_for_wd;
34
use crate::util::{existing_vcs_repo, FossilRepo, GitRepo, HgRepo, PijulRepo};
45
use crate::util::{restricted_names, Config};
56
use anyhow::{anyhow, Context as _};
@@ -801,10 +802,28 @@ fn mk(config: &Config, opts: &MkOptions<'_>) -> CargoResult<()> {
801802
}
802803
}
803804

804-
paths::write(
805-
&path.join("Cargo.toml"),
806-
format!("{}", manifest.to_string()),
807-
)?;
805+
let manifest_path = path.join("Cargo.toml");
806+
if let Ok(root_manifest_path) = find_root_manifest_for_wd(&manifest_path) {
807+
let root_manifest = paths::read(&root_manifest_path)?;
808+
// Sometimes the root manifest is not a valid manifest, so we only try to parse it if it is.
809+
// This should not block the creation of the new project. It is only a best effort to
810+
// inherit the workspace package keys.
811+
if let Ok(workspace_document) = root_manifest.parse::<toml_edit::Document>() {
812+
if let Some(workspace_package_keys) = workspace_document
813+
.get("workspace")
814+
.and_then(|workspace| workspace.get("package"))
815+
.and_then(|package| package.as_table())
816+
{
817+
update_manifest_with_inherited_workspace_package_keys(
818+
opts,
819+
&mut manifest,
820+
workspace_package_keys,
821+
)
822+
}
823+
}
824+
}
825+
826+
paths::write(&manifest_path, manifest.to_string())?;
808827

809828
// Create all specified source files (with respective parent directories) if they don't exist.
810829
for i in &opts.source_files {
@@ -863,3 +882,40 @@ mod tests {
863882

864883
Ok(())
865884
}
885+
886+
// Update the manifest with the inherited workspace package keys.
887+
// If the option is not set, the key is removed from the manifest.
888+
// If the option is set, keep the value from the manifest.
889+
fn update_manifest_with_inherited_workspace_package_keys(
890+
opts: &MkOptions<'_>,
891+
manifest: &mut toml_edit::Document,
892+
workspace_package_keys: &toml_edit::Table,
893+
) {
894+
if workspace_package_keys.is_empty() {
895+
return;
896+
}
897+
898+
let try_remove_and_inherit_package_key = |key: &str, manifest: &mut toml_edit::Document| {
899+
let package = manifest["package"]
900+
.as_table_mut()
901+
.expect("package is a table");
902+
package.remove(key);
903+
let mut table = toml_edit::Table::new();
904+
table.set_dotted(true);
905+
table["workspace"] = toml_edit::value(true);
906+
package.insert(key, toml_edit::Item::Table(table));
907+
};
908+
909+
// Inherit keys from the workspace.
910+
// Only keep the value from the manifest if the option is set.
911+
for (key, _) in workspace_package_keys {
912+
if key == "edition" && opts.edition.is_some() {
913+
continue;
914+
}
915+
if key == "publish" && opts.registry.is_some() {
916+
continue;
917+
}
918+
919+
try_remove_and_inherit_package_key(key, manifest);
920+
}
921+
}

0 commit comments

Comments
 (0)