From ce224725e22e839c63badbf8d0abf4771d5d2c93 Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Thu, 14 May 2026 17:56:02 +0200 Subject: [PATCH] feat(01-01): justfile with bootstrap, db, migrate, generate, dev, test, lint, build, clean - bootstrap: installs goose/templ/sqlc/air at pinned versions; downloads Tailwind v4 standalone binary via explicit OS/arch case mapping (darwin->macos, x86_64->x64, arm64/aarch64->arm64) resolving to one of {tailwindcss-macos-x64,tailwindcss-macos-arm64,tailwindcss-linux-x64,tailwindcss-linux-arm64} (Codex concern #2); bootstrap-downloads htmx.min.js from unpkg into static/ - migrate: GOOSE_DRIVER + GOOSE_DBSTRING + GOOSE_MIGRATION_DIR wired - generate / styles-watch / dev / test / lint / build / clean recipes complete - 'just --list' enumerates 11 recipes; no pnpm/npm/node references (D-12) - clean recipe removes bin/, tmp/, generated CSS, bootstrap-downloaded htmx, *_templ.go (Codex #10) - Tailwind watch is run separately (RESEARCH Open Q2 two-terminal workflow) - The only CDN URLs in the entire backend are inside this justfile's bootstrap recipe; served HTML/CSS/JS reference only /static/* (CONTEXT D-10 clarified) --- backend/justfile | 116 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 backend/justfile diff --git a/backend/justfile b/backend/justfile new file mode 100644 index 0000000..ec6bdfd --- /dev/null +++ b/backend/justfile @@ -0,0 +1,116 @@ +# Xtablo backend — task runner +# +# Portability: compose.yaml works under both `podman compose` and `docker compose` (CONTEXT D-11). +# This justfile uses `podman compose` by default; substitute `docker compose` if needed — +# the service definition is identical. +# +# Dev workflow (two terminals, per RESEARCH Open Question 2): +# Terminal 1: just dev # brings up postgres, generates assets, runs air for Go live-reload +# Terminal 2: just styles-watch # runs the Tailwind standalone CLI in --watch mode +# +# Tailwind is intentionally NOT chained into air's pre_cmd: piping CSS rebuilds through +# every .go save is wasteful, and the two concerns are independent (CONTEXT D-14). + +set shell := ["bash", "-cu"] + +# --- Pinned versions ------------------------------------------------------------------------ +# Runtime Go modules are pinned in go.mod (chi v5.2.5, templ v0.3.1020, pgx/v5 v5.9.2, +# goose v3.27.1, uuid v1.6.0). Below: CLI tools installed by `just bootstrap`. +goose_version := "v3.27.1" +templ_version := "v0.3.1020" +sqlc_version := "v1.31.1" +air_version := "v1.65.1" +# Tailwind standalone CLI version pinned for reproducible bootstrap. Update by bumping +# this string after verifying the release at https://github.com/tailwindlabs/tailwindcss/releases +tailwind_version := "v4.0.0" +# HTMX version pinned at bootstrap time. This is the SINGLE authoritative source for the +# HTMX version — no runtime CDN reference appears anywhere else (CONTEXT D-10). +htmx_version := "2" + +# --- Local config --------------------------------------------------------------------------- +database_url := "postgres://xtablo:xtablo@localhost:5432/xtablo?sslmode=disable" +tailwind := "./bin/tailwindcss" + +default: + @just --list + +# Install all CLI tools and bootstrap-download Tailwind + HTMX into local paths. +# Network access required. All downloaded artifacts are gitignored — `just bootstrap` is the +# canonical reproduction step. +bootstrap: + mkdir -p bin static + # 1. Go-based CLI tools (versions pinned above) + go install github.com/pressly/goose/v3/cmd/goose@{{goose_version}} + go install github.com/a-h/templ/cmd/templ@{{templ_version}} + go install github.com/sqlc-dev/sqlc/cmd/sqlc@{{sqlc_version}} + go install github.com/air-verse/air@{{air_version}} + # 2. Tailwind standalone CLI — explicit OS/arch mapping. The Tailwind release artifacts + # use 'macos'/'linux' and 'x64'/'arm64', which do NOT match raw `uname -s` / `uname -m` + # output (darwin vs macos, x86_64 vs x64). Resolve via case (Codex review concern #2). + # Resolves to one of: tailwindcss-macos-x64, tailwindcss-macos-arm64, + # tailwindcss-linux-x64, tailwindcss-linux-arm64 + os_name=$(uname -s); \ + arch_name=$(uname -m); \ + case "$os_name" in \ + Darwin) tw_os=macos ;; \ + Linux) tw_os=linux ;; \ + *) echo "Unsupported OS: $os_name (Tailwind standalone supports macos/linux)"; exit 1 ;; \ + esac; \ + case "$arch_name" in \ + x86_64|amd64) tw_arch=x64 ;; \ + arm64|aarch64) tw_arch=arm64 ;; \ + *) echo "Unsupported arch: $arch_name"; exit 1 ;; \ + esac; \ + asset="tailwindcss-${tw_os}-${tw_arch}"; \ + echo "Downloading $asset @ {{tailwind_version}}"; \ + curl -sSL -o bin/tailwindcss \ + "https://github.com/tailwindlabs/tailwindcss/releases/download/{{tailwind_version}}/${asset}"; \ + chmod +x bin/tailwindcss + # 3. HTMX — bootstrap-time download. This unpkg URL is the explicit allowed exception to + # the runtime no-CDN rule (CONTEXT D-10); served HTML references only /static/htmx.min.js. + curl -sSL -o static/htmx.min.js "https://unpkg.com/htmx.org@{{htmx_version}}/dist/htmx.min.js" + +db-up: + podman compose up -d postgres + +db-down: + podman compose down + +# `just migrate up`, `just migrate down`, `just migrate status`, etc. +migrate cmd="status": + GOOSE_DRIVER=postgres GOOSE_DBSTRING='{{database_url}}' GOOSE_MIGRATION_DIR=migrations \ + goose {{cmd}} + +# templ → Go, sqlc → Go, tailwind → static/tailwind.css. Consumers (templ files, queries, +# ui CSS) land in Plans 01-02 / 01-03; until then this recipe will fail when invoked but +# its declaration is the contract. +generate: + templ generate + sqlc generate + {{tailwind}} -i tailwind.input.css -o static/tailwind.css + +styles-watch: + {{tailwind}} -i tailwind.input.css -o static/tailwind.css --watch + +dev: db-up + just generate + DATABASE_URL='{{database_url}}' air -c .air.toml + +test: + just generate + go test ./... + +lint: + go vet ./... + gofmt -l . | (grep . && exit 1 || exit 0) + +build: + just generate + go build -o bin/web ./cmd/web + go build -o bin/worker ./cmd/worker + +# Remove all bootstrap-downloaded and generated artifacts. Does NOT touch the Postgres +# volume — run `just db-down` first if a full reset is needed. +clean: + rm -rf bin/ tmp/ static/htmx.min.js static/tailwind.css + find . -name '*_templ.go' -delete