Skip to content

Commit 70e7afa

Browse files
docs: update spec to reflect removal of comment preservation and simplified colon finding
1 parent c2bc380 commit 70e7afa

1 file changed

Lines changed: 11 additions & 23 deletions

File tree

doc/specs/2026-05-15-complex-value-replace-design.md

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,17 @@ Input: a `yamlpath::Document`, a `yamlpath::Route`, and a `serde_yaml::Value` (M
2525

2626
1. **Locate the feature**`document.query_pretty(&route)` to get the byte span with surrounding key context.
2727

28-
2. **Extract content**`extract_with_leading_whitespace(feature)` to get the full `key: value` text. Split at the first `: ` (colon-space) or `:\n` (colon-newline) into `key_part` (through the colon) and `value_part` (after the colon).
28+
2. **Extract content**`extract_with_leading_whitespace(feature)` to get the full `key: value` text. Split at the first `:` (naive `find(':')`, consistent with yamlpatch's own Replace implementation) into `key_part` (through the colon) and the rest.
2929

30-
3. **Detect inline comment**Scan the first line of `value_part` for a trailing `# comment`. Heuristic: after the value content on the first line, find `\s+#`. Save the comment text if found.
30+
3. **Compute indentation**Derive base indent from the number of leading spaces on the feature's line. Value content indentation = base indent + 2 spaces.
3131

32-
4. **Compute indentation**Derive base indent from the number of leading spaces on the feature's line. Value content indentation = base indent + 2 spaces.
32+
4. **Serialize the new value**`serde_yaml::to_string(&value)`, strip trailing newline, re-indent each line to the computed value indentation.
3333

34-
5. **Serialize the new value**`serde_yaml::to_string(&value)`, strip trailing newline, re-indent each line to the computed value indentation.
34+
5. **Assemble replacement text**`key:\n indented_value`. Inline comments on the value line are not preserved, consistent with yamlpatch's own Replace behavior for scalar values.
3535

36-
6. **Assemble replacement text**:
37-
- With comment: `key: # comment\n indented_value`
38-
- Without comment: `key:\n indented_value`
36+
6. **String surgery** — Replace the byte range from the feature's span (adjusted for leading whitespace) in the document source.
3937

40-
7. **String surgery** — Replace the byte range from the feature's span (adjusted for leading whitespace) in the document source.
41-
42-
8. **Re-parse**`yamlpath::Document::new(patched_source)` to validate.
38+
7. **Re-parse**`yamlpath::Document::new(patched_source)` to validate.
4339

4440
### Root-level replace
4541

@@ -64,17 +60,6 @@ Patches are applied sequentially. If a complex replace is encountered mid-batch,
6460

6561
`Document.upsert()` delegates to `replace()` when the path exists, and to `_create_at()` (which uses `Op.add`/`Op.merge_into`) when it doesn't. Since `Op.add` and `Op.merge_into` already handle complex values, the only broken path is the `replace` delegation — fixed by this change. No changes to `document.py`.
6662

67-
## Comment Relocation
68-
69-
When replacing a scalar that has an inline comment (e.g. `repos: [] # managed by tool`) with a multi-line block value:
70-
71-
- The comment is preserved on the key line: `repos: # managed by tool`
72-
- The block value starts on the next line, indented
73-
74-
Detection heuristic: after stripping the YAML value from the first line of `value_part`, look for `\s+#` at the end.
75-
76-
**Limitation:** Comments inside quoted strings that happen to contain `#` could be misdetected. This is unlikely for the scalar values being replaced and is documented as a known limitation.
77-
7863
## Serialization Style
7964

8065
No changes to `Op.add` behavior. Complex values in `Replace` use `serde_yaml::to_string()` which produces block style by default (block mappings, block sequences). This matches the pre-commit config use case where block style is expected.
@@ -88,16 +73,19 @@ New tests in `tests/test_document.py`:
8873
- `replace()` with nested dict-in-list-in-dict
8974
- `upsert()` with a dict value (path exists → goes through replace)
9075
- `upsert()` with a dict value (path doesn't exist → goes through add, already works)
91-
- Comment preservation when replacing scalar with complex value
9276
- Replacing a complex value with another complex value
9377
- Root-level replace with complex value
9478
- Indentation correctness at various nesting depths (0, 2, 4 spaces)
9579

80+
## Known Limitations
81+
82+
- **Quoted keys with colons**`find_key_colon` uses a naive `str::find(':')`, which will misparse keys like `"host:port": value`. This is consistent with yamlpatch's own Replace implementation. When yamlpatch fixes this upstream, yamltrip should inherit the fix.
83+
- **Inline comments** — Not preserved during complex replace, consistent with yamlpatch's scalar Replace behavior.
84+
9685
## Scope Boundaries
9786

9887
**In scope:**
9988
- `Replace` with Mapping/Sequence values
100-
- Inline comment relocation
10189
- Indentation handling
10290

10391
**Out of scope:**

0 commit comments

Comments
 (0)