mirror of
https://github.com/MadsLorentzen/ai-job-search.git
synced 2026-11-02 13:12:50 +00:00
chore(guards): ignore node_modules without a trailing slash and fail on any tracked node_modules path (#627)
.gitignore's `node_modules/` rule matched directories only, so a symlink named node_modules pointing at a contributor's absolute path was committed (#623), broke `bun install` in CI with a dangling link and checked out as a text file on Windows. The rule loses its slash, and security_guards gains a check that no tracked path has a node_modules component (skipped quietly outside a git checkout). Also qualifies the one bare `seen_jobs.json` mention left in README.md after #617. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
9c802a4aa2
commit
30158c0493
5 files changed
+78
-7
No files matched your search
@@ -28,6 +28,7 @@ Stdlib only. Exit 0 on success, 1 with a failure list otherwise.
|
||||
"""
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
@@ -279,10 +280,39 @@ def check_package_manifests() -> None:
|
||||
)
|
||||
|
||||
|
||||
def check_tracked_node_modules() -> None:
|
||||
"""Fail on any tracked path with a ``node_modules`` component.
|
||||
|
||||
``.gitignore``'s old ``node_modules/`` rule matched directories only, so a
|
||||
symlink or plain file named ``node_modules`` (a contributor's local symlink
|
||||
to an absolute path, #623) was committed, broke ``bun install`` in CI with a
|
||||
dangling link, and checked out as a text file on Windows. The rule now has
|
||||
no trailing slash; this check catches what the rule cannot, such as a copy
|
||||
force-added or inherited from before the rule changed. Skipped quietly when
|
||||
the tree is not a git checkout (the guard also runs from a bare copy).
|
||||
"""
|
||||
try:
|
||||
proc = subprocess.run(
|
||||
["git", "ls-files", "-z"], cwd=ROOT, capture_output=True, check=False
|
||||
)
|
||||
except OSError:
|
||||
return
|
||||
if proc.returncode != 0:
|
||||
return
|
||||
for rel in proc.stdout.decode("utf-8", errors="replace").split("\x00"):
|
||||
if rel and "node_modules" in rel.split("/"):
|
||||
errors.append(
|
||||
f"tracked path inside node_modules: {rel!r}. Installed dependencies "
|
||||
"(or a symlink standing in for them) must never be committed: run "
|
||||
"`git rm --cached` on it; .gitignore's `node_modules` rule keeps it out."
|
||||
)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
check_permissions()
|
||||
check_gitignore()
|
||||
check_package_manifests()
|
||||
check_tracked_node_modules()
|
||||
if errors:
|
||||
print(f"security_guards: {len(errors)} failure(s)")
|
||||
for err in errors:
|
||||
@@ -290,7 +320,7 @@ def main() -> int:
|
||||
return 1
|
||||
print(
|
||||
"security_guards: OK (permissions allowlist, hooks allowlist, gitignore rules, "
|
||||
"package manifests)"
|
||||
"package manifests, no tracked node_modules)"
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
Reference in new issue
Block a user