docs: document the library/CLI output split
CI / Test (push) Successful in 3m5s
CI / Check (push) Successful in 2m38s
CI / Format (push) Successful in 17s
CI / Clippy (push) Successful in 2m34s

The library is terminal-silent: diagnostics through the log facade,
progress through Progress sinks. The CLI owns all rendering.
This commit is contained in:
2026-10-03 00:13:34 +02:00
parent fe0b99ee6b
commit 57367faa01
2 changed files with 25 additions and 7 deletions
+21 -3
View File
@@ -10,7 +10,13 @@ Cargo workspace with two crates:
- `crates/ecr-cli` — the CLI front-end (package `ecr-cli`, binary `ecr`).
Parses flags, maps them onto the library API, propagates exit codes.
The library must not depend on CLI types (`clap` is a CLI-only dependency).
The library must not depend on CLI types (`clap` is a CLI-only
dependency), and it never writes to the terminal: diagnostics go
through the `log` facade, and long-running operations (downloads,
extraction, initramfs creation) report progress through an
`ecr::progress::Progress` sink (`NoProgress` discards everything).
All terminal output — the logger driven by `-v`, the bars and
spinners (indicatif) — is owned by `crates/ecr-cli`.
## Library API
@@ -18,12 +24,13 @@ The library must not depend on CLI types (`clap` is a CLI-only dependency).
- `RootfsCache::new(dir)` / `RootfsCache::default_dir()` — the image tarball
cache (default `~/.cache/ecr`).
- `cache.prepare(&PrepareRequest)` — parse the image reference, resolve
- `cache.prepare(&req, &progress)` — parse the image reference, resolve
floating version aliases ("latest", "lts", "edge") to a concrete version
before computing the cache key, run the OCI `:latest` digest freshness
check, download through the cache when needed, and extract into a scratch
directory. Returns a `PreparedRootfs` (TempDir-backed; dropped on drop).
- `cache.prepare_provisioned(&req, provision)` — hot-cell amortization: on a
- `cache.prepare_provisioned(&req, &progress, provision)` — hot-cell
amortization: on a
cache hit with a `.provisioned` sidecar the entry is extracted as-is (no
freshness check, no provisioning); otherwise the rootfs is prepared,
`provision(&PreparedRootfs)` runs once, and `persist` writes the result
@@ -58,6 +65,17 @@ the bind targets; `in_rootfs(rootfs, target)` maps in-chroot paths and
rejects escaping targets. Overlay upper/work directories are temp dirs the
caller must keep alive (returned by `setup_mounts`).
### Progress and logging (`ecr::progress`)
- `Progress` — sink trait for sequential operations: `begin(label, unit,
total)` starts the next operation (implicitly ending the previous one),
`advance(n)` counts completed units, `finish` ends it. Consumers
implement it to render UI; `NoProgress` discards every event.
- Diagnostics go through `log`: `debug` for narration (URLs, layer info,
extraction steps), `warn` for recoverable conditions (unreadable
entries, failed best-effort setup). Nothing is emitted unless the
consumer installs a logger.
## Synopsis
```