# Development convenience targets. This repo is exempt from the standard
# policy scaffold (no CI config, no REPO_POLICIES.md, no application
# Dockerfile) except for the lint container: per sneak's 2026-08-09
# ruling, linting runs in docker only, so Dockerfile.lint and script/lint
# are part of this repo. This Makefile is otherwise only a thin wrapper
# around the Go toolchain and prettier so `make fmt` / `make check` behave
# the same as in sneak's other repos.

GO_PKGS   := ./...
MD_FILES  := $(shell git ls-files '*.md')
PRETTIER  := prettier --tab-width 4 --prose-wrap always

# Every generated artifact goes here, and the whole directory is
# git-ignored. Targets that write outside it can commit their output.
BUILD_DIR := build
BIN       := $(BUILD_DIR)/rogue
COVERPROF := $(BUILD_DIR)/coverage.out
COVERHTML := $(BUILD_DIR)/coverage.html

.PHONY: build check cover cover-html fmt fmt-check lint test

# Format, lint, and test — the full local pre-commit gate. Keep this list
# to targets that write nothing into the working tree.
check: fmt-check lint test

# Build the executable into $(BUILD_DIR). `go build -o` does not create the
# parent directory.
build:
	@mkdir -p $(BUILD_DIR)
	go build -o $(BIN) ./cmd/rogue

# Per-function coverage, for finding which functions are untested. The
# percentage `make test` prints is a per-package total and cannot answer
# that. Writes files, so it stays out of `check`.
cover:
	@mkdir -p $(BUILD_DIR)
	go test -timeout 30s -coverprofile=$(COVERPROF) $(GO_PKGS)
	go tool cover -func=$(COVERPROF)

# Render the same profile as annotated source.
cover-html: cover
	go tool cover -html=$(COVERPROF) -o $(COVERHTML)
	@echo "wrote $(COVERHTML)"

# Format Go and Markdown in place.
fmt:
	gofmt -w .
	$(PRETTIER) --write $(MD_FILES)

# Fail if any Go or Markdown file is not formatted.
fmt-check:
	@unformatted="$$(gofmt -l .)"; \
	if [ -n "$$unformatted" ]; then \
		echo "gofmt needed on:"; echo "$$unformatted"; exit 1; \
	fi
	$(PRETTIER) --check $(MD_FILES)

# Run the house linter. golangci-lint is never installed on the host: the
# work happens inside the pinned container built by Dockerfile.lint, and
# this target is a thin shim over the script that builds it.
lint:
	./script/lint

# Run the test suite. Quiet on success; on failure, rerun verbosely for the
# full output and still fail the target (the first run already proved the
# tests are broken, so a flaky pass on the rerun must not rescue the build).
test:
	@go test -timeout 30s -race -cover $(GO_PKGS) || \
		{ echo "--- Rerunning with -v for details ---"; \
		  go test -timeout 30s -race -v $(GO_PKGS); exit 1; }
