Files
Scripts/Linux/Development/generate-config.sh
2026-01-12 23:52:33 +01:00

123 lines
3.7 KiB
Bash

#!/bin/bash
# Enable strict error handling
set -e
# Function to show usage instructions
show_usage() {
echo "Usage: $0 [file extensions] [environment] [--dry-run]"
echo " file extensions: A space-separated list of file extensions (e.g. .yml .json .conf)."
echo " environment: The target environment (e.g., development or production)."
echo " --dry-run : Simulate changes without modifying files."
}
# Parse command-line arguments
DRY_RUN=false
ENV=$1
if [[ -z "$ENV" ]]; then
show_usage
exit 1
fi
if [[ "$2" == "--dry-run" ]]; then
DRY_RUN=true
fi
shift # Shift arguments so we can get the file extensions after the environment
EXTENSIONS=("$@")
if [[ ${#EXTENSIONS[@]} -eq 0 ]]; then
echo "Error: You must specify at least one file extension."
show_usage
exit 1
fi
echo "Arguments passed correctly!"
# Load the appropriate .env file
if [ -f ".env.$ENV" ]; then
set -a
source ".env.$ENV"
set +a
else
echo "Environment file .env.$ENV not found!"
exit 1
fi
# Function to escape all special characters that might affect sed
escape_sed_special_chars() {
printf '%s' "$1" | sed 's|[&/\$]|\&|g; s|[[:space:]]|\\ |g; s|\\|\\\\|g'
}
# Process files for each extension
for EXT in "${EXTENSIONS[@]}"; do
# Find and process all *.template files with the current extension, including subdirectories
find . -name "*.template$EXT" | while read -r TEMPLATE_FILE; do
# Derive output file name by removing ".template"
OUTPUT_FILE="${TEMPLATE_FILE%.template$EXT}$EXT"
# Dry-run reporting or actual processing
if $DRY_RUN; then
echo "Dry run: would generate $OUTPUT_FILE from $TEMPLATE_FILE"
LINE_NUMBER=0
while IFS= read -r line || [[ -n "$line" ]]; do
LINE_NUMBER=$((LINE_NUMBER + 1))
while [[ "$line" =~ (\$\{([A-Za-z_][A-Za-z0-9_]*)\}) ]]; do
PLACEHOLDER="${BASH_REMATCH[1]}"
VAR_NAME="${BASH_REMATCH[2]}"
VAR_VALUE="${!VAR_NAME:-<UNDEFINED>}"
echo " Would have inputted '$VAR_VALUE' in place of '$VAR_NAME' in $OUTPUT_FILE at line $LINE_NUMBER"
if [[ "$VAR_VALUE" == "<UNDEFINED>" ]]; then
echo " Warning: Variable '$VAR_NAME' is undefined and will cause an error in actual mode."
fi
line="${line/$PLACEHOLDER/}"
done
done < "$TEMPLATE_FILE"
else
# Validate unresolved placeholders
UNRESOLVED=$(grep -oP '\${\K[A-Za-z_][A-Za-z0-9_]*(?=})' "$TEMPLATE_FILE" | while read -r var; do
if [ -z "${!var}" ]; then
echo "$var"
fi
done)
if [ -n "$UNRESOLVED" ]; then
echo "Error: Unresolved variable placeholders detected in $TEMPLATE_FILE!"
echo "Ensure all variables are defined in .env.$ENV. Missing: $UNRESOLVED"
exit 1
fi
# Backup existing output file if it exists
if [ -f "$OUTPUT_FILE" ]; then
mv "$OUTPUT_FILE" "${OUTPUT_FILE}.bak"
echo "Backup created for $OUTPUT_FILE as ${OUTPUT_FILE}.bak"
fi
# Replace placeholders with environment variables
sed_script=""
while IFS='=' read -r key value; do
# Skip invalid variable names
if [[ "$key" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]]; then
# Escape special characters in the key and value for sed
escaped_key=$(escape_sed_special_chars "${key}")
escaped_value=$(escape_sed_special_chars "${!key}")
sed_script+="s|\${${escaped_key}}|${escaped_value}|g;"
fi
done < <(env)
# Generate the output file
sed -e "$sed_script" "$TEMPLATE_FILE" > "$OUTPUT_FILE"
echo "Generated $OUTPUT_FILE from $TEMPLATE_FILE"
fi
done
done
# Keep the terminal open at the end
echo "Script completed. Press any key to exit..."
read -n 1 -s