chore: add root Makefile with namespaced targets
Namespaced go-* targets (build, run, test, test-verbose, check, cover, fmt, vet, tidy, install, lint, clean) plus umbrella targets that delegate to them. help is the default. py-* targets will slot in during the Python port. Updates .gitignore with coverage artifacts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,5 +1,7 @@
|
|||||||
# Go binaries
|
# Go binaries and artifacts
|
||||||
go/latprobe
|
go/latprobe
|
||||||
|
go/coverage.out
|
||||||
|
go/coverage.html
|
||||||
python/latprobe
|
python/latprobe
|
||||||
|
|
||||||
# Python
|
# Python
|
||||||
|
|||||||
10
CHANGELOG.md
10
CHANGELOG.md
@@ -4,6 +4,16 @@ All completed features are logged here in reverse-chronological order.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 2026-07-01 01:05 — Root Makefile
|
||||||
|
|
||||||
|
- Namespaced targets: `go-build`, `go-run`, `go-test`, `go-test-verbose`, `go-check`, `go-cover`, `go-fmt`, `go-vet`, `go-tidy`, `go-install`, `go-lint`, `go-clean`
|
||||||
|
- Umbrella targets (`build`, `test`, `check`, `fmt`, `vet`, `clean`, `all`) delegate to Go now; `py-*` will slot in during the Python port
|
||||||
|
- `help` is the default target; auto-generated from `##` comments
|
||||||
|
- `go-run` accepts `ARGS=` for passing flags, `go-lint` guards for `golangci-lint`
|
||||||
|
- `.gitignore` updated with coverage artifacts
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 2026-07-01 00:49 — Integration tests (Go, Step 6)
|
## 2026-07-01 00:49 — Integration tests (Go, Step 6)
|
||||||
|
|
||||||
- Extracted `run(args, stdout, stderr) int` from `main()` to make the CLI testable in-process
|
- Extracted `run(args, stdout, stderr) int` from `main()` to make the CLI testable in-process
|
||||||
|
|||||||
91
Makefile
Normal file
91
Makefile
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
GO_DIR := go
|
||||||
|
BINARY := latprobe
|
||||||
|
ARGS ?=
|
||||||
|
|
||||||
|
.DEFAULT_GOAL := help
|
||||||
|
|
||||||
|
# ── help ──────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
.PHONY: help
|
||||||
|
help: ## Show this help
|
||||||
|
@grep -E '^[a-zA-Z_-]+:.*##' $(MAKEFILE_LIST) \
|
||||||
|
| awk 'BEGIN {FS = ":.*##"}; {printf " \033[36m%-20s\033[0m %s\n", $$1, $$2}' \
|
||||||
|
| sort
|
||||||
|
|
||||||
|
# ── umbrella targets (delegate to Go now; py-* will be added during Python port) ──
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: check build ## Run checks then build
|
||||||
|
|
||||||
|
.PHONY: build
|
||||||
|
build: go-build ## Build binary (delegates to go-build)
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test: go-test ## Run tests (delegates to go-test; py-test added later)
|
||||||
|
|
||||||
|
.PHONY: check
|
||||||
|
check: go-check ## Run fmt + vet + test gate (delegates to go-check)
|
||||||
|
|
||||||
|
.PHONY: fmt
|
||||||
|
fmt: go-fmt ## Format source code (delegates to go-fmt)
|
||||||
|
|
||||||
|
.PHONY: vet
|
||||||
|
vet: go-vet ## Run go vet (delegates to go-vet)
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean: go-clean ## Remove build and coverage artifacts
|
||||||
|
|
||||||
|
# ── Go targets ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
.PHONY: go-build
|
||||||
|
go-build: ## go: build binary → go/latprobe
|
||||||
|
go -C $(GO_DIR) build -o $(BINARY) .
|
||||||
|
|
||||||
|
.PHONY: go-run
|
||||||
|
go-run: ## go: build and run (pass flags via ARGS="…")
|
||||||
|
go -C $(GO_DIR) run . $(ARGS)
|
||||||
|
|
||||||
|
.PHONY: go-test
|
||||||
|
go-test: ## go: run all tests
|
||||||
|
go -C $(GO_DIR) test ./...
|
||||||
|
|
||||||
|
.PHONY: go-test-verbose
|
||||||
|
go-test-verbose: ## go: run all tests with per-case output
|
||||||
|
go -C $(GO_DIR) test -v ./...
|
||||||
|
|
||||||
|
.PHONY: go-check
|
||||||
|
go-check: go-fmt go-vet go-test ## go: fmt + vet + test (pre-commit gate)
|
||||||
|
|
||||||
|
.PHONY: go-cover
|
||||||
|
go-cover: ## go: run tests with coverage → go/coverage.html
|
||||||
|
go -C $(GO_DIR) test -coverprofile=coverage.out ./...
|
||||||
|
go -C $(GO_DIR) tool cover -html=coverage.out -o coverage.html
|
||||||
|
@echo "Coverage report: $(GO_DIR)/coverage.html"
|
||||||
|
|
||||||
|
.PHONY: go-fmt
|
||||||
|
go-fmt: ## go: format all Go source files with gofmt
|
||||||
|
gofmt -w $(GO_DIR)
|
||||||
|
|
||||||
|
.PHONY: go-vet
|
||||||
|
go-vet: ## go: run go vet on all packages
|
||||||
|
go -C $(GO_DIR) vet ./...
|
||||||
|
|
||||||
|
.PHONY: go-tidy
|
||||||
|
go-tidy: ## go: run go mod tidy
|
||||||
|
go -C $(GO_DIR) mod tidy
|
||||||
|
|
||||||
|
.PHONY: go-install
|
||||||
|
go-install: ## go: install binary to $GOBIN / $GOPATH/bin
|
||||||
|
go -C $(GO_DIR) install .
|
||||||
|
|
||||||
|
.PHONY: go-lint
|
||||||
|
go-lint: ## go: run golangci-lint (must be installed)
|
||||||
|
@command -v golangci-lint >/dev/null 2>&1 || { \
|
||||||
|
echo "golangci-lint not installed — see https://golangci-lint.run/usage/install/"; \
|
||||||
|
exit 1; \
|
||||||
|
}
|
||||||
|
cd $(GO_DIR) && golangci-lint run
|
||||||
|
|
||||||
|
.PHONY: go-clean
|
||||||
|
go-clean: ## go: remove binary and coverage artifacts
|
||||||
|
rm -f $(GO_DIR)/$(BINARY) $(GO_DIR)/coverage.out $(GO_DIR)/coverage.html
|
||||||
20
README.md
20
README.md
@@ -105,6 +105,26 @@ connection timings via custom socket wrap or `httpx`/`urllib3` hooks).
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
A `Makefile` at the repo root provides all common tasks:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make # list all targets
|
||||||
|
make build # build go/latprobe
|
||||||
|
make test # run all tests
|
||||||
|
make check # fmt + vet + test (pre-commit gate)
|
||||||
|
make go-run ARGS="https://example.com"
|
||||||
|
make go-test-verbose
|
||||||
|
make go-cover # coverage report → go/coverage.html
|
||||||
|
make go-lint # golangci-lint
|
||||||
|
make clean # remove build artifacts
|
||||||
|
```
|
||||||
|
|
||||||
|
See [`docs/usage/makefile.md`](docs/usage/makefile.md) for the full target reference.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Development Environment
|
## Development Environment
|
||||||
|
|
||||||
- Go 1.26.4 / darwin arm64
|
- Go 1.26.4 / darwin arm64
|
||||||
|
|||||||
90
docs/plans/2026-07-01-01-05-makefile.md
Normal file
90
docs/plans/2026-07-01-01-05-makefile.md
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
# 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).
|
||||||
92
docs/usage/makefile.md
Normal file
92
docs/usage/makefile.md
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
# Makefile
|
||||||
|
|
||||||
|
The root `Makefile` provides a single entry point for all common development
|
||||||
|
tasks. Targets are namespaced by language (`go-*`, `py-*` when the Python port
|
||||||
|
lands) with short umbrella targets (`build`, `test`, …) that delegate to the
|
||||||
|
language-specific ones.
|
||||||
|
|
||||||
|
## Quick reference
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make # same as: make help
|
||||||
|
make help # list all targets with descriptions
|
||||||
|
```
|
||||||
|
|
||||||
|
## Umbrella targets
|
||||||
|
|
||||||
|
| Target | Description |
|
||||||
|
|--------|-------------|
|
||||||
|
| `all` | Run `check` then `build` |
|
||||||
|
| `build` | Build the binary (→ `go-build`) |
|
||||||
|
| `test` | Run all tests (→ `go-test`) |
|
||||||
|
| `check` | Pre-commit gate: fmt + vet + test (→ `go-check`) |
|
||||||
|
| `fmt` | Format source (→ `go-fmt`) |
|
||||||
|
| `vet` | Static analysis (→ `go-vet`) |
|
||||||
|
| `clean` | Remove binary and coverage artifacts |
|
||||||
|
|
||||||
|
## Go targets
|
||||||
|
|
||||||
|
| Target | Description |
|
||||||
|
|--------|-------------|
|
||||||
|
| `go-build` | Compile `go/latprobe` |
|
||||||
|
| `go-run` | Build and run (pass flags via `ARGS=`) |
|
||||||
|
| `go-test` | `go test ./...` |
|
||||||
|
| `go-test-verbose` | `go test -v ./...` — per-case PASS/FAIL output |
|
||||||
|
| `go-check` | `go-fmt` + `go-vet` + `go-test` |
|
||||||
|
| `go-cover` | Coverage report → `go/coverage.html` |
|
||||||
|
| `go-fmt` | `gofmt -w go/` |
|
||||||
|
| `go-vet` | `go vet ./...` |
|
||||||
|
| `go-tidy` | `go mod tidy` |
|
||||||
|
| `go-install` | Install binary to `$GOBIN` |
|
||||||
|
| `go-lint` | `golangci-lint run` (must be installed) |
|
||||||
|
| `go-clean` | Remove `go/latprobe`, `go/coverage.out`, `go/coverage.html` |
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Build and run a quick probe
|
||||||
|
make go-run ARGS="https://example.com"
|
||||||
|
make go-run ARGS="-n 5 --json https://example.com https://www.google.com"
|
||||||
|
|
||||||
|
# Run the full test suite
|
||||||
|
make test
|
||||||
|
|
||||||
|
# Verbose output showing each test case
|
||||||
|
make go-test-verbose
|
||||||
|
|
||||||
|
# Pre-commit gate (format, vet, test all in one)
|
||||||
|
make check
|
||||||
|
|
||||||
|
# Generate and open coverage report
|
||||||
|
make go-cover
|
||||||
|
open go/coverage.html # macOS
|
||||||
|
|
||||||
|
# Lint
|
||||||
|
make go-lint
|
||||||
|
|
||||||
|
# Clean up artifacts
|
||||||
|
make clean
|
||||||
|
```
|
||||||
|
|
||||||
|
## Passing arguments to `go-run`
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make go-run ARGS="<url> [url ...] [flags]"
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
make go-run ARGS="https://example.com"
|
||||||
|
make go-run ARGS="--timeout 2s --fail https://example.com"
|
||||||
|
make go-run ARGS="--json -n 3 https://example.com https://www.google.com"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Adding Python targets (when the port lands)
|
||||||
|
|
||||||
|
The umbrella targets are designed to accept Python targets alongside the Go ones.
|
||||||
|
The pattern will be:
|
||||||
|
|
||||||
|
```make
|
||||||
|
test: go-test py-test # py-test added here during the port
|
||||||
|
```
|
||||||
|
|
||||||
|
`go-lint` requires `golangci-lint` to be installed. If it's missing the target
|
||||||
|
prints an install link and exits 1.
|
||||||
Reference in New Issue
Block a user