#!/usr/bin/env bash # generate-coverage-matrix.sh — Component coverage matrix. # Shows which kernel primitives are used by which surfaces. # Flags deprecated component usage. # Usage: bash scripts/generate-coverage-matrix.sh set -euo pipefail # ── Kernel primitives (CSS class prefix : JS import name) ── declare -A PRIMITIVES=( [button]="sw-btn|Button" [input]="sw-input|sw-field|FormField" [dropdown]="sw-dropdown|Dropdown" [dialog]="sw-dialog|Dialog|confirm(" [toast]="sw-toast|toast(" [menu]="sw-menu|Menu" [tabs]="sw-tabs|Tabs" [avatar]="sw-avatar|Avatar" [spinner]="sw-spinner|Spinner" [tooltip]="sw-tooltip|Tooltip" [drawer]="sw-drawer|Drawer" [banner]="sw-banner|Banner" ) # Ordered list for consistent output PRIM_ORDER=(button input dropdown dialog toast menu tabs avatar spinner tooltip drawer banner) # ── Deprecated patterns ── DEPRECATED_PATTERNS="btn-primary|btn-small|btn-danger|btn-full|\.toast-container[^-]|popup-menu" # ── Surfaces to scan ── declare -A SURFACE_DIRS # Kernel surfaces for d in src/js/sw/surfaces/*/; do [ -d "$d" ] || continue name="$(basename "$d")" SURFACE_DIRS["kernel/$name"]="$d" done # Shell components SURFACE_DIRS["kernel/shell"]="src/js/sw/shell/" # Extension packages for d in packages/*/; do [ -d "$d" ] || continue slug="$(basename "$d")" SURFACE_DIRS["ext/$slug"]="$d" done # Sort surface names SURFACES=() while IFS= read -r s; do SURFACES+=("$s"); done < <(printf '%s\n' "${!SURFACE_DIRS[@]}" | sort) # ── Scan each surface for each primitive ── declare -A MATRIX # key="primitive:surface" value="1" or "D" (deprecated) for surface in "${SURFACES[@]}"; do dir="${SURFACE_DIRS[$surface]}" [ -d "$dir" ] || continue # Gather all JS and CSS in this surface content="" while IFS= read -r f; do content+="$(cat "$f")"$'\n' done < <(find "$dir" -type f \( -name '*.js' -o -name '*.css' \) 2>/dev/null) for prim in "${PRIM_ORDER[@]}"; do patterns="${PRIMITIVES[$prim]}" IFS='|' read -ra pats <<< "$patterns" for pat in "${pats[@]}"; do if echo "$content" | grep -qF "$pat"; then MATRIX["$prim:$surface"]="1" break fi done done # Check for deprecated patterns if echo "$content" | grep -qE "$DEPRECATED_PATTERNS"; then MATRIX["deprecated:$surface"]="1" fi done # ── Build markdown table ── echo "# Component Coverage Matrix" echo "" echo "Generated: $(date -u '+%Y-%m-%d %H:%M UTC')" echo "" # Header row header="| Primitive |" separator="|-----------|" for surface in "${SURFACES[@]}"; do short="${surface#*/}" # Remove kernel/ or ext/ prefix header+=" $short |" separator+="------|" done echo "$header" echo "$separator" # Data rows for prim in "${PRIM_ORDER[@]}"; do row="| **$prim** |" for surface in "${SURFACES[@]}"; do if [[ -n "${MATRIX["$prim:$surface"]:-}" ]]; then row+=" ✓ |" else row+=" · |" fi done echo "$row" done # Deprecated row row="| ⚠ deprecated |" has_deprecated=false for surface in "${SURFACES[@]}"; do if [[ -n "${MATRIX["deprecated:$surface"]:-}" ]]; then row+=" ⚠ |" has_deprecated=true else row+=" · |" fi done echo "$row" echo "" echo "Legend: ✓ = uses kernel primitive, · = not used, ⚠ = deprecated component detected" echo "" # ── Deprecated detail ── if $has_deprecated; then echo "## Deprecated Component Usage" echo "" for surface in "${SURFACES[@]}"; do [[ -z "${MATRIX["deprecated:$surface"]:-}" ]] && continue dir="${SURFACE_DIRS[$surface]}" echo "### $surface" grep -rnE "$DEPRECATED_PATTERNS" "$dir" --include='*.js' --include='*.css' 2>/dev/null | head -10 || true echo "" done fi # ── Summary ── total_cells=$(( ${#PRIM_ORDER[@]} * ${#SURFACES[@]} )) used=0 for prim in "${PRIM_ORDER[@]}"; do for surface in "${SURFACES[@]}"; do [[ -n "${MATRIX["$prim:$surface"]:-}" ]] && used=$((used + 1)) done done echo "---" echo "Coverage: $used / $total_cells cells ($((used * 100 / total_cells))%)" if $has_deprecated; then echo "STATUS: WARN — deprecated component usage found (see above)" else echo "STATUS: PASS — no deprecated component usage" fi