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

View file

@ -33,9 +33,9 @@ if [ -f .env ]; then
read -r
fi
PROJECT_NAME=$(prompt_default EVIBES_PROJECT_NAME eVibes)
FRONTEND_DOMAIN=$(prompt_default EVIBES_FRONTEND_DOMAIN evibes.com)
BASE_DOMAIN=$(prompt_default EVIBES_BASE_DOMAIN evibes.com)
EVIBES_PROJECT_NAME=$(prompt_default EVIBES_PROJECT_NAME eVibes)
EVIBES_FRONTEND_DOMAIN=$(prompt_default EVIBES_FRONTEND_DOMAIN evibes.com)
EVIBES_BASE_DOMAIN=$(prompt_default EVIBES_BASE_DOMAIN evibes.com)
SENTRY_DSN=$(prompt_default SENTRY_DSN "")
DEBUG=$(prompt_default DEBUG 1)
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")
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_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")
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
echo "Verifying all images are present…"
images=$(docker compose config --format json | jq -r '.services[].image // empty')
for image in $images; do
echo "Verifying all images are present..."
if command -v jq >/dev/null 2>&1; then
images=$(docker compose config --format json | jq -r '.services[].image // empty')
if [ -n "$images" ]; then
for image in $images; do
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
echo " - Found image: $image"
done
fi
else
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
echo "Services are up and healthy!"
echo "Applying migrations"
docker compose exec app uv run python manage.py migrate --no-input
echo "Applying migrations..."
docker compose exec app uv run python manage.py migrate --no-input --verbosity 0
echo "Migrations applied successfully!"
echo "Collecting static files"
docker compose exec app uv run python manage.py collectstatic --clear --no-input
echo "Collecting static files..."
docker compose exec app uv run python manage.py collectstatic --clear --no-input --verbosity 0
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
echo "Default caches set successfully!"
echo "Cleaning unused Docker data"
echo "Cleaning unused Docker data..."
docker system prune -f
echo "Unused Docker data cleaned successfully!"