Skip to content

Commit 79a3919

Browse files
committed
Automatically inherit workspace fields when running cargo new
Signed-off-by: hi-rustin <rustin.liu@gmail.com>
1 parent f69b46a commit 79a3919

File tree

1 file changed

+81
-4
lines changed

1 file changed

+81
-4
lines changed

src/cargo/ops/cargo_new.rs

Lines changed: 81 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, format!("{}", 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,61 @@ 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 remove_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+
};
904+
905+
let set_workspace_inherited_package_key = |key: &str, manifest: &mut toml_edit::Document| {
906+
let package = manifest["package"]
907+
.as_table_mut()
908+
.expect("package is a table");
909+
let mut table = toml_edit::Table::new();
910+
table.set_dotted(true);
911+
table["workspace"] = toml_edit::value(true);
912+
package.insert(key, toml_edit::Item::Table(table));
913+
};
914+
915+
let remove_and_inherit_package_key = |key: &str, manifest: &mut toml_edit::Document| {
916+
remove_package_key(key, manifest);
917+
set_workspace_inherited_package_key(key, manifest);
918+
};
919+
920+
// Try inherit the edition from the workspace if it is not specified.
921+
if opts.edition.is_none() && workspace_package_keys.contains_key("edition") {
922+
remove_and_inherit_package_key("edition", manifest);
923+
}
924+
925+
// Try inherit the version from the workspace.
926+
if workspace_package_keys.contains_key("version") {
927+
remove_and_inherit_package_key("version", manifest);
928+
}
929+
930+
// Try inherit the publish from the workspace if it is not specified.
931+
if opts.registry.is_none() && workspace_package_keys.contains_key("publish") {
932+
remove_and_inherit_package_key("publish", manifest);
933+
}
934+
935+
// Inherit other keys from the workspace.
936+
for (key, _) in workspace_package_keys
937+
.iter()
938+
.filter(|(key, _)| !["edition", "version", "publish"].contains(key))
939+
{
940+
set_workspace_inherited_package_key(key, manifest);
941+
}
942+
}

0 commit comments

Comments
 (0)