export GOTOOLCHAIN := go1.26.5
export GOPRIVATE := $(GOPRIVATE),amadan.net/oficina/estilo.git

APP := slides

# What `carlos ship -target` defaults to, and therefore what a release
# must be built for. Building for your own machine and shipping that is a
# silent architecture mismatch: the binary uploads fine and fails to exec
# on the instance. Override for a one-off:
#   make release RELEASE_GOARCH=amd64
RELEASE_GOOS   ?= linux
RELEASE_GOARCH ?= arm64
RELEASE_BIN := releases/$(APP)-$(RELEASE_GOOS)-$(RELEASE_GOARCH)

# What the running binary reports from GET /api/version. The platform's
# deploy verification polls that endpoint on every instance socket and
# compares what it finds against the release it believes it adopted; an
# unstamped binary answers "dev" from every build you have ever made, so
# those two facts can never disagree and a process that was never
# recycled onto the new release verifies green. Stamping this is what
# gives that check the ability to fail.
#
# git describe, because the tag is what you ship against. Outside a
# repository, or before the first commit, name it yourself:
#   make release VERSION=v0.1.0
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null)

.PHONY: build release version-check test vet fmt-check migration-check ci

# build is the compile check: with more than one package matched, go
# build discards the output, so this catches a broken package without
# producing an artifact.
build:
	CGO_ENABLED=0 go build ./...

# release is what ships. -s -w drops the symbol table and DWARF, which on
# this family's apps is 23-31% off the binary and 45-53% off the
# compressed artifact — and compressed size is what actually gets
# transferred. carlos is built the same way (see platform's Makefile).
#
# What survives: panic traces keep their function names AND line numbers
# (Go's pclntab is untouched by these flags), debug.ReadBuildInfo works,
# and go version -m still reports module metadata. What you lose is
# source-level debugging with delve or gdb — build without the flags for
# that. rastrillo dev never strips, for the same reason.
release: version-check
	@mkdir -p releases
	CGO_ENABLED=0 GOOS=$(RELEASE_GOOS) GOARCH=$(RELEASE_GOARCH) \
		go build -ldflags="-s -w -X 'amadan.net/rastrillo/rastrillo.BuildVersion=$(VERSION)'" \
		-o $(RELEASE_BIN) ./cmd/$(APP)
	@echo
	@echo "built $(RELEASE_BIN) reporting version $(VERSION)"
	@echo "ship it with:"
	@echo "  carlos ship -app $(APP) -target $(RELEASE_GOOS)-$(RELEASE_GOARCH) $(RELEASE_BIN)"

# version-check refuses rather than letting release ship a binary whose
# version is untrue. Both refusals are about the same thing: /api/version
# is only evidence if the answer identifies one artifact.
#
# An empty stamp is worse than the "dev" default, because "dev" is
# saying something true about itself and "" looks like a value that
# arrived from somewhere.
#
# A dirty tree is refused rather than suffixed. A -dirty stamp names a
# commit plus changes nobody can name, so two different binaries can
# carry the identical string — which does not fix the check, it makes
# it look reliable while it is not, and that is the more expensive
# failure. Refusing costs one `git stash`; a wrong stamp ships. If you
# mean to ship uncommitted work, say so out loud:
#   make release VERSION=v0.1.0-wip
version-check:
	@if [ -z "$(VERSION)" ]; then \
		echo "make release: no version to stamp."; \
		echo "  git describe found nothing here: no repository, or no commit yet."; \
		echo "  Commit, or name it:  make release VERSION=v0.1.0"; \
		exit 1; \
	fi
	@case "$(VERSION)" in *-dirty) \
		echo "make release: the tree is dirty, so $(VERSION) does not name what you are about to ship."; \
		echo "  Commit or stash first, or name it:  make release VERSION=v0.1.0-wip"; \
		exit 1;; \
	esac

test:
	go test ./...

vet:
	go vet ./...

fmt-check:
	@out=$$(gofmt -l .); if [ -n "$$out" ]; then echo "gofmt needed:"; echo "$$out"; exit 1; fi

# A step of its own, not folded into another target's recipe: ci.d/
# steps each exec one make target, so migration-check needs its own
# name to get its own reported step on a runner with step support.
#
# go run, not a bare "rastrillo": go.mod already requires rastrillo, so
# this needs nothing on PATH but the Go toolchain, and works offline
# after go mod download. A bare "rastrillo migration check" failed a
# fresh clone's very first CI run with "make: rastrillo: Command not
# found", and nothing in the scaffold said what to install.
#
# What makes the go run resolve is the tool directive at the foot of
# go.mod — it is what keeps the CLI's own dependencies in go.sum. See
# the comment there before removing it.
migration-check:
	go run amadan.net/rastrillo/rastrillo/cmd/rastrillo migration check

# ci is the one gate: what a runner executes and what you run before
# pushing are the same definition. amadan's runner falls back to this
# target when .amadan/ci is absent; ci.d/ carries the same targets,
# reported one by one, for a runner with step support. migration-check
# fails the build the moment models.go and migrations/ disagree,
# instead of at boot on whatever machine notices next. If the app
# declares manifest resources, also add: rastrillo generate --check
ci: vet fmt-check test migration-check

.PHONY: credits credits-check
credits:
	python3 scripts/credits.py

credits-check:
	python3 scripts/credits.py --check

ci: credits-check
