1 Commits
Author SHA1 Message Date
sneak 1e9644edbd Write only the document to stdout from snapshot remove --json (closes #251)
check / check (push) Waiting to run
When the destination store cannot be reached, `snapshot remove` still
removes the snapshot from the local index and warns. The warning went
through the UI, which writes to stdout, so under `--json` it landed
ahead of the document and `| jq` failed on a command that exited 0.
Under `--json` the UI warning is now skipped. The logger's warning,
which goes to stderr in every mode, now also says to run `vaultik
prune` once the destination store is reachable.

The new test runs the command through `Entry` against a missing
destination directory, decodes stdout as exactly one JSON document, and
finds the warning and the `vaultik prune` follow-up on stderr.

Model: opus-5-5
2026-10-07 00:27:59 +00:00
3 changed files with 8 additions and 4 deletions
+2 -1
View File
@@ -28,7 +28,8 @@ the tag exists and is exercised; what is left is merging `next` to
warning that the snapshot's metadata was left on the destination store warning that the snapshot's metadata was left on the destination store
went to stdout ahead of the document, breaking `| jq` on a command that went to stdout ahead of the document, breaking `| jq` on a command that
exited 0. Under `--json` the warning now reaches stderr only, through exited 0. Under `--json` the warning now reaches stderr only, through
the logger. the logger, whose record now also says to run `vaultik prune` once the
destination store is reachable.
- 2026-10-06: Made command output follow the README's stdout and stderr - 2026-10-06: Made command output follow the README's stdout and stderr
rules ([issue #224](https://git.eeqj.de/sneak/vaultik/issues/224)). The rules ([issue #224](https://git.eeqj.de/sneak/vaultik/issues/224)). The
+3 -1
View File
@@ -91,7 +91,8 @@ func TestEntryJSONFailureIsReportedOnStderr(t *testing.T) {
// --json` against a destination directory that does not exist. The // --json` against a destination directory that does not exist. The
// command still exits 0 after removing the snapshot from the local // command still exits 0 after removing the snapshot from the local
// index. Its stdout must hold the document alone, with the warning // index. Its stdout must hold the document alone, with the warning
// about the destination store on stderr. // about the destination store, and the `vaultik prune` follow-up, on
// stderr.
// //
//nolint:paralleltest // replaces os.Args, os.Stdout, os.Stderr and the xdg globals //nolint:paralleltest // replaces os.Args, os.Stdout, os.Stderr and the xdg globals
func TestEntrySnapshotRemoveJSONWarningIsOnStderr(t *testing.T) { func TestEntrySnapshotRemoveJSONWarningIsOnStderr(t *testing.T) {
@@ -104,6 +105,7 @@ func TestEntrySnapshotRemoveJSONWarningIsOnStderr(t *testing.T) {
requireExactlyOneJSONDocument(t, stdout) requireExactlyOneJSONDocument(t, stdout)
assert.Contains(t, stderr, assert.Contains(t, stderr,
"Could not remove snapshot metadata from remote storage") "Could not remove snapshot metadata from remote storage")
assert.Contains(t, stderr, "run 'vaultik prune'")
} }
// writeMissingDestinationConfig builds a config whose destination // writeMissingDestinationConfig builds a config whose destination
+3 -2
View File
@@ -1260,8 +1260,9 @@ func (v *Vaultik) removeSnapshotRemote(snapshotID string, opts *RemoveOptions) b
err := v.deleteRemoteSnapshotByKey(remoteKey) err := v.deleteRemoteSnapshotByKey(remoteKey)
if err != nil { if err != nil {
log.Warn("Could not remove snapshot metadata from remote storage", log.Warn("Could not remove snapshot metadata from remote storage; "+
"error", err) "run '"+pruneCommandHint+"' once the remote is reachable "+
"to finish cleanup", "error", err)
// The UI writes to stdout, which under --json holds only the // The UI writes to stdout, which under --json holds only the
// document; the log record above is the warning on stderr. // document; the log record above is the warning on stderr.