docs: add node1 runbooks, consolidation artifacts, and maintenance scripts
This commit is contained in:
112
scripts/docs/build_docs_hub_inventory.py
Normal file
112
scripts/docs/build_docs_hub_inventory.py
Normal file
@@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env python3
|
||||
import csv
|
||||
import fnmatch
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Dict, List
|
||||
|
||||
|
||||
EXTS = {".md", ".mdx", ".txt", ".ipynb", ".pdf", ".docx"}
|
||||
EXCLUDE_DIR_PATTERNS = [
|
||||
"*/.git/*",
|
||||
"*/node_modules/*",
|
||||
"*/venv/*",
|
||||
"*/.venv/*",
|
||||
"*/site-packages/*",
|
||||
"*/__pycache__/*",
|
||||
"*/rollback_backups/*",
|
||||
"*/.pytest_cache/*",
|
||||
]
|
||||
|
||||
|
||||
def excluded(path: str) -> bool:
|
||||
norm = path.replace("\\", "/")
|
||||
return any(fnmatch.fnmatch(norm, pat) for pat in EXCLUDE_DIR_PATTERNS)
|
||||
|
||||
|
||||
def classify(path: str, source_key: str) -> str:
|
||||
p = path.lower().replace("\\", "/")
|
||||
if source_key.startswith("node1_runtime"):
|
||||
return "runtime-fact"
|
||||
if "/.worktrees/" in p:
|
||||
return "legacy-worktree"
|
||||
if "/desktop/microdao/microdao 3/" in p:
|
||||
return "legacy-desktop"
|
||||
if "/docs/runbooks/" in p or p.endswith("/project-master-index.md") or p.endswith("/noda1-safe-deploy.md"):
|
||||
return "new-canonical"
|
||||
return "needs-triage"
|
||||
|
||||
|
||||
def status(path: str, source_key: str) -> str:
|
||||
c = classify(path, source_key)
|
||||
if c in {"runtime-fact", "new-canonical"}:
|
||||
return "active"
|
||||
if c.startswith("legacy"):
|
||||
return "legacy"
|
||||
return "unknown"
|
||||
|
||||
|
||||
def scan_root(root: Path, source_key: str) -> List[Dict[str, str]]:
|
||||
rows: List[Dict[str, str]] = []
|
||||
if not root.exists():
|
||||
return rows
|
||||
for fp in root.rglob("*"):
|
||||
if not fp.is_file():
|
||||
continue
|
||||
if fp.suffix.lower() not in EXTS:
|
||||
continue
|
||||
sp = str(fp)
|
||||
if excluded(sp):
|
||||
continue
|
||||
rows.append(
|
||||
{
|
||||
"source_key": source_key,
|
||||
"path": sp,
|
||||
"class": classify(sp, source_key),
|
||||
"status": status(sp, source_key),
|
||||
"mtime": str(int(fp.stat().st_mtime)),
|
||||
}
|
||||
)
|
||||
return rows
|
||||
|
||||
|
||||
def main() -> int:
|
||||
roots = {
|
||||
"canonical_repo": Path("/Users/apple/github-projects/microdao-daarion"),
|
||||
"legacy_repo": Path("/Users/apple/Desktop/MicroDAO/MicroDAO 3"),
|
||||
"worktrees": Path("/Users/apple/github-projects/microdao-daarion/.worktrees"),
|
||||
"notebooks": Path("/Users/apple/notebooks"),
|
||||
"node1_runtime_snapshot": Path("/Users/apple/github-projects/microdao-daarion/docs/consolidation/_node1_runtime_docs"),
|
||||
}
|
||||
|
||||
all_rows: List[Dict[str, str]] = []
|
||||
for key, root in roots.items():
|
||||
all_rows.extend(scan_root(root, key))
|
||||
|
||||
all_rows.sort(key=lambda r: (r["source_key"], r["path"]))
|
||||
|
||||
out_csv = Path("/Users/apple/github-projects/microdao-daarion/docs/consolidation/docs_inventory.csv")
|
||||
out_csv.parent.mkdir(parents=True, exist_ok=True)
|
||||
with out_csv.open("w", newline="", encoding="utf-8") as f:
|
||||
w = csv.DictWriter(f, fieldnames=["source_key", "path", "class", "status", "mtime"])
|
||||
w.writeheader()
|
||||
for row in all_rows:
|
||||
w.writerow(row)
|
||||
|
||||
# Tiny summary for quick review
|
||||
summary: Dict[str, int] = {}
|
||||
for row in all_rows:
|
||||
summary[row["class"]] = summary.get(row["class"], 0) + 1
|
||||
out_sum = Path("/Users/apple/github-projects/microdao-daarion/docs/consolidation/docs_inventory_summary.txt")
|
||||
with out_sum.open("w", encoding="utf-8") as f:
|
||||
f.write(f"total={len(all_rows)}\n")
|
||||
for k in sorted(summary.keys()):
|
||||
f.write(f"{k}={summary[k]}\n")
|
||||
|
||||
print(f"Wrote: {out_csv}")
|
||||
print(f"Wrote: {out_sum}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -116,6 +116,8 @@ doc_paths=(
|
||||
scripts/docs/session_bootstrap.sh
|
||||
scripts/docs/docs_backup.sh
|
||||
scripts/docs/docs_lint.sh
|
||||
scripts/docs/run_docs_maintenance.sh
|
||||
scripts/docs/install_local_cron.sh
|
||||
scripts/docs/jupyter_sync.sh
|
||||
scripts/docs/pieces_sync.sh
|
||||
scripts/docs/services_sync.sh
|
||||
|
||||
86
scripts/docs/install_local_cron.sh
Executable file
86
scripts/docs/install_local_cron.sh
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
SCHEDULE="${DOCS_CRON_SCHEDULE:-17 9 * * *}"
|
||||
DRY_RUN=0
|
||||
UNINSTALL=0
|
||||
MARK_START="# >>> microdao docs maintenance >>>"
|
||||
MARK_END="# <<< microdao docs maintenance <<<"
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage:
|
||||
bash scripts/docs/install_local_cron.sh [--schedule "17 9 * * *"] [--dry-run] [--uninstall]
|
||||
|
||||
Default schedule:
|
||||
17 9 * * * (local timezone)
|
||||
|
||||
Installs a single managed cron block that runs:
|
||||
bash scripts/docs/run_docs_maintenance.sh
|
||||
|
||||
No git push is performed by maintenance script.
|
||||
USAGE
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--schedule)
|
||||
SCHEDULE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--dry-run)
|
||||
DRY_RUN=1
|
||||
shift
|
||||
;;
|
||||
--uninstall)
|
||||
UNINSTALL=1
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown arg: $1" >&2
|
||||
usage
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if ! command -v crontab >/dev/null 2>&1; then
|
||||
echo "crontab command not found" >&2
|
||||
exit 3
|
||||
fi
|
||||
|
||||
current="$(crontab -l 2>/dev/null || true)"
|
||||
cleaned="$(printf '%s\n' "$current" | awk -v s="$MARK_START" -v e="$MARK_END" '
|
||||
BEGIN{skip=0}
|
||||
index($0,s)>0 {skip=1; next}
|
||||
index($0,e)>0 {skip=0; next}
|
||||
skip==0 {print}
|
||||
')"
|
||||
|
||||
if [[ "$UNINSTALL" -eq 1 ]]; then
|
||||
new_cron="$cleaned"
|
||||
else
|
||||
cmd="cd $ROOT_DIR && mkdir -p docs/consolidation/logs && bash scripts/docs/run_docs_maintenance.sh >> docs/consolidation/logs/cron_runner.log 2>&1"
|
||||
block="$MARK_START\n$SCHEDULE $cmd\n$MARK_END"
|
||||
if [[ -n "$cleaned" ]]; then
|
||||
new_cron="$cleaned\n$block"
|
||||
else
|
||||
new_cron="$block"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$DRY_RUN" -eq 1 ]]; then
|
||||
echo "[dry-run] resulting crontab:"
|
||||
printf '%b\n' "$new_cron"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
printf '%b\n' "$new_cron" | crontab -
|
||||
|
||||
echo "crontab updated"
|
||||
crontab -l
|
||||
62
scripts/docs/run_docs_maintenance.sh
Executable file
62
scripts/docs/run_docs_maintenance.sh
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
LOG_DIR="$ROOT_DIR/docs/consolidation/logs"
|
||||
STAMP="$(date +%Y%m%d-%H%M%S)"
|
||||
LOG_FILE="$LOG_DIR/docs_maintenance_${STAMP}.log"
|
||||
LATEST_LOG="$LOG_DIR/docs_maintenance_latest.log"
|
||||
DRY_RUN=0
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage:
|
||||
bash scripts/docs/run_docs_maintenance.sh [--dry-run]
|
||||
|
||||
Steps:
|
||||
1) services sync (--apply or --dry-run)
|
||||
2) docs lint
|
||||
|
||||
No git push is performed.
|
||||
USAGE
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--dry-run)
|
||||
DRY_RUN=1
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown arg: $1" >&2
|
||||
usage
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
{
|
||||
echo "[docs-maintenance] started: $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
|
||||
echo "[docs-maintenance] repo: $ROOT_DIR"
|
||||
if [[ "$DRY_RUN" -eq 1 ]]; then
|
||||
echo "[docs-maintenance] mode: dry-run"
|
||||
bash "$ROOT_DIR/scripts/docs/services_sync.sh" --dry-run
|
||||
else
|
||||
echo "[docs-maintenance] mode: apply"
|
||||
bash "$ROOT_DIR/scripts/docs/services_sync.sh" --apply
|
||||
fi
|
||||
|
||||
echo "[docs-maintenance] lint start"
|
||||
bash "$ROOT_DIR/scripts/docs/docs_lint.sh"
|
||||
echo "[docs-maintenance] success"
|
||||
} > "$LOG_FILE" 2>&1
|
||||
|
||||
cp "$LOG_FILE" "$LATEST_LOG"
|
||||
echo "Wrote: $LOG_FILE"
|
||||
echo "Updated: $LATEST_LOG"
|
||||
Reference in New Issue
Block a user