#!/usr/bin/env bash # garden.sh — the gardening loop. # # Reports doc sprawl and files that violate the "Discourse is the system of # record for documentation; gitea .md files are stubs" policy. Run via # `make garden`. Findings are WARNINGS (advisory); fix them at a natural break. # # What it checks: # 1. Markdown sprawl: count of .md files per directory (top-10 by count). # 2. Oversized .md files (default >300 lines) that don't cite a Discourse URL # — candidates to migrate to Discourse, leaving a stub. # 3. .md files with no Discourse link at all (informational; exempt: the # operational files in EXEMPT_FILES). set -euo pipefail HERE="$(cd "$(dirname "$0")" && pwd)" # shellcheck disable=SC1091 source "$HERE/lib/common.sh" REPO_ROOT="$(repo_root)" cd "$REPO_ROOT" SIZE_LIMIT="${GARDEN_MD_LINE_LIMIT:-300}" # Operational files that legitimately live next to code, not in Discourse. EXEMPT_FILES="${GARDEN_EXEMPT:-AGENTS.md STATUS.md WORKING.md questions-v.*.md PATTERNS.md BASELINE-PROMPT.md README.md}" log_step "Gardening report for $REPO_ROOT" # --- 1. sprawl by directory ------------------------------------------------- log_info "Markdown file count by directory (top 10):" find . -path ./.git -prune -o -name '*.md' -print 2>/dev/null \ | sed 's|/[^/]*$||' | sort | uniq -c | sort -rn | head -10 | sed 's/^/ /' # --- 2. oversized .md without a Discourse link ------------------------------ log_info "Oversized .md (>${SIZE_LIMIT} lines) lacking a Discourse URL — migrate candidates:" OVERSIZED=0 while IFS= read -r -d '' f; do # skip exempt files (glob match against basename and relative path) exempt=false base=$(basename "$f") rel=${f#./} for pat in $EXEMPT_FILES; do # shellcheck disable=SC2254 # glob match is intentional case "$base" in $pat) exempt=true; break ;; esac # shellcheck disable=SC2254 case "$rel" in $pat) exempt=true; break ;; esac done [ "$exempt" = true ] && continue lines=$(wc -l < "$f" 2>/dev/null || echo 0) if [ "$lines" -gt "$SIZE_LIMIT" ]; then if ! grep -qiE 'community\.turnsys\.com|discourse' "$f" 2>/dev/null; then printf ' %-60s %s lines\n' "$f" "$lines" OVERSIZED=$((OVERSIZED + 1)) fi fi done < <(find . -path ./.git -prune -o -name '*.md' -print0 2>/dev/null) [ "$OVERSIZED" -eq 0 ] && echo " (none)" # --- 3. summary ------------------------------------------------------------- log_step "Gardening summary" echo " Oversized non-Discourse .md files: $OVERSIZED" if [ "$OVERSIZED" -eq 0 ]; then log_ok "no migration candidates" else log_warn "$OVERSIZED file(s) to migrate to Discourse" fi