pr-checkmate 1.22.7 → 1.23.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/README.md +101 -333
- package/cspell.json +9 -1
- package/dist/cli.js +32 -2
- package/dist/config/constants.d.ts +25 -1
- package/dist/config/constants.js +157 -38
- package/dist/config/index.d.ts +15 -2
- package/dist/config/index.js +28 -7
- package/dist/config/loader.js +5 -1
- package/dist/core/checks/dependencies/banned-imports.d.ts +2 -0
- package/dist/core/checks/dependencies/banned-imports.js +71 -0
- package/dist/core/checks/{circular-deps.d.ts → dependencies/circular-deps.d.ts} +1 -1
- package/dist/core/checks/{circular-deps.js → dependencies/circular-deps.js} +9 -10
- package/dist/core/checks/{dependency-check.d.ts → dependencies/dependency-check.d.ts} +1 -1
- package/dist/core/checks/{dependency-check.js → dependencies/dependency-check.js} +3 -3
- package/dist/core/checks/{license-check.d.ts → dependencies/license-check.d.ts} +1 -1
- package/dist/core/checks/{license-check.js → dependencies/license-check.js} +3 -3
- package/dist/core/checks/{npm-audit.d.ts → dependencies/npm-audit.d.ts} +1 -1
- package/dist/core/checks/{npm-audit.js → dependencies/npm-audit.js} +3 -3
- package/dist/core/checks/{outdated-deps.d.ts → dependencies/outdated-deps.d.ts} +1 -1
- package/dist/core/checks/{outdated-deps.js → dependencies/outdated-deps.js} +3 -3
- package/dist/core/checks/dependencies/vuln-scan.d.ts +9 -0
- package/dist/core/checks/dependencies/vuln-scan.js +41 -0
- package/dist/core/checks/findings.d.ts +37 -1
- package/dist/core/checks/findings.js +80 -3
- package/dist/core/checks/git/custom-rules.d.ts +2 -0
- package/dist/core/checks/git/custom-rules.js +102 -0
- package/dist/core/checks/{diff-smell.d.ts → git/diff-smell.d.ts} +1 -1
- package/dist/core/checks/{diff-smell.js → git/diff-smell.js} +3 -3
- package/dist/core/checks/git/large-files.d.ts +2 -0
- package/dist/core/checks/git/large-files.js +83 -0
- package/dist/core/checks/git/leftover-debug.d.ts +2 -0
- package/dist/core/checks/git/leftover-debug.js +77 -0
- package/dist/core/checks/git/lockfile-drift.d.ts +2 -0
- package/dist/core/checks/git/lockfile-drift.js +114 -0
- package/dist/core/checks/git/merge-conflict.d.ts +2 -0
- package/dist/core/checks/git/merge-conflict.js +109 -0
- package/dist/core/checks/git/missing-tests.d.ts +2 -0
- package/dist/core/checks/git/missing-tests.js +92 -0
- package/dist/core/checks/git/todo-fixme.d.ts +7 -0
- package/dist/core/checks/git/todo-fixme.js +74 -0
- package/dist/core/checks/{cpp-format.d.ts → languages/cpp-format.d.ts} +1 -1
- package/dist/core/checks/{cpp-format.js → languages/cpp-format.js} +3 -3
- package/dist/core/checks/languages/csharp-format.d.ts +13 -0
- package/dist/core/checks/languages/csharp-format.js +52 -0
- package/dist/core/checks/languages/go-format.d.ts +8 -0
- package/dist/core/checks/languages/go-format.js +48 -0
- package/dist/core/checks/languages/go-lint.d.ts +8 -0
- package/dist/core/checks/languages/go-lint.js +48 -0
- package/dist/core/checks/{kotlin-lint.d.ts → languages/kotlin-lint.d.ts} +1 -1
- package/dist/core/checks/{kotlin-lint.js → languages/kotlin-lint.js} +13 -17
- package/dist/core/checks/{lint.d.ts → languages/lint.d.ts} +1 -1
- package/dist/core/checks/{lint.js → languages/lint.js} +25 -14
- package/dist/core/checks/languages/php-format.d.ts +9 -0
- package/dist/core/checks/languages/php-format.js +49 -0
- package/dist/core/checks/{prettier.d.ts → languages/prettier.d.ts} +1 -1
- package/dist/core/checks/{prettier.js → languages/prettier.js} +10 -10
- package/dist/core/checks/{python-format.d.ts → languages/python-format.d.ts} +1 -1
- package/dist/core/checks/{python-format.js → languages/python-format.js} +3 -3
- package/dist/core/checks/{python-lint.d.ts → languages/python-lint.d.ts} +1 -1
- package/dist/core/checks/{python-lint.js → languages/python-lint.js} +3 -3
- package/dist/core/checks/languages/python-typecheck.d.ts +9 -0
- package/dist/core/checks/languages/python-typecheck.js +66 -0
- package/dist/core/checks/languages/ruby-lint.d.ts +8 -0
- package/dist/core/checks/languages/ruby-lint.js +50 -0
- package/dist/core/checks/languages/rust-format.d.ts +9 -0
- package/dist/core/checks/languages/rust-format.js +45 -0
- package/dist/core/checks/languages/rust-lint.d.ts +8 -0
- package/dist/core/checks/languages/rust-lint.js +50 -0
- package/dist/core/checks/{swift-lint.d.ts → languages/swift-lint.d.ts} +1 -1
- package/dist/core/checks/{swift-lint.js → languages/swift-lint.js} +13 -17
- package/dist/core/checks/{typecheck.d.ts → languages/typecheck.d.ts} +1 -1
- package/dist/core/checks/{typecheck.js → languages/typecheck.js} +3 -3
- package/dist/core/checks/{commitlint.d.ts → pr/commitlint.d.ts} +1 -1
- package/dist/core/checks/{commitlint.js → pr/commitlint.js} +4 -4
- package/dist/core/checks/{pr-body.d.ts → pr/pr-body.d.ts} +1 -1
- package/dist/core/checks/{pr-body.js → pr/pr-body.js} +2 -2
- package/dist/core/checks/{pr-size-check.d.ts → pr/pr-size-check.d.ts} +1 -1
- package/dist/core/checks/{pr-size-check.js → pr/pr-size-check.js} +13 -11
- package/dist/core/checks/{pr-title-lint.d.ts → pr/pr-title-lint.d.ts} +1 -1
- package/dist/core/checks/{pr-title-lint.js → pr/pr-title-lint.js} +2 -2
- package/dist/core/checks/quality/case-collision.d.ts +8 -0
- package/dist/core/checks/quality/case-collision.js +40 -0
- package/dist/core/checks/quality/config-validation.d.ts +8 -0
- package/dist/core/checks/quality/config-validation.js +63 -0
- package/dist/core/checks/quality/coverage.d.ts +2 -0
- package/dist/core/checks/quality/coverage.js +63 -0
- package/dist/core/checks/{dead-code.d.ts → quality/dead-code.d.ts} +1 -1
- package/dist/core/checks/{dead-code.js → quality/dead-code.js} +4 -4
- package/dist/core/checks/{duplicate-check.d.ts → quality/duplicate-check.d.ts} +1 -1
- package/dist/core/checks/{duplicate-check.js → quality/duplicate-check.js} +11 -15
- package/dist/core/checks/quality/license-header.d.ts +7 -0
- package/dist/core/checks/quality/license-header.js +74 -0
- package/dist/core/checks/{markdown-lint.d.ts → quality/markdown-lint.d.ts} +1 -1
- package/dist/core/checks/{markdown-lint.js → quality/markdown-lint.js} +8 -21
- package/dist/core/checks/{spellcheck.d.ts → quality/spellcheck.d.ts} +1 -1
- package/dist/core/checks/{spellcheck.js → quality/spellcheck.js} +11 -19
- package/dist/core/checks/{diff-security.d.ts → security/diff-security.d.ts} +1 -1
- package/dist/core/checks/security/diff-security.js +262 -0
- package/dist/core/checks/security/dockerfile-security.d.ts +2 -0
- package/dist/core/checks/security/dockerfile-security.js +92 -0
- package/dist/core/checks/security/migration-safety.d.ts +2 -0
- package/dist/core/checks/security/migration-safety.js +110 -0
- package/dist/core/checks/{security.d.ts → security/security.d.ts} +1 -1
- package/dist/core/checks/{security.js → security/security.js} +4 -4
- package/dist/core/checks/{sensitive-file-guard.d.ts → security/sensitive-file-guard.d.ts} +1 -1
- package/dist/core/checks/{sensitive-file-guard.js → security/sensitive-file-guard.js} +4 -4
- package/dist/core/checks/security/workflow-security.d.ts +2 -0
- package/dist/core/checks/security/workflow-security.js +75 -0
- package/dist/core/context.js +54 -10
- package/dist/core/registry.js +73 -28
- package/dist/core/reporters.d.ts +4 -3
- package/dist/core/reporters.js +104 -4
- package/dist/core/run-checks.js +21 -3
- package/dist/core/targets.d.ts +17 -1
- package/dist/core/targets.js +74 -4
- package/dist/core/types.d.ts +13 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -1
- package/dist/init.js +86 -8
- package/dist/interfaces/index.d.ts +101 -1
- package/dist/scripts/copy-configs.js +6 -1
- package/dist/utils/detect-language.d.ts +1 -1
- package/dist/utils/detect-language.js +32 -3
- package/dist/utils/glob.d.ts +10 -0
- package/dist/utils/glob.js +25 -0
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/eslint-default-rules.json +62 -0
- package/eslint.config.mjs +6 -66
- package/package.json +3 -1
- package/pr-checkmate.schema.json +166 -0
- package/src/config/cspell.json +9 -1
- package/src/config/eslint-default-rules.json +62 -0
- package/src/config/pr-checkmate.schema.json +166 -0
- package/dist/core/checks/diff-security.js +0 -145
- package/dist/utils/delta.d.ts +0 -5
- package/dist/utils/delta.js +0 -53
- package/src/config/eslint.config.mjs +0 -180
- /package/dist/core/checks/{ruff-shared.d.ts → languages/ruff-shared.d.ts} +0 -0
- /package/dist/core/checks/{ruff-shared.js → languages/ruff-shared.js} +0 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.missingTestsCheck = void 0;
|
|
4
|
+
const config_1 = require("../../../config");
|
|
5
|
+
const utils_1 = require("../../../utils");
|
|
6
|
+
const execa_1 = require("../../../utils/execa");
|
|
7
|
+
const targets_1 = require("../../targets");
|
|
8
|
+
const types_1 = require("../../types");
|
|
9
|
+
const findings_1 = require("../findings");
|
|
10
|
+
/** Source-file extensions across the supported languages. */
|
|
11
|
+
const SOURCE_EXT = /\.(ts|tsx|js|jsx|mjs|cjs|py|kt|kts|java|swift|cpp|cc|cxx|c|h|hpp|go|rb)$/i;
|
|
12
|
+
/** Test-file conventions across languages. */
|
|
13
|
+
function isTestFile(file) {
|
|
14
|
+
return (/\.(test|spec)\.[cm]?[jt]sx?$/i.test(file) || // foo.test.ts, foo.spec.jsx
|
|
15
|
+
/(^|\/)__tests__\//.test(file) ||
|
|
16
|
+
/(^|\/)tests?\//i.test(file) || // test/ or tests/ dir
|
|
17
|
+
/(^|\/)test_[^/]+\.py$/.test(file) || // test_foo.py
|
|
18
|
+
/_test\.(py|go)$/.test(file) || // foo_test.py, foo_test.go
|
|
19
|
+
/(Test|Spec)s?\.(kt|java|swift)$/.test(file) // FooTest.kt, FooSpec.swift
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Source files that legitimately ship without a test of their own. Setting
|
|
24
|
+
* `missingTests.ignore` REPLACES this list (same convention as duplicate/
|
|
25
|
+
* dead-code ignores).
|
|
26
|
+
*/
|
|
27
|
+
const DEFAULT_IGNORE = [
|
|
28
|
+
'**/*.d.ts',
|
|
29
|
+
'**/index.ts',
|
|
30
|
+
'**/index.tsx',
|
|
31
|
+
'**/index.js',
|
|
32
|
+
'**/index.jsx',
|
|
33
|
+
'**/*.config.*',
|
|
34
|
+
'**/migrations/**',
|
|
35
|
+
'**/migrate/**',
|
|
36
|
+
'**/__init__.py',
|
|
37
|
+
];
|
|
38
|
+
exports.missingTestsCheck = {
|
|
39
|
+
name: 'Missing Tests',
|
|
40
|
+
phase: 'informational',
|
|
41
|
+
applies(ctx) {
|
|
42
|
+
return ctx.config.missingTests?.enabled !== false && Boolean(ctx.baseSha);
|
|
43
|
+
},
|
|
44
|
+
async run(ctx) {
|
|
45
|
+
// Scope the same way lint does — a client's `sourcePath` and `ignoreDirs`
|
|
46
|
+
// both apply, so generated/out-of-scope dirs never count as "new source".
|
|
47
|
+
const scopedList = await (0, targets_1.resolveScopedTargetFiles)(ctx, ['*'], (0, config_1.getSourcePaths)());
|
|
48
|
+
if (scopedList === null)
|
|
49
|
+
return (0, types_1.skip)('git unavailable');
|
|
50
|
+
const scoped = new Set(scopedList);
|
|
51
|
+
const added = [];
|
|
52
|
+
const touched = [];
|
|
53
|
+
try {
|
|
54
|
+
const { stdout } = await (0, execa_1.execa)('git', [
|
|
55
|
+
'diff',
|
|
56
|
+
'--name-status',
|
|
57
|
+
'--diff-filter=ACM',
|
|
58
|
+
ctx.baseSha,
|
|
59
|
+
ctx.headSha ?? 'HEAD',
|
|
60
|
+
], { cwd: ctx.cwd });
|
|
61
|
+
for (const line of stdout.split('\n')) {
|
|
62
|
+
if (!line)
|
|
63
|
+
continue;
|
|
64
|
+
const [status, ...rest] = line.split('\t');
|
|
65
|
+
const file = rest.join('\t');
|
|
66
|
+
if (!file || !scoped.has(file))
|
|
67
|
+
continue;
|
|
68
|
+
touched.push(file);
|
|
69
|
+
if (status === 'A')
|
|
70
|
+
added.push(file);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
utils_1.logger.warn(`[Missing Tests]: ⚠️ Could not analyze diff\n${err}`);
|
|
75
|
+
return (0, types_1.skip)('diff unavailable');
|
|
76
|
+
}
|
|
77
|
+
const ignore = ctx.config.missingTests?.ignore ?? DEFAULT_IGNORE;
|
|
78
|
+
const addedSource = added.filter(f => SOURCE_EXT.test(f) && !isTestFile(f) && !(0, utils_1.matchesAnyGlob)(f, ignore));
|
|
79
|
+
if (addedSource.length === 0)
|
|
80
|
+
return (0, types_1.pass)(); // no new source that would need a test
|
|
81
|
+
// A test added OR modified anywhere in scope satisfies the check.
|
|
82
|
+
if (touched.some(isTestFile))
|
|
83
|
+
return (0, types_1.pass)();
|
|
84
|
+
const sev = (0, findings_1.severityEmitter)(ctx.config.missingTests?.severity, 'warn');
|
|
85
|
+
addedSource
|
|
86
|
+
.slice(0, 5)
|
|
87
|
+
.forEach(f => sev.log(`[Missing Tests]: ${sev.icon} new source without tests: ${f}`));
|
|
88
|
+
if (addedSource.length > 5)
|
|
89
|
+
sev.log(`[Missing Tests]: ${sev.icon} ... and ${addedSource.length - 5} more`);
|
|
90
|
+
return sev.emit(`${addedSource.length} new source file(s) added without any test changes`);
|
|
91
|
+
},
|
|
92
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Check } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Flags leftover TODO/FIXME/XXX/HACK markers in Python and Kotlin/Java comments.
|
|
4
|
+
* JS/TS markers are already handled by the Diff Smells check, so this stays out
|
|
5
|
+
* of those globs to avoid double-reporting (same split as Leftover Debug).
|
|
6
|
+
*/
|
|
7
|
+
export declare const todoFixmeCheck: Check;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.todoFixmeCheck = void 0;
|
|
4
|
+
const utils_1 = require("../../../utils");
|
|
5
|
+
const types_1 = require("../../types");
|
|
6
|
+
const findings_1 = require("../findings");
|
|
7
|
+
const DEFAULT_KEYWORDS = ['TODO', 'FIXME', 'XXX', 'HACK'];
|
|
8
|
+
/** A ticket reference in the comment: `#123` or JIRA-style `PROJ-456`. */
|
|
9
|
+
const TICKET_PATTERN = /#\d+|[A-Z][A-Z0-9]+-\d+/;
|
|
10
|
+
/**
|
|
11
|
+
* Build an added-line matcher for a comment style. `commentFragment` is a regex
|
|
12
|
+
* alternation of the language's comment openers (`#` for Python; `//`/`/*` for
|
|
13
|
+
* Kotlin/Java). Keywords are escaped and captured so the finding is labelled.
|
|
14
|
+
*/
|
|
15
|
+
function buildPattern(commentFragment, keywords) {
|
|
16
|
+
const kw = keywords.map(k => k.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|');
|
|
17
|
+
return new RegExp(`^\\+.*(?:${commentFragment})\\s*(${kw})\\b`, 'i');
|
|
18
|
+
}
|
|
19
|
+
/** Bucket matching added lines by keyword, honouring opt-out and requireTicket. */
|
|
20
|
+
function scan(stdout, pattern, requireTicket, findings) {
|
|
21
|
+
for (const line of stdout.split('\n')) {
|
|
22
|
+
if (line.includes('pr-checkmate-ignore'))
|
|
23
|
+
continue;
|
|
24
|
+
const match = pattern.exec(line);
|
|
25
|
+
if (!match)
|
|
26
|
+
continue;
|
|
27
|
+
// With requireTicket, a marker that already links a ticket is acceptable.
|
|
28
|
+
if (requireTicket && TICKET_PATTERN.test(line))
|
|
29
|
+
continue;
|
|
30
|
+
const keyword = match[1].toUpperCase();
|
|
31
|
+
(findings[keyword] ?? (findings[keyword] = [])).push(line.slice(1).trim().substring(0, 100));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Flags leftover TODO/FIXME/XXX/HACK markers in Python and Kotlin/Java comments.
|
|
36
|
+
* JS/TS markers are already handled by the Diff Smells check, so this stays out
|
|
37
|
+
* of those globs to avoid double-reporting (same split as Leftover Debug).
|
|
38
|
+
*/
|
|
39
|
+
exports.todoFixmeCheck = {
|
|
40
|
+
name: 'TODO/FIXME',
|
|
41
|
+
phase: 'informational',
|
|
42
|
+
applies(ctx) {
|
|
43
|
+
return (ctx.config.todoFixme?.enabled !== false &&
|
|
44
|
+
Boolean(ctx.baseSha) &&
|
|
45
|
+
(ctx.languages.includes('python') || ctx.languages.includes('kotlin')));
|
|
46
|
+
},
|
|
47
|
+
async run(ctx) {
|
|
48
|
+
try {
|
|
49
|
+
const cfg = ctx.config.todoFixme;
|
|
50
|
+
const keywords = cfg?.keywords ?? DEFAULT_KEYWORDS;
|
|
51
|
+
const requireTicket = cfg?.requireTicket ?? false;
|
|
52
|
+
const findings = {};
|
|
53
|
+
if (ctx.languages.includes('python')) {
|
|
54
|
+
scan(await (0, findings_1.diffAddedLines)(ctx, ['*.py']), buildPattern('#', keywords), requireTicket, findings);
|
|
55
|
+
}
|
|
56
|
+
if (ctx.languages.includes('kotlin')) {
|
|
57
|
+
const ktPattern = buildPattern('//|/\\*', keywords);
|
|
58
|
+
scan(await (0, findings_1.diffAddedLines)(ctx, ['*.kt', '*.kts', '*.java']), ktPattern, requireTicket, findings);
|
|
59
|
+
}
|
|
60
|
+
if ((0, findings_1.bucketTotal)(findings) === 0)
|
|
61
|
+
return (0, types_1.pass)();
|
|
62
|
+
const sev = (0, findings_1.severityEmitter)(cfg?.severity, 'warn');
|
|
63
|
+
(0, findings_1.logFindings)(findings, { prefix: 'TODO/FIXME', sampleLimit: 3, isError: sev.icon === '❌' });
|
|
64
|
+
const summary = Object.entries(findings)
|
|
65
|
+
.map(([label, arr]) => `${arr.length}× ${label}`)
|
|
66
|
+
.join(', ') + (requireTicket ? ' (no ticket reference)' : '');
|
|
67
|
+
return sev.emit(summary);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
utils_1.logger.warn(`[TODO/FIXME]: ⚠️ Could not analyze diff\n${err}`);
|
|
71
|
+
return (0, types_1.skip)('diff unavailable');
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
};
|
|
@@ -6,9 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.cppFormatCheck = void 0;
|
|
7
7
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
-
const utils_1 = require("
|
|
10
|
-
const execa_1 = require("
|
|
11
|
-
const types_1 = require("
|
|
9
|
+
const utils_1 = require("../../../utils");
|
|
10
|
+
const execa_1 = require("../../../utils/execa");
|
|
11
|
+
const types_1 = require("../../types");
|
|
12
12
|
/**
|
|
13
13
|
* C/C++ source & header extensions clang-format understands. `.h` is intentionally
|
|
14
14
|
* included even though it is ambiguous with C — clang-format handles both.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Check } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Formats/verifies C# code with `dotnet format` (which also runs the configured
|
|
4
|
+
* analyzers/whitespace/style rules). Runner-dependency: needs the .NET SDK on
|
|
5
|
+
* the runner, gracefully skipping when absent. Read-only in check mode
|
|
6
|
+
* (`--verify-no-changes`); rewrites in place with `dotnet format` when `write`,
|
|
7
|
+
* so CI can auto-commit — mirrors the other format checks.
|
|
8
|
+
*
|
|
9
|
+
* Note: `dotnet format` operates on the project/solution (needs a prior
|
|
10
|
+
* `dotnet restore`), so it runs over the whole project; the delta check only
|
|
11
|
+
* gates whether it runs at all.
|
|
12
|
+
*/
|
|
13
|
+
export declare const csharpFormatCheck: Check;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.csharpFormatCheck = void 0;
|
|
4
|
+
const utils_1 = require("../../../utils");
|
|
5
|
+
const execa_1 = require("../../../utils/execa");
|
|
6
|
+
const targets_1 = require("../../targets");
|
|
7
|
+
const types_1 = require("../../types");
|
|
8
|
+
const CS_GLOBS = ['*.cs'];
|
|
9
|
+
/**
|
|
10
|
+
* Formats/verifies C# code with `dotnet format` (which also runs the configured
|
|
11
|
+
* analyzers/whitespace/style rules). Runner-dependency: needs the .NET SDK on
|
|
12
|
+
* the runner, gracefully skipping when absent. Read-only in check mode
|
|
13
|
+
* (`--verify-no-changes`); rewrites in place with `dotnet format` when `write`,
|
|
14
|
+
* so CI can auto-commit — mirrors the other format checks.
|
|
15
|
+
*
|
|
16
|
+
* Note: `dotnet format` operates on the project/solution (needs a prior
|
|
17
|
+
* `dotnet restore`), so it runs over the whole project; the delta check only
|
|
18
|
+
* gates whether it runs at all.
|
|
19
|
+
*/
|
|
20
|
+
exports.csharpFormatCheck = {
|
|
21
|
+
name: 'C# Format',
|
|
22
|
+
phase: 'format',
|
|
23
|
+
applies(ctx) {
|
|
24
|
+
return ctx.config.csharp?.enabled !== false && ctx.languages.includes('csharp');
|
|
25
|
+
},
|
|
26
|
+
async run(ctx) {
|
|
27
|
+
const targets = await (0, targets_1.resolveTargetFiles)(ctx, CS_GLOBS);
|
|
28
|
+
if (targets === null)
|
|
29
|
+
return (0, types_1.skip)('git unavailable');
|
|
30
|
+
if (targets.length === 0)
|
|
31
|
+
return (0, types_1.pass)('no C# files changed');
|
|
32
|
+
const check = await (0, execa_1.execa)('dotnet', ['format', '--verify-no-changes'], {
|
|
33
|
+
cwd: ctx.cwd,
|
|
34
|
+
reject: false,
|
|
35
|
+
});
|
|
36
|
+
if (check.code === 'ENOENT')
|
|
37
|
+
return (0, types_1.skip)('dotnet SDK not installed');
|
|
38
|
+
if (check.exitCode === 0)
|
|
39
|
+
return (0, types_1.pass)();
|
|
40
|
+
if (!ctx.write) {
|
|
41
|
+
utils_1.logger.warn('[C# Format]: ⚠️ C# code needs formatting (dotnet format --verify-no-changes failed)');
|
|
42
|
+
return (0, types_1.warn)('C# code needs formatting (run with write to fix)');
|
|
43
|
+
}
|
|
44
|
+
const fix = await (0, execa_1.execa)('dotnet', ['format'], { cwd: ctx.cwd, reject: false });
|
|
45
|
+
if (fix.exitCode !== 0) {
|
|
46
|
+
utils_1.logger.warn(`[C# Format]: ⚠️ dotnet format failed\n${fix.stderr}`);
|
|
47
|
+
return (0, types_1.warn)('dotnet format failed to rewrite files');
|
|
48
|
+
}
|
|
49
|
+
utils_1.logger.info('[C# Format]: ✅ Reformatted C# code');
|
|
50
|
+
return (0, types_1.pass)('reformatted C# code');
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Check } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Formats changed Go files with `gofmt`. Runner-dependency (needs `gofmt` on the
|
|
4
|
+
* runner), gracefully skipping when absent. Read-only in check mode (`gofmt -l`
|
|
5
|
+
* lists files that differ from gofmt output); rewrites in place with `gofmt -w`
|
|
6
|
+
* when `write`, so CI can auto-commit — mirrors the Prettier/C++/Ruff format checks.
|
|
7
|
+
*/
|
|
8
|
+
export declare const goFormatCheck: Check;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.goFormatCheck = void 0;
|
|
4
|
+
const utils_1 = require("../../../utils");
|
|
5
|
+
const execa_1 = require("../../../utils/execa");
|
|
6
|
+
const targets_1 = require("../../targets");
|
|
7
|
+
const types_1 = require("../../types");
|
|
8
|
+
const GO_GLOBS = ['*.go'];
|
|
9
|
+
/**
|
|
10
|
+
* Formats changed Go files with `gofmt`. Runner-dependency (needs `gofmt` on the
|
|
11
|
+
* runner), gracefully skipping when absent. Read-only in check mode (`gofmt -l`
|
|
12
|
+
* lists files that differ from gofmt output); rewrites in place with `gofmt -w`
|
|
13
|
+
* when `write`, so CI can auto-commit — mirrors the Prettier/C++/Ruff format checks.
|
|
14
|
+
*/
|
|
15
|
+
exports.goFormatCheck = {
|
|
16
|
+
name: 'Go Format',
|
|
17
|
+
phase: 'format',
|
|
18
|
+
applies(ctx) {
|
|
19
|
+
return ctx.config.go?.enabled !== false && ctx.languages.includes('go');
|
|
20
|
+
},
|
|
21
|
+
async run(ctx) {
|
|
22
|
+
const targets = await (0, targets_1.resolveTargetFiles)(ctx, GO_GLOBS);
|
|
23
|
+
if (targets === null)
|
|
24
|
+
return (0, types_1.skip)('git unavailable');
|
|
25
|
+
if (targets.length === 0)
|
|
26
|
+
return (0, types_1.pass)('no Go files changed');
|
|
27
|
+
const list = await (0, execa_1.execa)('gofmt', ['-l', ...targets], { cwd: ctx.cwd, reject: false });
|
|
28
|
+
// execa v9 with reject:false resolves (not throws) with `code: 'ENOENT'` when
|
|
29
|
+
// the binary is absent — detect the missing toolchain on the result.
|
|
30
|
+
if (list.code === 'ENOENT')
|
|
31
|
+
return (0, types_1.skip)('gofmt not installed');
|
|
32
|
+
const unformatted = list.stdout.split('\n').filter(Boolean);
|
|
33
|
+
if (unformatted.length === 0)
|
|
34
|
+
return (0, types_1.pass)();
|
|
35
|
+
if (!ctx.write) {
|
|
36
|
+
utils_1.logger.warn(`[Go Format]: ⚠️ ${unformatted.length} Go file(s) need formatting`);
|
|
37
|
+
unformatted.slice(0, 10).forEach(f => utils_1.logger.warn(` ${f}`));
|
|
38
|
+
return (0, types_1.warn)(`${unformatted.length} file(s) need formatting (run with write to fix)`);
|
|
39
|
+
}
|
|
40
|
+
const fix = await (0, execa_1.execa)('gofmt', ['-w', ...unformatted], { cwd: ctx.cwd, reject: false });
|
|
41
|
+
if (fix.exitCode !== 0) {
|
|
42
|
+
utils_1.logger.warn(`[Go Format]: ⚠️ gofmt -w failed\n${fix.stderr}`);
|
|
43
|
+
return (0, types_1.warn)('gofmt failed to rewrite files');
|
|
44
|
+
}
|
|
45
|
+
utils_1.logger.info(`[Go Format]: ✅ Reformatted ${unformatted.length} Go file(s)`);
|
|
46
|
+
return (0, types_1.pass)(`reformatted ${unformatted.length} file(s)`);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Check } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Vets changed Go code with `go vet ./...`. Runner-dependency: requires the Go
|
|
4
|
+
* toolchain on the runner (like SwiftLint/ktlint), and gracefully skips when
|
|
5
|
+
* `go` is absent. `go vet` operates per-package, so it runs over the module
|
|
6
|
+
* rather than a file list; the delta check only gates whether it runs at all.
|
|
7
|
+
*/
|
|
8
|
+
export declare const goLintCheck: Check;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.goLintCheck = void 0;
|
|
4
|
+
const utils_1 = require("../../../utils");
|
|
5
|
+
const execa_1 = require("../../../utils/execa");
|
|
6
|
+
const targets_1 = require("../../targets");
|
|
7
|
+
const types_1 = require("../../types");
|
|
8
|
+
const GO_GLOBS = ['*.go'];
|
|
9
|
+
/**
|
|
10
|
+
* Vets changed Go code with `go vet ./...`. Runner-dependency: requires the Go
|
|
11
|
+
* toolchain on the runner (like SwiftLint/ktlint), and gracefully skips when
|
|
12
|
+
* `go` is absent. `go vet` operates per-package, so it runs over the module
|
|
13
|
+
* rather than a file list; the delta check only gates whether it runs at all.
|
|
14
|
+
*/
|
|
15
|
+
exports.goLintCheck = {
|
|
16
|
+
name: 'Go Vet',
|
|
17
|
+
phase: 'informational',
|
|
18
|
+
applies(ctx) {
|
|
19
|
+
return ctx.config.go?.enabled !== false && ctx.languages.includes('go');
|
|
20
|
+
},
|
|
21
|
+
async run(ctx) {
|
|
22
|
+
const targets = await (0, targets_1.resolveTargetFiles)(ctx, GO_GLOBS);
|
|
23
|
+
if (targets === null)
|
|
24
|
+
return (0, types_1.skip)('git unavailable');
|
|
25
|
+
if (targets.length === 0)
|
|
26
|
+
return (0, types_1.pass)('no Go files changed');
|
|
27
|
+
const result = await (0, execa_1.execa)('go', ['vet', './...'], { cwd: ctx.cwd, reject: false });
|
|
28
|
+
// execa v9 with reject:false does NOT throw on a missing binary — it resolves
|
|
29
|
+
// with `code: 'ENOENT'`. Detect that on the result, not via try/catch.
|
|
30
|
+
if (result.code === 'ENOENT')
|
|
31
|
+
return (0, types_1.skip)('go not installed');
|
|
32
|
+
if (result.exitCode === 0) {
|
|
33
|
+
utils_1.logger.info('[Go Vet]: ✅ No issues found');
|
|
34
|
+
return (0, types_1.pass)();
|
|
35
|
+
}
|
|
36
|
+
// go vet writes diagnostics (and build errors) to stderr.
|
|
37
|
+
const lines = [result.stderr, result.stdout]
|
|
38
|
+
.filter(Boolean)
|
|
39
|
+
.join('\n')
|
|
40
|
+
.split('\n')
|
|
41
|
+
.filter(Boolean);
|
|
42
|
+
utils_1.logger.warn(`[Go Vet]: ⚠️ ${lines.length} line(s) of diagnostics:`);
|
|
43
|
+
lines.slice(0, 10).forEach(l => utils_1.logger.warn(` ${l}`));
|
|
44
|
+
if (lines.length > 10)
|
|
45
|
+
utils_1.logger.warn(` ... and ${lines.length - 10} more`);
|
|
46
|
+
return (0, types_1.warn)(`${lines.length} diagnostic line(s)`);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Check } from '
|
|
1
|
+
import { Check } from '../../types';
|
|
2
2
|
export declare const kotlinLintCheck: Check;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.kotlinLintCheck = void 0;
|
|
4
|
-
const utils_1 = require("
|
|
5
|
-
const execa_1 = require("
|
|
6
|
-
const targets_1 = require("
|
|
7
|
-
const types_1 = require("
|
|
4
|
+
const utils_1 = require("../../../utils");
|
|
5
|
+
const execa_1 = require("../../../utils/execa");
|
|
6
|
+
const targets_1 = require("../../targets");
|
|
7
|
+
const types_1 = require("../../types");
|
|
8
8
|
const KOTLIN_GLOBS = ['*.kt', '*.kts'];
|
|
9
9
|
exports.kotlinLintCheck = {
|
|
10
10
|
name: 'ktlint',
|
|
@@ -18,19 +18,15 @@ exports.kotlinLintCheck = {
|
|
|
18
18
|
return (0, types_1.skip)('git unavailable');
|
|
19
19
|
if (targets.length === 0)
|
|
20
20
|
return (0, types_1.pass)('no Kotlin files changed');
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return (0, types_1.skip)('ktlint not installed');
|
|
31
|
-
}
|
|
32
|
-
throw err;
|
|
33
|
-
}
|
|
21
|
+
const result = await (0, execa_1.execa)('ktlint', ['--reporter=plain', ...targets], {
|
|
22
|
+
cwd: ctx.cwd,
|
|
23
|
+
reject: false,
|
|
24
|
+
});
|
|
25
|
+
// execa v9 with reject:false does NOT throw on a missing binary — it resolves
|
|
26
|
+
// with `code: 'ENOENT'`. Detect the absent toolchain on the result, not via a
|
|
27
|
+
// try/catch (which never fires here and would let a missing linter pass silently).
|
|
28
|
+
if (result.code === 'ENOENT')
|
|
29
|
+
return (0, types_1.skip)('ktlint not installed');
|
|
34
30
|
const output = [result.stdout, result.stderr].filter(Boolean).join('\n').trim();
|
|
35
31
|
if (result.exitCode === 0 || !output) {
|
|
36
32
|
utils_1.logger.info('[ktlint]: ✅ No issues found');
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Check } from '
|
|
1
|
+
import { Check } from '../../types';
|
|
2
2
|
export declare const lintCheck: Check;
|
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.lintCheck = void 0;
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
4
|
+
const config_1 = require("../../../config");
|
|
5
|
+
const utils_1 = require("../../../utils");
|
|
6
|
+
const execa_1 = require("../../../utils/execa");
|
|
7
|
+
const targets_1 = require("../../targets");
|
|
8
|
+
const types_1 = require("../../types");
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the ESLint binary, preferring the consumer project's own copy so a
|
|
11
|
+
* repo pinned to ESLint 8 (+ legacy `.eslintrc.*`) keeps working. Falls back to
|
|
12
|
+
* the version bundled with pr-checkmate when the project has no local install.
|
|
13
|
+
*/
|
|
14
|
+
function resolveESLintBin(cwd) {
|
|
15
|
+
try {
|
|
16
|
+
return (0, utils_1.resolvePackageBin)('eslint', 'bin/eslint.js', { paths: [cwd] });
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return (0, utils_1.resolvePackageBin)('eslint', 'bin/eslint.js');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
13
22
|
async function getESLintMajorVersion(eslintBin) {
|
|
14
23
|
try {
|
|
15
24
|
const { stdout } = await (0, execa_1.execa)(process.execPath, [eslintBin, '--version']);
|
|
@@ -27,10 +36,12 @@ exports.lintCheck = {
|
|
|
27
36
|
return ctx.languages.includes('typescript') || ctx.languages.includes('javascript');
|
|
28
37
|
},
|
|
29
38
|
async run(ctx) {
|
|
30
|
-
const eslintBin = (
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
39
|
+
const eslintBin = resolveESLintBin(ctx.cwd);
|
|
40
|
+
const targets = await (0, targets_1.resolveScopedTargetFiles)(ctx, ['*.ts', '*.tsx', '*.js', '*.jsx'], (0, config_1.getSourcePaths)());
|
|
41
|
+
if (targets === null)
|
|
42
|
+
return (0, types_1.skip)('git unavailable');
|
|
43
|
+
if (targets.length === 0)
|
|
44
|
+
return (0, types_1.pass)('no TypeScript/JavaScript files to lint');
|
|
34
45
|
const hasLocal = (0, config_1.hasLocalConfig)([
|
|
35
46
|
'eslint.config.mjs',
|
|
36
47
|
'eslint.config.js',
|
|
@@ -50,7 +61,7 @@ exports.lintCheck = {
|
|
|
50
61
|
if (ctx.write)
|
|
51
62
|
args.push('--fix');
|
|
52
63
|
if (hasLocal) {
|
|
53
|
-
utils_1.logger.info(`[ESLint]: Using local config (
|
|
64
|
+
utils_1.logger.info(`[ESLint]: Using local config (${targets.length} file(s))`);
|
|
54
65
|
}
|
|
55
66
|
else {
|
|
56
67
|
const configFile = version >= 9 ? 'eslint.config.mjs' : '.eslintrc.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Check } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Formats changed PHP files with PHP-CS-Fixer. Runner-dependency: needs
|
|
4
|
+
* `php-cs-fixer` on the runner, gracefully skipping when absent. Read-only in
|
|
5
|
+
* check mode (`--dry-run`); rewrites in place when `write`, so CI can
|
|
6
|
+
* auto-commit — mirrors the other format checks. Uses the repo's own
|
|
7
|
+
* `.php-cs-fixer.php` config when present.
|
|
8
|
+
*/
|
|
9
|
+
export declare const phpFormatCheck: Check;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.phpFormatCheck = void 0;
|
|
4
|
+
const utils_1 = require("../../../utils");
|
|
5
|
+
const execa_1 = require("../../../utils/execa");
|
|
6
|
+
const targets_1 = require("../../targets");
|
|
7
|
+
const types_1 = require("../../types");
|
|
8
|
+
const PHP_GLOBS = ['*.php'];
|
|
9
|
+
/**
|
|
10
|
+
* Formats changed PHP files with PHP-CS-Fixer. Runner-dependency: needs
|
|
11
|
+
* `php-cs-fixer` on the runner, gracefully skipping when absent. Read-only in
|
|
12
|
+
* check mode (`--dry-run`); rewrites in place when `write`, so CI can
|
|
13
|
+
* auto-commit — mirrors the other format checks. Uses the repo's own
|
|
14
|
+
* `.php-cs-fixer.php` config when present.
|
|
15
|
+
*/
|
|
16
|
+
exports.phpFormatCheck = {
|
|
17
|
+
name: 'PHP CS Fixer',
|
|
18
|
+
phase: 'format',
|
|
19
|
+
applies(ctx) {
|
|
20
|
+
return ctx.config.php?.enabled !== false && ctx.languages.includes('php');
|
|
21
|
+
},
|
|
22
|
+
async run(ctx) {
|
|
23
|
+
const targets = await (0, targets_1.resolveTargetFiles)(ctx, PHP_GLOBS);
|
|
24
|
+
if (targets === null)
|
|
25
|
+
return (0, types_1.skip)('git unavailable');
|
|
26
|
+
if (targets.length === 0)
|
|
27
|
+
return (0, types_1.pass)('no PHP files changed');
|
|
28
|
+
const baseArgs = ['fix', '--using-cache=no', ...targets];
|
|
29
|
+
const dry = await (0, execa_1.execa)('php-cs-fixer', [...baseArgs, '--dry-run'], {
|
|
30
|
+
cwd: ctx.cwd,
|
|
31
|
+
reject: false,
|
|
32
|
+
});
|
|
33
|
+
if (dry.code === 'ENOENT')
|
|
34
|
+
return (0, types_1.skip)('php-cs-fixer not installed');
|
|
35
|
+
if (dry.exitCode === 0)
|
|
36
|
+
return (0, types_1.pass)();
|
|
37
|
+
if (!ctx.write) {
|
|
38
|
+
utils_1.logger.warn('[PHP CS Fixer]: ⚠️ PHP code needs formatting');
|
|
39
|
+
return (0, types_1.warn)('PHP code needs formatting (run with write to fix)');
|
|
40
|
+
}
|
|
41
|
+
const fix = await (0, execa_1.execa)('php-cs-fixer', baseArgs, { cwd: ctx.cwd, reject: false });
|
|
42
|
+
if (fix.exitCode !== 0) {
|
|
43
|
+
utils_1.logger.warn(`[PHP CS Fixer]: ⚠️ php-cs-fixer failed\n${fix.stderr}`);
|
|
44
|
+
return (0, types_1.warn)('php-cs-fixer failed to rewrite files');
|
|
45
|
+
}
|
|
46
|
+
utils_1.logger.info('[PHP CS Fixer]: ✅ Reformatted PHP code');
|
|
47
|
+
return (0, types_1.pass)('reformatted PHP code');
|
|
48
|
+
},
|
|
49
|
+
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Check } from '
|
|
1
|
+
import { Check } from '../../types';
|
|
2
2
|
export declare const prettierCheck: Check;
|
|
@@ -6,11 +6,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.prettierCheck = void 0;
|
|
7
7
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
-
const config_1 = require("
|
|
10
|
-
const utils_1 = require("
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const types_1 = require("
|
|
9
|
+
const config_1 = require("../../../config");
|
|
10
|
+
const utils_1 = require("../../../utils");
|
|
11
|
+
const execa_1 = require("../../../utils/execa");
|
|
12
|
+
const targets_1 = require("../../targets");
|
|
13
|
+
const types_1 = require("../../types");
|
|
14
14
|
function loadUserPrettierConfig(cwd) {
|
|
15
15
|
const configPath = node_path_1.default.join(cwd, 'pr-checkmate.json');
|
|
16
16
|
if (!node_fs_1.default.existsSync(configPath))
|
|
@@ -42,11 +42,11 @@ exports.prettierCheck = {
|
|
|
42
42
|
return ctx.languages.includes('typescript') || ctx.languages.includes('javascript');
|
|
43
43
|
},
|
|
44
44
|
async run(ctx) {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
const targets = await (0, targets_1.resolveScopedTargetFiles)(ctx, ['*.ts', '*.tsx', '*.js', '*.jsx', '*.json', '*.md'], (0, config_1.getSourcePaths)());
|
|
46
|
+
if (targets === null)
|
|
47
|
+
return (0, types_1.skip)('git unavailable');
|
|
48
|
+
if (targets.length === 0)
|
|
49
|
+
return (0, types_1.pass)('no files to format');
|
|
50
50
|
const projectIgnore = node_path_1.default.join(ctx.cwd, '.prettierignore');
|
|
51
51
|
const gitignore = node_path_1.default.join(ctx.cwd, '.gitignore');
|
|
52
52
|
let tempIgnore = null;
|
|
@@ -6,9 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.pythonFormatCheck = void 0;
|
|
7
7
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
-
const utils_1 = require("
|
|
10
|
-
const targets_1 = require("
|
|
11
|
-
const types_1 = require("
|
|
9
|
+
const utils_1 = require("../../../utils");
|
|
10
|
+
const targets_1 = require("../../targets");
|
|
11
|
+
const types_1 = require("../../types");
|
|
12
12
|
const ruff_shared_1 = require("./ruff-shared");
|
|
13
13
|
/**
|
|
14
14
|
* Formats changed Python files with Ruff's formatter (WASM, no Python/pip needed).
|
|
@@ -6,9 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.pythonLintCheck = void 0;
|
|
7
7
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
-
const utils_1 = require("
|
|
10
|
-
const targets_1 = require("
|
|
11
|
-
const types_1 = require("
|
|
9
|
+
const utils_1 = require("../../../utils");
|
|
10
|
+
const targets_1 = require("../../targets");
|
|
11
|
+
const types_1 = require("../../types");
|
|
12
12
|
const ruff_shared_1 = require("./ruff-shared");
|
|
13
13
|
/**
|
|
14
14
|
* Lints changed Python files with Ruff, bundled as a self-contained WASM module
|