Development
Build and test
go build ./cmd/ermite
go test ./...
go test ./... includes the end-to-end tests of internal/app (a real server per test). Run them before opening a pull request: CI runs them on main only.
Stamp the version with -ldflags "-X bnema.dev/ermite/internal/app.stamped=<version>".
Dev server
docker compose up # http://localhost:7341
docker compose down -v # also removes data and caches
The source is mounted and air rebuilds on each change to .go, .templ or web assets. The admin token is in compose.yaml. The container runs as root, which maps to your user under rootless Docker.
Docker image
docker build --build-arg VERSION="$(git describe --tags --always --dirty)" -t ermite .
Alpine with git, runs as uid 10001, data in /data. Behind a private route, --build-arg GIT_REWRITE_BASE=<url> rewrites the git host of the bnema.dev/ermite-* modules.
Tools
Pinned in go.mod:
go tool buf lint
go tool buf generate # proto/ -> gen/
go generate ./... # mockery mocks of the ports
go tool hexcheck -fail-on warn ./...
Architecture
cmd/ermite → internal/app → internal/usecase → internal/ports → internal/domain
↘ internal/adapters (Git, KV, HTTP, API, web, client)
internal/app: CLI and composition root.internal/usecaseimports onlydomainandports.- Adapters import
domain,portsandinternal/clientlimit; never a use case,appor another adapter. - The web adapter calls use cases through
ports, never the generated API code. internal/portsimports onlydomain;domainimports nothing from the module.internal/configis used byinternal/apponly.
internal/boundary/boundary_test.go enforces the imports; hexcheck (.hexcheck.yaml) checks the layering.