@vyuhlabs/dxkit 1.5.1 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +297 -0
- package/README.md +265 -352
- package/THIRD_PARTY_NOTICES.md +40 -0
- package/dist/analyzers/developer/detailed.d.ts +26 -0
- package/dist/analyzers/developer/detailed.d.ts.map +1 -0
- package/dist/analyzers/developer/detailed.js +193 -0
- package/dist/analyzers/developer/detailed.js.map +1 -0
- package/dist/analyzers/developer/gather.d.ts +11 -0
- package/dist/analyzers/developer/gather.d.ts.map +1 -0
- package/dist/analyzers/developer/gather.js +167 -0
- package/dist/analyzers/developer/gather.js.map +1 -0
- package/dist/analyzers/developer/index.d.ts +8 -0
- package/dist/analyzers/developer/index.d.ts.map +1 -0
- package/dist/analyzers/developer/index.js +168 -0
- package/dist/analyzers/developer/index.js.map +1 -0
- package/dist/analyzers/developer/types.d.ts +49 -0
- package/dist/analyzers/developer/types.d.ts.map +1 -0
- package/dist/analyzers/developer/types.js +6 -0
- package/dist/analyzers/developer/types.js.map +1 -0
- package/dist/analyzers/docs/shallow.d.ts +9 -0
- package/dist/analyzers/docs/shallow.d.ts.map +1 -0
- package/dist/analyzers/docs/shallow.js +8 -0
- package/dist/analyzers/docs/shallow.js.map +1 -0
- package/dist/analyzers/dx/shallow.d.ts +9 -0
- package/dist/analyzers/dx/shallow.d.ts.map +1 -0
- package/dist/analyzers/dx/shallow.js +8 -0
- package/dist/analyzers/dx/shallow.js.map +1 -0
- package/dist/analyzers/evidence.d.ts +36 -0
- package/dist/analyzers/evidence.d.ts.map +1 -0
- package/dist/analyzers/evidence.js +3 -0
- package/dist/analyzers/evidence.js.map +1 -0
- package/dist/analyzers/health/actions.d.ts +10 -0
- package/dist/analyzers/health/actions.d.ts.map +1 -0
- package/dist/analyzers/health/actions.js +284 -0
- package/dist/analyzers/health/actions.js.map +1 -0
- package/dist/analyzers/health/detailed.d.ts +26 -0
- package/dist/analyzers/health/detailed.d.ts.map +1 -0
- package/dist/analyzers/health/detailed.js +147 -0
- package/dist/analyzers/health/detailed.js.map +1 -0
- package/dist/analyzers/health.d.ts +22 -0
- package/dist/analyzers/health.d.ts.map +1 -0
- package/dist/analyzers/health.js +270 -0
- package/dist/analyzers/health.js.map +1 -0
- package/dist/analyzers/index.d.ts +3 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +6 -0
- package/dist/analyzers/index.js.map +1 -0
- package/dist/analyzers/maintainability/shallow.d.ts +9 -0
- package/dist/analyzers/maintainability/shallow.d.ts.map +1 -0
- package/dist/analyzers/maintainability/shallow.js +8 -0
- package/dist/analyzers/maintainability/shallow.js.map +1 -0
- package/dist/analyzers/quality/actions.d.ts +5 -0
- package/dist/analyzers/quality/actions.d.ts.map +1 -0
- package/dist/analyzers/quality/actions.js +158 -0
- package/dist/analyzers/quality/actions.js.map +1 -0
- package/dist/analyzers/quality/detailed.d.ts +17 -0
- package/dist/analyzers/quality/detailed.d.ts.map +1 -0
- package/dist/analyzers/quality/detailed.js +122 -0
- package/dist/analyzers/quality/detailed.js.map +1 -0
- package/dist/analyzers/quality/gather.d.ts +38 -0
- package/dist/analyzers/quality/gather.d.ts.map +1 -0
- package/dist/analyzers/quality/gather.js +279 -0
- package/dist/analyzers/quality/gather.js.map +1 -0
- package/dist/analyzers/quality/index.d.ts +12 -0
- package/dist/analyzers/quality/index.d.ts.map +1 -0
- package/dist/analyzers/quality/index.js +281 -0
- package/dist/analyzers/quality/index.js.map +1 -0
- package/dist/analyzers/quality/shallow.d.ts +9 -0
- package/dist/analyzers/quality/shallow.d.ts.map +1 -0
- package/dist/analyzers/quality/shallow.js +8 -0
- package/dist/analyzers/quality/shallow.js.map +1 -0
- package/dist/analyzers/quality/types.d.ts +66 -0
- package/dist/analyzers/quality/types.d.ts.map +1 -0
- package/dist/analyzers/quality/types.js +3 -0
- package/dist/analyzers/quality/types.js.map +1 -0
- package/dist/analyzers/remediation.d.ts +42 -0
- package/dist/analyzers/remediation.d.ts.map +1 -0
- package/dist/analyzers/remediation.js +28 -0
- package/dist/analyzers/remediation.js.map +1 -0
- package/dist/analyzers/scoring.d.ts +32 -0
- package/dist/analyzers/scoring.d.ts.map +1 -0
- package/dist/analyzers/scoring.js +410 -0
- package/dist/analyzers/scoring.js.map +1 -0
- package/dist/analyzers/security/actions.d.ts +7 -0
- package/dist/analyzers/security/actions.d.ts.map +1 -0
- package/dist/analyzers/security/actions.js +104 -0
- package/dist/analyzers/security/actions.js.map +1 -0
- package/dist/analyzers/security/detailed.d.ts +14 -0
- package/dist/analyzers/security/detailed.d.ts.map +1 -0
- package/dist/analyzers/security/detailed.js +124 -0
- package/dist/analyzers/security/detailed.js.map +1 -0
- package/dist/analyzers/security/gather.d.ts +12 -0
- package/dist/analyzers/security/gather.d.ts.map +1 -0
- package/dist/analyzers/security/gather.js +195 -0
- package/dist/analyzers/security/gather.js.map +1 -0
- package/dist/analyzers/security/index.d.ts +8 -0
- package/dist/analyzers/security/index.d.ts.map +1 -0
- package/dist/analyzers/security/index.js +178 -0
- package/dist/analyzers/security/index.js.map +1 -0
- package/dist/analyzers/security/scoring.d.ts +29 -0
- package/dist/analyzers/security/scoring.d.ts.map +1 -0
- package/dist/analyzers/security/scoring.js +40 -0
- package/dist/analyzers/security/scoring.js.map +1 -0
- package/dist/analyzers/security/shallow.d.ts +10 -0
- package/dist/analyzers/security/shallow.d.ts.map +1 -0
- package/dist/analyzers/security/shallow.js +8 -0
- package/dist/analyzers/security/shallow.js.map +1 -0
- package/dist/analyzers/security/types.d.ts +43 -0
- package/dist/analyzers/security/types.d.ts.map +1 -0
- package/dist/analyzers/security/types.js +6 -0
- package/dist/analyzers/security/types.js.map +1 -0
- package/dist/analyzers/tests/actions.d.ts +6 -0
- package/dist/analyzers/tests/actions.d.ts.map +1 -0
- package/dist/analyzers/tests/actions.js +80 -0
- package/dist/analyzers/tests/actions.js.map +1 -0
- package/dist/analyzers/tests/detailed.d.ts +14 -0
- package/dist/analyzers/tests/detailed.d.ts.map +1 -0
- package/dist/analyzers/tests/detailed.js +121 -0
- package/dist/analyzers/tests/detailed.js.map +1 -0
- package/dist/analyzers/tests/gather.d.ts +5 -0
- package/dist/analyzers/tests/gather.d.ts.map +1 -0
- package/dist/analyzers/tests/gather.js +270 -0
- package/dist/analyzers/tests/gather.js.map +1 -0
- package/dist/analyzers/tests/import-graph.d.ts +48 -0
- package/dist/analyzers/tests/import-graph.d.ts.map +1 -0
- package/dist/analyzers/tests/import-graph.js +231 -0
- package/dist/analyzers/tests/import-graph.js.map +1 -0
- package/dist/analyzers/tests/index.d.ts +8 -0
- package/dist/analyzers/tests/index.d.ts.map +1 -0
- package/dist/analyzers/tests/index.js +247 -0
- package/dist/analyzers/tests/index.js.map +1 -0
- package/dist/analyzers/tests/scoring.d.ts +27 -0
- package/dist/analyzers/tests/scoring.d.ts.map +1 -0
- package/dist/analyzers/tests/scoring.js +38 -0
- package/dist/analyzers/tests/scoring.js.map +1 -0
- package/dist/analyzers/tests/shallow.d.ts +9 -0
- package/dist/analyzers/tests/shallow.d.ts.map +1 -0
- package/dist/analyzers/tests/shallow.js +8 -0
- package/dist/analyzers/tests/shallow.js.map +1 -0
- package/dist/analyzers/tests/types.d.ts +49 -0
- package/dist/analyzers/tests/types.d.ts.map +1 -0
- package/dist/analyzers/tests/types.js +6 -0
- package/dist/analyzers/tests/types.js.map +1 -0
- package/dist/analyzers/tools/cloc.d.ts +8 -0
- package/dist/analyzers/tools/cloc.d.ts.map +1 -0
- package/dist/analyzers/tools/cloc.js +49 -0
- package/dist/analyzers/tools/cloc.js.map +1 -0
- package/dist/analyzers/tools/coverage.d.ts +59 -0
- package/dist/analyzers/tools/coverage.d.ts.map +1 -0
- package/dist/analyzers/tools/coverage.js +280 -0
- package/dist/analyzers/tools/coverage.js.map +1 -0
- package/dist/analyzers/tools/cvss-v4-lookup.d.ts +10 -0
- package/dist/analyzers/tools/cvss-v4-lookup.d.ts.map +1 -0
- package/dist/analyzers/tools/cvss-v4-lookup.js +284 -0
- package/dist/analyzers/tools/cvss-v4-lookup.js.map +1 -0
- package/dist/analyzers/tools/cvss-v4.d.ts +24 -0
- package/dist/analyzers/tools/cvss-v4.d.ts.map +1 -0
- package/dist/analyzers/tools/cvss-v4.js +362 -0
- package/dist/analyzers/tools/cvss-v4.js.map +1 -0
- package/dist/analyzers/tools/default-exclusions.gitignore +56 -0
- package/dist/analyzers/tools/exclusions.d.ts +70 -0
- package/dist/analyzers/tools/exclusions.d.ts.map +1 -0
- package/dist/analyzers/tools/exclusions.js +250 -0
- package/dist/analyzers/tools/exclusions.js.map +1 -0
- package/dist/analyzers/tools/generic.d.ts +4 -0
- package/dist/analyzers/tools/generic.d.ts.map +1 -0
- package/dist/analyzers/tools/generic.js +198 -0
- package/dist/analyzers/tools/generic.js.map +1 -0
- package/dist/analyzers/tools/gitleaks.d.ts +8 -0
- package/dist/analyzers/tools/gitleaks.d.ts.map +1 -0
- package/dist/analyzers/tools/gitleaks.js +58 -0
- package/dist/analyzers/tools/gitleaks.js.map +1 -0
- package/dist/analyzers/tools/graphify.d.ts +4 -0
- package/dist/analyzers/tools/graphify.d.ts.map +1 -0
- package/dist/analyzers/tools/graphify.js +222 -0
- package/dist/analyzers/tools/graphify.js.map +1 -0
- package/dist/analyzers/tools/osv.d.ts +51 -0
- package/dist/analyzers/tools/osv.d.ts.map +1 -0
- package/dist/analyzers/tools/osv.js +188 -0
- package/dist/analyzers/tools/osv.js.map +1 -0
- package/dist/analyzers/tools/parallel.d.ts +8 -0
- package/dist/analyzers/tools/parallel.d.ts.map +1 -0
- package/dist/analyzers/tools/parallel.js +195 -0
- package/dist/analyzers/tools/parallel.js.map +1 -0
- package/dist/analyzers/tools/runner.d.ts +13 -0
- package/dist/analyzers/tools/runner.d.ts.map +1 -0
- package/dist/analyzers/tools/runner.js +109 -0
- package/dist/analyzers/tools/runner.js.map +1 -0
- package/dist/analyzers/tools/suppressions.d.ts +55 -0
- package/dist/analyzers/tools/suppressions.d.ts.map +1 -0
- package/dist/analyzers/tools/suppressions.js +203 -0
- package/dist/analyzers/tools/suppressions.js.map +1 -0
- package/dist/analyzers/tools/timing.d.ts +9 -0
- package/dist/analyzers/tools/timing.d.ts.map +1 -0
- package/dist/analyzers/tools/timing.js +29 -0
- package/dist/analyzers/tools/timing.js.map +1 -0
- package/dist/analyzers/tools/tool-registry.d.ts +86 -0
- package/dist/analyzers/tools/tool-registry.d.ts.map +1 -0
- package/dist/analyzers/tools/tool-registry.js +705 -0
- package/dist/analyzers/tools/tool-registry.js.map +1 -0
- package/dist/analyzers/types.d.ts +125 -0
- package/dist/analyzers/types.d.ts.map +1 -0
- package/dist/analyzers/types.js +11 -0
- package/dist/analyzers/types.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +413 -0
- package/dist/cli.js.map +1 -1
- package/dist/detect.d.ts.map +1 -1
- package/dist/detect.js +24 -15
- package/dist/detect.js.map +1 -1
- package/dist/languages/csharp.d.ts +5 -0
- package/dist/languages/csharp.d.ts.map +1 -0
- package/dist/languages/csharp.js +265 -0
- package/dist/languages/csharp.js.map +1 -0
- package/dist/languages/go.d.ts +11 -0
- package/dist/languages/go.d.ts.map +1 -0
- package/dist/languages/go.js +321 -0
- package/dist/languages/go.js.map +1 -0
- package/dist/languages/index.d.ts +6 -0
- package/dist/languages/index.d.ts.map +1 -0
- package/dist/languages/index.js +18 -0
- package/dist/languages/index.js.map +1 -0
- package/dist/languages/python.d.ts +3 -0
- package/dist/languages/python.d.ts.map +1 -0
- package/dist/languages/python.js +284 -0
- package/dist/languages/python.js.map +1 -0
- package/dist/languages/rust.d.ts +17 -0
- package/dist/languages/rust.d.ts.map +1 -0
- package/dist/languages/rust.js +333 -0
- package/dist/languages/rust.js.map +1 -0
- package/dist/languages/types.d.ts +38 -0
- package/dist/languages/types.d.ts.map +1 -0
- package/dist/languages/types.js +3 -0
- package/dist/languages/types.js.map +1 -0
- package/dist/languages/typescript.d.ts +15 -0
- package/dist/languages/typescript.d.ts.map +1 -0
- package/dist/languages/typescript.js +353 -0
- package/dist/languages/typescript.js.map +1 -0
- package/dist/logger.d.ts +1 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +25 -12
- package/dist/logger.js.map +1 -1
- package/dist/project-yaml.d.ts.map +1 -1
- package/dist/project-yaml.js +1 -0
- package/dist/project-yaml.js.map +1 -1
- package/dist/tools-cli.d.ts +2 -0
- package/dist/tools-cli.d.ts.map +1 -0
- package/dist/tools-cli.js +231 -0
- package/dist/tools-cli.js.map +1 -0
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -2
- package/templates/.claude/commands/dev-report.md +34 -4
- package/templates/.claude/commands/health.md +45 -2
- package/templates/.claude/commands/quality.md.template +38 -15
- package/templates/.claude/commands/test-gaps.md +36 -2
- package/templates/.claude/commands/vulnerabilities.md +36 -2
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.go = void 0;
|
|
37
|
+
exports.mapGolangciLinterSeverity = mapGolangciLinterSeverity;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const coverage_1 = require("../analyzers/tools/coverage");
|
|
41
|
+
const osv_1 = require("../analyzers/tools/osv");
|
|
42
|
+
const runner_1 = require("../analyzers/tools/runner");
|
|
43
|
+
const tool_registry_1 = require("../analyzers/tools/tool-registry");
|
|
44
|
+
/**
|
|
45
|
+
* Tier a golangci-lint finding by the linter that produced it.
|
|
46
|
+
*
|
|
47
|
+
* golangci-lint bundles ~60 linters with different character. The
|
|
48
|
+
* `FromLinter` field identifies which one fired. `Severity` (often empty)
|
|
49
|
+
* is used only as a fallback floor for unknown linters.
|
|
50
|
+
*/
|
|
51
|
+
function mapGolangciLinterSeverity(linter) {
|
|
52
|
+
if (!linter)
|
|
53
|
+
return 'low';
|
|
54
|
+
// Security — gosec exclusively flags vuln patterns.
|
|
55
|
+
if (linter === 'gosec')
|
|
56
|
+
return 'critical';
|
|
57
|
+
// Correctness bugs — go vet, staticcheck analyses, type errors, etc.
|
|
58
|
+
if (linter === 'govet' ||
|
|
59
|
+
linter === 'staticcheck' ||
|
|
60
|
+
linter === 'typecheck' ||
|
|
61
|
+
linter === 'errorlint' ||
|
|
62
|
+
linter === 'ineffassign' ||
|
|
63
|
+
linter === 'unused' ||
|
|
64
|
+
linter === 'nilerr' ||
|
|
65
|
+
linter === 'bodyclose' ||
|
|
66
|
+
linter === 'rowserrcheck' ||
|
|
67
|
+
linter === 'sqlclosecheck' ||
|
|
68
|
+
linter === 'noctx') {
|
|
69
|
+
return 'high';
|
|
70
|
+
}
|
|
71
|
+
// Best practices / maintenance
|
|
72
|
+
if (linter === 'errcheck' ||
|
|
73
|
+
linter === 'gocritic' ||
|
|
74
|
+
linter === 'revive' ||
|
|
75
|
+
linter === 'goconst' ||
|
|
76
|
+
linter === 'gocyclo' ||
|
|
77
|
+
linter === 'funlen' ||
|
|
78
|
+
linter === 'dupl' ||
|
|
79
|
+
linter === 'gosimple' ||
|
|
80
|
+
linter === 'unconvert' ||
|
|
81
|
+
linter === 'unparam' ||
|
|
82
|
+
linter === 'prealloc' ||
|
|
83
|
+
linter === 'gocognit') {
|
|
84
|
+
return 'medium';
|
|
85
|
+
}
|
|
86
|
+
// Style / formatting
|
|
87
|
+
if (linter === 'gofmt' ||
|
|
88
|
+
linter === 'gofumpt' ||
|
|
89
|
+
linter === 'goimports' ||
|
|
90
|
+
linter === 'stylecheck' ||
|
|
91
|
+
linter === 'whitespace' ||
|
|
92
|
+
linter === 'misspell' ||
|
|
93
|
+
linter === 'godot' ||
|
|
94
|
+
linter === 'lll') {
|
|
95
|
+
return 'low';
|
|
96
|
+
}
|
|
97
|
+
return 'low';
|
|
98
|
+
}
|
|
99
|
+
function tierGolangciIssue(issue) {
|
|
100
|
+
const byLinter = mapGolangciLinterSeverity(issue.FromLinter);
|
|
101
|
+
// For unknown linters we fell through to 'low' — but golangci-lint's
|
|
102
|
+
// own Severity field may say otherwise. Use it as a floor.
|
|
103
|
+
if (byLinter === 'low' && issue.FromLinter) {
|
|
104
|
+
const sev = (issue.Severity || '').toLowerCase();
|
|
105
|
+
if (sev === 'error')
|
|
106
|
+
return 'high';
|
|
107
|
+
if (sev === 'warning')
|
|
108
|
+
return 'medium';
|
|
109
|
+
}
|
|
110
|
+
return byLinter;
|
|
111
|
+
}
|
|
112
|
+
exports.go = {
|
|
113
|
+
id: 'go',
|
|
114
|
+
displayName: 'Go',
|
|
115
|
+
sourceExtensions: ['.go'],
|
|
116
|
+
testFilePatterns: ['*_test.go'],
|
|
117
|
+
extraExcludes: ['vendor'],
|
|
118
|
+
detect(cwd) {
|
|
119
|
+
return (0, runner_1.fileExists)(cwd, 'go.mod');
|
|
120
|
+
},
|
|
121
|
+
tools: ['golangci-lint', 'govulncheck'],
|
|
122
|
+
semgrepRulesets: ['p/gosec'],
|
|
123
|
+
mapLintSeverity: mapGolangciLinterSeverity,
|
|
124
|
+
parseCoverage(cwd) {
|
|
125
|
+
for (const file of ['coverage.out', 'cover.out']) {
|
|
126
|
+
const abs = path.join(cwd, file);
|
|
127
|
+
let raw;
|
|
128
|
+
try {
|
|
129
|
+
raw = fs.readFileSync(abs, 'utf-8');
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
return (0, coverage_1.parseGoCoverProfile)(raw, file, cwd);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
},
|
|
143
|
+
extractImports(content) {
|
|
144
|
+
const out = [];
|
|
145
|
+
// Single-line: `import "fmt"` or `import foo "pkg/name"`
|
|
146
|
+
const singleRe = /^\s*import\s+(?:[a-zA-Z_]\w*\s+)?"([^"]+)"/gm;
|
|
147
|
+
let m;
|
|
148
|
+
while ((m = singleRe.exec(content)) !== null) {
|
|
149
|
+
out.push(m[1]);
|
|
150
|
+
}
|
|
151
|
+
// Multi-line: `import (\n "fmt"\n alias "pkg"\n)`
|
|
152
|
+
const blockRe = /import\s*\(([\s\S]*?)\)/g;
|
|
153
|
+
while ((m = blockRe.exec(content)) !== null) {
|
|
154
|
+
const block = m[1];
|
|
155
|
+
const lineRe = /(?:[a-zA-Z_]\w*\s+)?"([^"]+)"/g;
|
|
156
|
+
let lm;
|
|
157
|
+
while ((lm = lineRe.exec(block)) !== null) {
|
|
158
|
+
if (!out.includes(lm[1])) {
|
|
159
|
+
out.push(lm[1]);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return out;
|
|
164
|
+
},
|
|
165
|
+
resolveImport(fromFile, spec, cwd) {
|
|
166
|
+
// Go import paths are module-based, not file-relative.
|
|
167
|
+
// Internal packages resolve as <module>/internal/... → cwd/internal/...
|
|
168
|
+
let goMod;
|
|
169
|
+
try {
|
|
170
|
+
goMod = fs.readFileSync(path.join(cwd, 'go.mod'), 'utf-8');
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
const moduleMatch = goMod.match(/^module\s+(\S+)/m);
|
|
176
|
+
if (!moduleMatch)
|
|
177
|
+
return null;
|
|
178
|
+
const modulePath = moduleMatch[1];
|
|
179
|
+
if (!spec.startsWith(modulePath + '/'))
|
|
180
|
+
return null;
|
|
181
|
+
const rel = spec.slice(modulePath.length + 1);
|
|
182
|
+
const dir = path.join(cwd, rel);
|
|
183
|
+
try {
|
|
184
|
+
if (fs.statSync(dir).isDirectory()) {
|
|
185
|
+
return rel;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
// not found
|
|
190
|
+
}
|
|
191
|
+
return null;
|
|
192
|
+
},
|
|
193
|
+
async gatherMetrics(cwd) {
|
|
194
|
+
const metrics = {
|
|
195
|
+
toolsUsed: [],
|
|
196
|
+
toolsUnavailable: [],
|
|
197
|
+
};
|
|
198
|
+
const lint = (0, tool_registry_1.findTool)(tool_registry_1.TOOL_DEFS['golangci-lint'], cwd);
|
|
199
|
+
if (lint.available && lint.path) {
|
|
200
|
+
const raw = (0, runner_1.run)(`${lint.path} run --out-format json ./... 2>/dev/null`, cwd, 120000);
|
|
201
|
+
if (raw) {
|
|
202
|
+
try {
|
|
203
|
+
const data = JSON.parse(raw);
|
|
204
|
+
const issues = data.Issues || [];
|
|
205
|
+
// Tier each issue by its FromLinter, then collapse:
|
|
206
|
+
// critical + high → errors, medium + low → warnings.
|
|
207
|
+
let errors = 0;
|
|
208
|
+
let warnings = 0;
|
|
209
|
+
for (const issue of issues) {
|
|
210
|
+
const tier = tierGolangciIssue(issue);
|
|
211
|
+
if (tier === 'critical' || tier === 'high')
|
|
212
|
+
errors++;
|
|
213
|
+
else
|
|
214
|
+
warnings++;
|
|
215
|
+
}
|
|
216
|
+
metrics.lintErrors = errors;
|
|
217
|
+
metrics.lintWarnings = warnings;
|
|
218
|
+
metrics.lintTool = 'golangci-lint';
|
|
219
|
+
metrics.toolsUsed.push('golangci-lint');
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
metrics.toolsUnavailable.push('golangci-lint (parse error)');
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
metrics.lintErrors = 0;
|
|
227
|
+
metrics.lintWarnings = 0;
|
|
228
|
+
metrics.lintTool = 'golangci-lint';
|
|
229
|
+
metrics.toolsUsed.push('golangci-lint');
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
metrics.toolsUnavailable.push('golangci-lint');
|
|
234
|
+
}
|
|
235
|
+
const vuln = (0, tool_registry_1.findTool)(tool_registry_1.TOOL_DEFS.govulncheck, cwd);
|
|
236
|
+
if (vuln.available && vuln.path) {
|
|
237
|
+
const raw = (0, runner_1.run)(`${vuln.path} -json ./... 2>/dev/null`, cwd, 120000);
|
|
238
|
+
if (raw) {
|
|
239
|
+
try {
|
|
240
|
+
// govulncheck emits ndjson with three relevant shapes:
|
|
241
|
+
// { "osv": { ...full OSV record... } } — the advisory detail
|
|
242
|
+
// { "finding": { "osv": "GO-YYYY-NNNN", "trace": [...] } } — a call-site hit
|
|
243
|
+
// { "config": ... } / { "progress": ... } — ignored
|
|
244
|
+
const findingIds = new Set();
|
|
245
|
+
const embeddedOsv = new Map();
|
|
246
|
+
for (const line of raw.split('\n')) {
|
|
247
|
+
if (!line.trim())
|
|
248
|
+
continue;
|
|
249
|
+
try {
|
|
250
|
+
const obj = JSON.parse(line);
|
|
251
|
+
if (obj.finding?.osv)
|
|
252
|
+
findingIds.add(obj.finding.osv);
|
|
253
|
+
if (obj.osv?.id)
|
|
254
|
+
embeddedOsv.set(obj.osv.id, obj.osv);
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
/* skip non-JSON lines */
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
// Prefer severity from the embedded OSV record (already in the
|
|
261
|
+
// govulncheck output, no extra API call). Fall back to an OSV.dev
|
|
262
|
+
// lookup for IDs without embedded data. Fall back to 'high' (the
|
|
263
|
+
// legacy govulncheck default) for anything still unknown.
|
|
264
|
+
const ids = [...findingIds];
|
|
265
|
+
const needsLookup = ids.filter((id) => {
|
|
266
|
+
const rec = embeddedOsv.get(id);
|
|
267
|
+
if (!rec)
|
|
268
|
+
return true;
|
|
269
|
+
return (0, osv_1.classifyOsvSeverity)(rec) === 'unknown';
|
|
270
|
+
});
|
|
271
|
+
const lookedUp = needsLookup.length > 0 ? await (0, osv_1.enrichSeverities)(needsLookup) : new Map();
|
|
272
|
+
let critical = 0;
|
|
273
|
+
let high = 0;
|
|
274
|
+
let medium = 0;
|
|
275
|
+
let low = 0;
|
|
276
|
+
let enrichedCount = 0;
|
|
277
|
+
for (const id of ids) {
|
|
278
|
+
const rec = embeddedOsv.get(id);
|
|
279
|
+
let sev = rec ? (0, osv_1.classifyOsvSeverity)(rec) : 'unknown';
|
|
280
|
+
if (sev === 'unknown')
|
|
281
|
+
sev = lookedUp.get(id) ?? 'unknown';
|
|
282
|
+
if (sev !== 'unknown') {
|
|
283
|
+
enrichedCount++;
|
|
284
|
+
if (sev === 'critical')
|
|
285
|
+
critical++;
|
|
286
|
+
else if (sev === 'high')
|
|
287
|
+
high++;
|
|
288
|
+
else if (sev === 'medium')
|
|
289
|
+
medium++;
|
|
290
|
+
else
|
|
291
|
+
low++;
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
high++; // govulncheck legacy default
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
metrics.depVulnCritical = critical;
|
|
298
|
+
metrics.depVulnHigh = high;
|
|
299
|
+
metrics.depVulnMedium = medium;
|
|
300
|
+
metrics.depVulnLow = low;
|
|
301
|
+
metrics.depAuditTool = 'govulncheck';
|
|
302
|
+
metrics.toolsUsed.push('govulncheck');
|
|
303
|
+
if (enrichedCount > 0 && needsLookup.length > 0) {
|
|
304
|
+
metrics.toolsUsed.push('osv.dev');
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
308
|
+
metrics.toolsUnavailable.push('govulncheck (parse error)');
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
metrics.toolsUnavailable.push('govulncheck');
|
|
314
|
+
}
|
|
315
|
+
if ((0, runner_1.fileExists)(cwd, 'go.mod')) {
|
|
316
|
+
metrics.testFramework = 'go-test';
|
|
317
|
+
}
|
|
318
|
+
return metrics;
|
|
319
|
+
},
|
|
320
|
+
};
|
|
321
|
+
//# sourceMappingURL=go.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"go.js","sourceRoot":"","sources":["../../src/languages/go.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { LanguageId, LanguageSupport } from './types';
|
|
2
|
+
export type { LanguageId, LanguageSupport, LintSeverity } from './types';
|
|
3
|
+
export declare const LANGUAGES: readonly LanguageSupport[];
|
|
4
|
+
export declare function getLanguage(id: LanguageId): LanguageSupport | undefined;
|
|
5
|
+
export declare function detectActiveLanguages(cwd: string): LanguageSupport[];
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/languages/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAO3D,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEzE,eAAO,MAAM,SAAS,EAAE,SAAS,eAAe,EAA2C,CAAC;AAE5F,wBAAgB,WAAW,CAAC,EAAE,EAAE,UAAU,GAAG,eAAe,GAAG,SAAS,CAEvE;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,EAAE,CAEpE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LANGUAGES = void 0;
|
|
4
|
+
exports.getLanguage = getLanguage;
|
|
5
|
+
exports.detectActiveLanguages = detectActiveLanguages;
|
|
6
|
+
const csharp_1 = require("./csharp");
|
|
7
|
+
const go_1 = require("./go");
|
|
8
|
+
const python_1 = require("./python");
|
|
9
|
+
const rust_1 = require("./rust");
|
|
10
|
+
const typescript_1 = require("./typescript");
|
|
11
|
+
exports.LANGUAGES = [python_1.python, typescript_1.typescript, csharp_1.csharp, go_1.go, rust_1.rust];
|
|
12
|
+
function getLanguage(id) {
|
|
13
|
+
return exports.LANGUAGES.find((l) => l.id === id);
|
|
14
|
+
}
|
|
15
|
+
function detectActiveLanguages(cwd) {
|
|
16
|
+
return exports.LANGUAGES.filter((l) => l.detect(cwd));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/languages/index.ts"],"names":[],"mappings":";;;AAWA,kCAEC;AAED,sDAEC;AAhBD,qCAAkC;AAClC,6BAA0B;AAC1B,qCAAkC;AAClC,iCAA8B;AAC9B,6CAA0C;AAI7B,QAAA,SAAS,GAA+B,CAAC,eAAM,EAAE,uBAAU,EAAE,eAAM,EAAE,OAAE,EAAE,WAAI,CAAC,CAAC;AAE5F,SAAgB,WAAW,CAAC,EAAc;IACxC,OAAO,iBAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED,SAAgB,qBAAqB,CAAC,GAAW;IAC/C,OAAO,iBAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python.d.ts","sourceRoot":"","sources":["../../src/languages/python.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,SAAS,CAAC;AAoE7D,eAAO,MAAM,MAAM,EAAE,eAiLpB,CAAC"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.python = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const coverage_1 = require("../analyzers/tools/coverage");
|
|
40
|
+
const osv_1 = require("../analyzers/tools/osv");
|
|
41
|
+
const runner_1 = require("../analyzers/tools/runner");
|
|
42
|
+
const tool_registry_1 = require("../analyzers/tools/tool-registry");
|
|
43
|
+
function stripPyComments(src) {
|
|
44
|
+
return src.replace(/(^|[^\w"'])#[^\n]*/g, '$1');
|
|
45
|
+
}
|
|
46
|
+
function isFile(p) {
|
|
47
|
+
try {
|
|
48
|
+
return fs.statSync(p).isFile();
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function toRel(abs, cwd) {
|
|
55
|
+
return path.relative(cwd, abs).split(path.sep).join('/');
|
|
56
|
+
}
|
|
57
|
+
function hasPyFileWithinDepth(cwd, maxDepth = 2) {
|
|
58
|
+
function search(dir, depth) {
|
|
59
|
+
if (depth > maxDepth)
|
|
60
|
+
return false;
|
|
61
|
+
let entries;
|
|
62
|
+
try {
|
|
63
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
for (const e of entries) {
|
|
69
|
+
if (e.name.startsWith('.') ||
|
|
70
|
+
['node_modules', 'vendor', 'bin', 'obj', 'target'].includes(e.name)) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (e.isFile() && e.name.endsWith('.py'))
|
|
74
|
+
return true;
|
|
75
|
+
if (e.isDirectory() && search(path.join(dir, e.name), depth + 1))
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
return search(cwd, 0);
|
|
81
|
+
}
|
|
82
|
+
function mapRuffSeverity(code) {
|
|
83
|
+
const prefix = code.match(/^[A-Z]+/)?.[0] ?? '';
|
|
84
|
+
switch (prefix) {
|
|
85
|
+
case 'S':
|
|
86
|
+
return 'critical';
|
|
87
|
+
case 'F':
|
|
88
|
+
case 'B':
|
|
89
|
+
return 'high';
|
|
90
|
+
case 'E':
|
|
91
|
+
case 'C':
|
|
92
|
+
return 'medium';
|
|
93
|
+
default:
|
|
94
|
+
return 'low';
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.python = {
|
|
98
|
+
id: 'python',
|
|
99
|
+
displayName: 'Python',
|
|
100
|
+
sourceExtensions: ['.py'],
|
|
101
|
+
testFilePatterns: ['test_*.py', '*_test.py'],
|
|
102
|
+
extraExcludes: ['__pycache__', '.pytest_cache', '.ruff_cache', '.venv', 'venv', '.mypy_cache'],
|
|
103
|
+
detect(cwd) {
|
|
104
|
+
return ((0, runner_1.fileExists)(cwd, 'pyproject.toml') ||
|
|
105
|
+
(0, runner_1.fileExists)(cwd, 'setup.py') ||
|
|
106
|
+
(0, runner_1.fileExists)(cwd, 'requirements.txt') ||
|
|
107
|
+
(0, runner_1.fileExists)(cwd, 'Pipfile') ||
|
|
108
|
+
hasPyFileWithinDepth(cwd, 2));
|
|
109
|
+
},
|
|
110
|
+
tools: ['ruff', 'pip-audit', 'coverage-py'],
|
|
111
|
+
semgrepRulesets: ['p/python'],
|
|
112
|
+
parseCoverage(cwd) {
|
|
113
|
+
const file = path.join(cwd, 'coverage.json');
|
|
114
|
+
let raw;
|
|
115
|
+
try {
|
|
116
|
+
raw = fs.readFileSync(file, 'utf-8');
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
return (0, coverage_1.parseCoveragePy)(raw, 'coverage.json', cwd);
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
extractImports(content) {
|
|
129
|
+
const out = [];
|
|
130
|
+
for (const line of stripPyComments(content).split('\n')) {
|
|
131
|
+
const trimmed = line.trim();
|
|
132
|
+
const fromMatch = trimmed.match(/^from\s+([.\w]+)\s+import\s+/);
|
|
133
|
+
if (fromMatch) {
|
|
134
|
+
out.push(fromMatch[1]);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const impMatch = trimmed.match(/^import\s+(.+)$/);
|
|
138
|
+
if (impMatch) {
|
|
139
|
+
for (const part of impMatch[1].split(',')) {
|
|
140
|
+
const name = part
|
|
141
|
+
.trim()
|
|
142
|
+
.split(/\s+as\s+/)[0]
|
|
143
|
+
.trim();
|
|
144
|
+
if (name)
|
|
145
|
+
out.push(name);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return out;
|
|
150
|
+
},
|
|
151
|
+
resolveImport(fromFile, spec, cwd) {
|
|
152
|
+
const fromDir = path.dirname(path.join(cwd, fromFile));
|
|
153
|
+
const dotMatch = spec.match(/^(\.+)(.*)$/);
|
|
154
|
+
let baseDir;
|
|
155
|
+
let remainder;
|
|
156
|
+
if (dotMatch) {
|
|
157
|
+
const dots = dotMatch[1].length;
|
|
158
|
+
remainder = dotMatch[2];
|
|
159
|
+
baseDir = fromDir;
|
|
160
|
+
for (let i = 1; i < dots; i++)
|
|
161
|
+
baseDir = path.dirname(baseDir);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
baseDir = cwd;
|
|
165
|
+
remainder = spec;
|
|
166
|
+
}
|
|
167
|
+
if (!remainder)
|
|
168
|
+
return null;
|
|
169
|
+
const parts = remainder.split('.').filter(Boolean);
|
|
170
|
+
const candidate = path.join(baseDir, ...parts);
|
|
171
|
+
if (isFile(candidate + '.py'))
|
|
172
|
+
return toRel(candidate + '.py', cwd);
|
|
173
|
+
const init = path.join(candidate, '__init__.py');
|
|
174
|
+
if (isFile(init))
|
|
175
|
+
return toRel(init, cwd);
|
|
176
|
+
return null;
|
|
177
|
+
},
|
|
178
|
+
async gatherMetrics(cwd) {
|
|
179
|
+
const metrics = {
|
|
180
|
+
toolsUsed: [],
|
|
181
|
+
toolsUnavailable: [],
|
|
182
|
+
};
|
|
183
|
+
const ruff = (0, tool_registry_1.findTool)(tool_registry_1.TOOL_DEFS.ruff, cwd);
|
|
184
|
+
if (ruff.available && ruff.path) {
|
|
185
|
+
const raw = (0, runner_1.run)(`${ruff.path} check . --output-format json 2>/dev/null`, cwd, 60000);
|
|
186
|
+
if (raw) {
|
|
187
|
+
try {
|
|
188
|
+
const results = JSON.parse(raw);
|
|
189
|
+
if (Array.isArray(results)) {
|
|
190
|
+
let errors = 0;
|
|
191
|
+
let warnings = 0;
|
|
192
|
+
for (const r of results) {
|
|
193
|
+
const sev = mapRuffSeverity(r.code);
|
|
194
|
+
if (sev === 'critical' || sev === 'high')
|
|
195
|
+
errors++;
|
|
196
|
+
else
|
|
197
|
+
warnings++;
|
|
198
|
+
}
|
|
199
|
+
metrics.lintErrors = errors;
|
|
200
|
+
metrics.lintWarnings = warnings;
|
|
201
|
+
metrics.lintTool = 'ruff';
|
|
202
|
+
metrics.toolsUsed.push('ruff');
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
metrics.toolsUnavailable.push('ruff (parse error)');
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
metrics.lintErrors = 0;
|
|
211
|
+
metrics.lintWarnings = 0;
|
|
212
|
+
metrics.lintTool = 'ruff';
|
|
213
|
+
metrics.toolsUsed.push('ruff');
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
metrics.toolsUnavailable.push('ruff');
|
|
218
|
+
}
|
|
219
|
+
const pipAudit = (0, tool_registry_1.findTool)(tool_registry_1.TOOL_DEFS['pip-audit'], cwd);
|
|
220
|
+
if (pipAudit.available && pipAudit.path) {
|
|
221
|
+
const raw = (0, runner_1.run)(`${pipAudit.path} --format json 2>/dev/null`, cwd, 120000);
|
|
222
|
+
if (raw) {
|
|
223
|
+
try {
|
|
224
|
+
const data = JSON.parse(raw);
|
|
225
|
+
const vulnIds = [];
|
|
226
|
+
for (const dep of data.dependencies || []) {
|
|
227
|
+
for (const v of dep.vulns || []) {
|
|
228
|
+
if (v.id)
|
|
229
|
+
vulnIds.push(v.id);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// pip-audit doesn't carry severity per vuln — look up via OSV.dev.
|
|
233
|
+
// Unknown/unreachable IDs fall back to medium (pip-audit's legacy default).
|
|
234
|
+
const severities = await (0, osv_1.enrichSeverities)(vulnIds);
|
|
235
|
+
let critical = 0;
|
|
236
|
+
let high = 0;
|
|
237
|
+
let medium = 0;
|
|
238
|
+
let low = 0;
|
|
239
|
+
let enrichedCount = 0;
|
|
240
|
+
for (const id of vulnIds) {
|
|
241
|
+
const sev = severities.get(id);
|
|
242
|
+
if (sev && sev !== 'unknown') {
|
|
243
|
+
enrichedCount++;
|
|
244
|
+
if (sev === 'critical')
|
|
245
|
+
critical++;
|
|
246
|
+
else if (sev === 'high')
|
|
247
|
+
high++;
|
|
248
|
+
else if (sev === 'medium')
|
|
249
|
+
medium++;
|
|
250
|
+
else
|
|
251
|
+
low++;
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
medium++;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
metrics.depVulnCritical = critical;
|
|
258
|
+
metrics.depVulnHigh = high;
|
|
259
|
+
metrics.depVulnMedium = medium;
|
|
260
|
+
metrics.depVulnLow = low;
|
|
261
|
+
metrics.depAuditTool = 'pip-audit';
|
|
262
|
+
metrics.toolsUsed.push('pip-audit');
|
|
263
|
+
if (enrichedCount > 0)
|
|
264
|
+
metrics.toolsUsed.push('osv.dev');
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
metrics.toolsUnavailable.push('pip-audit (parse error)');
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
metrics.toolsUnavailable.push('pip-audit');
|
|
273
|
+
}
|
|
274
|
+
if ((0, runner_1.fileExists)(cwd, 'pytest.ini', 'conftest.py') || (0, runner_1.fileExists)(cwd, 'pyproject.toml')) {
|
|
275
|
+
const pyproject = (0, runner_1.run)('cat pyproject.toml 2>/dev/null', cwd);
|
|
276
|
+
if (pyproject?.includes('[tool.pytest') || (0, runner_1.fileExists)(cwd, 'pytest.ini', 'conftest.py')) {
|
|
277
|
+
metrics.testFramework = 'pytest';
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return metrics;
|
|
281
|
+
},
|
|
282
|
+
mapLintSeverity: mapRuffSeverity,
|
|
283
|
+
};
|
|
284
|
+
//# sourceMappingURL=python.js.map
|