#!/usr/bin/env bash # Parses a .env.example file into global metadata arrays. # Source this file; do not execute it directly. # # After calling parse_env_example, the following globals are populated: # ENV_VARS - ordered array of variable names # ENV_DESC_ - description string # ENV_TYPE_ - type annotation (string if absent) # ENV_REQUIRED_ - "true" or "false" # ENV_DEFAULT_ - default value (may be empty) # parse_env_example # Reads the given .env.example file and populates global metadata. parse_env_example() { local file="$1" if [[ ! -f "$file" ]]; then printf "Error: file not found: %s\n" "$file" >&2 return 1 fi ENV_VARS=() local desc="" local type="" local required="false" local in_block=0 # 1 once we've started accumulating comments for a var while IFS= read -r line || [[ -n "$line" ]]; do # --- Empty line: flush pending comment block --- if [[ -z "$line" ]]; then if [[ $in_block -eq 1 ]]; then desc="" type="" required="false" in_block=0 fi continue fi # --- Comment line --- if [[ "$line" =~ ^[[:space:]]*#(.*) ]]; then local comment="${BASH_REMATCH[1]}" # Trim one leading space if present comment="${comment# }" in_block=1 if [[ "$comment" =~ ^@required([[:space:]]|$) ]]; then required="true" elif [[ "$comment" =~ ^@type[[:space:]]+(.+)$ ]]; then type="${BASH_REMATCH[1]}" # Trim trailing whitespace type="${type%"${type##*[![:space:]]}"}" else # Regular description text — append if [[ -n "$desc" ]]; then desc="${desc} ${comment}" else desc="$comment" fi fi continue fi # --- KEY=VALUE line --- if [[ "$line" =~ ^([A-Za-z_][A-Za-z0-9_]*)=(.*)$ ]]; then local var_name="${BASH_REMATCH[1]}" local default="${BASH_REMATCH[2]}" ENV_VARS+=("$var_name") printf -v "ENV_DESC_${var_name}" '%s' "$desc" printf -v "ENV_TYPE_${var_name}" '%s' "${type:-string}" printf -v "ENV_REQUIRED_${var_name}" '%s' "$required" printf -v "ENV_DEFAULT_${var_name}" '%s' "$default" # Reset for next block desc="" type="" required="false" in_block=0 continue fi done < "$file" }