test-repo/scripts/audit-cli-coverage.sh
Matt Bruce f812643274 Complete CLI sync rule implementation
- Rule 2.5: CLI must stay in sync with Web UI
- Added audit-cli-coverage.sh template to workspace scripts
- Documented monthly audit process
- Reference implementation in gantt-board
2026-02-21 17:32:17 -06:00

151 lines
4.7 KiB
Bash
Executable File

#!/bin/bash
# CLI Coverage Audit Script
# Compares API endpoints to CLI commands to ensure sync
# Usage: ./scripts/audit-cli-coverage.sh
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
API_DIR="${PROJECT_ROOT}/src/app/api"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() { echo -e "${GREEN}${NC} $1"; }
log_warn() { echo -e "${YELLOW}${NC} $1"; }
log_error() { echo -e "${RED}${NC} $1"; }
echo "═══════════════════════════════════════════════════════════"
echo " CLI Coverage Audit"
echo "═══════════════════════════════════════════════════════════"
echo ""
# Check if API directory exists
if [ ! -d "$API_DIR" ]; then
log_error "API directory not found: $API_DIR"
exit 1
fi
# Find all API route files
echo "📁 Scanning API routes in $API_DIR..."
echo ""
# Extract API endpoints from route.ts files
declare -a API_ENDPOINTS=()
while IFS= read -r -d '' route_file; do
# Get the directory path relative to api/
rel_path=$(dirname "$route_file" | sed "s|$API_DIR/||")
# Check for HTTP methods in the file
if grep -q "export async function GET" "$route_file"; then
API_ENDPOINTS+=("GET /api/$rel_path")
fi
if grep -q "export async function POST" "$route_file"; then
API_ENDPOINTS+=("POST /api/$rel_path")
fi
if grep -q "export async function PATCH" "$route_file"; then
API_ENDPOINTS+=("PATCH /api/$rel_path")
fi
if grep -q "export async function DELETE" "$route_file"; then
API_ENDPOINTS+=("DELETE /api/$rel_path")
fi
if grep -q "export async function PUT" "$route_file"; then
API_ENDPOINTS+=("PUT /api/$rel_path")
fi
done < <(find "$API_DIR" -name "route.ts" -print0)
# Sort and dedupe API endpoints
IFS=$'\n' API_ENDPOINTS=($(sort <<< "${API_ENDPOINTS[*]}"))
unset IFS
echo "Found ${#API_ENDPOINTS[@]} API endpoint(s):"
for endpoint in "${API_ENDPOINTS[@]}"; do
echo "$endpoint"
done
echo ""
# Check CLI coverage
echo "🔍 Checking CLI coverage..."
echo ""
# Extract CLI commands from gantt.sh (or similar unified CLI)
CLI_FILE="${SCRIPT_DIR}/gantt.sh"
if [ ! -f "$CLI_FILE" ]; then
log_warn "Unified CLI not found at $CLI_FILE"
log_info "Checking for individual scripts..."
# Look for any shell scripts
CLI_SCRIPTS=($(find "$SCRIPT_DIR" -name "*.sh" -type f ! -name "audit-cli-coverage.sh" | sort))
if [ ${#CLI_SCRIPTS[@]} -eq 0 ]; then
log_error "No CLI scripts found!"
exit 1
fi
echo "Found CLI scripts:"
for script in "${CLI_SCRIPTS[@]}"; do
echo "$(basename "$script")"
done
fi
# Compare API to CLI coverage
echo ""
echo "═══════════════════════════════════════════════════════════"
echo " Coverage Report"
echo "═══════════════════════════════════════════════════════════"
echo ""
# This is project-specific - customize based on your CLI structure
# For gantt-board, we check against known CLI commands
declare -A CLI_MAP=(
["GET /api/tasks"]='task list'
["POST /api/tasks"]='task create'
["DELETE /api/tasks"]='task delete'
["POST /api/tasks/natural"]='task natural'
)
MISSING=0
COVERED=0
for endpoint in "${API_ENDPOINTS[@]}"; do
if [ -n "${CLI_MAP[$endpoint]}" ]; then
log_info "$endpoint${CLI_MAP[$endpoint]}"
((COVERED++))
else
log_error "$endpoint → NO CLI COMMAND"
((MISSING++))
fi
done
echo ""
echo "═══════════════════════════════════════════════════════════"
echo " Summary"
echo "═══════════════════════════════════════════════════════════"
echo ""
if [ $MISSING -eq 0 ]; then
log_info "All API endpoints have CLI coverage!"
echo ""
echo " Total endpoints: ${#API_ENDPOINTS[@]}"
echo " Covered: $COVERED"
echo " Missing: $MISSING"
echo ""
exit 0
else
log_error "CLI coverage incomplete!"
echo ""
echo " Total endpoints: ${#API_ENDPOINTS[@]}"
echo " Covered: $COVERED"
echo " Missing: $MISSING"
echo ""
echo "Add CLI commands for missing endpoints before committing."
echo "See Rule 2.5 in MEMORY.md for details."
echo ""
exit 1
fi