Skip to content

Add canonical JSON --show-config export and JsonConfigFormatter#165

Open
VolkerChristian wants to merge 5 commits into
masterfrom
codex/add-canonical-json-config-export
Open

Add canonical JSON --show-config export and JsonConfigFormatter#165
VolkerChristian wants to merge 5 commits into
masterfrom
codex/add-canonical-json-config-export

Conversation

@VolkerChristian

@VolkerChristian VolkerChristian commented Jul 7, 2026

Copy link
Copy Markdown
Member

Motivation

  • Provide a deterministic, versioned canonical JSON export for --show-config=json, emitted directly from the live CLI11/SNode.C configuration tree.
  • Preserve the existing legacy INI configuration output for -s, bare --show-config, and --show-config=ini.
  • Preserve subcommand hierarchy, option groups, option metadata, defaults, effective values, and required-state information without adding an external JSON dependency.
  • Provide a structured backend for tools such as snodec-control, while keeping the existing config-file workflow unchanged.

Description

  • Added utils::JsonWriter in src/utils/JsonWriter.{h,cpp} as a small deterministic JSON writer with proper string escaping.

  • Added utils::ConfigJsonFormatter in src/utils/ConfigJsonFormatter.{h,cpp} to serialize the live CLI11/SNode.C app tree into a canonical JSON document.

  • Preserved legacy behavior:

    • -s emits INI
    • bare --show-config emits INI
    • --show-config=ini emits INI
  • Added explicit JSON export:

    • --show-config=json
  • The JSON document uses:

    • format.name = "snodec.config"
    • format.version = 1
    • format.scope = "configurable-options-only"
  • The JSON tree preserves generic CLI11/SNode.C hierarchy. It does not hard-code Application -> Instances -> Sections; common node kinds such as instance and section are inferred from CLI11 group names and marked with source metadata.

  • Option groups are emitted as structured JSON objects instead of INI comment headers.

  • Option values separate semantic values from INI/config-file literals:

    • configured, effective, and apiDefault are semantic values
    • configuredLiteral, effectiveLiteral, and apiDefaultLiteral preserve config-file literal representation
  • Value-state flags were made explicit:

    • isEffectiveDefault
    • isExplicitlyConfigured
    • isMissingRequired
  • Anonymous / empty-name CLI11 subcommands are preserved with deterministic generated path segments such as <anonymous-0>, so every node and option receives a stable non-empty JSON id.

  • JSON stdout purity is preserved for successful --show-config=json; diagnostics for JSON export failures are written to stderr.

  • Added docs/config-json.md documenting the schema, compatibility behavior, value semantics, heuristic metadata, anonymous node IDs, output-purity contract, and known limitations.

  • Updated landing-page documentation to mention the canonical JSON configuration export.

Testing

Added and ran unit coverage in ConfigJsonFormatterTest, including:

  • JSON writer string escaping:

    • quotes
    • backslashes
    • newline / tab / carriage return
    • control bytes below 0x20
    • UTF-8 pass-through
  • exact expected JSON output for a small deterministic config tree

  • canonical format metadata and configurable-options-only scope

  • application metadata and root tree emission

  • arbitrary nested child nodes

  • option group preservation

  • exclusion of non-configurable options

  • semantic configured/effective values without INI quoting

  • explicit INI/config-file literal value fields

  • isEffectiveDefault, isExplicitlyConfigured, and isMissingRequired

  • required placeholder handling

  • needs / excludes relation output

  • anonymous subcommand ID generation

  • compatibility behavior:

    • -s defaults to INI
    • bare --show-config defaults to INI
    • --show-config=ini selects INI
    • --show-config=json selects JSON
    • invalid formats such as --show-config=xml are rejected

Manual validation commands used included:

./build/src/apps/echo/echoserver-legacy-in -s > /tmp/config.ini
head -20 /tmp/config.ini

./build/src/apps/echo/echoserver-legacy-in --show-config > /tmp/config-default.ini
head -20 /tmp/config-default.ini

./build/src/apps/echo/echoserver-legacy-in --show-config=ini > /tmp/config2.ini
head -20 /tmp/config2.ini

./build/src/apps/echo/echoserver-legacy-in --show-config=json > /tmp/config.json
jq . /tmp/config.json

Known limitations

  • This is a configuration export, not a complete command-line schema; only configurable options are included.
  • CLI11 does not currently expose enough origin metadata to distinguish command-line values from config-file values, so both are reported as command-line-or-config.
  • Validator metadata is opaque unless CLI11 exposes a decomposable description.
  • Config-file section is currently null for flattened dotted keys.
  • Semantic multi-value options are currently represented as deterministic space-joined strings; consumers should inspect type.items and the literal fields when round-tripping.
  • Some node, group, persistence, and type classifications are heuristic; these fields include source metadata so downstream tools can distinguish hints from authoritative CLI11 state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant