Files
brain/scripts/lib/setup-secrets.sh
T

86 lines
2.7 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# Resolve secret placeholders <<NAME>> in target file
# Modes:
# --secret=NAME=VALUE (non-interactive substitution; can be repeated)
# --list-unresolved (find <<*>> placeholders, no changes)
# --skip-unresolved (don't prompt for unresolved; leave + write to .brain-deferred-secrets.txt)
# (default) interactive prompt for each placeholder not provided via --secret
#
# Usage: setup-secrets.sh [--secret=NAME=VALUE ...] [--skip-unresolved | --list-unresolved] <target-file>
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/common.sh"
declare -A secrets=()
skip_unresolved=0
list_only=0
target=""
while [ $# -gt 0 ]; do
case "$1" in
--secret=*)
kv="${1#--secret=}"
name="${kv%%=*}"
value="${kv#*=}"
secrets["$name"]="$value"
;;
--skip-unresolved) skip_unresolved=1 ;;
--list-unresolved) list_only=1 ;;
*) target="$1" ;;
esac
shift
done
[ -n "$target" ] || { log_error "Target file required"; exit 1; }
[ -f "$target" ] || { log_error "Target not found: $target"; exit 1; }
# Find all placeholders (e.g. <<MAGIC_API_KEY>>); uppercase-only names.
placeholders=$(grep -oE '<<[A-Z_][A-Z0-9_]*>>' "$target" 2>/dev/null | sort -u || true)
if [ "$list_only" -eq 1 ]; then
if [ -z "$placeholders" ]; then
log_info "No unresolved placeholders in $target"
else
log_info "Unresolved placeholders in $target:"
echo "$placeholders"
fi
exit 0
fi
deferred_file="$(dirname "$target")/.brain-deferred-secrets.txt"
deferred=""
for p in $placeholders; do
name="${p#<<}"
name="${name%>>}"
if [ -n "${secrets[$name]:-}" ]; then
value="${secrets[$name]}"
# sed-replace via temp + mv (Windows-safe; avoids sed -i portability issues)
sed "s|<<$name>>|$value|g" "$target" > "$target.tmp"
mv "$target.tmp" "$target"
log_info "Resolved <<$name>>"
elif [ "$skip_unresolved" -eq 1 ]; then
deferred="$deferred$name\n"
log_warn "Skipped <<$name>> (deferred)"
else
# Interactive prompt (manual usage; tests always pass --secret or --skip)
printf "Enter value for <<%s>> (or empty to skip): " "$name" >&2
read -r value
if [ -n "$value" ]; then
sed "s|<<$name>>|$value|g" "$target" > "$target.tmp"
mv "$target.tmp" "$target"
log_info "Resolved <<$name>>"
else
deferred="$deferred$name\n"
log_warn "Skipped <<$name>>"
fi
fi
done
if [ -n "$deferred" ]; then
printf "%b" "$deferred" > "$deferred_file"
log_warn "Deferred secrets recorded: $deferred_file"
fi