BangSo/scripts/ensure-local-env.sh

118 lines
3.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Fill a local .env from .env.example without clobbering values already set.
# Blank keys and replace-with-* placeholders are injected:
# computer sudo + local-dev password, zh-TW UI, random app secrets.
set -euo pipefail
repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
ENV_FILE="${ENV_FILE:-$repo_dir/.env}"
EXAMPLE_FILE="${EXAMPLE_FILE:-$repo_dir/.env.example}"
LOCAL_COMPUTER_PASSWORD="${LOCAL_COMPUTER_PASSWORD:-bangso}"
LOCAL_COMPUTER_SUDO="${LOCAL_COMPUTER_SUDO:-1}"
LOCAL_UI_LOCALE="${LOCAL_UI_LOCALE:-zh-TW}"
if [[ ! -f "$EXAMPLE_FILE" ]]; then
echo "Missing $EXAMPLE_FILE. Run this from the repository root." >&2
exit 1
fi
if ! command -v openssl >/dev/null 2>&1; then
echo "Missing required command: openssl" >&2
exit 1
fi
is_placeholder() {
local value="$1"
[[ -z "$value" || "$value" == replace-with-* ]]
}
read_key() {
local file="$1"
local key="$2"
local value="" line
[[ -f "$file" ]] || return 0
while IFS= read -r line || [[ -n "$line" ]]; do
line="${line%$'\r'}"
case "$line" in
"${key}="*) value="${line#${key}=}" ;;
esac
done < "$file"
printf '%s' "$value"
}
upsert() {
local key="$1"
local value="$2"
local tmp line emitted=0
tmp="$(mktemp "${ENV_FILE}.XXXXXX")"
if [[ -f "$ENV_FILE" ]]; then
while IFS= read -r line || [[ -n "$line" ]]; do
line="${line%$'\r'}"
case "$line" in
"${key}="*)
if [[ "$emitted" -eq 0 ]]; then
printf '%s=%s\n' "$key" "$value"
emitted=1
fi
;;
*)
printf '%s\n' "$line"
;;
esac
done < "$ENV_FILE" > "$tmp"
fi
if [[ "$emitted" -eq 0 ]]; then
printf '%s=%s\n' "$key" "$value" >> "$tmp"
fi
mv "$tmp" "$ENV_FILE"
}
process_value() {
case "$1" in
BETTER_AUTH_SECRET) printf '%s' "${BETTER_AUTH_SECRET-}" ;;
ENCRYPTION_KEY) printf '%s' "${ENCRYPTION_KEY-}" ;;
SANDBOX_SUPERVISOR_TOKEN) printf '%s' "${SANDBOX_SUPERVISOR_TOKEN-}" ;;
SCREEN_PROXY_SECRET) printf '%s' "${SCREEN_PROXY_SECRET-}" ;;
COMPUTER_ALLOW_SUDO) printf '%s' "${COMPUTER_ALLOW_SUDO-}" ;;
COMPUTER_USER_PASSWORD) printf '%s' "${COMPUTER_USER_PASSWORD-}" ;;
VITE_DEFAULT_UI_LOCALE) printf '%s' "${VITE_DEFAULT_UI_LOCALE-}" ;;
esac
}
fill() {
local key="$1"
local fallback="$2"
local current proc val
current="$(read_key "$ENV_FILE" "$key")"
proc="$(process_value "$key")"
if ! is_placeholder "$current"; then
return 0
fi
if [[ -n "$proc" ]]; then
val="$proc"
elif [[ "$fallback" == "--random" ]]; then
val="$(openssl rand -hex 32)"
else
val="$fallback"
fi
upsert "$key" "$val"
printf 'injected %s\n' "$key"
}
if [[ ! -f "$ENV_FILE" ]]; then
umask 077
cp "$EXAMPLE_FILE" "$ENV_FILE"
chmod 600 "$ENV_FILE"
echo "created $ENV_FILE from $(basename "$EXAMPLE_FILE")"
fi
fill BETTER_AUTH_SECRET --random
fill ENCRYPTION_KEY --random
fill SANDBOX_SUPERVISOR_TOKEN --random
fill SCREEN_PROXY_SECRET --random
fill COMPUTER_ALLOW_SUDO "$LOCAL_COMPUTER_SUDO"
fill COMPUTER_USER_PASSWORD "$LOCAL_COMPUTER_PASSWORD"
fill VITE_DEFAULT_UI_LOCALE "$LOCAL_UI_LOCALE"
chmod 600 "$ENV_FILE"