@goliapkg/sentori-cli 1.9.0 → 1.10.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/LINT.md +237 -0
- package/README.md +14 -7
- package/examples/insight-lint.toml +32 -0
- package/lib/index.js +5 -0
- package/lib/index.js.map +1 -1
- package/lib/lint/config.d.ts +19 -0
- package/lib/lint/config.d.ts.map +1 -0
- package/lib/lint/config.js +149 -0
- package/lib/lint/config.js.map +1 -0
- package/lib/lint/index.d.ts +4 -0
- package/lib/lint/index.d.ts.map +1 -0
- package/lib/lint/index.js +204 -0
- package/lib/lint/index.js.map +1 -0
- package/lib/lint/report.d.ts +48 -0
- package/lib/lint/report.d.ts.map +1 -0
- package/lib/lint/report.js +136 -0
- package/lib/lint/report.js.map +1 -0
- package/lib/lint/rules.d.ts +28 -0
- package/lib/lint/rules.d.ts.map +1 -0
- package/lib/lint/rules.js +57 -0
- package/lib/lint/rules.js.map +1 -0
- package/package.json +4 -2
- package/src/__tests__/lint.test.ts +185 -0
- package/src/index.ts +4 -0
- package/src/lint/config.ts +102 -0
- package/src/lint/index.ts +163 -0
- package/src/lint/report.ts +129 -0
- package/src/lint/rules.ts +64 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { ruleById, rules, ruleLanguage, fileLanguage } from './rules.js';
|
|
2
|
+
// Deliberately small TOML schema: scalar strings/integers, single-line string
|
|
3
|
+
// arrays, [rules], and [[allow]]. Reject unsupported TOML rather than guessing.
|
|
4
|
+
export function parseConfig(source) {
|
|
5
|
+
const result = { version: 1, include: ['**'], exclude: [], tests: [], excludePathRegex: [], rules: {}, allow: [] };
|
|
6
|
+
const seen = new Set();
|
|
7
|
+
let section = '';
|
|
8
|
+
let allow;
|
|
9
|
+
const allowances = [];
|
|
10
|
+
const stringValue = (raw) => {
|
|
11
|
+
if (raw.startsWith("'") && raw.endsWith("'") && !raw.slice(1, -1).includes("'"))
|
|
12
|
+
return raw.slice(1, -1);
|
|
13
|
+
const value = JSON.parse(raw);
|
|
14
|
+
if (typeof value !== 'string')
|
|
15
|
+
throw Error('expected a string');
|
|
16
|
+
return value;
|
|
17
|
+
};
|
|
18
|
+
for (const [index, rawLine] of source.split(/\r?\n/).entries()) {
|
|
19
|
+
try {
|
|
20
|
+
// Comments are removed only outside quoted strings.
|
|
21
|
+
let quote = '', escaped = false, line = '';
|
|
22
|
+
for (const char of rawLine) {
|
|
23
|
+
if (!quote && char === '#')
|
|
24
|
+
break;
|
|
25
|
+
line += char;
|
|
26
|
+
if (escaped) {
|
|
27
|
+
escaped = false;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (quote === '"' && char === '\\') {
|
|
31
|
+
escaped = true;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (quote === char)
|
|
35
|
+
quote = '';
|
|
36
|
+
else if (!quote && (char === '"' || char === "'"))
|
|
37
|
+
quote = char;
|
|
38
|
+
}
|
|
39
|
+
line = line.trim();
|
|
40
|
+
if (!line)
|
|
41
|
+
continue;
|
|
42
|
+
if (line === '[rules]') {
|
|
43
|
+
if (seen.has('[rules]'))
|
|
44
|
+
throw Error('duplicate [rules]');
|
|
45
|
+
seen.add('[rules]');
|
|
46
|
+
section = 'rules';
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (line === '[[allow]]') {
|
|
50
|
+
section = 'allow';
|
|
51
|
+
allow = {};
|
|
52
|
+
allowances.push(allow);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const match = /^([A-Za-z][A-Za-z0-9_-]*)\s*=\s*(.+)$/.exec(line);
|
|
56
|
+
if (!match)
|
|
57
|
+
throw Error('unsupported TOML; use single-line values, [rules], or [[allow]]');
|
|
58
|
+
const [, key, raw] = match;
|
|
59
|
+
const identity = section === 'allow' ? `allow.${allowances.length}.${key}` : `${section}.${key}`;
|
|
60
|
+
if (seen.has(identity))
|
|
61
|
+
throw Error(`duplicate key ${key}`);
|
|
62
|
+
seen.add(identity);
|
|
63
|
+
if (section === 'allow') {
|
|
64
|
+
if (!['rule', 'path', 'reason'].includes(key))
|
|
65
|
+
throw Error(`unknown allowance key ${key}`);
|
|
66
|
+
allow[key] = stringValue(raw);
|
|
67
|
+
}
|
|
68
|
+
else if (section === 'rules') {
|
|
69
|
+
const rule = ruleById.get(key);
|
|
70
|
+
if (!rule)
|
|
71
|
+
throw Error(`unknown rule ${key}`);
|
|
72
|
+
const level = stringValue(raw);
|
|
73
|
+
if (!['off', 'warn', 'error'].includes(level))
|
|
74
|
+
throw Error(`invalid severity ${level}`);
|
|
75
|
+
if (rule.allowlistOnly && level !== 'error')
|
|
76
|
+
throw Error(`${key} requires error severity; use an allowance`);
|
|
77
|
+
result.rules[key] = level;
|
|
78
|
+
}
|
|
79
|
+
else if (key === 'version') {
|
|
80
|
+
if (raw !== '1')
|
|
81
|
+
throw Error('unsupported config version');
|
|
82
|
+
}
|
|
83
|
+
else if (['include', 'exclude', 'tests', 'excludePathRegex'].includes(key)) {
|
|
84
|
+
// Arrays use TOML basic strings, also valid JSON. No multiline arrays.
|
|
85
|
+
const value = JSON.parse(raw);
|
|
86
|
+
if (!Array.isArray(value) || value.some(v => typeof v !== 'string' || !v))
|
|
87
|
+
throw Error(`${key} requires nonempty strings`);
|
|
88
|
+
result[key] = value;
|
|
89
|
+
}
|
|
90
|
+
else
|
|
91
|
+
throw Error(`unknown configuration key ${key}`);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
throw Error(`config line ${index + 1}: ${error.message}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (!seen.has('.version'))
|
|
98
|
+
throw Error('config version = 1 is required');
|
|
99
|
+
if (!result.include.length)
|
|
100
|
+
throw Error('include must not be empty');
|
|
101
|
+
result.allow = allowances.map(a => {
|
|
102
|
+
if (typeof a.rule !== 'string' || !ruleById.has(a.rule))
|
|
103
|
+
throw Error('allowance needs a known rule');
|
|
104
|
+
if (typeof a.path !== 'string' || !a.path.trim() || a.path.startsWith('/') || a.path.split('/').includes('..'))
|
|
105
|
+
throw Error('allowance needs a repository-relative path pattern');
|
|
106
|
+
if (typeof a.reason !== 'string' || !a.reason.trim())
|
|
107
|
+
throw Error('allowance needs a nonempty reason');
|
|
108
|
+
return { rule: a.rule, path: a.path, reason: a.reason.trim() };
|
|
109
|
+
});
|
|
110
|
+
for (const pattern of [...result.include, ...result.exclude, ...result.tests, ...result.allow.map(a => a.path)])
|
|
111
|
+
glob(pattern);
|
|
112
|
+
for (const pattern of result.excludePathRegex)
|
|
113
|
+
new RegExp(pattern, 'i');
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
export function glob(pattern) {
|
|
117
|
+
if (pattern.startsWith('/') || pattern.includes('\\') || pattern.split('/').includes('..') || /[\[\]{}]/.test(pattern))
|
|
118
|
+
throw Error(`unsupported path glob: ${pattern}`);
|
|
119
|
+
let regex = '^';
|
|
120
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
121
|
+
const c = pattern[i];
|
|
122
|
+
if (c === '*' && pattern[i + 1] === '*') {
|
|
123
|
+
i++;
|
|
124
|
+
if (pattern[i + 1] === '/') {
|
|
125
|
+
regex += '(?:.*/)?';
|
|
126
|
+
i++;
|
|
127
|
+
}
|
|
128
|
+
else
|
|
129
|
+
regex += '.*';
|
|
130
|
+
}
|
|
131
|
+
else if (c === '*')
|
|
132
|
+
regex += '[^/]*';
|
|
133
|
+
else if (c === '?')
|
|
134
|
+
regex += '[^/]';
|
|
135
|
+
else
|
|
136
|
+
regex += c.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
137
|
+
}
|
|
138
|
+
return new RegExp(regex + '$');
|
|
139
|
+
}
|
|
140
|
+
export function selected(path, config) {
|
|
141
|
+
const any = (patterns) => patterns.some(p => glob(p).test(path));
|
|
142
|
+
return any(config.include) && !any(config.exclude)
|
|
143
|
+
&& (!any(config.tests) || rules.some(rule => ruleLanguage(rule.id) === fileLanguage(path) && rule.tests && (config.rules[rule.id] ?? rule.level) !== 'off'))
|
|
144
|
+
&& !config.excludePathRegex.some(p => new RegExp(p, 'i').test(path));
|
|
145
|
+
}
|
|
146
|
+
export function isTest(path, config) {
|
|
147
|
+
return config.tests.some(pattern => glob(pattern).test(path));
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lint/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lint/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AA8BzC,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,EAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CA0B5G;AA4BD,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAwE7D"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { closeSync, existsSync, fsyncSync, linkSync, lstatSync, openSync, readFileSync, realpathSync, renameSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { isAbsolute, relative, resolve, sep } from 'node:path';
|
|
4
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
5
|
+
import { parseArgs } from 'node:util';
|
|
6
|
+
import { parseConfig, selected } from './config.js';
|
|
7
|
+
import { initBaseline, lowerBaseline, makeReport, sarif, textReport, validateBaseline, validateResponse } from './report.js';
|
|
8
|
+
import { ruleById, ruleset } from './rules.js';
|
|
9
|
+
const help = `sentori lint [paths...] [options]
|
|
10
|
+
Swift and Kotlin syntax checks (preview 0.3.0).
|
|
11
|
+
--config FILE default: <git-root>/sentori-lint.toml
|
|
12
|
+
--swift-analyzer FILE executable (or SENTORI_LINT_SWIFT; default sentori-lint-swift)
|
|
13
|
+
--kotlin-analyzer FILE executable (or SENTORI_LINT_KOTLIN; default sentori-lint-kotlin)
|
|
14
|
+
--format text|json|sarif
|
|
15
|
+
--baseline FILE read a versioned rule/file-count baseline
|
|
16
|
+
--init-baseline initialize FILE, only if it does not exist
|
|
17
|
+
--update-baseline lower FILE after a successful full scan
|
|
18
|
+
--changed REF scan git diff REF plus untracked files; never update baselines
|
|
19
|
+
--fix run toolchain swift format, then reanalyze
|
|
20
|
+
--explain RULE print rule metadata
|
|
21
|
+
--version print lint protocol/ruleset version
|
|
22
|
+
Exit codes: 0 passed, 1 rule regressions, 2 configuration/analyzer/tool failure.
|
|
23
|
+
Configured tests participate only in function-length checks; generated exclusions apply to all rules.
|
|
24
|
+
`;
|
|
25
|
+
function command(executable, args, cwd, input) {
|
|
26
|
+
const result = spawnSync(executable, args, { cwd, input, encoding: 'utf8', maxBuffer: 64 * 1024 * 1024, timeout: 120_000 });
|
|
27
|
+
if (result.error || result.status !== 0) {
|
|
28
|
+
throw Error(`${executable} failed: ${result.error?.message ?? result.stderr.trim() ?? result.signal ?? result.status}`);
|
|
29
|
+
}
|
|
30
|
+
return result.stdout;
|
|
31
|
+
}
|
|
32
|
+
function git(root, args) { return command('git', ['--literal-pathspecs', '-C', root, ...args], root); }
|
|
33
|
+
function records(value) { return value.split('\0').filter(Boolean); }
|
|
34
|
+
export function discoverFiles(root, config, paths = [], changed) {
|
|
35
|
+
const all = records(git(root, ['ls-files', '--cached', '--others', '--exclude-standard', '-z']));
|
|
36
|
+
const changedPaths = changed === undefined ? undefined : new Set([
|
|
37
|
+
...records(git(root, ['diff', '--name-only', '-z', '--diff-filter=ACMR', changed, '--'])),
|
|
38
|
+
...records(git(root, ['ls-files', '--others', '--exclude-standard', '-z'])),
|
|
39
|
+
]);
|
|
40
|
+
const prefixes = paths.map(p => {
|
|
41
|
+
const path = relative(root, resolve(process.cwd(), p)).split(sep).join('/');
|
|
42
|
+
if (path === '..' || path.startsWith('../') || isAbsolute(path))
|
|
43
|
+
throw Error(`path outside repository: ${p}`);
|
|
44
|
+
if (!existsSync(resolve(root, path)))
|
|
45
|
+
throw Error(`path does not exist: ${p}`);
|
|
46
|
+
return path;
|
|
47
|
+
});
|
|
48
|
+
return [...new Set(all)].filter(path => {
|
|
49
|
+
if (!/\.(swift|kt)$/.test(path) || !selected(path, config))
|
|
50
|
+
return false;
|
|
51
|
+
if (changedPaths && !changedPaths.has(path))
|
|
52
|
+
return false;
|
|
53
|
+
if (prefixes.length && !prefixes.some(p => !p || path === p || path.startsWith(p + '/')))
|
|
54
|
+
return false;
|
|
55
|
+
const fullPath = resolve(root, path);
|
|
56
|
+
try {
|
|
57
|
+
lstatSync(fullPath);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error.code === 'ENOENT')
|
|
61
|
+
return false; // tracked deletion
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
const rel = relative(realpathSync(root), realpathSync(fullPath));
|
|
65
|
+
if (rel === '..' || rel.startsWith('..' + sep) || isAbsolute(rel) || lstatSync(fullPath).isSymbolicLink())
|
|
66
|
+
throw Error(`refusing source symlink/outside file: ${path}`);
|
|
67
|
+
if (!lstatSync(fullPath).isFile())
|
|
68
|
+
throw Error(`not a regular source file: ${path}`);
|
|
69
|
+
return true;
|
|
70
|
+
}).sort();
|
|
71
|
+
}
|
|
72
|
+
function analyze(root, executable, files, language) {
|
|
73
|
+
if (!files.length)
|
|
74
|
+
return [];
|
|
75
|
+
const output = command(executable, [], root, JSON.stringify({ version: 1, files }));
|
|
76
|
+
return validateResponse(JSON.parse(output), files, language);
|
|
77
|
+
}
|
|
78
|
+
function writeBaseline(path, baseline, original) {
|
|
79
|
+
const contents = JSON.stringify(baseline, null, 2) + '\n';
|
|
80
|
+
const lock = `${path}.lock`;
|
|
81
|
+
const lockFd = openSync(lock, 'wx');
|
|
82
|
+
const temporary = `${path}.${randomUUID()}.tmp`;
|
|
83
|
+
try {
|
|
84
|
+
writeFileSync(lockFd, JSON.stringify({ pid: process.pid }) + '\n');
|
|
85
|
+
const fd = openSync(temporary, 'wx');
|
|
86
|
+
try {
|
|
87
|
+
writeFileSync(fd, contents);
|
|
88
|
+
fsyncSync(fd);
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
closeSync(fd);
|
|
92
|
+
}
|
|
93
|
+
if (original === undefined) {
|
|
94
|
+
// Atomic create without replacement: interruption cannot leave half JSON.
|
|
95
|
+
linkSync(temporary, path);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
if (lstatSync(path).isSymbolicLink() || readFileSync(path, 'utf8') !== original)
|
|
99
|
+
throw Error('baseline changed during scan or is a symlink; retry');
|
|
100
|
+
renameSync(temporary, path);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
if (existsSync(temporary))
|
|
105
|
+
unlinkSync(temporary);
|
|
106
|
+
closeSync(lockFd);
|
|
107
|
+
unlinkSync(lock);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export async function cmdLint(argv) {
|
|
111
|
+
try {
|
|
112
|
+
const { values, positionals } = parseArgs({ args: argv, allowPositionals: true, options: {
|
|
113
|
+
config: { type: 'string' }, 'swift-analyzer': { type: 'string' }, 'kotlin-analyzer': { type: 'string' }, format: { type: 'string', default: 'text' },
|
|
114
|
+
baseline: { type: 'string' }, 'init-baseline': { type: 'boolean' }, 'update-baseline': { type: 'boolean' },
|
|
115
|
+
changed: { type: 'string' }, fix: { type: 'boolean' }, explain: { type: 'string' },
|
|
116
|
+
version: { type: 'boolean' }, help: { type: 'boolean', short: 'h' },
|
|
117
|
+
} });
|
|
118
|
+
if (values.help) {
|
|
119
|
+
console.log(help);
|
|
120
|
+
return 0;
|
|
121
|
+
}
|
|
122
|
+
if (values.version) {
|
|
123
|
+
console.log(`sentori lint preview 0.3.0 (${ruleset})`);
|
|
124
|
+
return 0;
|
|
125
|
+
}
|
|
126
|
+
if (values.explain) {
|
|
127
|
+
const rule = ruleById.get(values.explain);
|
|
128
|
+
if (!rule)
|
|
129
|
+
throw Error(`unknown rule ${values.explain}`);
|
|
130
|
+
console.log(JSON.stringify(rule, null, 2));
|
|
131
|
+
return 0;
|
|
132
|
+
}
|
|
133
|
+
if (!['text', 'json', 'sarif'].includes(values.format))
|
|
134
|
+
throw Error('format must be text, json, or sarif');
|
|
135
|
+
const initialize = values['init-baseline'], update = values['update-baseline'];
|
|
136
|
+
if (initialize && update)
|
|
137
|
+
throw Error('choose init-baseline or update-baseline');
|
|
138
|
+
if ((initialize || update) && !values.baseline)
|
|
139
|
+
throw Error('--baseline FILE is required');
|
|
140
|
+
if ((initialize || update) && (positionals.length || values.changed !== undefined))
|
|
141
|
+
throw Error('baseline writes require a full scan without paths or --changed');
|
|
142
|
+
if (values.changed?.startsWith('-'))
|
|
143
|
+
throw Error('--changed requires a git revision, not an option');
|
|
144
|
+
const root = command('git', ['rev-parse', '--show-toplevel'], process.cwd()).replace(/\r?\n$/, '');
|
|
145
|
+
const configPath = values.config ? resolve(values.config) : resolve(root, 'sentori-lint.toml');
|
|
146
|
+
const configSource = readFileSync(configPath, 'utf8');
|
|
147
|
+
const config = parseConfig(configSource);
|
|
148
|
+
const baselinePath = values.baseline ? resolve(values.baseline) : undefined;
|
|
149
|
+
if (initialize && existsSync(baselinePath))
|
|
150
|
+
throw Error('baseline already exists; initialization never overwrites it');
|
|
151
|
+
const original = baselinePath && !initialize ? readFileSync(baselinePath, 'utf8') : undefined;
|
|
152
|
+
const baseline = original === undefined ? undefined : validateBaseline(JSON.parse(original), config);
|
|
153
|
+
const files = discoverFiles(root, config, positionals, values.changed);
|
|
154
|
+
if (!files.length && values.changed === undefined)
|
|
155
|
+
throw Error('no Swift or Kotlin source files selected; check scope/exclusions');
|
|
156
|
+
const swiftFiles = files.filter(path => path.endsWith('.swift'));
|
|
157
|
+
const kotlinFiles = files.filter(path => path.endsWith('.kt'));
|
|
158
|
+
if (values.fix && kotlinFiles.length)
|
|
159
|
+
throw Error('--fix supports Swift only; select Swift paths for formatting');
|
|
160
|
+
const analyzerEnv = { swift: process.env.SENTORI_LINT_SWIFT, kotlin: process.env.SENTORI_LINT_KOTLIN };
|
|
161
|
+
const runAnalyzers = () => ['swift', 'kotlin'].flatMap(language => {
|
|
162
|
+
const requested = values[`${language}-analyzer`] ?? analyzerEnv[language] ?? `sentori-lint-${language}`;
|
|
163
|
+
const executable = requested.includes('/') || requested.includes('\\') ? resolve(requested) : requested;
|
|
164
|
+
return analyze(root, executable, language === 'swift' ? swiftFiles : kotlinFiles, language);
|
|
165
|
+
});
|
|
166
|
+
const sourceDigest = () => files.map(path => createHash('sha256').update(readFileSync(resolve(root, path))).digest('hex')).join(':');
|
|
167
|
+
let snapshot = initialize || update ? sourceDigest() : undefined;
|
|
168
|
+
let findings = runAnalyzers();
|
|
169
|
+
if (values.fix) {
|
|
170
|
+
// Validate all sources before touching any. Formatting is the only fix;
|
|
171
|
+
// the analyzer never rewrites forced operations or concurrency semantics.
|
|
172
|
+
for (let i = 0; i < files.length; i += 50)
|
|
173
|
+
command('swift', ['format', 'format', '--in-place', '--', ...files.slice(i, i + 50)], root);
|
|
174
|
+
snapshot = initialize || update ? sourceDigest() : undefined;
|
|
175
|
+
findings = runAnalyzers();
|
|
176
|
+
}
|
|
177
|
+
let report = makeReport(files, findings, config, baseline, !positionals.length && values.changed === undefined);
|
|
178
|
+
const cannotWrite = (initialize && report.regressions.some(r => r.kind === 'hard-limit' || ruleById.get(r.rule).allowlistOnly))
|
|
179
|
+
|| (update && report.regressions.length > 0);
|
|
180
|
+
if (cannotWrite)
|
|
181
|
+
console.error('baseline unchanged: resolve regressions/hard limits or add reviewed allowances first');
|
|
182
|
+
if ((initialize || update) && !cannotWrite) {
|
|
183
|
+
if (readFileSync(configPath, 'utf8') !== configSource || JSON.stringify(discoverFiles(root, config)) !== JSON.stringify(files) || sourceDigest() !== snapshot)
|
|
184
|
+
throw Error('source selection or contents changed during scan; baseline unchanged, retry');
|
|
185
|
+
}
|
|
186
|
+
if (initialize && !cannotWrite) {
|
|
187
|
+
const created = initBaseline(report, config);
|
|
188
|
+
writeBaseline(baselinePath, created);
|
|
189
|
+
report = makeReport(files, findings, config, created);
|
|
190
|
+
}
|
|
191
|
+
else if (update && !cannotWrite) {
|
|
192
|
+
const lowered = lowerBaseline(report, baseline);
|
|
193
|
+
writeBaseline(baselinePath, lowered, original);
|
|
194
|
+
report = makeReport(files, findings, config, lowered);
|
|
195
|
+
}
|
|
196
|
+
console.log(values.format === 'text' ? textReport(report) : JSON.stringify(values.format === 'sarif' ? sarif(report) : report, null, 2));
|
|
197
|
+
return report.regressions.length ? 1 : 0;
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
console.error(`sentori lint: ${error.message}`);
|
|
201
|
+
return 2;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lint/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Config } from './config.js';
|
|
2
|
+
import type { Level } from './rules.js';
|
|
3
|
+
export type Finding = {
|
|
4
|
+
rule: string;
|
|
5
|
+
path: string;
|
|
6
|
+
line: number;
|
|
7
|
+
column: number;
|
|
8
|
+
measured?: number;
|
|
9
|
+
};
|
|
10
|
+
export type Result = Finding & {
|
|
11
|
+
level: Level;
|
|
12
|
+
message: string;
|
|
13
|
+
allowance?: string;
|
|
14
|
+
hardLimitExceeded?: boolean;
|
|
15
|
+
};
|
|
16
|
+
export type Baseline = {
|
|
17
|
+
version: 1;
|
|
18
|
+
ruleset: string;
|
|
19
|
+
scope: string;
|
|
20
|
+
counts: Record<string, Record<string, number>>;
|
|
21
|
+
};
|
|
22
|
+
export type Regression = {
|
|
23
|
+
path: string;
|
|
24
|
+
rule: string;
|
|
25
|
+
count: number;
|
|
26
|
+
allowed: number;
|
|
27
|
+
kind: 'count' | 'hard-limit';
|
|
28
|
+
};
|
|
29
|
+
export type Report = {
|
|
30
|
+
version: 1;
|
|
31
|
+
ruleset: string;
|
|
32
|
+
language: 'swift' | 'kotlin' | 'mixed';
|
|
33
|
+
fullScan: boolean;
|
|
34
|
+
files: string[];
|
|
35
|
+
results: Result[];
|
|
36
|
+
regressions: Regression[];
|
|
37
|
+
baselineCanDecrease: boolean;
|
|
38
|
+
};
|
|
39
|
+
export declare function scope(config: Config): string;
|
|
40
|
+
export declare function validateBaseline(value: unknown, config: Config): Baseline;
|
|
41
|
+
export declare function validateResponse(value: unknown, files: string[], language?: 'swift' | 'kotlin'): Finding[];
|
|
42
|
+
export declare function makeReport(files: string[], findings: Finding[], config: Config, baseline?: Baseline, fullScan?: boolean): Report;
|
|
43
|
+
export declare function countResults(results: Result[]): Record<string, Record<string, number>>;
|
|
44
|
+
export declare function initBaseline(report: Report, config: Config): Baseline;
|
|
45
|
+
export declare function lowerBaseline(report: Report, baseline: Baseline): Baseline;
|
|
46
|
+
export declare function sarif(report: Report): unknown;
|
|
47
|
+
export declare function textReport(report: Report): string;
|
|
48
|
+
//# sourceMappingURL=report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/lint/report.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AACvC,MAAM,MAAM,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AACrG,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAAE,CAAA;AACjH,MAAM,MAAM,QAAQ,GAAG;IAAE,OAAO,EAAE,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAAE,CAAA;AACrH,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,GAAG,YAAY,CAAA;CAAE,CAAA;AACrH,MAAM,MAAM,MAAM,GAAG;IACnB,OAAO,EAAE,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;IAC1H,WAAW,EAAE,UAAU,EAAE,CAAC;IAAC,mBAAmB,EAAE,OAAO,CAAA;CACxD,CAAA;AACD,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAI5C;AACD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,CAYzE;AACD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,QAAQ,GAAE,OAAO,GAAG,QAAkB,GAAG,OAAO,EAAE,CAenH;AACD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,QAAQ,UAAO,GAAG,MAAM,CAsB7H;AACD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAQtF;AACD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,CAIrE;AACD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAY1E;AACD,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAwB7C;AACD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAMjD"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { glob, isTest } from './config.js';
|
|
3
|
+
import { ruleById, rules, ruleset, swiftRuleset, kotlinRuleset, ruleLanguage, fileLanguage } from './rules.js';
|
|
4
|
+
export function scope(config) {
|
|
5
|
+
// A different policy is a migration, not an improvement. This also prevents
|
|
6
|
+
// disabling/excluding rules or files from silently erasing baseline debt.
|
|
7
|
+
return createHash('sha256').update(JSON.stringify({ ...config, rules: Object.fromEntries(Object.entries(config.rules).sort()) })).digest('hex');
|
|
8
|
+
}
|
|
9
|
+
export function validateBaseline(value, config) {
|
|
10
|
+
const b = value;
|
|
11
|
+
if (!b || b.version !== 1 || b.ruleset !== ruleset || b.scope !== scope(config) || !b.counts || typeof b.counts !== 'object' || Array.isArray(b.counts)) {
|
|
12
|
+
throw Error('baseline version/ruleset/scope mismatch; policy changes require an explicit baseline migration');
|
|
13
|
+
}
|
|
14
|
+
for (const [path, counts] of Object.entries(b.counts)) {
|
|
15
|
+
if (!path || path.startsWith('/') || path.split('/').includes('..') || !/\.(swift|kt)$/.test(path) || !counts || typeof counts !== 'object' || Array.isArray(counts))
|
|
16
|
+
throw Error('invalid baseline path/counts');
|
|
17
|
+
for (const [id, count] of Object.entries(counts)) {
|
|
18
|
+
if (!ruleById.has(id) || ruleLanguage(id) !== fileLanguage(path) || ruleById.get(id).allowlistOnly || !Number.isSafeInteger(count) || count < 0)
|
|
19
|
+
throw Error(`invalid baseline count for ${path}: ${id}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return b;
|
|
23
|
+
}
|
|
24
|
+
export function validateResponse(value, files, language = 'swift') {
|
|
25
|
+
const response = value;
|
|
26
|
+
if (!response || response.version !== 1 || response.ruleset !== (language === 'swift' ? swiftRuleset : kotlinRuleset) || !Array.isArray(response.files)
|
|
27
|
+
|| JSON.stringify([...response.files].sort()) !== JSON.stringify([...files].sort()) || !Array.isArray(response.diagnostics))
|
|
28
|
+
throw Error('incomplete or incompatible analyzer response');
|
|
29
|
+
const paths = new Set(files), seen = new Set();
|
|
30
|
+
for (const d of response.diagnostics) {
|
|
31
|
+
if (!d || !ruleById.has(d.rule) || ruleLanguage(d.rule) !== language || fileLanguage(d.path) !== language || !paths.has(d.path) || !Number.isSafeInteger(d.line) || d.line < 1 || !Number.isSafeInteger(d.column) || d.column < 1)
|
|
32
|
+
throw Error('invalid analyzer diagnostic');
|
|
33
|
+
const thresholds = ruleById.get(d.rule).thresholds;
|
|
34
|
+
if (thresholds && (!Number.isSafeInteger(d.measured) || d.measured <= thresholds.target))
|
|
35
|
+
throw Error('missing or invalid analyzer measurement');
|
|
36
|
+
if (!thresholds && d.measured !== undefined)
|
|
37
|
+
throw Error('unexpected analyzer measurement');
|
|
38
|
+
const key = JSON.stringify([d.rule, d.path, d.line, d.column]);
|
|
39
|
+
if (seen.has(key))
|
|
40
|
+
throw Error('duplicate analyzer diagnostic');
|
|
41
|
+
seen.add(key);
|
|
42
|
+
}
|
|
43
|
+
return response.diagnostics;
|
|
44
|
+
}
|
|
45
|
+
export function makeReport(files, findings, config, baseline, fullScan = true) {
|
|
46
|
+
const results = findings.filter(d => !isTest(d.path, config) || ruleById.get(d.rule).tests).map(d => {
|
|
47
|
+
const rule = ruleById.get(d.rule);
|
|
48
|
+
const allowance = config.allow.find(a => a.rule === d.rule && glob(a.path).test(d.path))?.reason;
|
|
49
|
+
const hardLimitExceeded = rule.thresholds?.hard !== undefined && d.measured > rule.thresholds.hard;
|
|
50
|
+
const configured = config.rules[d.rule] ?? rule.level;
|
|
51
|
+
const level = configured === 'off' ? 'off' : hardLimitExceeded ? 'error' : configured;
|
|
52
|
+
const measured = rule.thresholds ? ` Measured ${d.measured} ${rule.thresholds.unit}; target ${rule.thresholds.target}${rule.thresholds.hard !== undefined ? `; hard limit ${rule.thresholds.hard}` : ''}.` : '';
|
|
53
|
+
return { ...d, level, message: rule.message + measured, ...(hardLimitExceeded ? { hardLimitExceeded: true } : {}), ...(allowance ? { allowance } : {}) };
|
|
54
|
+
}).filter(d => d.level !== 'off').sort((a, b) => a.path.localeCompare(b.path) || a.line - b.line || a.column - b.column || a.rule.localeCompare(b.rule));
|
|
55
|
+
const counts = countResults(results);
|
|
56
|
+
const regressions = [];
|
|
57
|
+
for (const [path, byRule] of Object.entries(counts)) {
|
|
58
|
+
for (const [rule, count] of Object.entries(byRule)) {
|
|
59
|
+
const allowed = ruleById.get(rule).allowlistOnly ? 0 : baseline?.counts[path]?.[rule] ?? 0;
|
|
60
|
+
const hard = results.some(d => d.path === path && d.rule === rule && d.hardLimitExceeded && !d.allowance);
|
|
61
|
+
if (hard || count > allowed)
|
|
62
|
+
regressions.push({ path, rule, count, allowed, kind: hard ? 'hard-limit' : 'count' });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const scanned = new Set(files);
|
|
66
|
+
const baselineCanDecrease = !!baseline && Object.entries(baseline.counts).some(([path, byRule]) => (fullScan || scanned.has(path)) && Object.entries(byRule).some(([rule, count]) => (counts[path]?.[rule] ?? 0) < count));
|
|
67
|
+
return { version: 1, ruleset, language: files.every(p => p.endsWith('.swift')) ? 'swift' : files.every(p => p.endsWith('.kt')) ? 'kotlin' : 'mixed', fullScan, files, results, regressions, baselineCanDecrease };
|
|
68
|
+
}
|
|
69
|
+
export function countResults(results) {
|
|
70
|
+
const counts = Object.create(null);
|
|
71
|
+
for (const d of results) {
|
|
72
|
+
if (d.allowance || d.level !== 'error')
|
|
73
|
+
continue;
|
|
74
|
+
const byRule = counts[d.path] ??= Object.create(null);
|
|
75
|
+
byRule[d.rule] = (byRule[d.rule] ?? 0) + 1;
|
|
76
|
+
}
|
|
77
|
+
return counts;
|
|
78
|
+
}
|
|
79
|
+
export function initBaseline(report, config) {
|
|
80
|
+
if (!report.fullScan)
|
|
81
|
+
throw Error('cannot initialize baseline from a partial scan');
|
|
82
|
+
if (report.regressions.some(r => r.kind === 'hard-limit' || ruleById.get(r.rule).allowlistOnly))
|
|
83
|
+
throw Error('hard limits and concurrency escape hatches require an allowance; they cannot enter a baseline');
|
|
84
|
+
return { version: 1, ruleset, scope: scope(config), counts: countResults(report.results) };
|
|
85
|
+
}
|
|
86
|
+
export function lowerBaseline(report, baseline) {
|
|
87
|
+
if (!report.fullScan)
|
|
88
|
+
throw Error('cannot update baseline from a partial scan');
|
|
89
|
+
if (report.regressions.length)
|
|
90
|
+
throw Error('cannot update baseline while violations exceed it');
|
|
91
|
+
const current = countResults(report.results);
|
|
92
|
+
const counts = Object.create(null);
|
|
93
|
+
for (const [path, byRule] of Object.entries(baseline.counts)) {
|
|
94
|
+
for (const [id, previous] of Object.entries(byRule)) {
|
|
95
|
+
const count = Math.min(previous, current[path]?.[id] ?? 0);
|
|
96
|
+
if (count)
|
|
97
|
+
(counts[path] ??= Object.create(null))[id] = count;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return { ...baseline, counts };
|
|
101
|
+
}
|
|
102
|
+
export function sarif(report) {
|
|
103
|
+
return {
|
|
104
|
+
$schema: 'https://json.schemastore.org/sarif-2.1.0.json', version: '2.1.0',
|
|
105
|
+
runs: [{
|
|
106
|
+
tool: { driver: { name: 'sentori-lint', semanticVersion: '0.3.0', rules: rules.map(r => ({
|
|
107
|
+
id: r.id, name: r.name, shortDescription: { text: r.message }, fullDescription: { text: r.rationale },
|
|
108
|
+
helpUri: r.reference, defaultConfiguration: { level: r.level === 'warn' ? 'warning' : 'error' },
|
|
109
|
+
properties: { group: r.group, basis: r.basis, section: r.section, fixable: r.fixable, allowlistOnly: r.allowlistOnly, tests: !!r.tests, ...(r.thresholds ? { thresholds: r.thresholds } : {}) },
|
|
110
|
+
})) } },
|
|
111
|
+
columnKind: 'utf16CodeUnits',
|
|
112
|
+
results: report.results.map(d => ({
|
|
113
|
+
ruleId: d.rule, ruleIndex: rules.findIndex(r => r.id === d.rule),
|
|
114
|
+
level: d.level === 'warn' ? 'warning' : 'error', message: { text: d.message },
|
|
115
|
+
locations: [{ physicalLocation: {
|
|
116
|
+
artifactLocation: { uri: d.path.split('/').map(encodeURIComponent).join('/') },
|
|
117
|
+
region: { startLine: d.line, startColumn: d.column },
|
|
118
|
+
} }],
|
|
119
|
+
...(d.measured !== undefined ? { properties: { measured: d.measured, hardLimitExceeded: !!d.hardLimitExceeded } } : {}),
|
|
120
|
+
...(d.allowance ? { suppressions: [{ kind: 'external', justification: d.allowance, status: 'accepted' }] } : {}),
|
|
121
|
+
})),
|
|
122
|
+
properties: { language: report.language, fullScan: report.fullScan, filesScanned: report.files.length, regressions: report.regressions, baselineCanDecrease: report.baselineCanDecrease },
|
|
123
|
+
invocations: [{ executionSuccessful: true }],
|
|
124
|
+
}],
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
export function textReport(report) {
|
|
128
|
+
const lines = report.results.map(d => `${d.path}:${d.line}:${d.column}: ${d.level} ${d.rule} ${d.message}${d.allowance ? ` [allowed: ${d.allowance}]` : ''}`);
|
|
129
|
+
for (const r of report.regressions)
|
|
130
|
+
lines.push(r.kind === 'hard-limit' ? `hard limit exceeded: ${r.path} ${r.rule}` : `regression: ${r.path} ${r.rule}: ${r.count} > ${r.allowed}`);
|
|
131
|
+
lines.push(`${report.language}: ${report.files.length} files, ${report.results.length} findings, ${report.regressions.length} failing rule/file groups.`);
|
|
132
|
+
if (report.baselineCanDecrease)
|
|
133
|
+
lines.push('Baseline can decrease; run a full scan with --update-baseline.');
|
|
134
|
+
return lines.join('\n');
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/lint/report.ts"],"names":[],"mappings":"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"}
|