Skip to content

Commit 5a89b99

Browse files
Document deterministic YAML formatting
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 7dc2079 commit 5a89b99

2 files changed

Lines changed: 46 additions & 0 deletions

File tree

README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ The module exports:
3030
| `ConvertFrom-Yaml` | Parse one or more YAML documents into PowerShell values. |
3131
| `ConvertTo-Yaml` | Serialize supported PowerShell values as YAML 1.2-compatible text. |
3232
| `Export-Yaml` | Serialize values and atomically write one YAML file. |
33+
| `Format-Yaml` | Normalize YAML streams without projecting representation nodes to PowerShell values. |
3334
| `Import-Yaml` | Strictly decode and parse YAML files. |
3435
| `Test-Yaml` | Test YAML syntax, tags, duplicate keys, and configured resource limits. |
3536

@@ -143,6 +144,36 @@ Repeated acyclic collection references are emitted with anchors and aliases.
143144
Cyclic graphs and unsupported runtime objects fail specifically; values are
144145
never silently truncated or converted with `ToString()`.
145146

147+
## Format YAML streams
148+
149+
`Format-Yaml` normalizes existing YAML without converting it through
150+
`PSCustomObject` or dictionary values. It retains document order and empty
151+
documents, node kinds, scalar content, effective tags, anchors and aliases,
152+
recursive graphs, complex keys, collection structure, and mapping order.
153+
154+
```powershell
155+
$normalized = Get-Content -Path '.\config.yaml' | Format-Yaml -Indent 4
156+
```
157+
158+
Pipeline records are joined with LF and parsed as one stream. The output is one
159+
string with LF line endings and no final newline. Every document starts with
160+
`---`; document-end markers, comments, directives, flow presentation, scalar
161+
styles, and original anchor names are normalized. Effective standard tags use
162+
`!!` shorthand where possible, while local and global tags use a deterministic
163+
verbatim form.
164+
165+
Formatting is byte-idempotent at the same options:
166+
167+
```powershell
168+
$normalized -ceq ($normalized | Format-Yaml -Indent 4)
169+
```
170+
171+
`-Indent` accepts 2 through 9 spaces. The `-Depth`, `-MaxNodes`, `-MaxAliases`,
172+
`-MaxScalarLength`, `-MaxTagLength`, `-MaxTotalTagLength`, and
173+
`-MaxNumericLength` defaults and ranges match `ConvertFrom-Yaml`. Invalid YAML,
174+
duplicate representation keys, undefined aliases, malformed tags, and resource
175+
limit violations terminate with the same classified YAML errors as parsing.
176+
146177
## Export YAML files
147178

148179
`Export-Yaml` aggregates pipeline records like `ConvertTo-Yaml`, serializes the
@@ -217,6 +248,7 @@ The archive contains 402 inputs:
217248
| `out.yaml` projection | 241 | 1 | 0 | 160 |
218249
| Official `emit.yaml` fixtures | 55 | 0 | 0 | 347 |
219250
| Module self-round-trip | 305 | 3 | 0 | 94 |
251+
| `Format-Yaml` representation and idempotence | 400 | 0 | 0 | 2 |
220252

221253
All 94 fixtures marked invalid are rejected. The valid `2JQS` and `X38W`
222254
inputs are syntactically recognized and produce matching representation
@@ -225,6 +257,13 @@ mapping keys must be unique. They are not unsupported grammar. Both are
225257
reported as policy differences for module self-round-trip; `X38W`, the one
226258
case with an `out.yaml` fixture, is also reported that way on that surface.
227259

260+
The formatter surface directly compares representation events and graph
261+
identity before and after formatting, validates the emitted stream, and
262+
requires byte-identical second formatting. It passes all 306 loadable valid
263+
inputs and confirms that all 94 invalid inputs remain rejected. The two valid
264+
duplicate-key policy cases are not applicable because `Format-Yaml` applies
265+
the same representation-key uniqueness policy as `ConvertFrom-Yaml`.
266+
228267
The two JSON projection differences are `565N`, where `!!binary` intentionally
229268
becomes `byte[]` instead of a Base64 string, and `J7PZ`, where legacy `!!omap`
230269
intentionally becomes `System.Collections.Specialized.OrderedDictionary`

examples/General.ps1

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ $outputYaml = [ordered]@{
4040
$outputYaml
4141
$outputYaml | ConvertFrom-Yaml
4242

43+
# Normalize YAML presentation without projecting its representation graph.
44+
$normalizedYaml = @'
45+
# Presentation differences are removed.
46+
{ name: example, ports: [80, 443] }
47+
'@ | Format-Yaml -Indent 4
48+
$normalizedYaml
49+
4350
# Atomically export one file, then import it with strict decoding.
4451
$configPath = Join-Path $env:TEMP 'yaml-example.yaml'
4552
$config | Export-Yaml -Path $configPath -PassThru

0 commit comments

Comments
 (0)