Skip to content

Commit 040d26d

Browse files
committed
wip
1 parent b33bd6c commit 040d26d

2 files changed

Lines changed: 52 additions & 2 deletions

File tree

dep_checker/npm_audit.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ def find_package_json_files(self) -> List[Path]:
110110
def has_package_lock(self, package_dir: Path) -> bool:
111111
return (package_dir / "package-lock.json").exists()
112112

113+
def has_node_modules(self, package_dir: Path) -> bool:
114+
return (package_dir / "node_modules").is_dir()
115+
113116

114117
def run_npm_install(self, package_dir: Path) -> bool:
115118
"""Install non-dev dependencies needed for an audit when no lockfile is present."""
@@ -366,9 +369,11 @@ def check_npm_vulnerabilities(self, vulnerability_class) -> List:
366369
logger.info(f"Processing {package_json}")
367370

368371
try:
369-
package_lock_only = self.has_package_lock(package_dir)
372+
has_package_lock = self.has_package_lock(package_dir)
373+
has_node_modules = self.has_node_modules(package_dir)
374+
package_lock_only = has_package_lock and not has_node_modules
370375

371-
if not package_lock_only and not self.run_npm_install(package_dir):
376+
if not has_node_modules and not has_package_lock and not self.run_npm_install(package_dir):
372377
logger.warning(f"Skipping npm audit for {package_dir} due to install failure")
373378
self.failed_packages.append(f"{package_dir}: npm install failed")
374379
continue

dep_checker/test_npm_audit.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,57 @@ def fake_run(cmd, **kwargs):
114114
assert ["npm", "audit", "--omit=dev", "--package-lock-only", "--json"] in calls
115115

116116

117+
def test_node_modules_skips_install_and_lockfile_only() -> None:
118+
calls = []
119+
120+
class Result:
121+
def __init__(self, returncode: int = 0, stdout: str = "", stderr: str = ""):
122+
self.returncode = returncode
123+
self.stdout = stdout
124+
self.stderr = stderr
125+
126+
def fake_run(cmd, **kwargs):
127+
calls.append(cmd)
128+
if cmd[:2] == ["npm", "audit"]:
129+
return Result(stdout='{"vulnerabilities": {}}')
130+
if cmd == ["npm", "--version"]:
131+
raise AssertionError("install should be skipped when node_modules exists")
132+
if cmd[:2] == ["npm", "install"]:
133+
raise AssertionError("install should be skipped when node_modules exists")
134+
raise AssertionError(cmd)
135+
136+
original_run = npm_audit.subprocess.run
137+
npm_audit.subprocess.run = fake_run
138+
try:
139+
with tempfile.TemporaryDirectory() as temp_dir:
140+
package_dir = Path(temp_dir) / "deps" / "pkg"
141+
write_package_json(
142+
package_dir / "package.json",
143+
{"name": "pkg", "version": "1.0.0", "dependencies": {"lodash": "4.17.0"}},
144+
)
145+
write_package_json(
146+
package_dir / "package-lock.json",
147+
{"name": "pkg", "lockfileVersion": 3},
148+
)
149+
(package_dir / "node_modules").mkdir(parents=True)
150+
151+
checker = NPMAuditChecker(Path(temp_dir), timeout=60)
152+
vulnerabilities = checker.check_npm_vulnerabilities(Vulnerability)
153+
assert vulnerabilities == [], vulnerabilities
154+
finally:
155+
npm_audit.subprocess.run = original_run
156+
157+
assert ["npm", "audit", "--omit=dev", "--json"] in calls
158+
assert ["npm", "audit", "--omit=dev", "--package-lock-only", "--json"] not in calls
159+
160+
117161
def test_npm_audit_basic() -> None:
118162
"""Test basic npm audit functionality"""
119163
print("Testing npm audit functionality...")
120164
test_find_package_json_files_skips_nested_manifests()
121165
test_npm_commands_omit_dev()
122166
test_lockfile_skips_install()
167+
test_node_modules_skips_install_and_lockfile_only()
123168

124169
with tempfile.TemporaryDirectory() as temp_dir:
125170
temp_path = Path(temp_dir)

0 commit comments

Comments
 (0)