Files
interpres/docs/DEVELOPMENT.md
T
petrbalvin 9a1b922712
Test / test (push) Failing after 24s
ci: fence the test recipes and rebuild the pipelines around the gate set
Assisted-by: DeepSeek V4.1 Flash
2026-10-04 21:15:21 +02:00

5.1 KiB

Development

How to work on interpres.

Prerequisites

  • Go 1.27.1, the version the go directive in go.mod declares.
  • just for the recipes.
  • The toml-test binary on PATH for the compliance recipe, installed with go install github.com/toml-lang/toml-test/v2/cmd/toml-test@v2.2.0.

The module has no third-party dependencies, so there is nothing else to fetch.

Setup

git clone https://sourcedock.dev/petrbalvin/interpres.git
cd interpres
just build
just test

Recipes

Every recipe in the project's justfile, and what it does. Taken from the file itself, so the names and the list match it exactly; just with no arguments prints the same list.

Recipe What it does
just gates the definition of done: build, format check, vet, the test suite with the coverage floor, and the race detector
just build compiles ./cmd/interpres-decode into bin/interpres-decode, with -trimpath -buildvcs=true
just test the suite with no cache, then the coverage floor of 80 percent from coverage.out, under the memory fence
just race the same suite under the race detector, fenced too
just unit ./... TestName a fast scoped run for iterating; the second argument is a -run pattern, .* by default, fenced
just fuzz FuzzParse . 30s time-boxed fuzzing of one target in exactly one package; go test -fuzz rejects ./...; never a gate, fenced
just bench benchmarks, -benchmem -count=5, on an idle machine only
just fmt gofmt -w ., format in place
just fmt-check gofmt -l ., zero diff
just vet go vet ./... and go fix -diff ./...
just run go run ./cmd/interpres-decode, reads TOML from stdin
just dev the same run, for iterating
just example go run ./examples/basic, the usage tour
just toml-test builds the adapter and runs the official toml-test compliance suite against it, decoder and encoder
just coverage-html just test, then go tool cover -html into coverage.html
just install builds, then copies the binary into ~/.local/bin (BINDIR overrides)
just uninstall removes the installed binary
just clean removes bin/ and coverage.out
just cross cross-compile smoke of the library and the command for arm64, loong64, riscv64 and the browser and edge runtimes; a hand-run convenience, not a gate
just release-check X.Y.Z the release pre-flight: the branch, a clean tree, a sync with origin, the gates, and a CHANGELOG section ready to release
just docs-drift compares the toml-test counts the documentation quotes with a live suite run

Running a single test

just unit ./... TestParseMultilineString
go test -run 'TestRejectsSpecInvalid/table_over_array' ./...
go test ./cmd/interpres-decode/

Add -v for the sub-test names, and -race when the change touches concurrency. -count=1 defeats the test cache when a result looks stale.

Coverage

just test
go tool cover -func=coverage.out
just coverage-html

just test prints the total itself and fails below 80 percent, which is the same floor CI enforces. The profile is coverage.out; the HTML map is coverage.html. Both are ignored by git.

Benchmarks

just bench

Benchmark on an idle machine, and compare only runs made in one process against each other. The recipe sweeps ./... five times with -benchmem. The binding measurement method, and what counts as a result, is in docs/BENCHMARKING.md.

Debugging the build

go build -gcflags='-m' ./...   # inlining decisions
go build -gcflags='-S' ./...   # what the compiler generated

Continuous integration

Workflows live in .gitea/workflows/ and run on the project's own runners. They are written by hand rather than through just, but between them they carry the same set of gates, so a green just gates locally is the fastest way to a green pipeline.

Workflow Trigger What it does
test.yml push or pull request to development format check, vet, and the suite's short layer with the 80 percent coverage floor, inside the two-minute push budget
suite.yml workflow_dispatch, by hand the complete gate set minus race: build, format, vet, modernisation, the full suite and the coverage floor
release.yml a v* tag tag validation, then the Gitea release from the CHANGELOG section and nothing else. No gate runs at the tag: the tree was tested on every push, and a library ships no assets

Race never runs in CI: it belongs to the local just gates, which races the tree on the machine at the keyboard before the commit. The toml-test compliance suite is a local recipe (just toml-test) and a development record rather than a push gate.

Releases

Releases are cut by merging development into main and tagging vX.Y.Z. The tag drives the release workflow: it validates the tag, extracts the matching ## [X.Y.Z] section from CHANGELOG.md, and publishes the release with that section as its body. No gate runs at the tag; a library ships no binaries, so the release carries the notes and nothing else.