CLI: add metadata-only JSON output to environment comparisons

Open
#522 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@MayurK-cmd is already working on this.

Since Oct 7, 2026.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
78/100
Issue type
Feature
Clarity
Clearly specified
Activity status
Active
Tech stack
rust
Domain
cli

Research direction

Read EnvCommand::Diff and env_diff() in crates/cli/src/main.rs, then inspect App::env_diff() and DiffStatus in crates/cli/src/commands.rs to reuse the existing comparison states. Use the sotto env ls --json serializer and parser tests as a pattern. Add the metadata-only JSON option and focused tests; done means all four statuses, empty output, escaped/non-ASCII names, and absence of value fields are covered, with help updated and focused CLI tests passing.

Written by the indexing model from the issue text.

Description

enhancement good first issue help wanted

Need

Scripts comparing environment configuration currently have to parse the presentation markers from sotto env diff: =, !, < and >, with explanatory text around names. Add an opt-in JSON form for inspecting which names are equal, different, or present on only one side.

This should expose comparison metadata only. The existing human-readable command and its explicit --reveal behaviour remain available.

Current implementation

Source-reviewed on current main at 38fab371340be0aff7970b0f5f9b1282fabc21f7 in a clean macOS arm64 checkout:

  • EnvCommand::Diff and env_diff() offer left, right and --reveal, but no JSON flag. They render one marker line per name and a summary on stderr.
  • App::env_diff() and DiffStatus already calculate a sorted union with four explicit comparison states.
  • sotto env ls --json and its serializer/parser tests provide a nearby implementation pattern.

This is a feature request based on the existing interface, not a runtime defect. No live environment comparison was performed. #288 documented the current text markers; it did not add machine-readable output.

Output contract

Use sotto env diff dev staging --json to emit an array like this (synthetic names):

[
  {"name":"API_URL","status":"differs"},
  {"name":"LOG_LEVEL","status":"equal"},
  {"name":"STAGING_FLAG","status":"only_right"}
]

The four status strings are equal, differs, only_left, and only_right. Left and right refer to the positional arguments.

Acceptance criteria

  • Add --json, with stdout containing just a JSON array sorted by name; two empty environments produce [].
  • Emit only name and status. Do not serialize DiffEntry's secret value fields into this output.
  • Make --json and --reveal explicitly conflict in argument parsing so the metadata-only contract is unambiguous.
  • Preserve existing text output, error behaviour and exit status when --json is absent; differences themselves should not acquire a new exit-code policy.
  • Add parser/serialization tests for all four statuses, empty output, escaped/non-ASCII names, and absence of value fields. Reuse the existing comparison logic rather than implementing a second diff.
  • Add the JSON example and status meanings to command help, and run the focused CLI tests.

This is a bounded CLI output feature. No server or cryptographic change is needed. Follow CONTRIBUTING.md, including DCO sign-off (git commit -s).

Dominant language
Rust
Stars
31
Forks
42
Avg merge
2d 18h
Merged PRs (30d)
142

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from getsotto/sotto

All issues in getsotto/sotto

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.