feat(data delete): --output-json + the one-page JSON scripting contract#314
Conversation
…ct (#297) data delete is the destructive, script-invoked verb with zero JSON support today. Add --output-json mirroring data_list.go's contract exactly: - RunE splits streams the same way (human -> stderr via printerForWriter, JSON -> stdout) and, like data ingest's implies---no-input, never wires a prompter in JSON mode — a scripted delete must say --yes (or --dry-run) explicitly, else it fails closed (exit 3). - runDataDelete gains the jsonEmitted + deferred-error-writer pattern (Bugbot #53 lineage): every failure return emits {status:"error", error, exit_code} so stdout is never empty; the error shape is byte-compatible with writeDataListErrorJSON's. - Terminal statuses: deleted / dry-run / declined — all exit 0 like the human flow, so scripts branch on status. The payload carries the case-RESOLVED table spelling (backend#1027), namespace, release, database, pvc_paths and removed_paths ([] never null). - Exit codes unchanged; documented in the command Long text. docs/json-output.md (new): which commands emit JSON (version, data ingest, data list, data delete), the one-object-on-stdout rule, the shared error shape, exit-code lockstep, and the additive-only stability promise. doctor/resources/auth status extension deferred pending epic OQ5. Tests: success (case-resolved spelling + stream separation), dry-run ([] not null), confirm-declined, early failure (exit 2), off-TTY refusal (exit 3), late teardown failure (exit 7), and a wiring-level test pinning that --output-json never prompts. Fixes #297 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
👋 Heads-up — Code review queue is at 56 / 30 Above the WIP limit. The team convention is to review existing PRs before opening new work. Open PRs currently in Code review (oldest first):
Pull from review before opening new work. (This is a nudge from the kanban WIP check, not a block.) |
|
@BugBot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 3453bb2. Configure here.
saadqbal
left a comment
There was a problem hiding this comment.
👍 Careful feature. The stdout-always-JSON contract is the crux and it's right — the deferred error-JSON emit (with the exitError code, guarded by jsonEmitted) covers every failure return, so a scripted delete never gets empty stdout (good that Bugbot #53's gap is closed). JSON mode never prompts, the table field is the case-resolved spelling, and exit codes are unchanged. Solid 233-line test. Clean.
What
WS-F.3 of the customer-surface pass (epic tracebloc/backend#1106):
data deleteis the destructive, script-invoked verb, and it had zero--output-jsonsupport. This adds it, mirroringdata_list.go's contract exactly, plus the one-page JSON scripting policy the epic asked for.Changes
internal/cli/data_delete.go(strictly this file — the sibling WS-B PR ownsdata.go):--output-jsonflag; RunE splits streams exactly likedata list(human → stderr viaprinterForWriter, JSON → stdout) and — likedata ingest's implies---no-input— never wires a prompter in JSON mode: a scripted delete must pass--yes(or--dry-run), else it fails closed with the documented exit 3.runDataDeletegains thejsonEmitted+ deferred error-writer pattern copied fromrunDataList(Bugbot feat: add dataset list command #53 lineage): every failure return emits{status:"error", error, exit_code}, byte-compatible withwriteDataListErrorJSON's shape, so--output-json | jqnever sees empty stdout.deleted/dry-run/declined— all exit 0, matching the human flow (exit codes are unchanged; scripts branch onstatus). Payload carries the case-resolved table spelling (backend#1027), namespace, release, database,pvc_paths,removed_paths([], nevernull).docs/json-output.md(new one-pager): which commands emit JSON (version,data ingest,data list,data delete), the one-object-on-stdout rule, the shared error shape, exit-code lockstep, and the additive-only stability promise. Extension todoctor/resources/auth statusexplicitly deferred pending epic OQ5.internal/cli/data_delete_json_test.go(new): success (case-resolved spelling + no human leak into the JSON stream), dry-run ([] not null), confirm-declined, early failure (exit 2, pre-discovery), off-TTY refusal (exit 3), late teardown failure (exit 7), and a wiring-level test pinning that--output-jsonnever prompts (root'sSilenceUsagemirrored in-test).Verification (ran locally)
go build ./...,go vet ./internal/cli/,gofmt -lclean.go test ./...green (all 15 packages).go run ./cmd/tracebloc data delete --helpshows the new flag + the Long-text JSON note.Independent of the other WS-F PRs (#300/#307) — no shared files; merge order flexible.
Fixes #297
🤖 Generated with Claude Code
Note
Medium Risk
Touches a destructive cluster teardown path, but behavior matches existing JSON commands, requires explicit
--yesin JSON mode, and only changes machine-readable output—not teardown logic itself.Overview
Adds
--output-jsontotracebloc data delete, aligned withdata list/data ingest: one JSON object on stdout, human UI on stderr, documented exit codes unchanged, and failures always emit{status:"error", error, exit_code}via a deferred writer so parsers never see empty stdout.JSON mode is non-interactive (no prompts); scripts must pass
--yesor--dry-run, otherwise the command fails closed (exit 3). Success payloads usestatusvaluesdeleted,dry-run, ordeclined(all exit 0—branch onstatus, not exit code alone), and include case-resolvedtable,database,pvc_paths, andremoved_paths(empty arrays as[], notnull).Introduces
docs/json-output.mdas the cross-command scripting contract (which verbs emit JSON, stdout/stderr split, shared error shape, additive stability promise, anddata deleterequirements).Adds
data_delete_json_test.gocovering success, dry-run, declined confirm, early/late failures, stream separation, and wiring that JSON mode never prompts.Reviewed by Cursor Bugbot for commit 3453bb2. Bugbot is set up for automated code reviews on this repo. Configure here.