Skip to content

0.23.0-alpha

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 01 Oct 03:14
· 33 commits to main since this release
9c2a1f6

Added

  • --color auto|always|never (also --color=<mode>), for ANSI colour in every diff the tool
    prints: --diff, --diff-layers, and set's automatic diff after a write. Accepted in every
    mode. GitDiff.Render always passed --color=always before this, so a redirect or pipe
    (--diff > change.diff) captured raw escape codes. See docs/USAGE.md.

Changed

  • JSON/YAML keys now match case-sensitively across layers, and a patch key that matches an
    existing key only by case is an error.
    Repo owner's decision, following the tree merge below
    (docs/TREE_MERGE_DESIGN.md's "Key matching is case-sensitive"). Before, a patch's apiUrl
    silently overrode the base's ApiUrl. That was wrong for case-sensitive consumers (a Python or
    Node app sees two different keys), and plain case-sensitivity would instead deploy a file with
    both keys, which .NET's configuration loader refuses to load. The merge now stops with an error
    naming the patch file, the key path and the existing spelling. set checks its --match key=
    path the same way before writing (Try: --match key=Logging:LogLevel:Default), and now merges
    the new overlay content before writing it, so a write the merge would reject leaves nothing on
    disk. An existing overlay whose key casing differs from its base now fails to resolve — fix
    the spelling the error names.
  • JSON and YAML now merge each patch into the base document's own tree, keeping the source's
    key order, key spelling, and every value exactly as written
    (docs/TREE_MERGE_DESIGN.md).
    Both engines used to flatten the base and patches through Microsoft.Extensions.Configuration
    and rebuild a document from string keys. That sorted keys alphabetically, re-quoted YAML, and
    corrupted values: "007" became 7, "1.10" became 1.1, "true" became true, a 20-digit
    integer lost precision, null became "", {}/[] were dropped, a patch's key spelling
    replaced the base's, and a patch scalar landing on a base object was silently dropped. --diff
    hid all of it, since it renders the unpatched side through the same merge. Kept on purpose:
    IConfiguration's merge rules (key-by-key, arrays by index, the {"1": ...} index-keyed idiom)
    and $elemMatch resolution; key matching became case-sensitive (entry above). Also changed: a later
    layer now replaces a value of a different kind outright (the old merge always kept the object);
    keys differing only by case within one file are allowed (YAML used to throw); an index-keyed
    patch that would leave a gap in an array is an error; a multi-document YAML file is refused;
    YAML output reuses the base file's indentation and sequence style. Comments are still not carried
    into the output. Deployed JSON/YAML files can change wherever they relied on the old
    reordering or type-guessing — compare before rolling out. Microsoft.Extensions.Configuration,
    Microsoft.Extensions.Configuration.Json and NetEscapades.Configuration.Yaml are no longer
    dependencies. New golden expected-output fixtures (Fixtures/*/Expected/) pin the full output.
  • Diff output is no longer coloured by default when stdout isn't a terminal. The default,
    --color auto, colours only on a terminal with the NO_COLOR environment variable unset. A CI
    log that renders ANSI (GitHub Actions does, even though a job's stdout isn't a terminal) now
    gets plain text unless the step passes --color always. GitDiff.Render now passes
    --color=never explicitly when colour is off, so a user's own color.ui = always git config
    can't force it back on.

Fixed

  • A JSON patch file containing // or /* */ comments no longer crashes the merge. Comments
    and trailing commas were accepted in a base file but not in a patch (the $elemMatch pre-scan
    parsed patches strictly). Fixed by the tree merge above, which reads every file the same way.

  • --diff-layers spaces a layer's second and later hunks with a blank line, the same as
    between two layers' sections. Before, a layer's second [<layer>] tag followed the previous
    hunk's last line with no gap. See docs/DIFF_LAYERS_DESIGN.md decision log #5.

  • JSON output keeps non-ASCII and < > & ' + as written, instead of \uXXXX escapes.
    Found during the same read-through as the console fix below. System.Text.Json's default encoder
    wrote a password a+b as a\u002Bb and a Hebrew value as a run of \u05XX escapes. This
    affected --output deploy files too, not just console output. It was always valid JSON, but
    unreadable in a deployed file or a --diff. Every JSON write site now uses
    JavaScriptEncoder.UnsafeRelaxedJsonEscaping: JsonLayerMerger (both the plain and $elemMatch
    paths), JsonFieldAuthor (set), JsonElemMatchResolver's ambiguous-match error message, and
    LayerManifestSerializer (configtransform.json files written by set/init, where a client
    named Acme & Co used to come out as Acme \u0026 Co). New values in the DotNetCore,
    GenericJson and ElemMatch fixtures cover it. See docs/CONFIG_MANAGEMENT.md §5.3, including the
    one quirk left over from System.Text.Json itself (emoji are always written as escaped surrogate pairs).

  • Console output is always UTF-8, so redirected output no longer loses characters on
    Windows.
    Found while running the tool against config-transform-pilot from Git Bash: on a
    console code page like 437 (the Windows default for cmd.exe and Git Bash), .NET encoded
    stdout/stderr in that code page. The resolution report's ↓ came out as the invisible control
    byte 0x19, and a non-ASCII config value printed by --dry-run (e.g. Hebrew) became ?, which
    is real data loss for --dry-run > file. --output files were never affected. The new
    Utf8Console (ConfigTransform.Cli) writes redirected output as UTF-8 with no BOM. On a real
    console it switches the code page to UTF-8 for the run and restores the original on exit. See
    docs/CONFIG_MANAGEMENT.md §6. Regression test Utf8ConsoleTests runs the real CLI as a child
    process with redirected stdout; an in-process CliRunner.Run test with a StringWriter can't
    reach this code.