fix(env): emit JSON results and route status text to stderr#119
Open
tcerqueira wants to merge 3 commits into
Open
fix(env): emit JSON results and route status text to stderr#119tcerqueira wants to merge 3 commits into
tcerqueira wants to merge 3 commits into
Conversation
The mutating `env` subcommands (add, update-value, update-contexts,
delete, load) printed their human success confirmation to stdout and
never emitted a machine-readable result, so `--json` (and any piped)
output was polluted with non-JSON text.
Route all confirmation/status text to stderr and, under `--json`, emit a
single JSON object per command on stdout: add/update-* report the
affected variable shaped exactly like an `env list` item (id, key,
masked value, isSecret, contexts), delete reports `{ id, key, deleted }`,
and load reports an `{ file, added, updated, skipped }` summary. The
shared `shapeEnvVar` helper is reused by `list` so all JSON stays
consistent.
Add an end-to-end test exercising the env add/update-value/delete cycle with `--json --non-interactive`, asserting stdout carries exactly one JSON object per command. Gated on DENO_DEPLOY_TEST_ORG/APP and run from an isolated temp cwd so it never touches the repo's deno.json; skipped when throwaway creds are absent.
…te miss
fetchShapedEnvVar returned null when the variable could not be read back
after a successful add/update-value/update-contexts mutation (e.g. a
backend read-after-write miss or key-normalization difference), and the
call sites passed that straight to writeJsonResult, printing a bare
`null` to stdout and breaking the agent/JSON contract.
Fold the miss handling into fetchShapedEnvVar: it now exits via error()
with ExitCode.NOT_FOUND / errorCode ENV_VAR_NOT_FOUND (message naming the
key) so the command always yields either the documented variable object
on stdout or a structured {error:{...}} envelope on stderr. The normal
found path is unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The mutating
envsubcommands —add,update-value,update-contexts,delete, andload— printed their human success confirmation to stdout and never emitted a machine-readable result. Under--json(the agent/CI contract) this corrupted stdout: a piped/parsed consumer got a non-JSON line like✔ Environment variable 'X' has been successfully set.instead of a result payload. This is theenvinstance of the--jsonstdout-pollution rough edge tracked in #112;env list(a read) already complied.Changes
console.error), including the interactive "already defined" prompt chrome inload.--json, emit exactly one JSON object per mutating command on stdout viawriteJsonResult:add/update-value/update-contexts→ the affected variable shaped exactly like anenv listitem:{ id, key, value (null for secrets), isSecret, contexts }.delete→{ id, key, deleted: true }.load→{ file, added, updated, skipped }summary.shapeEnvVarhelper, reused bylistso every command's JSON shape stays identical.tests/env.test.ts) covering the add/update-value/delete cycle under--json --non-interactive, asserting stdout is a single JSON object per command. Gated onDENO_DEPLOY_TEST_ORG/APPand run from an isolated temp cwd so it never dirties the repodeno.json; skipped when throwaway creds are absent.Verification
Ran each mutating subcommand with
--json --non-interactiveagainst a throwaway org/app: stdout is pure JSON, human text is on stderr, and all created vars were cleaned up.deno fmt --check,deno lint,deno check, and the new test all pass.