Files
interpres/docs/DEVELOPMENT.md
T

116 lines
5.1 KiB
Markdown
Raw Normal View History

2026-08-19 18:44:00 +02:00
# Development
How to work on interpres.
## Prerequisites
2026-09-17 19:41:22 +02:00
- Go 1.27.1, the version the `go` directive in `go.mod` declares.
2026-08-19 18:44:00 +02:00
- [just](https://github.com/casey/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`.
2026-08-19 18:44:00 +02:00
The module has no third-party dependencies, so there is nothing else to fetch.
## Setup
```sh
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` |
| `just test` | the suite with no cache, then the coverage floor of 80 percent from `coverage.out` |
| `just race` | the same suite under the race detector |
| `just unit ./... TestName` | a fast scoped run for iterating; the second argument is a `-run` pattern, `.*` by default |
| `just fuzz FuzzParse . 30s` | time-boxed fuzzing of one target in exactly one package; `go test -fuzz` rejects `./...`; never a gate |
| `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 |
2026-08-19 18:44:00 +02:00
| `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; nightly 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 |
2026-08-19 18:44:00 +02:00
## Running a single test
```sh
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
```sh
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
```sh
just bench
```
Benchmark on an idle machine, and compare only runs made in one process against
2026-09-18 00:20:42 +02:00
each other. The recipe sweeps `./...` five times with `-benchmem`. The binding
measurement method, and what counts as a result, is in
[docs/BENCHMARKING.md](BENCHMARKING.md).
2026-08-19 18:44:00 +02:00
## Debugging the build
```sh
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 they enforce 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, modernisation, build, the test suite with the 80 percent coverage floor, then the toml-test compliance suite |
| `race.yml` | `workflow_dispatch`, plus a nightly schedule at 03:00 UTC | the suite under the race detector, the same race gate `just gates` runs locally; the nightly schedule runs on the default branch, the released line |
| `fuzz.yml` | `workflow_dispatch`, plus a nightly schedule at 03:30 UTC | a 30 second fuzz smoke per target over the seeds and the gathered corpus |
| `release.yml` | a `v*` tag | tag validation, then format, vet, modernisation, build and the test suite with the coverage floor, then the Gitea release from the CHANGELOG section. No race detector: race never runs on a push path, and the local `just gates` raced the tree before the tag was cut |
2026-08-19 18:44:00 +02:00
## Releases
Releases are cut by merging `development` into `main` and tagging `vX.Y.Z`. The
tag drives the release workflow: it validates the tag, runs the static gates
and the test suite with the coverage floor, extracts the matching `## [X.Y.Z]`
section from `CHANGELOG.md`, and publishes the release with that section as its
body. A library ships no binaries, so the release carries the notes and nothing
else.