2025-06-07 00:14:39 -04:00
|
|
|
#!/usr/bin/env node
|
|
|
|
|
|
|
|
|
|
// Standalone script to run govulncheck locally
|
2026-02-21 02:54:49 -05:00
|
|
|
import GovulncheckRunner from './lib/govulncheck.js';
|
|
|
|
|
import VulnerabilityParser from './lib/parser.js';
|
|
|
|
|
import AnnotationCreator from './lib/annotator.js';
|
2025-06-07 00:14:39 -04:00
|
|
|
|
|
|
|
|
// Mock core for local testing
|
|
|
|
|
const mockCore = {
|
|
|
|
|
info: (message) => console.log(`[INFO] ${message}`),
|
|
|
|
|
warning: (message, properties) => {
|
|
|
|
|
console.log(`[WARNING] ${message}`);
|
|
|
|
|
if (properties) {
|
|
|
|
|
console.log(` Annotation:`, JSON.stringify(properties, null, 2));
|
|
|
|
|
}
|
2026-02-21 02:54:49 -05:00
|
|
|
},
|
|
|
|
|
notice: (message, properties) => {
|
|
|
|
|
console.log(`[NOTICE] ${message}`);
|
|
|
|
|
if (properties) {
|
|
|
|
|
console.log(` Annotation:`, JSON.stringify(properties, null, 2));
|
|
|
|
|
}
|
|
|
|
|
},
|
2025-06-07 00:14:39 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
async function runLocal() {
|
|
|
|
|
const workingDirectory = process.argv[2] || './example';
|
|
|
|
|
console.log(`Running govulncheck in ${workingDirectory}...`);
|
2026-02-21 02:54:49 -05:00
|
|
|
|
2025-06-07 00:14:39 -04:00
|
|
|
const govulncheck = new GovulncheckRunner();
|
|
|
|
|
const parser = new VulnerabilityParser();
|
|
|
|
|
const annotator = new AnnotationCreator(mockCore);
|
2026-02-21 02:54:49 -05:00
|
|
|
|
2025-06-07 00:14:39 -04:00
|
|
|
try {
|
|
|
|
|
// Change to working directory
|
|
|
|
|
if (workingDirectory !== '.') {
|
|
|
|
|
console.log(`Changing to directory: ${workingDirectory}`);
|
|
|
|
|
process.chdir(workingDirectory);
|
|
|
|
|
}
|
2026-02-21 02:54:49 -05:00
|
|
|
|
2025-06-07 00:14:39 -04:00
|
|
|
// Install/check govulncheck
|
|
|
|
|
console.log('Checking govulncheck installation...');
|
|
|
|
|
await govulncheck.install();
|
2026-02-21 02:54:49 -05:00
|
|
|
|
2025-06-07 00:14:39 -04:00
|
|
|
// Run govulncheck
|
|
|
|
|
console.log('Running govulncheck...');
|
|
|
|
|
const { output, errorOutput } = await govulncheck.run();
|
2026-02-21 02:54:49 -05:00
|
|
|
|
2025-06-07 00:14:39 -04:00
|
|
|
if (errorOutput) {
|
|
|
|
|
console.log(`[STDERR] ${errorOutput}`);
|
|
|
|
|
}
|
2026-02-21 02:54:49 -05:00
|
|
|
|
2025-06-07 00:14:39 -04:00
|
|
|
// Show raw output length
|
|
|
|
|
console.log(`[INFO] Raw output length: ${output.length} characters`);
|
2026-02-21 02:54:49 -05:00
|
|
|
|
2025-06-07 00:14:39 -04:00
|
|
|
// Parse results
|
|
|
|
|
const vulnerabilities = parser.parse(output);
|
2026-02-21 02:54:49 -05:00
|
|
|
|
2025-06-07 00:14:39 -04:00
|
|
|
// Create annotations
|
|
|
|
|
await annotator.createAnnotations(vulnerabilities, parser, '.');
|
2026-02-21 02:54:49 -05:00
|
|
|
|
2025-06-07 00:14:39 -04:00
|
|
|
// Summary
|
|
|
|
|
console.log('\n=== SUMMARY ===');
|
|
|
|
|
console.log(`Total vulnerabilities found: ${vulnerabilities.length}`);
|
2026-02-21 02:54:49 -05:00
|
|
|
|
2025-06-07 00:14:39 -04:00
|
|
|
if (vulnerabilities.length > 0) {
|
|
|
|
|
console.log('\nVulnerabilities:');
|
|
|
|
|
vulnerabilities.forEach((v, i) => {
|
|
|
|
|
console.log(`\n${i + 1}. ${v.finding?.osv || 'Unknown'}`);
|
|
|
|
|
if (v.finding?.trace) {
|
|
|
|
|
console.log(' Trace:');
|
|
|
|
|
v.finding.trace.forEach((t, j) => {
|
2026-02-21 02:54:49 -05:00
|
|
|
console.log(
|
|
|
|
|
` ${j + 1}. ${t.module || t.package || 'unknown'} - ${
|
|
|
|
|
t.function || 'unknown function'
|
|
|
|
|
}`
|
|
|
|
|
);
|
2025-06-07 00:14:39 -04:00
|
|
|
if (t.position) {
|
|
|
|
|
console.log(` at ${t.position.filename}:${t.position.line}`);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error:', error.message);
|
|
|
|
|
process.exit(1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-21 02:54:49 -05:00
|
|
|
runLocal();
|