Features: 1) Add fallback for missing jq in image verification; 2) Enhance verbosity control for management commands in run.sh; 3) Update generate-environment-file.sh to use consistent variable names and handle CORS origins dynamically.

Fixes: 1) Correct `.env` export script to handle sorted variables without associative arrays; 2) Fix incomplete `.env` output in `generate-environment-file.sh`.

Extra: 1) Improve code readability and maintainability across shell scripts; 2) Standardize echo statements and reduce excessive formatting.
This commit is contained in:
Egor Pavlovich Gorbunov 2025-10-28 15:31:26 +03:00
parent 9412b0dd7a
commit 0dc3daaa4f
3 changed files with 96 additions and 40 deletions

View file

@ -9,27 +9,26 @@ if [ ! -f "$env_file" ]; then
exit 1 exit 1
fi fi
declare -A env_vars # Read .env and export variables; collect for sorted output (portable: no associative arrays)
while IFS= read -r line; do mapfile -t lines < <(sed -e 's/^\s*//;s/\s*$//' "$env_file" | awk 'NF && $0 !~ /^#/ && $0 ~ /=/')
line="${line#"${line%%[![:space:]]*}"}"
line="${line%"${line##*[![:space:]]}"}" kv_list=()
if [ -z "$line" ] || [[ "$line" == \#* ]] || [[ "$line" != *=* ]]; then for raw in "${lines[@]}"; do
continue key=${raw%%=*}
fi value=${raw#*=}
key="${line%%=*}" # Trim whitespace around key and value
value="${line#*=}" key=$(echo "$key" | sed -e 's/^\s*//' -e 's/\s*$//')
if [[ ( "$value" == \"*\" && "$value" == *\" ) || ( "$value" == \'*\' && "$value" == *\' ) ]]; then value=$(echo "$value" | sed -e 's/^\s*//' -e 's/\s*$//')
value="${value:1:-1}" # Strip matching quotes
if [ -n "$value" ] && [ "${value:0:1}" = '"' ] && [ "${value: -1}" = '"' ]; then
value=${value:1:${#value}-2}
elif [ -n "$value" ] && [ "${value:0:1}" = "'" ] && [ "${value: -1}" = "'" ]; then
value=${value:1:${#value}-2}
fi fi
export "$key=$value" export "$key=$value"
env_vars["$key"]="$value" kv_list+=("$key=$value")
done < "$env_file" done
if [ "${#env_vars[@]}" -gt 0 ]; then if [ ${#kv_list[@]} -gt 0 ]; then
IFS=$'\n' sorted=($(for k in "${!env_vars[@]}"; do echo "${k}=${env_vars[$k]}"; done | sort)) printf "%s\n" "${kv_list[@]}" | sort | tr "\n" ";" | sed 's/;$/\n/'
printf "%s" "${sorted[0]}"
for entry in "${sorted[@]:1}"; do
printf ";%s" "$entry"
done
echo
fi fi

View file

@ -33,9 +33,9 @@ if [ -f .env ]; then
read -r read -r
fi fi
PROJECT_NAME=$(prompt_default EVIBES_PROJECT_NAME eVibes) EVIBES_PROJECT_NAME=$(prompt_default EVIBES_PROJECT_NAME eVibes)
FRONTEND_DOMAIN=$(prompt_default EVIBES_FRONTEND_DOMAIN evibes.com) EVIBES_FRONTEND_DOMAIN=$(prompt_default EVIBES_FRONTEND_DOMAIN evibes.com)
BASE_DOMAIN=$(prompt_default EVIBES_BASE_DOMAIN evibes.com) EVIBES_BASE_DOMAIN=$(prompt_default EVIBES_BASE_DOMAIN evibes.com)
SENTRY_DSN=$(prompt_default SENTRY_DSN "") SENTRY_DSN=$(prompt_default SENTRY_DSN "")
DEBUG=$(prompt_default DEBUG 1) DEBUG=$(prompt_default DEBUG 1)
TIME_ZONE=$(prompt_default TIME_ZONE "Europe/London") TIME_ZONE=$(prompt_default TIME_ZONE "Europe/London")
@ -45,7 +45,7 @@ JWT_SIGNING_KEY=$(prompt_autogen JWT_SIGNING_KEY 64)
ALLOWED_HOSTS=$(prompt_default ALLOWED_HOSTS "evibes.com api.evibes.com b2b.evibes.com") ALLOWED_HOSTS=$(prompt_default ALLOWED_HOSTS "evibes.com api.evibes.com b2b.evibes.com")
CSRF_TRUSTED_ORIGINS=$(prompt_default CSRF_TRUSTED_ORIGINS "https://evibes.com https://api.evibes.com https://www.evibes.com https://b2b.evibes.com") CSRF_TRUSTED_ORIGINS=$(prompt_default CSRF_TRUSTED_ORIGINS "https://evibes.com https://api.evibes.com https://www.evibes.com https://b2b.evibes.com")
CORS_ALLOWED_ORIGINS=$CSRF_TRUSTED_ORIGINS CORS_ALLOWED_ORIGINS=$(prompt_default CORS_ALLOWED_ORIGINS "$CSRF_TRUSTED_ORIGINS")
POSTGRES_DB=$(prompt_default POSTGRES_DB evibes) POSTGRES_DB=$(prompt_default POSTGRES_DB evibes)
POSTGRES_USER=$(prompt_default POSTGRES_USER evibes_user) POSTGRES_USER=$(prompt_default POSTGRES_USER evibes_user)
@ -80,4 +80,55 @@ ABSTRACT_API_KEY=$(prompt_default ABSTRACT_API_KEY "Haha, really? x2")
DEEPL_AUTH_KEY=$(prompt_default DEEPL_AUTH_KEY "Haha, really? x3") DEEPL_AUTH_KEY=$(prompt_default DEEPL_AUTH_KEY "Haha, really? x3")
cat > .env <<EOF cat > .env <<EOF
EVIBES_PROJECT_NAME="$PR EVIBES_PROJECT_NAME="${EVIBES_PROJECT_NAME}"
EVIBES_FRONTEND_DOMAIN="${EVIBES_FRONTEND_DOMAIN}"
EVIBES_BASE_DOMAIN="${EVIBES_BASE_DOMAIN}"
SENTRY_DSN="${SENTRY_DSN}"
DEBUG=${DEBUG}
SECRET_KEY="${SECRET_KEY}"
JWT_SIGNING_KEY="${JWT_SIGNING_KEY}"
ALLOWED_HOSTS="${ALLOWED_HOSTS}"
CSRF_TRUSTED_ORIGINS="${CSRF_TRUSTED_ORIGINS}"
CORS_ALLOWED_ORIGINS="${CORS_ALLOWED_ORIGINS}"
POSTGRES_DB="${POSTGRES_DB}"
POSTGRES_USER="${POSTGRES_USER}"
POSTGRES_PASSWORD="${POSTGRES_PASSWORD}"
DBBACKUP_TYPE="${DBBACKUP_TYPE}"
DBBACKUP_HOST="${DBBACKUP_HOST}"
DBBACKUP_USER="${DBBACKUP_USER}"
DBBACKUP_PASS="${DBBACKUP_PASS}"
ELASTIC_PASSWORD="${ELASTIC_PASSWORD}"
REDIS_PASSWORD="${REDIS_PASSWORD}"
CELERY_BROKER_URL="redis://:${REDIS_PASSWORD}@redis:6379/0"
CELERY_RESULT_BACKEND="redis://:${REDIS_PASSWORD}@redis:6379/0"
PROMETHEUS_USER="${PROMETHEUS_USER}"
PROMETHEUS_PASSWORD="${PROMETHEUS_PASSWORD}"
EMAIL_BACKEND="${EMAIL_BACKEND}"
EMAIL_HOST="${EMAIL_HOST}"
EMAIL_PORT="${EMAIL_PORT}"
EMAIL_USE_TLS=${EMAIL_USE_TLS}
EMAIL_USE_SSL=${EMAIL_USE_SSL}
EMAIL_HOST_USER="${EMAIL_HOST_USER}"
EMAIL_HOST_PASSWORD="${EMAIL_HOST_PASSWORD}"
EMAIL_FROM="${EMAIL_FROM}"
COMPANY_NAME="${COMPANY_NAME}"
COMPANY_PHONE_NUMBER="${COMPANY_PHONE_NUMBER}"
COMPANY_ADDRESS="${COMPANY_ADDRESS}"
OPENAI_API_KEY="${OPENAI_API_KEY}"
ABSTRACT_API_KEY="${ABSTRACT_API_KEY}"
DEEPL_AUTH_KEY="${DEEPL_AUTH_KEY}"
EOF
echo ".env file generated with fresh values."

View file

@ -3,33 +3,39 @@ set -euo pipefail
source ./scripts/Unix/starter.sh source ./scripts/Unix/starter.sh
echo "Verifying all images are present…" echo "Verifying all images are present..."
images=$(docker compose config --format json | jq -r '.services[].image // empty') if command -v jq >/dev/null 2>&1; then
for image in $images; do images=$(docker compose config --format json | jq -r '.services[].image // empty')
if ! docker image inspect "$image" > /dev/null 2>&1; then if [ -n "$images" ]; then
echo "Required images not found. Please run install.sh first." >&2 for image in $images; do
exit 1 if ! docker image inspect "$image" > /dev/null 2>&1; then
echo "Required images not found. Please run install.sh first." >&2
exit 1
fi
echo " - Found image: $image"
done
fi fi
echo " • Found image: $image" else
done echo "jq is not installed; skipping image verification step."
fi
echo "Spinning services up…" echo "Spinning services up..."
docker compose up --no-build --detach --wait docker compose up --no-build --detach --wait
echo "Services are up and healthy!" echo "Services are up and healthy!"
echo "Applying migrations" echo "Applying migrations..."
docker compose exec app uv run python manage.py migrate --no-input docker compose exec app uv run python manage.py migrate --no-input --verbosity 0
echo "Migrations applied successfully!" echo "Migrations applied successfully!"
echo "Collecting static files" echo "Collecting static files..."
docker compose exec app uv run python manage.py collectstatic --clear --no-input docker compose exec app uv run python manage.py collectstatic --clear --no-input --verbosity 0
echo "Static files collected successfully!" echo "Static files collected successfully!"
echo "Setting default caches" echo "Setting default caches..."
docker compose exec app uv run python manage.py set_default_caches docker compose exec app uv run python manage.py set_default_caches
echo "Default caches set successfully!" echo "Default caches set successfully!"
echo "Cleaning unused Docker data" echo "Cleaning unused Docker data..."
docker system prune -f docker system prune -f
echo "Unused Docker data cleaned successfully!" echo "Unused Docker data cleaned successfully!"