diff --git a/backend/justfile b/backend/justfile index ec6bdfd..70c7e36 100644 --- a/backend/justfile +++ b/backend/justfile @@ -16,101 +16,115 @@ 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" + +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" + +htmx_version := "2" # --- Local config --------------------------------------------------------------------------- + database_url := "postgres://xtablo:xtablo@localhost:5432/xtablo?sslmode=disable" -tailwind := "./bin/tailwindcss" +tailwind := "./bin/tailwindcss" +compose_config_dir := ".podman-compose" default: - @just --list + @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" + 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 +compose-config: + mkdir -p {{ compose_config_dir }} + printf '%s\n' '{"auths":{}}' > {{ compose_config_dir }}/config.json + +db-up: compose-config + DOCKER_CONFIG="$PWD/{{ compose_config_dir }}" podman compose up -d postgres db-down: - podman compose 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}} + 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 + templ generate + @if ls internal/db/queries/*.sql >/dev/null 2>&1; then sqlc generate; else echo "(no SQL queries yet — skipping sqlc generate)"; fi + {{ tailwind }} -i tailwind.input.css -o static/tailwind.css styles-watch: - {{tailwind}} -i tailwind.input.css -o static/tailwind.css --watch + {{ tailwind }} -i tailwind.input.css -o static/tailwind.css --watch dev: db-up - just generate - DATABASE_URL='{{database_url}}' air -c .air.toml + just generate + DATABASE_URL='{{ database_url }}' air -c .air.toml test: - just generate - go test ./... + just generate + go test ./... lint: - go vet ./... - gofmt -l . | (grep . && exit 1 || exit 0) + 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 + 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 + rm -rf bin/ tmp/ static/htmx.min.js static/tailwind.css + find . -name '*_templ.go' -delete diff --git a/backend/tailwind.input.css b/backend/tailwind.input.css index 8c4faf8..f034efd 100644 --- a/backend/tailwind.input.css +++ b/backend/tailwind.input.css @@ -1,10 +1,10 @@ @import "tailwindcss"; -@source "../templates/**/*.templ"; -@source "../internal/web/**/*.templ"; -@source "../internal/web/**/*.go"; +@source "./templates/**/*.templ"; +@source "./internal/web/**/*.templ"; +@source "./internal/web/**/*.go"; -@import "../internal/web/ui/base.css"; -@import "../internal/web/ui/button.css"; -@import "../internal/web/ui/card.css"; -@import "../internal/web/ui/badge.css"; +@import "./internal/web/ui/base.css"; +@import "./internal/web/ui/button.css"; +@import "./internal/web/ui/card.css"; +@import "./internal/web/ui/badge.css";