#!/bin/sh set -eu ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd) env_file=${1:-"$ROOT/.env"} template_file=${2:-"$ROOT/.env.example"} case "$env_file" in /*) ;; *) env_file="$ROOT/$env_file" ;; esac case "$template_file" in /*) ;; *) template_file="$ROOT/$template_file" ;; esac if [ ! -f "$env_file" ]; then echo "Environment file does not exist: $env_file" >&2 exit 1 fi if [ ! -f "$template_file" ]; then echo "Environment template does not exist: $template_file" >&2 exit 1 fi if [ "$(stat -c '%a' "$env_file")" != 600 ]; then echo "Environment file must have mode 0600: $env_file" >&2 exit 1 fi env_dir=$(CDPATH='' cd -- "$(dirname -- "$env_file")" && pwd) env_name=$(basename -- "$env_file") temporary_env=$(mktemp "$env_dir/$env_name.tmp.XXXXXX") trap 'rm -f "$temporary_env"' EXIT HUP INT TERM chmod 600 "$temporary_env" if ! awk ' BEGIN { current_file = 1 } FNR == 1 && NR != 1 { current_file = 0 } current_file { separator = index($0, "=") if (separator > 1) { key = substr($0, 1, separator - 1) if (key ~ /^[A-Z][A-Z0-9_]*$/) { if (key in current) { exit 40 } current[key] = substr($0, separator + 1) current_order[++current_count] = key } } next } { separator = index($0, "=") if (separator > 1) { key = substr($0, 1, separator - 1) if (key ~ /^[A-Z][A-Z0-9_]*$/) { if (key in template_seen) { exit 41 } template_seen[key] = 1 if (key in current) { print key "=" current[key] emitted[key] = 1 next } } } print } END { unknown_count = 0 for (position = 1; position <= current_count; position++) { key = current_order[position] if (!(key in emitted) && !(key in template_seen)) { unknown[++unknown_count] = key } } if (unknown_count > 0) { print "" print "# Local keys not present in the current template." for (position = 1; position <= unknown_count; position++) { key = unknown[position] print key "=" current[key] } } } ' "$env_file" "$template_file" >"$temporary_env"; then echo "Refusing to synchronize the environment: invalid or duplicate keys were found." >&2 exit 1 fi mv "$temporary_env" "$env_file" trap - EXIT HUP INT TERM echo "Environment synchronized with the template without printing values: $env_file"