# Plan: Root Makefile ## Context The project has grown to a multi-step Go implementation with a test suite, and a Python port is planned. Common workflows (build, test, vet, coverage) are currently typed by hand with `cd go && go ...`. A root `Makefile` gives a single, discoverable entry point for these tasks and a place to hang the future Python targets. Decisions confirmed with the user: - Include **all** proposed targets: core set + `cover` + `tidy`/`install` + `lint`. - **Namespaced** naming (`go-build`, `go-test`, …) with umbrella targets (`build`, `test`, …) that delegate to the language-specific ones, so `py-*` can slot in cleanly during the Python port. Environment: GNU Make 3.81, Go 1.26.4, `golangci-lint` installed. Go commands use `go -C go …` (Go 1.20+ directory flag) to avoid `cd`. ## File: `Makefile` (repo root) Variables: ```make GO_DIR := go BINARY := latprobe ARGS ?= .DEFAULT_GOAL := help ``` ### Umbrella targets (delegate now to Go; Python added later) | Target | Delegates to | Notes | |--------|--------------|-------| | `help` | — | Default. Auto-generated from `##` comments. | | `build` | `go-build` | `py-build` appended during Python port | | `test` | `go-test` | `py-test` appended later | | `check` | `go-check` | fmt + vet + test gate | | `fmt` | `go-fmt` | | | `vet` | `go-vet` | | | `clean` | `go-clean` | | | `all` | `check build` | | A comment marks where `py-*` will be added (e.g. `test: go-test # + py-test later`). ### Go targets | Target | Command | |--------|---------| | `go-build` | `go -C $(GO_DIR) build -o $(BINARY) .` | | `go-run` | `go -C $(GO_DIR) run . $(ARGS)` | | `go-test` | `go -C $(GO_DIR) test ./...` | | `go-test-verbose` | `go -C $(GO_DIR) test -v ./...` | | `go-fmt` | `gofmt -w $(GO_DIR)` | | `go-vet` | `go -C $(GO_DIR) vet ./...` | | `go-check` | depends on `go-fmt go-vet go-test` | | `go-cover` | `go -C $(GO_DIR) test -coverprofile=coverage.out ./...` then `go -C $(GO_DIR) tool cover -html=coverage.out -o coverage.html` | | `go-tidy` | `go -C $(GO_DIR) mod tidy` | | `go-install` | `go -C $(GO_DIR) install .` | | `go-lint` | guard for `golangci-lint` presence, then `cd $(GO_DIR) && golangci-lint run` | | `go-clean` | `rm -f $(GO_DIR)/$(BINARY) $(GO_DIR)/coverage.out $(GO_DIR)/coverage.html` | Details: - `make run ARGS="https://example.com -n 3"` passes flags through. - All targets listed in `.PHONY`. - `help` recipe: `grep`/`awk` over `$(MAKEFILE_LIST)` printing `target ## description` (works on GNU Make 3.81). - `go-lint` guard: ```make @command -v golangci-lint >/dev/null 2>&1 || { echo "golangci-lint not installed: https://golangci-lint.run"; exit 1; } ``` ## Other changes - `.gitignore`: add `go/coverage.out` and `go/coverage.html`. - `docs/usage/makefile.md`: new user doc — target table + examples. - `CHANGELOG.md`: timestamped entry. - `README.md`: short "Development" note pointing at `make help`. - `docs/plans/2026-07-01-01-05-makefile.md`: copy of this plan. ## Verification ```sh make help # lists all targets with descriptions make build # produces go/latprobe make run ARGS="https://example.com" make test # go test ./... make go-test-verbose # per-test PASS/FAIL output make check # fmt + vet + test make go-cover # writes go/coverage.html make go-lint # runs golangci-lint (installed) make clean # removes binary + coverage artifacts ``` Confirm `make` with no args shows help, and that `clean` leaves the tree as `git status` clean (no tracked files removed).