Files
foodster/Makefile
T
Esa Kataja c6f44bb427 Keep the database in ./data and bind-mount it
SQLite writes three files — the database plus its -wal and -shm companions.
Putting them in one directory means a deployment mounts a single path and a
backup copies a single directory.

- FOODSTER_DB defaults to ./data/foodster.db, and openDB creates the parent
  directory on startup rather than failing on a fresh checkout
- compose bind-mounts ./data instead of using a named volume, so the file can
  be listed, copied and opened with any sqlite client without going through
  the container engine
- the image runs as UID 65534, which cannot write to a host directory owned
  by someone else, so compose now sets user: from FOODSTER_UID/FOODSTER_GID
- `make up` creates ./data first: left to the engine it appears root-owned
  and the app silently cannot write to it
2026-09-05 18:17:14 +03:00

97 lines
3.2 KiB
Makefile

# Foodster. Run `make` for the target list.
COMPOSE ?= podman compose
BIN := foodster
PKG := ./cmd/foodster
# Vendored Datastar client. Bump, run `make vendor`, commit the result.
DATASTAR_VERSION ?= v1.0.3
SEED ?= seeds/testi.json
# Registry coordinates, shared password and TZ live here. Gitignored.
ifneq (,$(wildcard .env))
include .env
export
endif
# Generated templ output is excluded — it is not ours to format.
GOFILES = $(shell find . -name '*.go' -not -name '*_templ.go' 2>/dev/null)
.DEFAULT_GOAL := help
.PHONY: help generate build run seed test smoke check lint fix vendor image push release up down logs clean
help: ## Show this help
@grep -hE '^[a-zA-Z_-]+:.*## ' $(MAKEFILE_LIST) \
| awk -F':.*## ' '{printf " \033[1m%-9s\033[0m %s\n", $$1, $$2}'
generate: ## Generate Go from .templ files
go tool templ generate
build: generate ## Build ./foodster
CGO_ENABLED=0 go build -trimpath \
-ldflags="-s -w -X main.version=dev" -o $(BIN) $(PKG)
run: generate ## Run locally on :8080 (database in ./data)
FOODSTER_PASSWORD=$${FOODSTER_PASSWORD:-dev} go run $(PKG)
seed: ## Import a dish bundle (SEED=seeds/testi.json)
go run $(PKG) -import $(SEED)
test: generate ## Run unit tests
go test ./...
smoke: generate ## End-to-end check: auth, static assets, bundle import
./scripts/smoke.sh
check: lint test smoke ## Everything that must pass before a commit
@echo "check: all passed"
vendor: ## Re-download the Datastar client (DATASTAR_VERSION=v1.0.3)
curl -sSfL -o cmd/foodster/static/datastar.js \
"https://cdn.jsdelivr.net/gh/starfederation/datastar@$(DATASTAR_VERSION)/bundles/datastar.js"
@head -1 cmd/foodster/static/datastar.js
lint: ## go vet, gofmt check, golangci-lint when installed
go vet ./...
@bad=$$(gofmt -l $(GOFILES) 2>/dev/null); \
if [ -n "$$bad" ]; then echo "gofmt needed:"; echo "$$bad"; exit 1; fi
@if command -v golangci-lint >/dev/null 2>&1; then golangci-lint run; \
else echo "golangci-lint not installed - skipped"; fi
fix: ## Format Go and templ sources, tidy go.mod
@if [ -n "$(GOFILES)" ]; then gofmt -w $(GOFILES); fi
go tool templ fmt .
go mod tidy
image: ## Build and tag an image as vYYYYMMDD-N. Creates a git tag.
@test -n "$(FOODSTER_REPO)" || { echo "set FOODSTER_REPO in .env"; exit 1; }
@day=$$(date +%Y%m%d); \
tag="v$$day-$$(( $$(git tag -l "v$$day-*" | wc -l) + 1 ))"; \
echo "==> $$tag"; \
git tag "$$tag"; \
podman build --platform linux/amd64 --build-arg VERSION="$$tag" \
-t "$(FOODSTER_REPO):$$tag" -t "$(FOODSTER_REPO):latest" .
push: ## Push the newest tag and :latest
@test -n "$(FOODSTER_REPO)" || { echo "set FOODSTER_REPO in .env"; exit 1; }
@tag=$$(git tag -l 'v*' --sort=-creatordate | head -n1); \
test -n "$$tag" || { echo "no tags yet - run make image"; exit 1; }; \
podman push "$(FOODSTER_REPO):$$tag"; \
podman push "$(FOODSTER_REPO):latest"
release: image push ## Build, tag and push in one go
up: ## Start the stack
@mkdir -p data # or the engine creates it root-owned and the app cannot write
$(COMPOSE) up -d
down: ## Stop the stack
$(COMPOSE) down
logs: ## Follow app logs
$(COMPOSE) logs -f app
clean: ## Remove the binary and generated templates
rm -f $(BIN)
find . -name '*_templ.go' -delete