Skip to content

Commit

Permalink
Use toml_edit
Browse files Browse the repository at this point in the history
Signed-off-by: hi-rustin <[email protected]>
  • Loading branch information
Rustin170506 committed May 13, 2023
1 parent 38babd5 commit 079af54
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 56 deletions.
88 changes: 37 additions & 51 deletions src/cargo/ops/cargo_new.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::core::{Edition, Shell, Workspace};
use crate::util::errors::CargoResult;
use crate::util::toml::parse_document;
use crate::util::toml_mut::manifest::LocalManifest;
use crate::util::{existing_vcs_repo, FossilRepo, GitRepo, HgRepo, PijulRepo};
use crate::util::{restricted_names, Config};
use anyhow::{anyhow, Context as _};
Expand Down Expand Up @@ -879,16 +880,9 @@ mod tests {
.and_then(|workspace| workspace.get("package"))
.and_then(|package| package.as_table())
{
// We create a new manifest with the inherited package field.
// We do not use the existing manifest because we do not want
// to couple those two write operations together.
// Moreover, if we want to add the package as a member of the workspace automatically,
// we can directly reuse this function.
return create_manifest_with_inherited_workspace_package_fields(
opts,
path,
name,
cargotoml_path_specifier.as_str(),
workspace_package_keys,
);
}
Expand All @@ -909,75 +903,67 @@ mod tests {
fn create_manifest_with_inherited_workspace_package_fields(
opts: &MkOptions<'_>,
path: &Path,
name: &str,
cargotoml_path_specifier: &str,
workspace_package_keys: &toml::value::Table,
) -> CargoResult<()> {
if workspace_package_keys.is_empty() {
return Ok(());
}

let manifest_path = path.join("Cargo.toml");
let mut manifest = LocalManifest::try_new(&manifest_path)?;

let remove_and_inherit_package_key =
|key: &str, manifest: &mut LocalManifest| -> CargoResult<()> {
manifest.remove_package_key(key)?;
manifest.set_workspace_inherited_package_key(key)?;
Ok(())
};

// Try inherit the edition from the workspace if it is not specified.
let edition = match opts.edition {
match opts.edition {
Some(edition) => {
format!("edition = {}", toml::Value::String(edition.to_string()))
manifest.set_package_key("edition", toml_edit::value(edition))?;
}
None => {
if workspace_package_keys.contains_key("edition") {
format!("edition.workspace = {}", toml::Value::Boolean(true))
remove_and_inherit_package_key("edition", &mut manifest)?;
} else {
format!(
"edition = {}",
toml::Value::String(Edition::LATEST_STABLE.to_string())
)
manifest.set_package_key(
"edition",
toml_edit::value(Edition::LATEST_STABLE.to_string()),
)?;
}
}
};
// Try inherit the version from the workspace if it is not specified.
let version = if workspace_package_keys.contains_key("version") {
format!("version.workspace = {}", toml::Value::Boolean(true))
if workspace_package_keys.contains_key("version") {
remove_and_inherit_package_key("version", &mut manifest)?;
} else {
"version = \"0.1.0\"".to_string()
manifest.set_package_key("version", toml_edit::value("0.1.0"))?;
};
// Try inherit the publish from the workspace if it is not specified.
let publish = match opts.registry {
Some(registry) => format!(
"publish = {}\n",
toml::Value::Array(vec!(toml::Value::String(registry.to_string())))
),
match opts.registry {
Some(registry) => {
let mut array = toml_edit::Array::default();
array.push(registry);
manifest.set_package_key("publish", toml_edit::value(array))?;
}
None => {
if workspace_package_keys.contains_key("publish") {
format!("publish.workspace = {}\n", toml::Value::Boolean(true))
} else {
"".to_string()
remove_and_inherit_package_key("publish", &mut manifest)?;
}
}
};
// Inherit other keys from the workspace.
let workspace_package_fields = workspace_package_keys
for (key, _) in workspace_package_keys
.iter()
.filter(|(key, _)| *key != "edition" && *key != "version" && *key != "publish")
.map(|(key, _)| format!("{}.workspace = {}", key, toml::Value::Boolean(true)))
.collect::<Vec<String>>();
paths::write(
&path.join("Cargo.toml"),
format!(
r#"[package]
name = "{}"
{}
{}
{}{}
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
{
manifest.set_workspace_inherited_package_key(key)?;
}

[dependencies]
{}"#,
name,
version,
edition,
publish,
workspace_package_fields.join("\n"),
cargotoml_path_specifier
)
.as_bytes(),
)?;
return Ok(());
// Re-write the `Cargo.toml` file with the inherited fields.
manifest.write()?;

Ok(())
}
30 changes: 30 additions & 0 deletions src/cargo/util/toml_mut/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,36 @@ impl LocalManifest {
}
status
}

pub fn set_package_key(&mut self, key: &str, value: toml_edit::Item) -> CargoResult<()> {
let package = self.data["package"]
.as_table_mut()
.ok_or_else(parse_manifest_err)?;
package[key] = value;

Ok(())
}

pub fn remove_package_key(&mut self, key: &str) -> CargoResult<()> {
let package = self.data["package"]
.as_table_mut()
.ok_or_else(parse_manifest_err)?;
package.remove(key);

Ok(())
}

pub fn set_workspace_inherited_package_key(&mut self, key: &str) -> CargoResult<()> {
let package = self.data["package"]
.as_table_mut()
.ok_or_else(parse_manifest_err)?;
let mut table = toml_edit::Table::new();
table.set_dotted(true);
table["workspace"] = toml_edit::value(true);
package.insert(key, toml_edit::Item::Table(table));

Ok(())
}
}

impl std::fmt::Display for LocalManifest {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "foo"
version.workspace = true
edition.workspace = true
version.workspace = true
publish.workspace = true
authors.workspace = true
categories.workspace = true
Expand All @@ -15,6 +15,7 @@ license.workspace = true
readme.workspace = true
repository.workspace = true
rust-version.workspace = true

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

[dependencies]
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "foo"
version.workspace = true
edition = "2021"
version.workspace = true
publish.workspace = true
authors.workspace = true
categories.workspace = true
Expand All @@ -15,6 +15,7 @@ license.workspace = true
readme.workspace = true
repository.workspace = true
rust-version.workspace = true

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

[dependencies]
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[package]
name = "foo"
version.workspace = true
edition.workspace = true
publish = ["foo"]
edition.workspace = true
version.workspace = true
authors.workspace = true
categories.workspace = true
description.workspace = true
Expand All @@ -15,6 +15,7 @@ license.workspace = true
readme.workspace = true
repository.workspace = true
rust-version.workspace = true

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

[dependencies]
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ license.workspace = true
readme.workspace = true
repository.workspace = true
rust-version.workspace = true

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

[dependencies]
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "foo"
version.workspace = true
edition.workspace = true
version.workspace = true
publish.workspace = true
authors.workspace = true
categories.workspace = true
Expand All @@ -15,6 +15,7 @@ license.workspace = true
readme.workspace = true
repository.workspace = true
rust-version.workspace = true

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

[dependencies]

0 comments on commit 079af54

Please sign in to comment.