mirror of https://github.com/garrytan/gstack.git
103 lines
3.6 KiB
Bash
Executable File
103 lines
3.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Migration: v1.38.1.0 — add root-level design + test-plan patterns to
|
|
# .brain-allowlist, .brain-privacy-map.json, and .gitattributes (#1452).
|
|
#
|
|
# Why a migration: gstack-artifacts-init regenerates these files but also
|
|
# does `git commit + push` on ~/.gstack/, which would clobber user state on
|
|
# upgrade. Instead, we do targeted per-file in-place repairs.
|
|
#
|
|
# Per-file independent — if one file is missing we still repair the others.
|
|
#
|
|
# Idempotent: each insertion is gated on `not already present` so re-running
|
|
# the migration is a no-op.
|
|
|
|
# No `set -e` — we intentionally tolerate per-file failures so other repairs
|
|
# still run. `set -u` is fine.
|
|
set -u
|
|
|
|
GSTACK_HOME="${HOME}/.gstack"
|
|
ALLOWLIST="${GSTACK_HOME}/.brain-allowlist"
|
|
PRIVACY="${GSTACK_HOME}/.brain-privacy-map.json"
|
|
GITATTRS="${GSTACK_HOME}/.gitattributes"
|
|
|
|
MIGRATION_DIR="${GSTACK_HOME}/.migrations"
|
|
DONE="${MIGRATION_DIR}/v1.38.1.0.done"
|
|
|
|
mkdir -p "${MIGRATION_DIR}" 2>/dev/null || true
|
|
if [ -f "${DONE}" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
NEW_PATTERNS=(
|
|
'projects/*/*-design-*.md'
|
|
'projects/*/*-test-plan-*.md'
|
|
)
|
|
|
|
added_any=0
|
|
|
|
# ----- .brain-allowlist ---------------------------------------------------
|
|
if [ -f "${ALLOWLIST}" ]; then
|
|
for PATTERN in "${NEW_PATTERNS[@]}"; do
|
|
if ! grep -Fq -- "${PATTERN}" "${ALLOWLIST}" 2>/dev/null; then
|
|
# Insert before USER ADDITIONS marker. BSD sed (-i.bak) compat for macOS;
|
|
# the backup file is removed afterward.
|
|
if grep -q '^# ---- USER ADDITIONS BELOW' "${ALLOWLIST}" 2>/dev/null; then
|
|
sed -i.bak "/^# ---- USER ADDITIONS BELOW/i\\
|
|
${PATTERN}
|
|
" "${ALLOWLIST}" && rm -f "${ALLOWLIST}.bak"
|
|
added_any=1
|
|
else
|
|
# Marker missing — append at end of file as a fallback. User may have
|
|
# custom-edited the file; better to add than skip silently.
|
|
printf '%s\n' "${PATTERN}" >> "${ALLOWLIST}"
|
|
added_any=1
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# ----- .brain-privacy-map.json -------------------------------------------
|
|
# Uses jq to preserve JSON validity. Skips with a warning if jq is missing.
|
|
if [ -f "${PRIVACY}" ]; then
|
|
if command -v jq >/dev/null 2>&1; then
|
|
for PATTERN in "${NEW_PATTERNS[@]}"; do
|
|
if ! jq -e --arg p "${PATTERN}" 'map(select(.pattern == $p)) | length > 0' "${PRIVACY}" >/dev/null 2>&1; then
|
|
if jq --arg p "${PATTERN}" '. += [{"pattern": $p, "class": "artifact"}]' "${PRIVACY}" > "${PRIVACY}.tmp" 2>/dev/null; then
|
|
mv "${PRIVACY}.tmp" "${PRIVACY}"
|
|
added_any=1
|
|
else
|
|
rm -f "${PRIVACY}.tmp"
|
|
echo " [v1.38.1.0] WARN: jq failed to patch ${PRIVACY}; skipping pattern ${PATTERN}." >&2
|
|
fi
|
|
fi
|
|
done
|
|
else
|
|
echo " [v1.38.1.0] WARN: jq not found; skipping privacy-map repair. Install jq and re-run gstack-upgrade, or run gstack-artifacts-init manually." >&2
|
|
fi
|
|
fi
|
|
|
|
# ----- .gitattributes -----------------------------------------------------
|
|
if [ -f "${GITATTRS}" ]; then
|
|
for PATTERN in "${NEW_PATTERNS[@]}"; do
|
|
RULE="${PATTERN} merge=union"
|
|
if ! grep -Fq -- "${RULE}" "${GITATTRS}" 2>/dev/null; then
|
|
printf '%s\n' "${RULE}" >> "${GITATTRS}"
|
|
added_any=1
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Mark done. Even if no patches were applied (already-current install), we
|
|
# write the touchfile so the migration runs once.
|
|
touch "${DONE}"
|
|
|
|
if [ "${added_any}" = "1" ]; then
|
|
echo " [v1.38.1.0] allowlist/privacy-map/gitattributes patched for root-level design + test-plan artifacts (idempotent)" >&2
|
|
fi
|
|
|
|
# NEVER `git commit + push` from this migration. The user controls when the
|
|
# patches ship into their federated artifacts repo (next gstack-brain-sync
|
|
# --once or a manual commit).
|
|
|
|
exit 0
|