| 1 | #!/usr/bin/env bash |
| 2 | # SPDX-License-Identifier: AGPL-3.0-or-later |
| 3 | # |
| 4 | # Fail when any Go source file carries `var _ = <symbol>` "silence |
| 5 | # unused import" shims. The pattern accumulated during S00–S40 |
| 6 | # refactors (audit 2026-05-08 found 3 instances; audit 2026-05-10 |
| 7 | # found 8 — the same shape kept growing because nothing failed CI |
| 8 | # on it). |
| 9 | # |
| 10 | # False positives: |
| 11 | # - Test files use `var _ = ...` interface assertions legitimately |
| 12 | # (e.g. `var _ http.Handler = (*X)(nil)`); we exclude *_test.go. |
| 13 | # - Genuine type contracts of the form `var _ TypeName = (*X)(nil)` |
| 14 | # are useful and explicitly allowed by the grep below — we only |
| 15 | # match the `var _ = SOMETHING` (no type) form, which is the |
| 16 | # shim shape. |
| 17 | # |
| 18 | # Allowlist: rare cases where a true contract assertion happens |
| 19 | # to take this exact shape. Add a path here and explain WHY in a |
| 20 | # comment if you really need an exception. |
| 21 | |
| 22 | set -euo pipefail |
| 23 | |
| 24 | ALLOWED_FILES=( |
| 25 | # (none currently) |
| 26 | ) |
| 27 | |
| 28 | cd "$(git rev-parse --show-toplevel)" |
| 29 | |
| 30 | # Match: `var _ = <ident>` at line start, possibly indented. |
| 31 | # Reject: `var _ Type = ...` (the legitimate interface-assertion form). |
| 32 | matches=$(grep -rE '^[[:space:]]*var _ = [A-Za-z]' \ |
| 33 | --include='*.go' \ |
| 34 | --exclude='*_test.go' \ |
| 35 | --exclude-dir='vendor' \ |
| 36 | --exclude-dir='.git' \ |
| 37 | internal/ cmd/ 2>/dev/null || true) |
| 38 | |
| 39 | if [ -z "$matches" ]; then |
| 40 | echo "lint-unused: ok" |
| 41 | exit 0 |
| 42 | fi |
| 43 | |
| 44 | # Strip allowlisted files. ${arr[@]:-} guards against bash 3.2's |
| 45 | # unbound-empty-array behavior under set -u (macOS default shell). |
| 46 | for allowed in "${ALLOWED_FILES[@]:-}"; do |
| 47 | [ -z "$allowed" ] && continue |
| 48 | matches=$(echo "$matches" | grep -v "^${allowed}:" || true) |
| 49 | done |
| 50 | |
| 51 | if [ -z "$matches" ]; then |
| 52 | echo "lint-unused: ok (allowlisted hits skipped)" |
| 53 | exit 0 |
| 54 | fi |
| 55 | |
| 56 | echo "lint-unused: dead-code 'silence unused import' shims found:" >&2 |
| 57 | echo >&2 |
| 58 | echo "$matches" >&2 |
| 59 | echo >&2 |
| 60 | echo "Drop the line and the import it was silencing. If the import is" >&2 |
| 61 | echo "still needed, the shim was lying — investigate the actual usage." >&2 |
| 62 | echo "If you need to keep one for a legitimate reason, allowlist it in" >&2 |
| 63 | echo "scripts/lint-unused.sh with a comment explaining why." >&2 |
| 64 | exit 1 |