Skip to content

Commit dbe5272

Browse files
authored
Merge pull request #340 from Homebrew/audit-scanner-failures
pip-audit-bulk: fail when any scan is incomplete
2 parents fae3142 + 2ee4807 commit dbe5272

1 file changed

Lines changed: 20 additions & 4 deletions

File tree

‎pip-audit-bulk‎

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ assert shutil.which("osv-scanner"), "missing osv-scanner"
4949

5050
def _audit_formula(formula, requirements):
5151
# osv-scanner wants a requirements.txt file, so we make a temporary one.
52+
# These are pinned formula resources, including packaged transitive dependencies.
53+
# Resolving additional dependencies would scan packages outside that inventory.
5254
with NamedTemporaryFile(mode="w") as req_file:
5355
req_file.write("\n".join(requirements))
5456
req_file.flush()
@@ -58,6 +60,7 @@ def _audit_formula(formula, requirements):
5860
"osv-scanner",
5961
"--lockfile",
6062
f"requirements.txt:{req_file.name}",
63+
"--no-resolve",
6164
"--format=json",
6265
"--config=osv-scanner-config.toml",
6366
],
@@ -78,10 +81,14 @@ with concurrent.futures.ThreadPoolExecutor(max_workers=_JOBS) as pool:
7881
formula, result = fut.result()
7982
prefix = f"[{n_complete:>{width}}/{n_total}]"
8083

81-
# If we don't see anything on stdout, osv-scanner probably failed.
82-
# Log it as an error.
83-
if not result.stdout:
84-
print(f"\t{prefix} >:( osv-scanner failed: {result.stderr}", file=sys.stderr)
84+
# osv-scanner exits 0 for a clean scan and 1 when it finds vulnerabilities.
85+
# Other exits or missing output mean we do not have a complete scan.
86+
if result.returncode not in (0, 1) or not result.stdout:
87+
print(
88+
f"\t{prefix} >:( osv-scanner failed for {formula} "
89+
f"(exit {result.returncode}): {result.stderr}",
90+
file=sys.stderr,
91+
)
8592
audits["failures"].append(formula)
8693
continue
8794

@@ -123,6 +130,15 @@ for (dep, vuln), formulas in sorted(_SUMMARY_RESULTS.items()):
123130
formulas_rendered = ", ".join(f"`{f}`" for f in formulas)
124131
render += f"| `{dep}` | [`{vuln}`](https://osv.dev/vulnerability/{vuln}) | {formulas_rendered} |\n"
125132

133+
if audits["failures"]:
134+
failures_rendered = "\n".join(f"- `{f}`" for f in sorted(audits["failures"]))
135+
failure_message = f"Audit incomplete: failed to scan {len(audits['failures'])} of {n_total} formulae."
136+
render = f"## Audit incomplete\n\n{failure_message}\n\n{failures_rendered}\n\n{render}"
137+
126138
if _SUMMARY:
127139
with _SUMMARY.open(mode="a") as io:
128140
print(render, file=io)
141+
142+
if audits["failures"]:
143+
print(failure_message, file=sys.stderr)
144+
sys.exit(1)

0 commit comments

Comments
 (0)