mirror of
https://github.com/jhd3197/ServerKit.git
synced 2026-11-02 10:07:29 +09:00
The raw-subprocess census and the thread-ownership guard walked the filesystem under backend/app, which on a dev box also holds *installed* extension copies under app/plugins/ that git does not track. The census therefore measured 28 on dev machines but 24 on CI's clean checkout — four sites of invisible ceiling slack, a stale thread classification for the locally-installed analytics extension, and a red migration-inventory freshness test on every CI run since the range landed. Both instruments now intersect their walk with git ls-files (falling back to walking everything when git cannot answer), the analytics thread entry is removed (extension repos own their own threads), the ceiling ratchets down 28 -> 24, and the inventory is regenerated. Proving test: test_untracked_files_are_not_counted plants an untracked file with a raw call inside app/ and asserts the census does not see it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
45 lines
1.7 KiB
Python
45 lines
1.7 KiB
Python
"""Scope tree-measuring instruments to the files that ship with the repo.
|
|
|
|
The censuses and structural guards measure ``backend/app`` by walking the
|
|
filesystem — but a dev box's ``app/plugins/`` also holds *installed* extension
|
|
copies that are not tracked in git (only the builtin extensions are). A walk
|
|
that counts those measures the machine, not the product: the raw-subprocess
|
|
ceiling picked up 4 call sites from locally-installed extensions that CI's
|
|
clean checkout can never see, which is exactly the silent-slack failure mode
|
|
the ceilings exist to prevent.
|
|
|
|
``tracked_py_files()`` returns the set of git-tracked ``.py`` paths under a
|
|
root, so an instrument can skip everything else. When git is unavailable it
|
|
returns ``None`` and callers fall back to walking everything — measuring too
|
|
much is recoverable; measuring nothing is not.
|
|
"""
|
|
|
|
import os
|
|
import subprocess
|
|
|
|
|
|
def tracked_py_files(root):
|
|
"""Absolute, ``os.path.normcase``-normalised paths of git-tracked ``.py``
|
|
files under *root*, or ``None`` when git cannot answer."""
|
|
try:
|
|
proc = subprocess.run(
|
|
['git', 'ls-files', '-z', '--', '.'],
|
|
cwd=root, capture_output=True, text=True, timeout=30,
|
|
)
|
|
except (OSError, subprocess.TimeoutExpired):
|
|
return None
|
|
if proc.returncode != 0:
|
|
return None
|
|
return {
|
|
os.path.normcase(os.path.abspath(os.path.join(root, rel)))
|
|
for rel in proc.stdout.split('\0')
|
|
if rel.endswith('.py')
|
|
}
|
|
|
|
|
|
def is_tracked(path, tracked):
|
|
"""True when *path* is in *tracked*, or when there is no filter."""
|
|
if tracked is None:
|
|
return True
|
|
return os.path.normcase(os.path.abspath(path)) in tracked
|