The Go style guide: "Use log/slog for structured logging. Import sneak.berlin/go/simplelog for sensible defaults."
internal/log/log.go is built on github.com/apex/log plus pterm. Its
package doc says so outright: "provides leveled logging with progress output
helpers on top of apex/log and pterm". go.mod carries github.com/apex/log v1.9.0, and every logging call in the codebase routes
through it.
This is a third-party dependency doing a job the standard library has done
since Go 1.21. Beyond the policy, apex/log is effectively unmaintained,
and shipping a 1.0 library that drags it into every consumer's dependency
graph is a cost imposed on everyone who imports mfer.
This is the largest single item in the 1.0 backlog and it is deliberately
scoped as its own unit.
Definition of done
internal/log is implemented on log/slog, with sneak.berlin/go/simplelog used for defaults.
github.com/apex/log is gone from go.mod and go.sum, and go mod tidy
has been run.
The package's existing public surface — the leveled helpers, the Level
enum, Progressf / ProgressDone line-overwrite helpers — either survives
unchanged or changes deliberately, with every call site updated. Callers
outside internal/log should not need to care.
Human-facing CLI output is unchanged: --verbose and --quiet behave as
before, progress lines still overwrite in place on a TTY, and the banner
output is preserved or its removal is called out explicitly.
The tests in internal/log/log_test.go still pass and are extended to
cover level filtering and the progress helpers against the new backend.
make check passes with -race. TODO.md updated in the same commit.
Implementation requirements
Decide explicitly what happens to pterm. It is a separate concern from
the logging backend (it does the terminal rendering), and it may be
legitimate to keep it for progress output while moving leveled logging to slog. State the decision in the commit message; do not silently keep or
silently drop it.
slog's handler model does not natively do in-place line overwriting.
Progress output is a terminal-rendering concern, not a log-record concern —
do not force it through a slog.Handler just to keep it in one place.
The CLI wires a process-global logger, and the test suite already
serializes CLI runs behind a mutex because of it. Do not make that worse.
If the migration lets the logger become an injected dependency rather than
a global, that is a real improvement — but only if it does not balloon
this PR. If you leave it global, say why.
Run the tests with -race. A logging rewrite touching a process-global is
exactly where races appear.
Do not change any log message text as a drive-by. Message wording is
audited separately.
This is a large change. If it cannot be done without also restructuring
unrelated code, stop and report back rather than expanding scope.
Commit title must end with (closes #77).
## Context
The Go style guide: "Use `log/slog` for structured logging. Import
`sneak.berlin/go/simplelog` for sensible defaults."
`internal/log/log.go` is built on `github.com/apex/log` plus `pterm`. Its
package doc says so outright: "provides leveled logging with progress output
helpers on top of apex/log and pterm". `go.mod` carries
`github.com/apex/log v1.9.0`, and every logging call in the codebase routes
through it.
This is a third-party dependency doing a job the standard library has done
since Go 1.21. Beyond the policy, `apex/log` is effectively unmaintained,
and shipping a 1.0 library that drags it into every consumer's dependency
graph is a cost imposed on everyone who imports `mfer`.
This is the largest single item in the 1.0 backlog and it is deliberately
scoped as its own unit.
## Definition of done
- `internal/log` is implemented on `log/slog`, with
`sneak.berlin/go/simplelog` used for defaults.
- `github.com/apex/log` is gone from `go.mod` and `go.sum`, and `go mod tidy`
has been run.
- The package's existing public surface — the leveled helpers, the `Level`
enum, `Progressf` / `ProgressDone` line-overwrite helpers — either survives
unchanged or changes deliberately, with every call site updated. Callers
outside `internal/log` should not need to care.
- Human-facing CLI output is unchanged: `--verbose` and `--quiet` behave as
before, progress lines still overwrite in place on a TTY, and the banner
output is preserved or its removal is called out explicitly.
- The tests in `internal/log/log_test.go` still pass and are extended to
cover level filtering and the progress helpers against the new backend.
- `make check` passes with `-race`. `TODO.md` updated in the same commit.
## Implementation requirements
- Decide explicitly what happens to `pterm`. It is a separate concern from
the logging backend (it does the terminal rendering), and it may be
legitimate to keep it for progress output while moving leveled logging to
`slog`. State the decision in the commit message; do not silently keep or
silently drop it.
- `slog`'s handler model does not natively do in-place line overwriting.
Progress output is a terminal-rendering concern, not a log-record concern —
do not force it through a `slog.Handler` just to keep it in one place.
- The CLI wires a process-global logger, and the test suite already
serializes CLI runs behind a mutex because of it. Do not make that worse.
If the migration lets the logger become an injected dependency rather than
a global, that is a real improvement — but only if it does not balloon
this PR. If you leave it global, say why.
- Run the tests with `-race`. A logging rewrite touching a process-global is
exactly where races appear.
- Do not change any log message text as a drive-by. Message wording is
audited separately.
- This is a large change. If it cannot be done without also restructuring
unrelated code, stop and report back rather than expanding scope.
- Commit title must end with ` (closes #77)`.
clawbot
added this to the 1.0.0 milestone 2026-08-09 03:42:56 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Context
The Go style guide: "Use
log/slogfor structured logging. Importsneak.berlin/go/simplelogfor sensible defaults."internal/log/log.gois built ongithub.com/apex/logpluspterm. Itspackage doc says so outright: "provides leveled logging with progress output
helpers on top of apex/log and pterm".
go.modcarriesgithub.com/apex/log v1.9.0, and every logging call in the codebase routesthrough it.
This is a third-party dependency doing a job the standard library has done
since Go 1.21. Beyond the policy,
apex/logis effectively unmaintained,and shipping a 1.0 library that drags it into every consumer's dependency
graph is a cost imposed on everyone who imports
mfer.This is the largest single item in the 1.0 backlog and it is deliberately
scoped as its own unit.
Definition of done
internal/logis implemented onlog/slog, withsneak.berlin/go/simplelogused for defaults.github.com/apex/logis gone fromgo.modandgo.sum, andgo mod tidyhas been run.
Levelenum,
Progressf/ProgressDoneline-overwrite helpers — either survivesunchanged or changes deliberately, with every call site updated. Callers
outside
internal/logshould not need to care.--verboseand--quietbehave asbefore, progress lines still overwrite in place on a TTY, and the banner
output is preserved or its removal is called out explicitly.
internal/log/log_test.gostill pass and are extended tocover level filtering and the progress helpers against the new backend.
make checkpasses with-race.TODO.mdupdated in the same commit.Implementation requirements
pterm. It is a separate concern fromthe logging backend (it does the terminal rendering), and it may be
legitimate to keep it for progress output while moving leveled logging to
slog. State the decision in the commit message; do not silently keep orsilently drop it.
slog's handler model does not natively do in-place line overwriting.Progress output is a terminal-rendering concern, not a log-record concern —
do not force it through a
slog.Handlerjust to keep it in one place.serializes CLI runs behind a mutex because of it. Do not make that worse.
If the migration lets the logger become an injected dependency rather than
a global, that is a real improvement — but only if it does not balloon
this PR. If you leave it global, say why.
-race. A logging rewrite touching a process-global isexactly where races appear.
audited separately.
unrelated code, stop and report back rather than expanding scope.
(closes #77).