fix: use v.Stdout/v.Stdin instead of os.Stdout for all user-facing output

Multiple methods wrote directly to os.Stdout instead of using the injectable
v.Stdout writer, breaking the TestVaultik testing infrastructure and making
output impossible to capture or redirect.

Fixed in: ListSnapshots, PurgeSnapshots, VerifySnapshotWithOptions,
PruneBlobs, outputPruneBlobsJSON, outputRemoveJSON, ShowInfo, RemoteInfo.
This commit is contained in:
clawbot
2026-02-08 12:03:01 -08:00
committed by user
parent df0e8c275b
commit 0a0d9f33b0
2 changed files with 68 additions and 69 deletions

View File

@@ -3,7 +3,6 @@ package vaultik
import (
"encoding/json"
"fmt"
"os"
"strings"
"git.eeqj.de/sneak/vaultik/internal/log"
@@ -121,29 +120,29 @@ func (v *Vaultik) PruneBlobs(opts *PruneOptions) error {
if len(unreferencedBlobs) == 0 {
log.Info("No unreferenced blobs found")
if opts.JSON {
return outputPruneBlobsJSON(result)
return v.outputPruneBlobsJSON(result)
}
fmt.Println("No unreferenced blobs to remove.")
_, _ = fmt.Fprintln(v.Stdout, "No unreferenced blobs to remove.")
return nil
}
// Show what will be deleted
log.Info("Found unreferenced blobs", "count", len(unreferencedBlobs), "total_size", humanize.Bytes(uint64(totalSize)))
if !opts.JSON {
fmt.Printf("Found %d unreferenced blob(s) totaling %s\n", len(unreferencedBlobs), humanize.Bytes(uint64(totalSize)))
_, _ = fmt.Fprintf(v.Stdout, "Found %d unreferenced blob(s) totaling %s\n", len(unreferencedBlobs), humanize.Bytes(uint64(totalSize)))
}
// Confirm unless --force is used (skip in JSON mode - require --force)
if !opts.Force && !opts.JSON {
fmt.Printf("\nDelete %d unreferenced blob(s)? [y/N] ", len(unreferencedBlobs))
_, _ = fmt.Fprintf(v.Stdout, "\nDelete %d unreferenced blob(s)? [y/N] ", len(unreferencedBlobs))
var confirm string
if _, err := fmt.Scanln(&confirm); err != nil {
if _, err := fmt.Fscanln(v.Stdin, &confirm); err != nil {
// Treat EOF or error as "no"
fmt.Println("Cancelled")
_, _ = fmt.Fprintln(v.Stdout, "Cancelled")
return nil
}
if strings.ToLower(confirm) != "y" {
fmt.Println("Cancelled")
_, _ = fmt.Fprintln(v.Stdout, "Cancelled")
return nil
}
}
@@ -185,20 +184,20 @@ func (v *Vaultik) PruneBlobs(opts *PruneOptions) error {
)
if opts.JSON {
return outputPruneBlobsJSON(result)
return v.outputPruneBlobsJSON(result)
}
fmt.Printf("\nDeleted %d blob(s) totaling %s\n", deletedCount, humanize.Bytes(uint64(deletedSize)))
_, _ = fmt.Fprintf(v.Stdout, "\nDeleted %d blob(s) totaling %s\n", deletedCount, humanize.Bytes(uint64(deletedSize)))
if deletedCount < len(unreferencedBlobs) {
fmt.Printf("Failed to delete %d blob(s)\n", len(unreferencedBlobs)-deletedCount)
_, _ = fmt.Fprintf(v.Stdout, "Failed to delete %d blob(s)\n", len(unreferencedBlobs)-deletedCount)
}
return nil
}
// outputPruneBlobsJSON outputs the prune result as JSON
func outputPruneBlobsJSON(result *PruneBlobsResult) error {
encoder := json.NewEncoder(os.Stdout)
func (v *Vaultik) outputPruneBlobsJSON(result *PruneBlobsResult) error {
encoder := json.NewEncoder(v.Stdout)
encoder.SetIndent("", " ")
return encoder.Encode(result)
}