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>
This commit is contained in:
@@ -15,7 +15,7 @@ pre_commit_hook_install() {
|
||||
|
||||
local hooks_dir="$repo_dir/.git/hooks"
|
||||
local hook_path="$hooks_dir/pre-commit"
|
||||
local marker="# fn_registry-pre-commit-v1"
|
||||
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
|
||||
@@ -23,7 +23,8 @@ pre_commit_hook_install() {
|
||||
fi
|
||||
|
||||
if [[ -f "$hook_path" ]]; then
|
||||
if grep -qF "$marker" "$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
|
||||
@@ -42,28 +43,46 @@ pre_commit_hook_install() {
|
||||
|
||||
cat > "$hook_path" <<'HOOK'
|
||||
#!/usr/bin/env bash
|
||||
# fn_registry-pre-commit-v1
|
||||
# fn_registry-pre-commit-v2
|
||||
set -e
|
||||
|
||||
# Localizar fn_registry root: env var FN_REGISTRY_ROOT o asumir mismo repo si tiene registry.db en raiz
|
||||
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
||||
|
||||
# Localizar fn_registry root
|
||||
REGISTRY_ROOT="${FN_REGISTRY_ROOT:-}"
|
||||
if [ -z "$REGISTRY_ROOT" ]; then
|
||||
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
||||
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" ] || [ ! -f "$REGISTRY_ROOT/bash/functions/cybersecurity/scan_secrets_in_dirty.sh" ]; then
|
||||
echo "[pre-commit] fn_registry no localizable; saltando scan de secrets" >&2
|
||||
if [ -z "$REGISTRY_ROOT" ] || [ ! -d "$REGISTRY_ROOT/bash/functions" ]; then
|
||||
echo "[pre-commit] fn_registry no localizable; saltando checks" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Ejecutar scan en repo actual (cwd)
|
||||
bash "$REGISTRY_ROOT/bash/functions/cybersecurity/scan_secrets_in_dirty.sh" "$(git rev-parse --show-toplevel)"
|
||||
# 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
|
||||
|
||||
Reference in New Issue
Block a user