diff --git a/init/scripts/compose_gen.sh b/init/scripts/compose_gen.sh index 403d06e..3c2327e 100755 --- a/init/scripts/compose_gen.sh +++ b/init/scripts/compose_gen.sh @@ -4,12 +4,12 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/functions.sh" resolve_paths +require_env -TEMPLATE_FILE="${INIT_DIR}/templates/compose.yaml.template" +TEMPLATE_FILE="${INIT_DIR}/templates/main.yaml" OUTPUT_FILE="${ROOT_DIR}/compose.yaml" require_file "$TEMPLATE_FILE" "Compose template" -require_env log_info "Configuring optional services..." diff --git a/init/scripts/functions.sh b/init/scripts/functions.sh index ad1bba7..5f42553 100644 --- a/init/scripts/functions.sh +++ b/init/scripts/functions.sh @@ -20,11 +20,24 @@ NC='\033[0m' # --- Path Resolution --- # Standardised for project structure: /init/scripts/xxx.sh # Sets: SCRIPT_DIR, INIT_DIR, ROOT_DIR +# --- Path Resolution --- resolve_paths() { SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[1]}")" && pwd)" - INIT_DIR="$(dirname "$SCRIPT_DIR")" - ROOT_DIR="$(dirname "$INIT_DIR")" - export SCRIPT_DIR INIT_DIR ROOT_DIR + + # Detect if we're in init/scripts/ or at project root + if [[ "$SCRIPT_DIR" == */init/scripts ]]; then + # Called from init/scripts/ (e.g., set_env.sh, config_gen.sh) + INIT_DIR="$(dirname "$SCRIPT_DIR")" + ROOT_DIR="$(dirname "$INIT_DIR")" + else + # Called from project root (e.g., setup.sh) + ROOT_DIR="$SCRIPT_DIR" + INIT_DIR="${ROOT_DIR}/init" + fi + + ENV_FILE="${ROOT_DIR}/.env" + COMPOSE_FILE="${ROOT_DIR}/compose.yaml" + export SCRIPT_DIR INIT_DIR ROOT_DIR ENV_FILE COMPOSE_FILE } # --- Logging --- @@ -68,6 +81,44 @@ generate_secret() { fi } +# --- Interactive Prompts --- +prompt_var() { + local var_name="$1" + local prompt_text="$2" + local default_val="$3" + local is_password="$4" + local base_domain="${5:-}" + + local input + local final_value + + echo -n "$prompt_text [Default: $default_val]: " + read -r input + + if [[ -z "$input" ]]; then + if [[ "$is_password" == "yes" ]]; then + input=$(generate_secret 32) + else + input="$default_val" + fi + fi + + # Append base domain if provided + if [[ -n "$base_domain" ]]; then + final_value="${input}.${base_domain}" + else + final_value="$input" + fi + + # Escape special characters for .env file + final_value="${final_value//\\/\\\\}" + final_value="${final_value//\"/\\\"}" + final_value="${final_value//\$/\\\$}" + final_value="${final_value//\`/\\\`}" + + echo "${var_name}=\"${final_value}\"" >> "$ENV_FILE" +} + # --- File Permissions --- fix_ownership() { local target="$1" @@ -89,6 +140,14 @@ require_command() { fi } +require_docker() { + require_command "docker" + if ! docker compose version &> /dev/null; then + log_error "Docker Compose plugin not found. Install it and retry." + exit 1 + fi +} + require_file() { local file="$1" local description="${2:-File}" @@ -99,17 +158,21 @@ require_file() { } require_env() { - local file="${ROOT_DIR}/.env" + local file="${ENV_FILE:-${ROOT_DIR}/.env}" + if [[ ! -f "$file" ]]; then - log_error ".env file not found. Run set_env.sh first." + log_error ".env file not found at ${file}. Run set_env.sh first." exit 1 fi - source "$file" -} -require_docker() { - require_command "docker" - require_command "docker compose" + # Source the file + source "$file" + + # Verify critical variables exist + if [[ -z "${DOMAIN:-}" ]]; then + log_error "DOMAIN variable missing in .env. Re-run set_env.sh." + exit 1 + fi } # --- Volume Path Resolution ---