learning_ai_common_plat/scripts/sync-docker-prep.sh
saravanakumardb1 a418a23e56 feat(scripts): canonical hardened docker-prep + sync tooling (Phase B7)
Promotes docker-prep.sh to canonical home in common-plat with full Phase B
hardening from the docker-build-optimization-roadmap:

- B1: --dry-run mode (lists actions, no side effects)
- B2: idempotency guard (refuses to run if *.bak exists, --force to bypass)
- B5: trap-based auto-restore on error (--keep to disable)
- B6: standardized header + usage block
- B7: canonical home + sync + drift-check (mirrors npmrc.template pattern)
- B8: --strip-overrides for safety-net cleanup
- New: --check mode for CI-friendly state verification
- New: auto-discovers package.json files with @bytelyst/* deps
- New: portable sed -i (BSD on macOS, GNU on Linux)
- New: preserves .docker-deps/.gitkeep on clear (fixes earlier regression)
- New: 2 small JS helpers (_docker-prep-*.js) avoid bash 3.2 heredoc quirks

Verified on clock + peakpulse: dry-run, pack, check, idempotency guard,
restore, and post-restore git status all clean.
2026-05-27 03:48:46 -07:00

109 lines
2.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# Sync canonical docker-prep.template.sh into every product repo's scripts/docker-prep.sh.
# Mirrors scripts/sync-npmrc.sh pattern.
#
# Usage:
# bash scripts/sync-docker-prep.sh # sync all known consumers
# bash scripts/sync-docker-prep.sh --check # exit 1 if any drift
# bash scripts/sync-docker-prep.sh --repo PATH # sync just one repo
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
TEMPLATE="$SCRIPT_DIR/docker-prep.template.sh"
COMMON_PLAT="$(cd "$SCRIPT_DIR/.." && pwd)"
SIBLING_ROOT="$(cd "$COMMON_PLAT/.." && pwd)"
CHECK_ONLY=false
SINGLE_REPO=""
while [ $# -gt 0 ]; do
case "$1" in
--check) CHECK_ONLY=true ;;
--repo) SINGLE_REPO="${2:-}"; shift ;;
-h|--help) sed -n '2,11p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
*) echo "Unknown arg: $1" >&2; exit 2 ;;
esac
shift
done
if [ ! -f "$TEMPLATE" ]; then
echo "✗ Template not found: $TEMPLATE" >&2; exit 1
fi
# Repos that consume docker-prep.sh (have scripts/docker-prep.sh today)
CONSUMERS=(
"learning_ai_clock"
"learning_ai_peakpulse"
"learning_ai_notes"
"learning_ai_fastgap"
"learning_ai_jarvis_jr"
"learning_ai_flowmonk"
"learning_ai_trails"
"learning_ai_local_memory_gpt"
"learning_ai_efforise"
)
if [ -n "$SINGLE_REPO" ]; then
CONSUMERS=("$(basename "$SINGLE_REPO")")
SIBLING_ROOT="$(cd "$(dirname "$SINGLE_REPO")" && pwd)"
fi
drift=0
synced=0
skipped=0
for repo in "${CONSUMERS[@]}"; do
target_dir="$SIBLING_ROOT/$repo"
target="$target_dir/scripts/docker-prep.sh"
if [ ! -d "$target_dir" ]; then
echo " ⊘ skip $repo (not present at $target_dir)"
skipped=$((skipped+1))
continue
fi
if [ ! -f "$target" ]; then
echo " ⊘ skip $repo (no existing scripts/docker-prep.sh)"
skipped=$((skipped+1))
continue
fi
# Sync 3 files together: main script + 2 JS helpers
HELPER_INJECT="$SCRIPT_DIR/_docker-prep-inject.js"
HELPER_STRIP="$SCRIPT_DIR/_docker-prep-strip.js"
T_HELPER_INJECT="$(dirname "$target")/_docker-prep-inject.js"
T_HELPER_STRIP="$(dirname "$target")/_docker-prep-strip.js"
in_sync=true
cmp -s "$TEMPLATE" "$target" || in_sync=false
cmp -s "$HELPER_INJECT" "$T_HELPER_INJECT" 2>/dev/null || in_sync=false
cmp -s "$HELPER_STRIP" "$T_HELPER_STRIP" 2>/dev/null || in_sync=false
if $in_sync; then
echo "$repo (in sync)"
continue
fi
if $CHECK_ONLY; then
echo "$repo DRIFT"
drift=$((drift+1))
else
mkdir -p "$(dirname "$target")"
cp "$TEMPLATE" "$target"
cp "$HELPER_INJECT" "$T_HELPER_INJECT"
cp "$HELPER_STRIP" "$T_HELPER_STRIP"
chmod +x "$target"
echo "$repo synced (script + 2 helpers)"
synced=$((synced+1))
fi
done
echo ""
if $CHECK_ONLY; then
if [ $drift -gt 0 ]; then
echo "$drift repo(s) drifted from canonical template"
exit 1
fi
echo "✅ All repos in sync with canonical docker-prep template"
else
echo "✅ Synced: $synced, skipped: $skipped"
fi