Skip to content

Commit

Permalink
fix: Don't duplicate comments when editing TOML
Browse files Browse the repository at this point in the history
`toml_edit` <0.22 has a bug that will cause
```toml
[lints]
rust.unsafe_op_in_unsafe_fn = "deny"

rust.explicit_outlives_requirements = "warn"

clippy.cast_lossless = "warn"
clippy.doc_markdown = "warn"
clippy.exhaustive_enums = "warn"
```
to be written out as
[lints]
rust.unsafe_op_in_unsafe_fn = "deny"
rust.explicit_outlives_requirements = "warn"

clippy.cast_lossless = "warn"

clippy.doc_markdown = "warn"

clippy.exhaustive_enums = "warn"
```
when it is parsed and then saved.

See toml-rs/toml#675

This affects any format-preserving edits we do, including:
- `cargo add`
- `cargo remove`
- `cargo init` / `cargo new` editing the workspace
  • Loading branch information
epage committed Feb 5, 2024
1 parent e3de3bf commit 12cf56a
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 12 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ tar = { version = "0.4.40", default-features = false }
tempfile = "3.9.0"
thiserror = "1.0.56"
time = { version = "0.3", features = ["parsing", "formatting", "serde"] }
toml = "0.8.9"
toml_edit = { version = "0.21.1", features = ["serde"] }
toml = "0.8.10"
toml_edit = { version = "0.22.4", features = ["serde"] }
tracing = "0.1.40" # be compatible with rustc_log: https://github.com/rust-lang/rust/blob/e51e98dde6a/compiler/rustc_log/Cargo.toml#L9
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
unicase = "2.7.0"
Expand Down
19 changes: 13 additions & 6 deletions src/cargo/util/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1349,11 +1349,14 @@ impl Config {
let doc: toml_edit::Document = arg.parse().with_context(|| {
format!("failed to parse value from --config argument `{arg}` as a dotted key expression")
})?;
fn non_empty(d: Option<&toml_edit::RawString>) -> bool {
d.map_or(false, |p| !p.as_str().unwrap_or_default().trim().is_empty())
}
fn non_empty_decor(d: &toml_edit::Decor) -> bool {
d.prefix()
.map_or(false, |p| !p.as_str().unwrap_or_default().trim().is_empty())
|| d.suffix()
.map_or(false, |s| !s.as_str().unwrap_or_default().trim().is_empty())
non_empty(d.prefix()) || non_empty(d.suffix())
}
fn non_empty_key_decor(k: &toml_edit::Key) -> bool {
non_empty_decor(k.leaf_decor()) || non_empty_decor(k.dotted_decor())
}
let ok = {
let mut got_to_value = false;
Expand All @@ -1367,7 +1370,7 @@ impl Config {
let (k, n) = table.iter().next().expect("len() == 1 above");
match n {
Item::Table(nt) => {
if table.key_decor(k).map_or(false, non_empty_decor)
if table.key(k).map_or(false, non_empty_key_decor)
|| non_empty_decor(nt.decor())
{
bail!(
Expand All @@ -1384,7 +1387,11 @@ impl Config {
);
}
Item::Value(v) => {
if non_empty_decor(v.decor()) {
if table
.key(k)
.map_or(false, |k| non_empty(k.leaf_decor().prefix()))
|| non_empty_decor(v.decor())
{
bail!(
"--config argument `{arg}` \
includes non-whitespace decoration"
Expand Down

0 comments on commit 12cf56a

Please sign in to comment.