Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ across the whole thing, honestly*.

### Added

- **Generated-marker exclusion (opt-in)** (#114, plan 0002 Phase 2): with
`CHECKUP_EXCLUDE_GENERATED=1`, files whose head carries a **banner-shaped**
generated marker (Go `// Code generated … DO NOT EDIT.`, a comment-leader
`@generated`, or C# `<auto-generated>`) are dropped from **both** the lizard
inventory and the scc keep-set — the lever that stops a codegen-heavy repo from
drowning the measurement (corvus: 39,208 → 3,569 source files) and pre-empts the
#105 lizard blow-ups. Markers are case-sensitive and anchored (not the loose
substrings a draft used), so first-party code that merely *quotes* a marker — or
owns a bare `DO NOT EDIT` (IaC, hand-written migrations) — is kept. Every drop is
**enumerated** to `raw/…​.generated` (loud, not a silent count). Default off until
field-tested; surfacing "% generated" as a headline signal is Phase 3.
- **First-party source — the scc-based engines honour the inventory** (#109,
plan 0002 Phase 1; closes #18): `codebase-stats`, stack-identity, the scc
complexity arm and tech-viability now filter + re-aggregate a single
Expand Down
40 changes: 40 additions & 0 deletions lib/source-inventory.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ INV_JSTS_RE='\.(ts|tsx|js|jsx|mjs|cjs|svelte|vue)$'
INV_NONJS_RE='\.(py|cs|java|kt|kts|go|rb|php|rs|c|cc|cpp|cxx|h|hpp|m|mm|swift|scala|lua)$' # lizard's non-JS slice (#68)
INV_LIZARD_RE='\.(ts|tsx|js|jsx|py|cs|java|kt|kts|go|rb|php|rs|c|cc|cpp|cxx|h|hpp|m|mm|swift|scala|lua)$' # everything lizard tokenises

# Generated-file markers (#114, plan 0002 Phase 2). BANNER-SHAPED + case-sensitive,
# NOT loose substrings: the spike's `@generated|DO NOT EDIT|…` (case-insensitive)
# fired on first-party code that merely *mentions* a marker (codegen tooling,
# Flow/Relay, lint configs) or owns it (IaC `# DO NOT EDIT`, hand-written
# migrations) — Morlock M1. Three anchored forms, matched as whole comment lines:
# 1. Go canonical: `// Code generated <by …>. DO NOT EDIT.` (full line)
# 2. `@generated`: only inside a comment leader at line start (//, #, *, /*, --, <!--)
# 3. C# designer: `<auto-generated>` at line start (optionally `// `-prefixed)
# Bare `DO NOT EDIT` is deliberately NOT a marker (too weak; it owns IaC/migrations).
INV_GENERATED_RE='^//[[:space:]]*Code generated .* DO NOT EDIT\.[[:space:]]*$|^[[:space:]]*(//|#|\*|/\*|--|<!--)[[:space:]]*@generated([[:space:]]|\(|$)|^[[:space:]]*(//[[:space:]]*)?<auto-generated'

# Should this path be excluded as tracked-but-noisy? `.gitignore` already drops
# generated/ignored output; this catches the COMMITTED noise it doesn't —
# vendored trees, minified bundles, migrations, snapshots — that would otherwise
Expand Down Expand Up @@ -118,6 +129,7 @@ build_source_inventory() {
-type f -print0 2>/dev/null | _filter_inventory > "$lst"
fi
_apply_gitattr_excludes "$lst" # author-declared generated/vendored (.gitattributes)
_apply_generated_excludes "$lst" # generated-file markers (#114, opt-in CHECKUP_EXCLUDE_GENERATED)
[ -n "${CHECKUP_SRC_ROOTS:-}" ] && SOURCE_SCOPE="override:$SOURCE_SCOPE"
SOURCE_LST="$lst"
SOURCE_FILE_COUNT=$(tr -cd '\0' < "$lst" | wc -c | tr -d ' ')
Expand Down Expand Up @@ -165,6 +177,33 @@ _apply_gitattr_excludes() {
return 0
}

# Drop files whose head carries a BANNER-SHAPED generated marker (#114, plan 0002
# Phase 2) — the corvus lever. OPT-IN via CHECKUP_EXCLUDE_GENERATED (default off)
# so the regex is field-tested with zero default-behaviour change before any flip
# to default-on. Rewrites the NUL list at $1 in place (order-preserving) and
# ENUMERATES the dropped files to "<lst>.generated" (loud, not a silent count —
# the guard that earns the subtractive design; over-exclusion is the danger).
# Sets GENERATED_EXCLUDED_COUNT. Runs with cwd == TARGET so the relative paths open.
_apply_generated_excludes() {
local lst="$1"
[ -n "${CHECKUP_EXCLUDE_GENERATED:-}" ] && [ -s "$lst" ] || return 0
local flagged="$lst.generated"
# grep -l short-circuits on the first match per file (the marker is at the head),
# so even a mostly-generated tree is cheap; -I skips binaries; LC_ALL=C makes the
# match byte-deterministic (#96). xargs streams the list (ARG_MAX-safe, #105).
LC_ALL=C xargs -0 grep -lIZ -E "$INV_GENERATED_RE" < "$lst" 2>/dev/null > "$flagged" || true
if [ ! -s "$flagged" ]; then rm -f "$flagged"; return 0; fi
local p out="$lst.gen"
declare -A _gen=()
while IFS= read -r -d '' p; do _gen["$p"]=1; done < "$flagged"
while IFS= read -r -d '' p; do
[ -n "${_gen[$p]:-}" ] || printf '%s\0' "$p"
done < "$lst" > "$out"
mv "$out" "$lst"
GENERATED_EXCLUDED_COUNT="${#_gen[@]}"
return 0
}

# Build the scc keep-set: VCS-tracked files (ALL extensions) minus the exclusions,
# as a JSON array at $RAW_DIR/scc-keep.json (sets SCC_KEEP_JSON). The scc-based
# engines filter their --by-file output against this (lib/scc-inventory.sh), so
Expand All @@ -183,6 +222,7 @@ build_scc_keepset() {
-type f -print0 2>/dev/null | _filter_keep > "$lst"
fi
_apply_gitattr_excludes "$lst" # author-declared generated/vendored (.gitattributes)
_apply_generated_excludes "$lst" # generated-file markers (#114, opt-in CHECKUP_EXCLUDE_GENERATED)
jq -Rs 'split("\u0000") | map(select(length > 0))' < "$lst" > "$SCC_KEEP_JSON" 2>/dev/null \
|| printf '[]' > "$SCC_KEEP_JSON"
return 0
Expand Down
32 changes: 32 additions & 0 deletions test/source-inventory.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,38 @@ else
echo " ⊘ skipped — git not installed"
fi

echo ""
echo "generated-marker exclusion: opt-in, banner-shaped, keeps marker-quoting first-party (#114)"
if command -v git > /dev/null 2>&1; then
G="$HOME/.checkup-gen.$$"; rm -rf "$G"; mkdir -p "$G/gen" "$G/src"
( cd "$G"
git init -q && git config user.email t@t && git config user.name t
printf '// Code generated by protoc-gen-go. DO NOT EDIT.\npackage x\n' > gen/api.pb.go # Go banner → drop
printf '// @generated\nexport const w=1;\n' > src/widget.js # @generated → drop
printf '// <auto-generated>\nclass M {}\n' > src/Model.cs # C# designer → drop
printf '// normal hand-written\nexport const a=1;\n' > src/app.js # keep
printf '// This documents the @generated convention\npackage y\n' > src/notes.go # prose → keep
printf '# DO NOT EDIT - managed by our own tool\nx=1\n' > src/migrate.py # bare DO NOT EDIT → keep
git add -A && git commit -qm init >/dev/null 2>&1 )
# Opt-in OFF (default): nothing dropped on markers.
off=$( cd "$G"; GIT_OK=true; RAW_DIR="$G/raw"; SCAN_ROOTS=(.); build_source_inventory; tr '\0' '\n' < "$SOURCE_LST" | sort | paste -sd',' - )
assert_eq "default (opt-in off) keeps everything" \
"gen/api.pb.go,src/Model.cs,src/app.js,src/migrate.py,src/notes.go,src/widget.js" "$off"
# Opt-in ON: the three banner-shaped generated files drop; the marker-quoting
# first-party files (prose, bare DO NOT EDIT) are kept (Morlock M1).
on=$( cd "$G"; GIT_OK=true; RAW_DIR="$G/raw"; SCAN_ROOTS=(.); CHECKUP_EXCLUDE_GENERATED=1; build_source_inventory
tr '\0' '\n' < "$SOURCE_LST" | sort | paste -sd',' - )
assert_eq "opt-in drops banner-shaped generated, keeps marker-quoting first-party" \
"src/app.js,src/migrate.py,src/notes.go" "$on"
cnt=$( cd "$G"; GIT_OK=true; RAW_DIR="$G/raw"; SCAN_ROOTS=(.); CHECKUP_EXCLUDE_GENERATED=1; build_source_inventory; printf '%s' "$GENERATED_EXCLUDED_COUNT" )
assert_eq "GENERATED_EXCLUDED_COUNT set" "3" "$cnt"
enum=$( cd "$G"; GIT_OK=true; RAW_DIR="$G/raw"; SCAN_ROOTS=(.); CHECKUP_EXCLUDE_GENERATED=1; build_source_inventory; tr '\0' '\n' < "$RAW_DIR/source-files.lst.generated" | sort | paste -sd',' - )
assert_eq "drops enumerated (loud, not silent)" "gen/api.pb.go,src/Model.cs,src/widget.js" "$enum"
rm -rf "$G"
else
echo " ⊘ skipped — git not installed"
fi

echo ""
echo "coverage helpers: by-area grouping and exclusion-source label"
SOURCE_LST="$TMP/cov.lst"
Expand Down