123 lines
3.7 KiB
Bash
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
|