Fix style gate: file-level --exclude was cancelling every --include
The gate reported 2277 lines of findings and had become unreadable, which read as accumulated debt. It was a tooling bug. In this grep build a single file-level --exclude= silently cancels every --include= on the same command; --exclude-dir= is unaffected. Two innocuous entries, --exclude=findings.sarif and --exclude=report.md, had therefore been disabling the include filters on every check that used the EXCLUDES array. That is why a check whose flags say .py/.vue/.js/.ts was reporting .md, .ps1, .json, .gitignore and vendored DLLs: it was scanning the whole tree including build artifacts. Removes all file-level excludes and reproduces their intent with a drop_generated post-filter, adds grep -I so binaries can never be reported (there is no line to fix in a DLL), excludes bin/obj/publish/dev-bin and exports/backups, and adds the drop_scratch the shorthand loop was missing while every other check had it. Findings drop from 2277 lines to 11 with all ten checks passing. Verified with a planted canary file that the gate still catches cfg, a snake_case __tablename__ and a snake_case db.Column - a green gate immediately after a filtering change is worth distrusting until shown to still fail. Do not re-add --exclude=<file> to that array.
This commit is contained in:
@@ -34,16 +34,51 @@ EXCLUDES=(
|
||||
--exclude-dir=bundle
|
||||
--exclude-dir=dist-subpath
|
||||
--exclude-dir=.git
|
||||
# Visual Studio's local state, gitignored. CopilotSnapshots keeps a full
|
||||
# per-edit copy of touched source files, so every real finding is reported
|
||||
# again once per snapshot - hundreds of duplicates that bury the actual
|
||||
# hits and make the scan take minutes instead of seconds.
|
||||
--exclude-dir=.vs
|
||||
--exclude-dir=versions
|
||||
--exclude-dir=staticdocs
|
||||
# Local, gitignored scratch notes (see .gitignore devnotes/). Not product
|
||||
# source, never committed, and free to hold pasted logs full of em-dashes
|
||||
# and arrows - grep does not consult .gitignore, so exclude it explicitly.
|
||||
--exclude-dir=devnotes
|
||||
--exclude=findings.sarif
|
||||
--exclude=report.md
|
||||
# .NET build output. The agent projects emit vendored runtime DLLs and
|
||||
# generated *.nuget.g.props/.targets under bin/ and obj/; both are full of
|
||||
# bytes nobody here wrote. Same failure as the .vs case above: thousands of
|
||||
# hits that bury every real finding and make the gate unreadable, so it
|
||||
# stops being run at all.
|
||||
--exclude-dir=bin
|
||||
--exclude-dir=obj
|
||||
--exclude-dir=publish
|
||||
--exclude-dir=dev-bin
|
||||
# Data, not source: exported CSVs carry vendor mojibake and backups are
|
||||
# snapshots of a moment. Neither is something a convention applies to.
|
||||
--exclude-dir=exports
|
||||
--exclude-dir=backups
|
||||
)
|
||||
|
||||
# DO NOT ADD --exclude=<file> TO THE ARRAY ABOVE.
|
||||
#
|
||||
# In this grep build a single file-level --exclude silently CANCELS EVERY
|
||||
# --include filter on the same command. Bisected: with only --exclude-dir flags
|
||||
# a shorthand scan restricted to --include='*.py' returns 0 markdown hits; add
|
||||
# any one --exclude and the same scan returns 1142. Directory excludes are
|
||||
# unaffected - it is specifically the file form.
|
||||
#
|
||||
# This is not theoretical, it was live: --exclude=findings.sarif and
|
||||
# --exclude=report.md sat in this array and had been quietly disabling the
|
||||
# include lists for every check that used them. That is why the shorthand check
|
||||
# reported .md, .ps1, .cs, .json and .gitignore hits when its flags say it only
|
||||
# ever looks at .py/.vue/.js/.ts, and why the gate accumulated thousands of
|
||||
# unactionable findings that made it unreadable enough to be ignored.
|
||||
#
|
||||
# To skip a FILE, filter it out of the pipeline afterwards (see drop_scratch and
|
||||
# the post-filters on the ADR-015 check) or exclude the directory holding it.
|
||||
# Binaries are handled by grep -I on the scan itself.
|
||||
|
||||
# Root-level gitignored scratch: review writeups and chat handoffs, free to hold
|
||||
# pasted logs full of em-dashes and arrows. grep does not consult .gitignore, so
|
||||
# it has to be dropped here.
|
||||
@@ -54,6 +89,15 @@ EXCLUDES=(
|
||||
# that nothing would report. This drops only the path we mean.
|
||||
drop_scratch() { grep -v '^\./devnotes/' || true; }
|
||||
|
||||
# Generated scan output, replacing the --exclude=findings.sarif and
|
||||
# --exclude=report.md that used to live in EXCLUDES. Same intent, but as a
|
||||
# post-filter, because the flag form cancelled every --include on the command
|
||||
# (see the warning above the EXCLUDES array). Also drops .env, which is local
|
||||
# configuration rather than source.
|
||||
drop_generated() {
|
||||
grep -vP '^\./(.*/)?(findings\.sarif|report\.md|\.env):' || true
|
||||
}
|
||||
|
||||
INCLUDES_CODE=(
|
||||
--include='*.py'
|
||||
--include='*.vue'
|
||||
@@ -77,7 +121,11 @@ INCLUDES_ALL=(
|
||||
# and did, including in files this repo's own convention forbids them in.
|
||||
# Markdown, JSON and YAML are now covered too.
|
||||
echo "==> Checking for non-ASCII characters..."
|
||||
NON_ASCII=$(grep -rPn '[^\x00-\x7F]' "${EXCLUDES[@]}" "${INCLUDES_ALL[@]}" . 2>/dev/null | drop_scratch || true)
|
||||
# -I skips binary files. Without it grep reports "Binary file X matches" for any
|
||||
# archive or compiled artifact that slips past the excludes, which is noise no
|
||||
# author can act on: there is no line to fix. The excludes above are the primary
|
||||
# defence; this is the backstop for whatever they miss.
|
||||
NON_ASCII=$(grep -rPnI '[^\x00-\x7F]' "${EXCLUDES[@]}" "${INCLUDES_ALL[@]}" . 2>/dev/null | drop_scratch | drop_generated || true)
|
||||
if [ -n "$NON_ASCII" ]; then
|
||||
echo "FAIL: non-ASCII characters found (em-dashes, smart quotes, arrows, emojis):"
|
||||
echo "$NON_ASCII"
|
||||
@@ -92,6 +140,8 @@ echo "==> Checking for banned shorthand (standalone)..."
|
||||
for word in cfg ctx mgr req res; do
|
||||
HITS=$(grep -rPn "(^|[^a-zA-Z0-9_])${word}([^a-zA-Z0-9_]|\$)" "${EXCLUDES[@]}" --include='*.py' --include='*.vue' --include='*.js' --include='*.ts' . 2>/dev/null \
|
||||
| grep -vP "(^|[^a-zA-Z0-9_])(request_obj|response_obj)" \
|
||||
| drop_scratch \
|
||||
| drop_generated \
|
||||
|| true)
|
||||
if [ -n "$HITS" ]; then
|
||||
echo "FAIL: banned shorthand '$word' (standalone) found:"
|
||||
|
||||
Reference in New Issue
Block a user