#!/usr/bin/env bash # generate-env.sh — Interactively generate a .env file from a .env.example template. # Run with -h for usage information. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck source=lib/colors.sh source "${SCRIPT_DIR}/lib/colors.sh" # shellcheck source=lib/parse.sh source "${SCRIPT_DIR}/lib/parse.sh" # shellcheck source=lib/validate.sh source "${SCRIPT_DIR}/lib/validate.sh" # shellcheck source=lib/prompt.sh source "${SCRIPT_DIR}/lib/prompt.sh" # shellcheck source=lib/output.sh source "${SCRIPT_DIR}/lib/output.sh" # --------------------------------------------------------------------------- # Defaults # --------------------------------------------------------------------------- INPUT_FILE=".env.example" OUTPUT_FILE=".env" # --------------------------------------------------------------------------- # Argument parsing # --------------------------------------------------------------------------- usage() { cat "${SCRIPT_DIR}/HELP" >&2 exit 0 } while getopts ":o:h" opt; do case "$opt" in o) OUTPUT_FILE="$OPTARG" ;; h) usage ;; :) printf "${RED}Error: option -%s requires an argument.${NC}\n" "$OPTARG" >&2; exit 1 ;; \?) printf "${RED}Error: unknown option -%s${NC}\n" "$OPTARG" >&2; exit 1 ;; esac done shift $((OPTIND - 1)) if [[ $# -gt 0 ]]; then INPUT_FILE="$1" fi # --------------------------------------------------------------------------- # Guard: don't silently overwrite an existing .env without confirmation # --------------------------------------------------------------------------- if [[ -f "$OUTPUT_FILE" ]]; then printf "${YELLOW}Warning: %s already exists.${NC}\n" "$OUTPUT_FILE" >&2 read -r -p "Overwrite? [y/N]: " confirm >&2 case "${confirm,,}" in y|yes) ;; *) printf "Aborted.\n" >&2; exit 0 ;; esac fi # --------------------------------------------------------------------------- # Main # --------------------------------------------------------------------------- printf "${BOLD}generate-env${NC} %s → %s\n" "$INPUT_FILE" "$OUTPUT_FILE" >&2 printf "${DIM}Fill in each variable. Press Enter to accept the default value.${NC}\n" >&2 parse_env_example "$INPUT_FILE" if [[ ${#ENV_VARS[@]} -eq 0 ]]; then printf "${YELLOW}No variables found in %s.${NC}\n" "$INPUT_FILE" >&2 exit 0 fi printf "${DIM}Found %d variable(s).${NC}\n" "${#ENV_VARS[@]}" >&2 prompt_all_variables write_env_file "$OUTPUT_FILE"