- Add canonical .golangci.yml (v2 schema, default: all, project
thresholds for lll/funlen/cyclop/dupl)
- Bump golangci-lint pins from v2.0.2 to v2.12.2 in Makefile
(go install, new /v2 module path) and Dockerfile (tagged+digest
Debian image pin)
- Fix all lint findings surfaced by the new linter set across
cmd/mfer, internal/bork, internal/cli, internal/log, and mfer:
static sentinel errors (err113), context-aware HTTP and exec
(noctx), guarded integer conversions and stricter permissions
(gosec), named constants (mnd, goconst), function decomposition
(funlen, cyclop, gocognit, nestif), declaration ordering
(funcorder), t.Parallel/t.TempDir/t.Setenv adoption in tests
(paralleltest, usetesting), protobuf getters (protogetter), plus
formatting and style cleanups (wsl_v5, nlreturn, lll, revive,
testifylint, and others)
- Serialize CLI runs in tests behind a mutex so parallel tests do
not cross-wire the process-global logger's captured output
The decompositions are behavior-preserving. In particular:
- REPO_POLICIES.md is untouched and stays byte-identical to the
authoritative copy in the prompts repo
- the mfer.manifest type stays unexported; whether to export it is an
open owner design question (README question 13)
- directories created by fetch keep mode 0755, because fetched trees
are content meant to be readable by other uids
- an absent MFFilePath.Mtime is handled explicitly and identically in
freshen, list, and export rather than being read as the Unix epoch,
which would classify every entry as changed and rewrite the manifest
on every freshen
- every user-visible error message renders byte-identically to what it
did before, with the err113 sentinels wrapped mid-sentence where
needed; the rendered strings are now pinned by tests
Also fixes an argument-injection defect the lint pass surfaced: key IDs
reach gpg as bare positional arguments, so a key ID beginning with "-"
was parsed by gpg as an option. All positional arguments now follow an
explicit "--" end-of-options marker.
The symlink-escape gap in fetch's path handling, which sanitizePath
does not and cannot address, is filed separately as #86.
Closes#39
Splits the Dockerfile into a dedicated lint stage using the `golangci/golangci-lint` image directly, rather than copying the binary into the builder stage.
## Changes
### Dockerfile
- **Lint stage** (`AS lint`): Uses the pre-built `golangci/golangci-lint` image (pinned by sha256) to run `make fmt-check` and `make lint`. This is a self-contained stage with its own `go mod download` and source copy.
- **Builder stage** (`AS builder`): Runs only `make test` and the final binary build. No longer needs golangci-lint installed.
- **Stage dependency**: `COPY --from=lint /src/go.sum /dev/null` forces BuildKit to always execute the lint stage (without this, unused stages are silently skipped).
- Both stages touch `mfer/mf.pb.go` to prevent make from trying to regenerate via protoc.
With BuildKit, the lint and builder stages run in parallel after their shared `go mod download` layers complete, so lint/formatting failures surface much faster without blocking on test execution.
### Makefile
- Added `lint` to the `check` target prereqs: `check: test lint fmt-check` (was `check: test fmt-check`), matching the [REPO_POLICIES](https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md) requirement.
Co-authored-by: clawbot <clawbot@noreply.git.eeqj.de>
Reviewed-on: #45
Co-authored-by: clawbot <clawbot@noreply.example.org>
Co-committed-by: clawbot <clawbot@noreply.example.org>