308 lines
10 KiB
Nix
308 lines
10 KiB
Nix
{ pkgs ? import <nixpkgs> {} }:
|
|
|
|
pkgs.mkShell {
|
|
buildInputs = with pkgs; [
|
|
# PHP and tools
|
|
php84
|
|
php84Packages.composer
|
|
symfony-cli
|
|
|
|
# Node.js and npm (React/Vite SPA)
|
|
nodejs_22
|
|
|
|
# Container tools
|
|
podman
|
|
podman-compose
|
|
|
|
# Database client (for direct DB access)
|
|
postgresql
|
|
|
|
# Utilities
|
|
git
|
|
curl
|
|
gnumake
|
|
];
|
|
|
|
shellHook = ''
|
|
export USER_ID=$(id -u)
|
|
export GROUP_ID=$(id -g)
|
|
export PODMAN_USERNS=keep-id
|
|
|
|
# Compose files (symfony-docker convention: root compose.yaml + compose.override.yaml).
|
|
# Both must be passed explicitly so the dev override is merged.
|
|
# NOTE: $COMPOSE is invoked unquoted (word-split into args) — assumes the repo path
|
|
# contains no spaces. Fine here; would break if checked out under a path with spaces.
|
|
COMPOSE="podman-compose -f $PWD/compose.yaml -f $PWD/compose.override.yaml"
|
|
|
|
# ===================
|
|
# ALIASES
|
|
# ===================
|
|
alias pc="$COMPOSE"
|
|
|
|
# ===================
|
|
# DEV COMMANDS
|
|
# ===================
|
|
dev-up() {
|
|
echo "Starting services..."
|
|
PODMAN_USERNS=keep-id $COMPOSE up -d "$@"
|
|
echo ""
|
|
$COMPOSE ps
|
|
echo ""
|
|
echo "App available at: http://localhost:8100"
|
|
}
|
|
|
|
dev-down() {
|
|
if [[ "$1" == "-v" ]]; then
|
|
echo "Stopping services and removing volumes..."
|
|
$COMPOSE down -v
|
|
else
|
|
echo "Stopping services..."
|
|
$COMPOSE down
|
|
fi
|
|
}
|
|
|
|
dev-restart() {
|
|
echo "Restarting services..."
|
|
$COMPOSE restart "$@"
|
|
}
|
|
|
|
dev-rebuild() {
|
|
echo "Rebuilding services (down -v + up)..."
|
|
$COMPOSE down -v
|
|
PODMAN_USERNS=keep-id $COMPOSE up -d "$@"
|
|
echo ""
|
|
$COMPOSE ps
|
|
echo ""
|
|
echo "App available at: http://localhost:8100"
|
|
}
|
|
|
|
dev-logs() {
|
|
$COMPOSE logs -f php "$@"
|
|
}
|
|
|
|
dev-logs-db() {
|
|
$COMPOSE logs -f database "$@"
|
|
}
|
|
|
|
dev-shell() {
|
|
$COMPOSE exec php sh
|
|
}
|
|
|
|
dev-console() {
|
|
$COMPOSE exec php php bin/console "$@"
|
|
}
|
|
|
|
dev-composer() {
|
|
$COMPOSE exec php composer "$@"
|
|
}
|
|
|
|
# ===================
|
|
# QA COMMANDS (run in the php container)
|
|
# ===================
|
|
dev-test() {
|
|
$COMPOSE exec php php bin/phpunit "$@"
|
|
}
|
|
|
|
dev-coverage() {
|
|
# Code coverage as a plain text table in the terminal (needs Xdebug, which is installed).
|
|
# --colors=never keeps the table readable (the ANSI colors garble it).
|
|
# Pass-through args, e.g. scope to one class: dev-coverage --filter BucketRoomCalculator
|
|
$COMPOSE exec -e XDEBUG_MODE=coverage php php bin/phpunit --coverage-text --colors=never "$@"
|
|
}
|
|
|
|
dev-stan() {
|
|
# Warm the dev cache so phpstan-symfony can read the compiled container, then analyse.
|
|
$COMPOSE exec php php bin/console cache:warmup --quiet
|
|
$COMPOSE exec php vendor/bin/phpstan analyse --memory-limit=512M "$@"
|
|
}
|
|
|
|
dev-cs() {
|
|
# Dry-run code-style check (no changes). Use for CI / verification.
|
|
$COMPOSE exec php vendor/bin/php-cs-fixer check --diff "$@"
|
|
}
|
|
|
|
dev-cs-fix() {
|
|
# Apply code-style fixes in place.
|
|
$COMPOSE exec php vendor/bin/php-cs-fixer fix "$@"
|
|
}
|
|
|
|
# ===================
|
|
# FRONTEND COMMANDS (run in the frontend/Vite container)
|
|
# ===================
|
|
dev-fe-test() {
|
|
# Run the Vitest suite once. Pass-through args, e.g.: dev-fe-test src/auth
|
|
$COMPOSE exec frontend npm test "$@"
|
|
}
|
|
|
|
dev-fe-test-watch() {
|
|
$COMPOSE exec frontend npm run test:watch "$@"
|
|
}
|
|
|
|
dev-fe-lint() {
|
|
$COMPOSE exec frontend npm run lint "$@"
|
|
}
|
|
|
|
dev-fe-cs() {
|
|
# Prettier formatting check (no changes).
|
|
$COMPOSE exec frontend npm run format:check "$@"
|
|
}
|
|
|
|
dev-fe-cs-fix() {
|
|
$COMPOSE exec frontend npm run format "$@"
|
|
}
|
|
|
|
dev-fe-build() {
|
|
$COMPOSE exec frontend npm run build "$@"
|
|
}
|
|
|
|
dev-e2e() {
|
|
# Run the Playwright e2e smoke suite in the `playwright` compose service
|
|
# (browsers preinstalled). Needs the stack up (dev-up). NOT the Vitest
|
|
# suite — that's dev-fe-test. Pass-through args, e.g.: dev-e2e --headed
|
|
PODMAN_USERNS=keep-id $COMPOSE --profile e2e run --rm playwright npm test -- "$@"
|
|
}
|
|
|
|
dev-check() {
|
|
# Fast pre-commit gate: all static/unit checks, back + front. Fail-fast
|
|
# (stops at the first failure). No coverage, no e2e — use dev-check-all
|
|
# for the thorough version.
|
|
echo "▶ backend: tests" && dev-test \
|
|
&& echo "▶ backend: phpstan" && dev-stan \
|
|
&& echo "▶ backend: cs" && dev-cs \
|
|
&& echo "▶ frontend: tests" && dev-fe-test \
|
|
&& echo "▶ frontend: lint" && dev-fe-lint \
|
|
&& echo "▶ frontend: cs" && dev-fe-cs \
|
|
&& echo "▶ frontend: build" && dev-fe-build \
|
|
&& echo "✓ dev-check passed"
|
|
}
|
|
|
|
dev-check-all() {
|
|
# Thorough gate: everything in dev-check, but with COVERAGE instead of the
|
|
# plain test runs, plus the Playwright e2e. Slow; needs the stack up.
|
|
# NOTE: frontend coverage (dev-fe-coverage) is not wired yet — added in #62
|
|
# alongside the @vitest/coverage-v8 setup; until then this runs the plain
|
|
# frontend test suite for the frontend leg.
|
|
echo "▶ backend: coverage" && dev-coverage \
|
|
&& echo "▶ backend: phpstan" && dev-stan \
|
|
&& echo "▶ backend: cs" && dev-cs \
|
|
&& echo "▶ frontend: tests (coverage pending #62)" && dev-fe-test \
|
|
&& echo "▶ frontend: lint" && dev-fe-lint \
|
|
&& echo "▶ frontend: cs" && dev-fe-cs \
|
|
&& echo "▶ frontend: build" && dev-fe-build \
|
|
&& echo "▶ e2e" && dev-e2e \
|
|
&& echo "✓ dev-check-all passed"
|
|
}
|
|
|
|
# ===================
|
|
# DATABASE / MIGRATION COMMANDS
|
|
# ===================
|
|
# The Doctrine migration workflow, simplified. Typical loop:
|
|
# 1. change an entity mapping
|
|
# 2. dev-migrate-diff -> generate ONE migration from the mapping (review it!)
|
|
# 3. dev-migrate -> apply to BOTH dev and test DBs
|
|
# If you generated/applied a wrong migration: dev-migrate-prev rolls back BOTH DBs,
|
|
# then delete the bad migrations/Version*.php file and re-run dev-migrate-diff.
|
|
|
|
dev-migrate-diff() {
|
|
# Generate a migration from the diff between entity mappings and the dev DB schema.
|
|
# ALWAYS read the generated migrations/Version*.php before applying it.
|
|
echo "Generating migration from entity mapping diff..."
|
|
$COMPOSE exec php php bin/console doctrine:migrations:diff "$@"
|
|
echo ""
|
|
echo ">> Review the new file in migrations/ before running dev-migrate."
|
|
}
|
|
|
|
dev-migrate() {
|
|
# Apply pending migrations to BOTH the dev and test databases.
|
|
# Interactive: Doctrine will prompt before destructive/unregistered changes — read them.
|
|
echo "=== Migrating DEV database (buckets) ==="
|
|
$COMPOSE exec php php bin/console doctrine:migrations:migrate "$@"
|
|
echo ""
|
|
echo "=== Migrating TEST database (buckets_test) ==="
|
|
$COMPOSE exec php php bin/console doctrine:migrations:migrate --env=test "$@"
|
|
}
|
|
|
|
dev-migrate-prev() {
|
|
# Roll back the most recent migration on BOTH the dev and test databases.
|
|
echo "=== Rolling back DEV database (buckets) one step ==="
|
|
$COMPOSE exec php php bin/console doctrine:migrations:migrate prev "$@"
|
|
echo ""
|
|
echo "=== Rolling back TEST database (buckets_test) one step ==="
|
|
$COMPOSE exec php php bin/console doctrine:migrations:migrate prev --env=test "$@"
|
|
}
|
|
|
|
# ===================
|
|
# BUILD COMMANDS
|
|
# ===================
|
|
base-build() {
|
|
local image="forge.lvl0.xyz/lvl0/buckets:latest"
|
|
|
|
# Check if logged in, prompt if not
|
|
if ! podman login --get-login forge.lvl0.xyz &>/dev/null; then
|
|
echo "Not logged in to forge.lvl0.xyz"
|
|
podman login forge.lvl0.xyz || return 1
|
|
fi
|
|
|
|
echo "Building image: $image"
|
|
if ! podman build -t "$image" -f Dockerfile .; then
|
|
echo "Build failed!"
|
|
return 1
|
|
fi
|
|
|
|
echo ""
|
|
echo "Pushing to registry..."
|
|
if ! podman push "$image"; then
|
|
echo "Push failed!"
|
|
return 1
|
|
fi
|
|
|
|
echo ""
|
|
echo "Done! Image pushed: $image"
|
|
}
|
|
|
|
# ===================
|
|
# WELCOME MESSAGE
|
|
# ===================
|
|
echo ""
|
|
echo "================================================="
|
|
echo " Buckets Dev Environment "
|
|
echo "================================================="
|
|
echo ""
|
|
echo " PHP: $(php --version | head -1 | cut -d' ' -f2)"
|
|
echo " Symfony: $(symfony version 2>/dev/null | head -1 || echo 'symfony-cli')"
|
|
echo " Podman: $(podman --version | cut -d' ' -f3)"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " dev-up [services] Start all or specific services"
|
|
echo " dev-down [-v] Stop services (-v removes volumes)"
|
|
echo " dev-rebuild Fresh start (down -v + up)"
|
|
echo " dev-restart Restart services"
|
|
echo " dev-logs Tail app logs"
|
|
echo " dev-logs-db Tail database logs"
|
|
echo " dev-shell Shell into app container"
|
|
echo " dev-console <cmd> Run Symfony console command"
|
|
echo " dev-composer <cmd> Run composer in the container"
|
|
echo " dev-test [args] Run PHPUnit (bin/phpunit)"
|
|
echo " dev-stan [args] Run PHPStan static analysis"
|
|
echo " dev-cs [args] Check code style (dry-run)"
|
|
echo " dev-cs-fix [args] Apply code style fixes"
|
|
echo " dev-fe-test [args] Run frontend Vitest suite"
|
|
echo " dev-fe-lint [args] Lint frontend (oxlint)"
|
|
echo " dev-fe-cs [args] Check frontend formatting (Prettier)"
|
|
echo " dev-fe-cs-fix Apply frontend formatting"
|
|
echo " dev-fe-build Build the frontend (tsc + vite build)"
|
|
echo " dev-e2e [args] Run Playwright e2e smoke suite (container)"
|
|
echo " dev-check Fast gate: all back+front tests/stan/cs/build"
|
|
echo " dev-check-all Thorough gate: dev-check + coverage + e2e"
|
|
echo " dev-migrate-diff Generate a migration from entity mappings"
|
|
echo " dev-migrate Apply migrations to dev + test DBs"
|
|
echo " dev-migrate-prev Roll back one migration on dev + test DBs"
|
|
echo " base-build Build and push image"
|
|
echo ""
|
|
echo "Services:"
|
|
echo " php Symfony/FrankenPHP http://localhost:8100"
|
|
echo " frontend React/Vite SPA http://localhost:5173"
|
|
echo " database Postgres 16 localhost:5433"
|
|
echo ""
|
|
'';
|
|
}
|