Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a81e5f4
Make the rsync host publishable
rabarbra Aug 22, 2026
9c6cc15
Let two artifacts of one version hold identical bytes
rabarbra Aug 22, 2026
b984f7c
Add a short test mode for the inner loop
rabarbra Aug 22, 2026
7d7bfb6
Read a bare 404 from a blob store as a missing blob
rabarbra Aug 22, 2026
ced7b62
s3 fixes
rabarbra Aug 22, 2026
7a8dabc
Show setup the flags this repository actually uses
rabarbra Aug 22, 2026
aef6351
Stop .gitignore hiding the cmd/snailmail directory
rabarbra Aug 22, 2026
87b99e3
Add the setup flag scope table that 1c15786 was missing
rabarbra Aug 22, 2026
26ec659
Exit with what to do about the failure
rabarbra Aug 22, 2026
d28b4b3
Decide what an S3 error means in one place
rabarbra Aug 22, 2026
025086c
Let the caller say how to reach hosts
rabarbra Aug 22, 2026
ae88d7a
Put install instructions and the endpoint probe on the format
rabarbra Aug 22, 2026
86b3300
Verify a rendered tree through the format that produced it
rabarbra Aug 22, 2026
5e36fd4
Register client verification instead of switching on the format
rabarbra Aug 22, 2026
dbb2b76
Let a host adapter check bytes without knowing about ecosystems
rabarbra Aug 22, 2026
b5da976
Give a host the configuration of that host
rabarbra Aug 22, 2026
36fa3d4
Separate the decision apply makes from the work it does
rabarbra Aug 22, 2026
27baafe
Let status describe a workspace that is not tidy
rabarbra Aug 22, 2026
251fa74
Say what would have worked
rabarbra Aug 22, 2026
e5c675c
Give the output one vocabulary
rabarbra Aug 22, 2026
9552041
Repin the build image past the patched standard library
rabarbra Aug 22, 2026
d111b7d
Decide what a valid endpoint is in one place
rabarbra Aug 22, 2026
2c44d61
Put the comments back on the methods they describe
rabarbra Aug 22, 2026
590e6b8
Run staticcheck, and fix what it found
rabarbra Aug 22, 2026
b1f0abd
Bump dependencies and correct what the docs claim
rabarbra Aug 22, 2026
c8bca68
Split the reference out of the front page
rabarbra Aug 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ jobs:
test -e /proc/sys/fs/binfmt_misc/qemu-aarch64
- run: make fmt
- run: make vet
- run: make lint
- run: make test-race
# The S3 adapters are build-tagged out for smaller binaries; that
# configuration has to keep compiling and passing.
Expand Down
11 changes: 8 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
dist
snailmail
# Anchored to the repository root. Without the leading slash, "snailmail"
# matched any path component of that name — which includes the cmd/snailmail
# directory, so every new file added to the CLI was silently invisible to git.
# Already-tracked files kept working, which is what hid it.
/snailmail
/build/
/dist/
*.test

# Workspace runtime state: a lock and a staging directory, written wherever a
# command runs. Never reviewed, never published.
.snailmail/
11 changes: 9 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1@sha256:87999aa3d42bdc6bea60565083ee17e86d1f3339802f543c0d03998580f9cb89
FROM golang:1.25-alpine@sha256:56961d79ea8129efddcc0b8643fd8a5416b4e6228cfd477e3fd61deb2672c587 AS build
FROM golang:1.25-alpine@sha256:1ae0735f00daffa3aaf1363a5184c0d2dc55c78e3db4ec70241cdac97bf84b59 AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
Expand All @@ -9,7 +9,14 @@ RUN CGO_ENABLED=0 go test -c -o /out/openpgp.test ./signer/openpgp

# Scanned here rather than on the runner: `go run tool@version` builds the tool
# with the ambient toolchain, so a runner older than go.mod's requirement cannot
# load these packages at all. The build image is digest-pinned and current.
# load these packages at all.
#
# The build image is digest-pinned, which means it has to be repinned when the
# standard library is patched — a pin freezes the toolchain along with
# everything else, so this job failing is the pin doing its job rather than a
# surprise. The digest above is what `docker pull golang:1.25-alpine` resolves
# to; take the new one from there and check `go version` moved past whatever
# govulncheck named.
FROM build AS vulncheck
RUN go run golang.org/x/vuln/cmd/govulncheck@v1.1.4 ./...

Expand Down
24 changes: 23 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ help: ## Show the available targets
# ---------------------------------------------------------------- checks

.PHONY: check
check: fmt vet test ## Everything CI checks, in the order that fails fastest
check: fmt vet lint test ## Everything CI checks, in the order that fails fastest

.PHONY: fmt
fmt: ## Fail if anything is unformatted
Expand All @@ -63,10 +63,32 @@ vet: ## Vet the default build and the one with S3 compiled out
go vet ./...
go vet -tags nos3 ./...

.PHONY: lint
# staticcheck finds what vet does not: unused code, impossible conditions,
# results ignored where they matter. An error taxonomy sat here fully populated
# and entirely unread for long enough to be worth a tool that says so.
#
# Pinned like every other tool here, so a lint that passes today passes
# tomorrow and an upgrade is a reviewable change rather than a surprise. The pin
# has to be recent enough to read the toolchain go.mod asks for: an older
# staticcheck cannot decode a newer Go export format and fails on the standard
# library rather than on this code.
STATICCHECK ?= go run honnef.co/go/tools/cmd/staticcheck@2026.2.1
lint: ## Run staticcheck
$(STATICCHECK) ./...

.PHONY: test
test: ## Run the suite
go test -count=1 ./...

.PHONY: test-short
# The inner loop. Leaves out what needs a container, a pip install, or a lock
# sharded past its threshold — everything whose cost is the machine rather than
# the code. `check` and CI still run the full suite, so this skips nothing
# permanently, only between edits.
test-short: ## Run the suite without the slow machine-dependent tests
go test -short -count=1 ./...

.PHONY: test-race
# The race detector is written in C, so it needs cgo — and the CGO_ENABLED=0 above
# turns that into "go: -race requires cgo" rather than into a static binary. That
Expand Down
6 changes: 4 additions & 2 deletions PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -1450,8 +1450,10 @@ The format-and-host coupling that this phase owed is closed for its first
cases: GitHub Pages serves signed Debian, rpm, apk, raw and Helm alongside PyPI.
The matrix itself is declared in `host/support.go` rather than inferred, so the
gaps that remain are readable rather than discovered — and each undeclared pair
records why. Remaining: S3 beyond PyPI, additional key backends, `import`, and
the TUI. The next formats are nix cache, cargo, go, and maven, in that order.
records why. Remaining: additional key backends and the TUI. The next formats
are nix cache, cargo, go, and maven, in that order. `import` is implemented, and
so is S3 beyond PyPI — see the paragraph below, which was written when it landed
and outlived this sentence.

S3 beyond PyPI turned out not to be a declaration. The adapter no longer
hardcodes `simple/index.html`: `host.Repository` carries `CommitPaths`, filled
Expand Down
Loading
Loading