Files
fn_registry/bash/functions/infra/pre_commit_hook_install.sh
T
egutierrez 75714c9007 feat: dagu backup DAG + pre-commit drift hook + sync 6 apps
Priority 1: Daily backup automation via Dagu DAG (~/dagu/dags/fn_backup.yaml,
schedule "0 3 * * *"). Backs up registry.db, each operations.db, and vaults
via rsync --link-dest. Fixes set -e arithmetic bugs in rotate_backups.sh and
backup_all.sh ((var++) returns 1 when var=0). Fixes && chain set -e bug in
vault rotation.

Priority 2: Pre-commit hook v2 chains scan_secrets + uses_functions audit.
New function git_hook_audit_app_drift_bash_infra blocks commits that touch
app code when that app has uses_functions drift. Allows corrective app.md-only
edits. Installed on fn_registry + 32 sub-repos.

Priority 3: Synced uses_functions in 6 sub-repo apps (commits in their own
repos): dag_engine, script_navegador, deploy_server, docker_tui,
auto_metabase, metabase_registry. Drift went from 7/12 to 4/12 apps.
Remaining drift = audit heuristic limitations (Python nested imports,
Go symbol name detection).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 02:09:33 +02:00

89 lines
2.6 KiB
Bash

#!/usr/bin/env bash
# pre_commit_hook_install — instala hook pre-commit que invoca scan_secrets_in_dirty
pre_commit_hook_install() {
local repo_dir="$1"
local force=0
shift
while [[ $# -gt 0 ]]; do
case "$1" in
--force) force=1 ;;
esac
shift
done
local hooks_dir="$repo_dir/.git/hooks"
local hook_path="$hooks_dir/pre-commit"
local marker="# fn_registry-pre-commit-v2"
if [[ ! -d "$hooks_dir" ]]; then
echo "[pre_commit_hook_install] ERROR: '$repo_dir' no es un repo git valido (falta .git/hooks)" >&2
return 1
fi
if [[ -f "$hook_path" ]]; then
# Detect either v1 or v2 marker as "ours"
if grep -qE "fn_registry-pre-commit-v[12]" "$hook_path"; then
if [[ $force -eq 0 ]]; then
echo "SKIP $hook_path (already installed)"
return 0
else
local backup="$hook_path.bak.$(date +%s)"
cp "$hook_path" "$backup"
echo "[pre_commit_hook_install] Backup: $backup" >&2
fi
else
if [[ $force -eq 0 ]]; then
echo "[pre_commit_hook_install] ERROR: '$hook_path' existe y no es nuestro. Usa --force para sobreescribir." >&2
return 2
fi
fi
fi
cat > "$hook_path" <<'HOOK'
#!/usr/bin/env bash
# fn_registry-pre-commit-v2
set -e
REPO_ROOT="$(git rev-parse --show-toplevel)"
# Localizar fn_registry root
REGISTRY_ROOT="${FN_REGISTRY_ROOT:-}"
if [ -z "$REGISTRY_ROOT" ]; then
if [ -f "$REPO_ROOT/registry.db" ]; then
REGISTRY_ROOT="$REPO_ROOT"
elif [ -f "$REPO_ROOT/../../registry.db" ]; then
REGISTRY_ROOT="$(cd "$REPO_ROOT/../.." && pwd)"
elif [ -f "$REPO_ROOT/../../../registry.db" ]; then
REGISTRY_ROOT="$(cd "$REPO_ROOT/../../.." && pwd)"
fi
fi
if [ -z "$REGISTRY_ROOT" ] || [ ! -d "$REGISTRY_ROOT/bash/functions" ]; then
echo "[pre-commit] fn_registry no localizable; saltando checks" >&2
exit 0
fi
# Check 1: scan secrets
SECRETS_SH="$REGISTRY_ROOT/bash/functions/cybersecurity/scan_secrets_in_dirty.sh"
if [ -f "$SECRETS_SH" ]; then
bash "$SECRETS_SH" "$REPO_ROOT"
fi
# Check 2: app uses_functions drift (only blocks if a touched app has drift)
DRIFT_SH="$REGISTRY_ROOT/bash/functions/infra/git_hook_audit_app_drift.sh"
if [ -f "$DRIFT_SH" ]; then
FN_REGISTRY_ROOT="$REGISTRY_ROOT" bash "$DRIFT_SH" "$REPO_ROOT"
fi
HOOK
chmod +x "$hook_path"
echo "INSTALLED $hook_path"
return 0
}
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
pre_commit_hook_install "$@"
fi