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:
59
README.md
59
README.md
@@ -389,6 +389,65 @@ Items for future releases:
|
||||
|
||||
---
|
||||
|
||||
## output style
|
||||
|
||||
All user-facing output goes through helpers in `internal/ui` and conforms
|
||||
to a uniform style. Color is enabled when stdout is a TTY and the
|
||||
`NO_COLOR` environment variable is unset (https://no-color.org/).
|
||||
|
||||
Message classes:
|
||||
|
||||
| Class | Marker | Alignment | Use for |
|
||||
|-------|--------|-----------|---------|
|
||||
| Banner | none | column 0 | The startup line printed once per invocation |
|
||||
| Begin | `》` (white) | column 0 | An operation is about to start (present-continuous verb) |
|
||||
| Complete | `》` (green) | column 0 | An operation just finished (past-tense verb) |
|
||||
| Info | `》` (white) | column 0 | Neutral status update |
|
||||
| Notice | `》` (cyan) | column 0 | Important note that is not a warning |
|
||||
| Warning | `Warning:` (orange/yellow) | column 0 | Recoverable problem |
|
||||
| Error | `ERROR:` (red) | column 0 | Operation aborted |
|
||||
| Progress | ` 》` (white) | column 2 | Heartbeat or per-item status during a long-running operation |
|
||||
|
||||
Conventions:
|
||||
|
||||
* Messages are complete English sentences ending with a period.
|
||||
* Fully qualify terms — say "backup destination store" instead of
|
||||
"storage", "snapshot source files enumeration" instead of "scan",
|
||||
"local index database" instead of "database".
|
||||
* Every operation that emits a Complete also emits a corresponding
|
||||
Begin. Operations that print only a Begin (because completion is
|
||||
obvious from a later Begin) should be rare and intentional.
|
||||
* Use natural verb tense to signal state: "Uploading" for Begin,
|
||||
"Uploaded" for Complete. Never write the words "begin" or "complete"
|
||||
in the body — the marker color already conveys that.
|
||||
* All elapsed and remaining-time fields are explicitly scoped to their
|
||||
subject: write "blob upload elapsed 30s, blob upload estimated remaining
|
||||
time (14s), finish at 2026-06-17T03:15:00Z", never just "elapsed 30s,
|
||||
ETA 14s".
|
||||
* "ETA" means an absolute clock time (when the operation will finish),
|
||||
not a remaining-duration. Use `ui.Time()` for the former and
|
||||
`ui.Duration()` for the latter, and label both.
|
||||
|
||||
Value colorizers in `internal/ui` colorize specific value types
|
||||
consistently. Compose messages from these helpers rather than embedding
|
||||
ANSI escapes inline:
|
||||
|
||||
| Helper | Color | Use for |
|
||||
|--------|-------|---------|
|
||||
| `Hex` | cyan | Blob hashes, chunk hashes (truncated to 12 chars + `...`) |
|
||||
| `Snapshot` | bold cyan | Snapshot IDs (untruncated) |
|
||||
| `Path` | blue | Filesystem paths |
|
||||
| `Size` | magenta | Byte counts (human-readable) |
|
||||
| `Speed` | magenta | Bytes-per-second rates |
|
||||
| `Duration` | yellow | Elapsed or remaining time |
|
||||
| `Time` | yellow | Absolute clock times |
|
||||
| `Count` | magenta | Integer counts with thousands separators |
|
||||
| `Percent` | magenta | Percentages |
|
||||
|
||||
When `NO_COLOR` is set or output is not a TTY, all helpers return plain
|
||||
text and the marker prefixes (`》`, `Warning:`, `ERROR:`) emit without
|
||||
ANSI escapes.
|
||||
|
||||
## requirements
|
||||
|
||||
* Go 1.26 or later
|
||||
|
||||
Reference in New Issue
Block a user