Introduce internal/ui package and rewrite user-facing output

All user-facing output now goes through a single ui.Writer with a
uniform style:

  》 (white)     for begin / info / notice
  》 (green)     for complete / success
  Warning:      for warnings (orange)
  ERROR:        for errors (red)
    》          (indented) for progress heartbeats

Color is enabled when stdout is a TTY and NO_COLOR is unset.

Standards:
- Complete-sentence messages with fully qualified terms ("backup
  destination store", "local index database", "snapshot source
  files enumeration").
- Every Complete has a matching Begin.
- Natural verb tense conveys state ("Uploading" -> "Uploaded"). The
  words "begin"/"complete" never appear in message bodies; the marker
  color carries that information.
- ETA means clock time, not duration. Progress lines say "estimated
  remaining time (<dur>), finish at <time>" with both labeled.

Adds globals.CommitDate (populated by Makefile/Dockerfile/goreleaser
via ldflags from `git show -s --format=%cI HEAD`) and a startup banner
printed once per invocation.

Strips fx call-chain noise from startup errors so users see the actual
underlying error (e.g. "creating base path: mkdir /Volumes/BACKUPS:
permission denied" instead of three layers of "could not build
arguments for function ...").

README documents the output style and the ui package conventions.
This commit is contained in:
sneak committed 2026-06-17 04:32:05 +02:00
1 parent 8de8f8e5cc
commit 00d4b36e35
14 files changed
+533 -187

No files matched your search

+8
View File
@@ -15,6 +15,7 @@ import (
"sneak.berlin/go/vaultik/internal/globals"
"sneak.berlin/go/vaultik/internal/snapshot"
"sneak.berlin/go/vaultik/internal/storage"
"sneak.berlin/go/vaultik/internal/ui"
)
// Vaultik contains all dependencies needed for vaultik operations
@@ -37,6 +38,12 @@ type Vaultik struct {
Stdout io.Writer
Stderr io.Writer
Stdin io.Reader
// UI is the writer for user-facing status, progress, warnings, errors.
// See package internal/ui for formatting conventions. Defaults to a
// writer wrapping Stdout; the cli layer replaces it with a discarding
// writer in --cron mode.
UI *ui.Writer
}
// VaultikParams contains all parameters for New that can be provided by fx
@@ -83,6 +90,7 @@ func New(params VaultikParams) *Vaultik {
Stdout: os.Stdout,
Stderr: os.Stderr,
Stdin: os.Stdin,
UI: ui.New(os.Stdout),
}
}