# Load per-worktree overrides (project name, image tag, ports) generated by `just init` set dotenv-load := true set dotenv-filename := ".env.local" # Generate a per-worktree COMPOSE_PROJECT_NAME, IMAGES_PREFIX and free host ports in .env.local, # so multiple worktrees/checkouts of this repo can run `just up` at the same time without their # containers, volumes, images or ports colliding. Safe to re-run; no-ops if already configured. init: #!/usr/bin/env bash set -euo pipefail if [ -f .env.local ] && grep -q '^COMPOSE_PROJECT_NAME=' .env.local; then echo ".env.local already configured for this worktree, skipping (delete it to regenerate)." exit 0 fi free_port() { local port="$1" max="$2" while [ "$port" -le "$max" ]; do if ! (exec 3<>/dev/tcp/127.0.0.1/"$port") 2>/dev/null; then echo "$port" return fi exec 3>&- 2>/dev/null || true port=$((port + 1)) done echo "no free port found between $1 and $2" >&2 exit 1 } if command -v sha1sum >/dev/null 2>&1; then hash_cmd=(sha1sum) elif command -v shasum >/dev/null 2>&1; then hash_cmd=(shasum) else hash_cmd=(sha256sum) fi hash=$(pwd | "${hash_cmd[@]}" | cut -c1-8) project="tvdt-${hash}" http_port=$(free_port 8080 8179) https_port=$(free_port 8443 8542) postgres_port=$(free_port 5430 5529) mailpit_port=$(free_port 8025 8124) spotlight_port=$(free_port 8969 9068) { echo "COMPOSE_PROJECT_NAME=${project}" echo "IMAGES_PREFIX=${project}-" echo "HTTP_PORT=${http_port}" echo "HTTPS_PORT=${https_port}" echo "POSTGRES_PORT=${postgres_port}" echo "MAILPIT_PORT=${mailpit_port}" echo "SPOTLIGHT_PORT=${spotlight_port}" } >> .env.local echo "Generated .env.local for this worktree:" cat .env.local up *args: init #!/usr/bin/env bash set -a [ -f .env.local ] && source .env.local set +a docker compose up -d {{ args }} down *args: docker compose down --remove-orphans {{ args }} # Show the host ports assigned to this worktree (see `just init`) ports: @cat .env.local 2>/dev/null || echo "No .env.local yet, run 'just up' or 'just init' first." stop: docker compose stop exec *args: docker compose exec php {{ args }} [no-exit-message] shell: @docker compose exec php bash [no-exit-message] shell-run: @docker compose run --rm php bash migrate: up docker compose run --rm php bin/console doctrine:migrations:migrate --no-interaction fixtures: docker compose exec php bin/console doctrine:fixtures:load --purge-with-truncate --no-interaction --group=dev translations: docker compose exec php bin/console translation:extract --force --format=xliff --sort=asc nl fix-cs: docker compose exec php vendor/bin/php-cs-fixer fix docker compose exec php vendor/bin/twig-cs-fixer fix rector *args: docker compose exec php vendor/bin/rector {{ args }} phpstan *args: docker compose exec php vendor/bin/phpstan analyse {{ args }} test *args: docker compose exec php vendor/bin/phpunit {{ args }} [confirm] clean: docker compose down -v --remove-orphans rm -rf vendor var assets/vendor public/assets public/bundles .php-cs-fixer.cache .twig-cs-fixer.cache reload-tests: @docker compose exec php bin/console --env=test doctrine:database:drop --if-exists --force @docker compose exec php bin/console --env=test doctrine:database:create @docker compose exec php bin/console --env=test doctrine:migrations:migrate -n @docker compose exec php bin/console --env=test doctrine:fixtures:load -n --group=test install-hooks: git config core.hooksPath .githooks chmod +x .githooks/pre-commit @echo "Pre-commit hook installed." trust-cert: sudo security add-trusted-cer -d \ -r trustRoot \ -k "$HOME/Library/Keychains/login.keychain" \ ./frankenphp/data/caddy/pki/authorities/local/root.crt