{ pkgs ? import {} }: 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 "$@" } # =================== # 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 Run Symfony console command" echo " dev-composer 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-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 " database Postgres 16 localhost:5433" echo "" ''; }