legion-audit 0.1.0
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 +7 -0
- package/LICENSE +21 -0
- package/README.md +84 -0
- package/dist/args.d.ts +18 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +97 -0
- package/dist/args.js.map +1 -0
- package/dist/audit.d.ts +4 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +81 -0
- package/dist/audit.js.map +1 -0
- package/dist/checks/directives.d.ts +8 -0
- package/dist/checks/directives.d.ts.map +1 -0
- package/dist/checks/directives.js +108 -0
- package/dist/checks/directives.js.map +1 -0
- package/dist/checks/gates.d.ts +16 -0
- package/dist/checks/gates.d.ts.map +1 -0
- package/dist/checks/gates.js +153 -0
- package/dist/checks/gates.js.map +1 -0
- package/dist/checks/git.d.ts +4 -0
- package/dist/checks/git.d.ts.map +1 -0
- package/dist/checks/git.js +36 -0
- package/dist/checks/git.js.map +1 -0
- package/dist/checks/lint.d.ts +10 -0
- package/dist/checks/lint.d.ts.map +1 -0
- package/dist/checks/lint.js +157 -0
- package/dist/checks/lint.js.map +1 -0
- package/dist/checks/lockfile.d.ts +3 -0
- package/dist/checks/lockfile.d.ts.map +1 -0
- package/dist/checks/lockfile.js +21 -0
- package/dist/checks/lockfile.js.map +1 -0
- package/dist/checks/test-coverage.d.ts +4 -0
- package/dist/checks/test-coverage.d.ts.map +1 -0
- package/dist/checks/test-coverage.js +62 -0
- package/dist/checks/test-coverage.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +100 -0
- package/dist/cli.js.map +1 -0
- package/dist/exec.d.ts +15 -0
- package/dist/exec.d.ts.map +1 -0
- package/dist/exec.js +43 -0
- package/dist/exec.js.map +1 -0
- package/dist/files.d.ts +7 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +87 -0
- package/dist/files.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/report/baseline.d.ts +3 -0
- package/dist/report/baseline.d.ts.map +1 -0
- package/dist/report/baseline.js +54 -0
- package/dist/report/baseline.js.map +1 -0
- package/dist/report/markdown.d.ts +3 -0
- package/dist/report/markdown.d.ts.map +1 -0
- package/dist/report/markdown.js +122 -0
- package/dist/report/markdown.js.map +1 -0
- package/dist/report/score.d.ts +18 -0
- package/dist/report/score.d.ts.map +1 -0
- package/dist/report/score.js +40 -0
- package/dist/report/score.js.map +1 -0
- package/dist/types.d.ts +99 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +57 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { runAudit, DEFAULT_OPTIONS } from './audit.js';
|
|
2
|
+
export { scanDirectives, parseDirectivesInSource, isFileWideDisable, } from './checks/directives.js';
|
|
3
|
+
export { parseOxlintJson, parseEslintJson, countByRule, summarizeFindings, detectLinter, } from './checks/lint.js';
|
|
4
|
+
export { summarizeTestOutput, countTypeErrors } from './checks/gates.js';
|
|
5
|
+
export { summarizePrHygiene } from './checks/git.js';
|
|
6
|
+
export { classify } from './checks/test-coverage.js';
|
|
7
|
+
export { lockfileCheck } from './checks/lockfile.js';
|
|
8
|
+
export { computeScore, SCORE_WEIGHTS } from './report/score.js';
|
|
9
|
+
export { findRegressions } from './report/baseline.js';
|
|
10
|
+
export { renderMarkdown } from './report/markdown.js';
|
|
11
|
+
export { parseArgs, HELP } from './args.js';
|
|
12
|
+
export type { CliArgs, FailOn } from './args.js';
|
|
13
|
+
export type * from './types.js';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,eAAe,EACf,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC5C,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACjD,mBAAmB,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { runAudit, DEFAULT_OPTIONS } from './audit.js';
|
|
2
|
+
export { scanDirectives, parseDirectivesInSource, isFileWideDisable, } from './checks/directives.js';
|
|
3
|
+
export { parseOxlintJson, parseEslintJson, countByRule, summarizeFindings, detectLinter, } from './checks/lint.js';
|
|
4
|
+
export { summarizeTestOutput, countTypeErrors } from './checks/gates.js';
|
|
5
|
+
export { summarizePrHygiene } from './checks/git.js';
|
|
6
|
+
export { classify } from './checks/test-coverage.js';
|
|
7
|
+
export { lockfileCheck } from './checks/lockfile.js';
|
|
8
|
+
export { computeScore, SCORE_WEIGHTS } from './report/score.js';
|
|
9
|
+
export { findRegressions } from './report/baseline.js';
|
|
10
|
+
export { renderMarkdown } from './report/markdown.js';
|
|
11
|
+
export { parseArgs, HELP } from './args.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,eAAe,EACf,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline.d.ts","sourceRoot":"","sources":["../../src/report/baseline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAQ3D,eAAO,MAAM,eAAe,GAC1B,QAAQ,WAAW,EACnB,OAAO,WAAW,KACjB,UAAU,EAkDZ,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const gateStatus = (result, name) => result.gates.find((gate) => gate.name === name)?.status ?? 'skipped';
|
|
2
|
+
const legionErrors = (result) => result.lint.legion.filter((finding) => finding.severity === 'error').length;
|
|
3
|
+
export const findRegressions = (before, after) => {
|
|
4
|
+
const regressions = [];
|
|
5
|
+
for (const gate of after.gates) {
|
|
6
|
+
const previous = gateStatus(before, gate.name);
|
|
7
|
+
if (previous === 'pass' && gate.status === 'fail') {
|
|
8
|
+
regressions.push({
|
|
9
|
+
area: `gate: ${gate.name}`,
|
|
10
|
+
before: previous,
|
|
11
|
+
after: gate.status,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
const beforeLegion = legionErrors(before);
|
|
16
|
+
const afterLegion = legionErrors(after);
|
|
17
|
+
if (afterLegion > beforeLegion) {
|
|
18
|
+
regressions.push({
|
|
19
|
+
area: 'legion rule errors',
|
|
20
|
+
before: String(beforeLegion),
|
|
21
|
+
after: String(afterLegion),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
if (after.lint.errors > before.lint.errors) {
|
|
25
|
+
regressions.push({
|
|
26
|
+
area: 'lint errors',
|
|
27
|
+
before: String(before.lint.errors),
|
|
28
|
+
after: String(after.lint.errors),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
if (after.directives.fileWide.length > before.directives.fileWide.length) {
|
|
32
|
+
regressions.push({
|
|
33
|
+
area: 'file-wide disables',
|
|
34
|
+
before: String(before.directives.fileWide.length),
|
|
35
|
+
after: String(after.directives.fileWide.length),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
if (after.testCoverage.missing.length > before.testCoverage.missing.length) {
|
|
39
|
+
regressions.push({
|
|
40
|
+
area: 'files without tests',
|
|
41
|
+
before: String(before.testCoverage.missing.length),
|
|
42
|
+
after: String(after.testCoverage.missing.length),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
if (after.score < before.score) {
|
|
46
|
+
regressions.push({
|
|
47
|
+
area: 'score',
|
|
48
|
+
before: String(before.score),
|
|
49
|
+
after: String(after.score),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return regressions;
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=baseline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline.js","sourceRoot":"","sources":["../../src/report/baseline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/report/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAuB,UAAU,EAAE,MAAM,aAAa,CAAC;AAgIhF,eAAO,MAAM,cAAc,GACzB,QAAQ,WAAW,EACnB,aAAa,UAAU,EAAE,GAAG,IAAI,KAC/B,MA6BF,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
const ICONS = {
|
|
2
|
+
pass: 'pass',
|
|
3
|
+
fail: 'FAIL',
|
|
4
|
+
skipped: 'skipped',
|
|
5
|
+
};
|
|
6
|
+
const MAX_LISTED = 25;
|
|
7
|
+
const table = (header, rows) => {
|
|
8
|
+
const line = (cells) => `| ${cells.join(' | ')} |`;
|
|
9
|
+
const divider = `|${header.map(() => '---').join('|')}|`;
|
|
10
|
+
return [line(header), divider, ...rows.map(line)].join('\n');
|
|
11
|
+
};
|
|
12
|
+
const percent = (ratio) => `${Math.round(ratio * 100)}%`;
|
|
13
|
+
const listFindings = (findings) => {
|
|
14
|
+
const shown = findings.slice(0, MAX_LISTED);
|
|
15
|
+
const lines = shown.map((finding) => `- \`${finding.file}:${finding.line}\` ${finding.rule}: ${finding.message}`);
|
|
16
|
+
if (findings.length > MAX_LISTED) {
|
|
17
|
+
lines.push(`- ... and ${findings.length - MAX_LISTED} more`);
|
|
18
|
+
}
|
|
19
|
+
return lines.join('\n');
|
|
20
|
+
};
|
|
21
|
+
const gatesSection = (result) => {
|
|
22
|
+
const rows = result.gates.map((gate) => [
|
|
23
|
+
gate.name,
|
|
24
|
+
ICONS[gate.status],
|
|
25
|
+
gate.summary,
|
|
26
|
+
]);
|
|
27
|
+
return table(['Gate', 'Result', 'Detail'], rows);
|
|
28
|
+
};
|
|
29
|
+
const lockfileLine = (result) => {
|
|
30
|
+
if (result.lockfile.found.length === 0) {
|
|
31
|
+
return `${ICONS[result.lockfile.status]}: no lockfile found`;
|
|
32
|
+
}
|
|
33
|
+
return `${ICONS[result.lockfile.status]}: ${result.lockfile.found.join(', ')}`;
|
|
34
|
+
};
|
|
35
|
+
const rulesSection = (result) => {
|
|
36
|
+
const legion = result.lint.rules.filter((rule) => rule.rule.startsWith('legion/'));
|
|
37
|
+
if (legion.length === 0)
|
|
38
|
+
return 'No `legion/*` findings (or the plugin is not installed in this repo).';
|
|
39
|
+
const rows = legion.map((rule) => [
|
|
40
|
+
rule.rule,
|
|
41
|
+
String(rule.errors),
|
|
42
|
+
String(rule.warnings),
|
|
43
|
+
]);
|
|
44
|
+
return table(['Rule', 'Errors', 'Warnings'], rows);
|
|
45
|
+
};
|
|
46
|
+
const bypassSection = (result) => {
|
|
47
|
+
const { directives } = result;
|
|
48
|
+
const disables = directives.all.filter((hit) => hit.kind === 'disable');
|
|
49
|
+
const parts = [];
|
|
50
|
+
parts.push(`${disables.length} disable directive(s), ${directives.nosonar.length} NOSONAR marker(s), ${directives.fileWide.length} file-wide disable(s).`);
|
|
51
|
+
const byRule = Object.entries(directives.byRule).sort((a, b) => b[1] - a[1]);
|
|
52
|
+
if (byRule.length > 0) {
|
|
53
|
+
parts.push(table(['Bypassed rule', 'Count'], byRule.map(([rule, count]) => [rule, String(count)])));
|
|
54
|
+
}
|
|
55
|
+
if (directives.fileWide.length > 0) {
|
|
56
|
+
parts.push('File-wide disables (hard fail):');
|
|
57
|
+
parts.push(directives.fileWide
|
|
58
|
+
.map((hit) => `- \`${hit.file}:${hit.line}\``)
|
|
59
|
+
.join('\n'));
|
|
60
|
+
}
|
|
61
|
+
const explained = disables.filter((hit) => hit.description.length > 0).length;
|
|
62
|
+
if (disables.length > 0) {
|
|
63
|
+
parts.push(`${explained}/${disables.length} directives carry a reason.`);
|
|
64
|
+
}
|
|
65
|
+
return parts.join('\n\n');
|
|
66
|
+
};
|
|
67
|
+
const prSection = (result) => {
|
|
68
|
+
const { prHygiene } = result;
|
|
69
|
+
if (prHygiene.status === 'skipped')
|
|
70
|
+
return 'Not a git repository.';
|
|
71
|
+
const lines = [
|
|
72
|
+
`${prHygiene.withPr} of the last ${prHygiene.inspected} commits carry a PR number (${percent(prHygiene.ratio)}).`,
|
|
73
|
+
];
|
|
74
|
+
if (prHygiene.lastPrCommit)
|
|
75
|
+
lines.push(`Most recent PR-tagged commit: \`${prHygiene.lastPrCommit}\`.`);
|
|
76
|
+
return lines.join('\n');
|
|
77
|
+
};
|
|
78
|
+
const coverageSection = (result) => {
|
|
79
|
+
const { testCoverage } = result;
|
|
80
|
+
const total = testCoverage.components + testCoverage.hooks;
|
|
81
|
+
const lines = [
|
|
82
|
+
`${testCoverage.components} component(s) and ${testCoverage.hooks} hook(s) found; ${testCoverage.missing.length} of ${total} have no test file.`,
|
|
83
|
+
];
|
|
84
|
+
if (testCoverage.missing.length > 0) {
|
|
85
|
+
const shown = testCoverage.missing.slice(0, MAX_LISTED);
|
|
86
|
+
lines.push(shown.map((entry) => `- \`${entry.file}\` (${entry.kind})`).join('\n'));
|
|
87
|
+
if (testCoverage.missing.length > MAX_LISTED) {
|
|
88
|
+
lines.push(`- ... and ${testCoverage.missing.length - MAX_LISTED} more`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return lines.join('\n');
|
|
92
|
+
};
|
|
93
|
+
const regressionSection = (regressions) => {
|
|
94
|
+
if (regressions.length === 0)
|
|
95
|
+
return 'No regressions against the baseline.';
|
|
96
|
+
return table(['Area', 'Baseline', 'Now'], regressions.map((entry) => [entry.area, entry.before, entry.after]));
|
|
97
|
+
};
|
|
98
|
+
export const renderMarkdown = (result, regressions) => {
|
|
99
|
+
const sections = [
|
|
100
|
+
`# Legion audit`,
|
|
101
|
+
`Generated ${result.generatedAt} for \`${result.root}\` (${result.packageManager}). Score: **${result.score}/100**.`,
|
|
102
|
+
`## Gates`,
|
|
103
|
+
gatesSection(result),
|
|
104
|
+
`## Legion rules`,
|
|
105
|
+
rulesSection(result),
|
|
106
|
+
];
|
|
107
|
+
if (result.lint.componentCap.length > 0) {
|
|
108
|
+
sections.push(`## Components over the line cap`, listFindings(result.lint.componentCap));
|
|
109
|
+
}
|
|
110
|
+
if (result.lint.legion.length > 0) {
|
|
111
|
+
sections.push(`## Legion findings`, listFindings(result.lint.legion));
|
|
112
|
+
}
|
|
113
|
+
sections.push(`## Lint bypasses`, bypassSection(result));
|
|
114
|
+
sections.push(`## PR hygiene`, prSection(result));
|
|
115
|
+
sections.push(`## Tests by file`, coverageSection(result));
|
|
116
|
+
sections.push(`## Lockfile`, lockfileLine(result));
|
|
117
|
+
if (regressions !== null)
|
|
118
|
+
sections.push(`## Baseline`, regressionSection(regressions));
|
|
119
|
+
sections.push(`## Score formula`, 'Start at 100. Minus 2 per `legion/*` error (cap 40), 0.5 per lint warning (cap 10), 15 for a failed typecheck, 15 for a failed lint, 20 for failed tests, 5 for unformatted files, up to 10 scaled by the share of commits without a PR number, 1 per component or hook without a test (cap 15), 5 per file-wide disable (cap 15). The number is for comparing runs of the same repo, not for comparing repos.');
|
|
120
|
+
return `${sections.join('\n\n')}\n`;
|
|
121
|
+
};
|
|
122
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/report/markdown.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AuditResult } from '../types.js';
|
|
2
|
+
export declare const SCORE_WEIGHTS: {
|
|
3
|
+
readonly legionError: 2;
|
|
4
|
+
readonly legionErrorCap: 40;
|
|
5
|
+
readonly warning: 0.5;
|
|
6
|
+
readonly warningCap: 10;
|
|
7
|
+
readonly typecheckFail: 15;
|
|
8
|
+
readonly lintFail: 15;
|
|
9
|
+
readonly testsFail: 20;
|
|
10
|
+
readonly formatFail: 5;
|
|
11
|
+
readonly prHygieneMax: 10;
|
|
12
|
+
readonly missingTest: 1;
|
|
13
|
+
readonly missingTestCap: 15;
|
|
14
|
+
readonly fileWideDisable: 5;
|
|
15
|
+
readonly fileWideDisableCap: 15;
|
|
16
|
+
};
|
|
17
|
+
export declare const computeScore: (result: Omit<AuditResult, "score" | "schema" | "generatedAt">) => number;
|
|
18
|
+
//# sourceMappingURL=score.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"score.d.ts","sourceRoot":"","sources":["../../src/report/score.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,eAAO,MAAM,aAAa;;;;;;;;;;;;;;CAchB,CAAC;AAeX,eAAO,MAAM,YAAY,GACvB,QAAQ,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,QAAQ,GAAG,aAAa,CAAC,KAC5D,MA0BF,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export const SCORE_WEIGHTS = {
|
|
2
|
+
legionError: 2,
|
|
3
|
+
legionErrorCap: 40,
|
|
4
|
+
warning: 0.5,
|
|
5
|
+
warningCap: 10,
|
|
6
|
+
typecheckFail: 15,
|
|
7
|
+
lintFail: 15,
|
|
8
|
+
testsFail: 20,
|
|
9
|
+
formatFail: 5,
|
|
10
|
+
prHygieneMax: 10,
|
|
11
|
+
missingTest: 1,
|
|
12
|
+
missingTestCap: 15,
|
|
13
|
+
fileWideDisable: 5,
|
|
14
|
+
fileWideDisableCap: 15,
|
|
15
|
+
};
|
|
16
|
+
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
17
|
+
const gatePenalty = (result, name, penalty) => {
|
|
18
|
+
const gate = result.gates.find((entry) => entry.name === name);
|
|
19
|
+
if (gate?.status === 'fail')
|
|
20
|
+
return penalty;
|
|
21
|
+
return 0;
|
|
22
|
+
};
|
|
23
|
+
export const computeScore = (result) => {
|
|
24
|
+
const w = SCORE_WEIGHTS;
|
|
25
|
+
let score = 100;
|
|
26
|
+
const legionErrors = result.lint.legion.filter((finding) => finding.severity === 'error').length;
|
|
27
|
+
score -= clamp(legionErrors * w.legionError, 0, w.legionErrorCap);
|
|
28
|
+
score -= clamp(result.lint.warnings * w.warning, 0, w.warningCap);
|
|
29
|
+
score -= gatePenalty(result, 'typecheck', w.typecheckFail);
|
|
30
|
+
score -= gatePenalty(result, 'lint', w.lintFail);
|
|
31
|
+
score -= gatePenalty(result, 'tests', w.testsFail);
|
|
32
|
+
score -= gatePenalty(result, 'format', w.formatFail);
|
|
33
|
+
if (result.prHygiene.status !== 'skipped') {
|
|
34
|
+
score -= (1 - result.prHygiene.ratio) * w.prHygieneMax;
|
|
35
|
+
}
|
|
36
|
+
score -= clamp(result.testCoverage.missing.length * w.missingTest, 0, w.missingTestCap);
|
|
37
|
+
score -= clamp(result.directives.fileWide.length * w.fileWideDisable, 0, w.fileWideDisableCap);
|
|
38
|
+
return Math.round(clamp(score, 0, 100));
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=score.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"score.js","sourceRoot":"","sources":["../../src/report/score.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,WAAW,EAAE,CAAC;IACd,cAAc,EAAE,EAAE;IAClB,OAAO,EAAE,GAAG;IACZ,UAAU,EAAE,EAAE;IACd,aAAa,EAAE,EAAE;IACjB,QAAQ,EAAE,EAAE;IACZ,SAAS,EAAE,EAAE;IACb,UAAU,EAAE,CAAC;IACb,YAAY,EAAE,EAAE;IAChB,WAAW,EAAE,CAAC;IACd,cAAc,EAAE,EAAE;IAClB,eAAe,EAAE,CAAC;IAClB,kBAAkB,EAAE,EAAE;CACd,CAAC;AAEX,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,GAAW,EAAE,GAAW,EAAU,EAAE,CAChE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAEtC,MAAM,WAAW,GAAG,CAClB,MAAkC,EAClC,IAAY,EACZ,OAAe,EACP,EAAE;IACV,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAC/D,IAAI,IAAI,EAAE,MAAM,KAAK,MAAM;QAAE,OAAO,OAAO,CAAC;IAC5C,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,MAA6D,EACrD,EAAE;IACV,MAAM,CAAC,GAAG,aAAa,CAAC;IACxB,IAAI,KAAK,GAAG,GAAG,CAAC;IAChB,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAC5C,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAC1C,CAAC,MAAM,CAAC;IACT,KAAK,IAAI,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,CAAC;IAClE,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;IAClE,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC;IAC3D,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;IACjD,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;IACnD,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;IACrD,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1C,KAAK,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC;IACzD,CAAC;IACD,KAAK,IAAI,KAAK,CACZ,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,WAAW,EAClD,CAAC,EACD,CAAC,CAAC,cAAc,CACjB,CAAC;IACF,KAAK,IAAI,KAAK,CACZ,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,eAAe,EACrD,CAAC,EACD,CAAC,CAAC,kBAAkB,CACrB,CAAC;IACF,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;AAC1C,CAAC,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
export type GateStatus = 'pass' | 'fail' | 'skipped';
|
|
2
|
+
export interface GateResult {
|
|
3
|
+
name: string;
|
|
4
|
+
status: GateStatus;
|
|
5
|
+
summary: string;
|
|
6
|
+
command?: string;
|
|
7
|
+
exitCode?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface RuleCount {
|
|
10
|
+
rule: string;
|
|
11
|
+
errors: number;
|
|
12
|
+
warnings: number;
|
|
13
|
+
}
|
|
14
|
+
export interface Finding {
|
|
15
|
+
rule: string;
|
|
16
|
+
file: string;
|
|
17
|
+
line: number;
|
|
18
|
+
message: string;
|
|
19
|
+
severity: 'error' | 'warning';
|
|
20
|
+
}
|
|
21
|
+
export interface LintResult {
|
|
22
|
+
linter: 'oxlint' | 'eslint' | 'none';
|
|
23
|
+
status: GateStatus;
|
|
24
|
+
errors: number;
|
|
25
|
+
warnings: number;
|
|
26
|
+
rules: RuleCount[];
|
|
27
|
+
legion: Finding[];
|
|
28
|
+
componentCap: Finding[];
|
|
29
|
+
}
|
|
30
|
+
export interface DirectiveHit {
|
|
31
|
+
file: string;
|
|
32
|
+
line: number;
|
|
33
|
+
tool: 'eslint' | 'oxlint';
|
|
34
|
+
kind: 'disable' | 'enable';
|
|
35
|
+
scope: 'file' | 'next-line' | 'line';
|
|
36
|
+
rules: string[];
|
|
37
|
+
description: string;
|
|
38
|
+
}
|
|
39
|
+
export interface NosonarHit {
|
|
40
|
+
file: string;
|
|
41
|
+
line: number;
|
|
42
|
+
}
|
|
43
|
+
export interface DirectivesResult {
|
|
44
|
+
fileWide: DirectiveHit[];
|
|
45
|
+
all: DirectiveHit[];
|
|
46
|
+
nosonar: NosonarHit[];
|
|
47
|
+
byRule: Record<string, number>;
|
|
48
|
+
}
|
|
49
|
+
export interface PrHygiene {
|
|
50
|
+
status: GateStatus;
|
|
51
|
+
inspected: number;
|
|
52
|
+
withPr: number;
|
|
53
|
+
ratio: number;
|
|
54
|
+
lastPrCommit: string | null;
|
|
55
|
+
}
|
|
56
|
+
export interface MissingTest {
|
|
57
|
+
file: string;
|
|
58
|
+
kind: 'component' | 'hook';
|
|
59
|
+
}
|
|
60
|
+
export interface TestCoverage {
|
|
61
|
+
components: number;
|
|
62
|
+
hooks: number;
|
|
63
|
+
missing: MissingTest[];
|
|
64
|
+
}
|
|
65
|
+
export interface LockfileResult {
|
|
66
|
+
status: GateStatus;
|
|
67
|
+
found: string[];
|
|
68
|
+
packageManager: PackageManager;
|
|
69
|
+
}
|
|
70
|
+
export type PackageManager = 'yarn' | 'npm' | 'pnpm' | 'bun' | 'unknown';
|
|
71
|
+
export interface AuditResult {
|
|
72
|
+
schema: 1;
|
|
73
|
+
generatedAt: string;
|
|
74
|
+
root: string;
|
|
75
|
+
packageManager: PackageManager;
|
|
76
|
+
score: number;
|
|
77
|
+
gates: GateResult[];
|
|
78
|
+
lint: LintResult;
|
|
79
|
+
directives: DirectivesResult;
|
|
80
|
+
prHygiene: PrHygiene;
|
|
81
|
+
testCoverage: TestCoverage;
|
|
82
|
+
lockfile: LockfileResult;
|
|
83
|
+
}
|
|
84
|
+
export interface AuditOptions {
|
|
85
|
+
root: string;
|
|
86
|
+
depsAudit: boolean;
|
|
87
|
+
runTests: boolean;
|
|
88
|
+
runTypecheck: boolean;
|
|
89
|
+
runFormat: boolean;
|
|
90
|
+
quiet: boolean;
|
|
91
|
+
commitsToInspect: number;
|
|
92
|
+
ignore: string[];
|
|
93
|
+
}
|
|
94
|
+
export interface Regression {
|
|
95
|
+
area: string;
|
|
96
|
+
before: string;
|
|
97
|
+
after: string;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "legion-audit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Read-only repo scorecard against LEGION-STANDARDS: gates (typecheck, lint, tests, format), per-rule counts, lint bypasses, file-wide disables, PR hygiene, test coverage by file, lockfile sanity. Markdown and JSON output with baseline diffing for CI.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Veracium LLC",
|
|
7
|
+
"homepage": "https://github.com/Kprince1101/legion-toolkit/tree/main/packages/audit#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/Kprince1101/legion-toolkit.git",
|
|
11
|
+
"directory": "packages/audit"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/Kprince1101/legion-toolkit/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"audit",
|
|
18
|
+
"lint",
|
|
19
|
+
"code-quality",
|
|
20
|
+
"scorecard",
|
|
21
|
+
"ci",
|
|
22
|
+
"legion"
|
|
23
|
+
],
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"bin": "./dist/cli.js",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"default": "./dist/index.js"
|
|
32
|
+
},
|
|
33
|
+
"./cli": "./dist/cli.js",
|
|
34
|
+
"./package.json": "./package.json"
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"!dist/**/*.test.*",
|
|
39
|
+
"!dist/**/__tests__",
|
|
40
|
+
"LICENSE",
|
|
41
|
+
"README.md"
|
|
42
|
+
],
|
|
43
|
+
"sideEffects": false,
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public",
|
|
46
|
+
"registry": "https://registry.npmjs.org/"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "node ../../scripts/copy-license.ts && tsc -p tsconfig.build.json && node -e \"require('node:fs').chmodSync('dist/cli.js', 0o755)\"",
|
|
50
|
+
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true}); require('node:fs').rmSync('LICENSE',{force:true})\"",
|
|
51
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
52
|
+
"prepublishOnly": "node ../../scripts/require-ci.ts"
|
|
53
|
+
},
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=22"
|
|
56
|
+
}
|
|
57
|
+
}
|