pr-checkmate 2.1.2 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -268
- package/cspell.json +470 -447
- package/dist/cli.js +1 -1
- package/dist/config/constants.d.ts +6 -1
- package/dist/config/constants.js +9 -7
- package/dist/config/index.d.ts +23 -11
- package/dist/config/index.js +27 -33
- package/dist/core/checks/dependencies/banned-imports.js +4 -1
- package/dist/core/checks/dependencies/circular-deps.js +14 -5
- package/dist/core/checks/dependencies/dependency-check.js +1 -1
- package/dist/core/checks/dependencies/grype-scan.js +2 -1
- package/dist/core/checks/dependencies/vuln-scan.js +2 -1
- package/dist/core/checks/findings.d.ts +46 -2
- package/dist/core/checks/findings.js +140 -2
- package/dist/core/checks/git/custom-rules.js +2 -0
- package/dist/core/checks/git/diff-smell.js +6 -1
- package/dist/core/checks/git/leftover-debug.js +8 -2
- package/dist/core/checks/git/lockfile-drift.js +6 -1
- package/dist/core/checks/git/merge-conflict.js +1 -1
- package/dist/core/checks/git/missing-tests.js +1 -1
- package/dist/core/checks/git/todo-fixme.js +10 -2
- package/dist/core/checks/languages/cpp-format.js +19 -42
- package/dist/core/checks/languages/external-checks.d.ts +77 -0
- package/dist/core/checks/languages/external-checks.js +200 -0
- package/dist/core/checks/languages/external-runner.d.ts +119 -0
- package/dist/core/checks/languages/external-runner.js +143 -0
- package/dist/core/checks/languages/go-format.d.ts +4 -4
- package/dist/core/checks/languages/go-format.js +151 -30
- package/dist/core/checks/languages/lint.js +19 -19
- package/dist/core/checks/languages/prettier.js +2 -7
- package/dist/core/checks/languages/python-typecheck.d.ts +10 -5
- package/dist/core/checks/languages/python-typecheck.js +161 -37
- package/dist/core/checks/languages/ruff-shared.d.ts +3 -3
- package/dist/core/checks/languages/ruff-shared.js +27 -4
- package/dist/core/checks/languages/typecheck.js +10 -8
- package/dist/core/checks/pr/commitlint.js +7 -1
- package/dist/core/checks/quality/case-collision.js +6 -4
- package/dist/core/checks/quality/config-validation.d.ts +0 -7
- package/dist/core/checks/quality/config-validation.js +30 -0
- package/dist/core/checks/quality/coverage.js +6 -1
- package/dist/core/checks/quality/dead-code.js +12 -3
- package/dist/core/checks/quality/duplicate-check.js +54 -27
- package/dist/core/checks/quality/license-header.js +7 -4
- package/dist/core/checks/quality/markdown-lint.js +1 -6
- package/dist/core/checks/quality/package-size.d.ts +15 -0
- package/dist/core/checks/quality/package-size.js +130 -0
- package/dist/core/checks/quality/spellcheck.js +34 -5
- package/dist/core/checks/quality/symlinks.js +6 -4
- package/dist/core/checks/security/diff-security.js +26 -18
- package/dist/core/checks/security/dockerfile-security.js +7 -1
- package/dist/core/checks/security/migration-safety.js +32 -4
- package/dist/core/checks/security/security.d.ts +56 -0
- package/dist/core/checks/security/security.js +135 -11
- package/dist/core/checks/security/sensitive-file-guard.js +40 -6
- package/dist/core/checks/security/workflow-security.js +7 -1
- package/dist/core/checks/tool-install.d.ts +102 -0
- package/dist/core/checks/tool-install.js +69 -0
- package/dist/core/commands.js +1 -0
- package/dist/core/context.js +9 -1
- package/dist/core/install/cache.d.ts +20 -1
- package/dist/core/install/cache.js +65 -12
- package/dist/core/install/doctor.js +49 -15
- package/dist/core/install/ensure.d.ts +31 -14
- package/dist/core/install/ensure.js +165 -61
- package/dist/core/install/lock.d.ts +2 -1
- package/dist/core/install/merge.d.ts +47 -0
- package/dist/core/install/merge.js +91 -0
- package/dist/core/install/prepare.d.ts +76 -0
- package/dist/core/install/prepare.js +147 -0
- package/dist/core/install/profiles.d.ts +17 -3
- package/dist/core/install/profiles.js +27 -0
- package/dist/core/install/reuse.d.ts +41 -0
- package/dist/core/install/reuse.js +107 -0
- package/dist/core/registry.js +12 -18
- package/dist/core/run-checks.js +74 -3
- package/dist/core/targets.d.ts +116 -5
- package/dist/core/targets.js +101 -16
- package/dist/core/types.d.ts +8 -2
- package/dist/init.js +21 -1
- package/dist/interfaces/index.d.ts +6 -0
- package/dist/utils/resolve-bin.d.ts +56 -6
- package/dist/utils/resolve-bin.js +136 -26
- package/gitleaks.toml +14 -0
- package/install-manifests/commitlint/package-lock.json +128 -250
- package/install-manifests/commitlint/package.json +2 -2
- package/install-manifests/core/package-lock.json +76 -76
- package/install-manifests/core/package.json +1 -1
- package/install-manifests/duplicate/package-lock.json +45 -45
- package/install-manifests/duplicate/package.json +1 -1
- package/install-manifests/go/package-lock.json +24 -0
- package/install-manifests/go/package.json +8 -0
- package/install-manifests/js/package-lock.json +248 -283
- package/install-manifests/js/package.json +9 -9
- package/install-manifests/python/package-lock.json +4 -4
- package/install-manifests/python/package.json +1 -1
- package/install-manifests/pytypes/package-lock.json +45 -0
- package/install-manifests/pytypes/package.json +8 -0
- package/package.json +21 -19
- package/pr-checkmate.schema.json +41 -13
- package/src/config/cspell.json +470 -447
- package/src/config/pr-checkmate.schema.json +41 -13
- package/dist/core/checks/languages/csharp-format.d.ts +0 -13
- package/dist/core/checks/languages/csharp-format.js +0 -52
- package/dist/core/checks/languages/go-lint.d.ts +0 -8
- package/dist/core/checks/languages/go-lint.js +0 -48
- package/dist/core/checks/languages/kotlin-lint.d.ts +0 -2
- package/dist/core/checks/languages/kotlin-lint.js +0 -42
- package/dist/core/checks/languages/php-format.d.ts +0 -9
- package/dist/core/checks/languages/php-format.js +0 -49
- package/dist/core/checks/languages/ruby-lint.d.ts +0 -8
- package/dist/core/checks/languages/ruby-lint.js +0 -50
- package/dist/core/checks/languages/rust-format.d.ts +0 -9
- package/dist/core/checks/languages/rust-format.js +0 -45
- package/dist/core/checks/languages/rust-lint.d.ts +0 -8
- package/dist/core/checks/languages/rust-lint.js +0 -50
- package/dist/core/checks/languages/shellcheck.d.ts +0 -8
- package/dist/core/checks/languages/shellcheck.js +0 -55
- package/dist/core/checks/languages/swift-lint.d.ts +0 -2
- package/dist/core/checks/languages/swift-lint.js +0 -46
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"default": "."
|
|
25
25
|
},
|
|
26
26
|
"excludePaths": {
|
|
27
|
-
"description": "Files and folders no check ever looks at, as globs (\"src/generated/**\", \"vendor/legacy.ts\", \"**/*.min.js\"). Unlike ignoreDirs
|
|
27
|
+
"description": "Files and folders no check ever looks at, as globs (\"src/generated/**\", \"vendor/legacy.ts\", \"**/*.min.js\"). Unlike ignoreDirs \u2014 which matches a directory NAME on any segment \u2014 this addresses one path or one file.",
|
|
28
28
|
"type": "array",
|
|
29
29
|
"items": {
|
|
30
30
|
"type": "string"
|
|
@@ -270,7 +270,7 @@
|
|
|
270
270
|
"description": "Secret scanning (gitleaks) and npm audit."
|
|
271
271
|
},
|
|
272
272
|
"mergeConflict": {
|
|
273
|
-
"description": "Conflict markers left in a file. Blocking by default
|
|
273
|
+
"description": "Conflict markers left in a file. Blocking by default \u2014 this is breakage, not an opinion.",
|
|
274
274
|
"type": "object",
|
|
275
275
|
"properties": {
|
|
276
276
|
"enabled": {
|
|
@@ -336,7 +336,7 @@
|
|
|
336
336
|
"type": "object",
|
|
337
337
|
"properties": {
|
|
338
338
|
"ignorePaths": {
|
|
339
|
-
"description": "Globs for files this check never looks at
|
|
339
|
+
"description": "Globs for files this check never looks at \u2014 the exclusion for a single false positive (a .pem fixture). Unlike \"ignore\", it does not silence a whole category.",
|
|
340
340
|
"type": "array",
|
|
341
341
|
"items": {
|
|
342
342
|
"type": "string"
|
|
@@ -502,7 +502,7 @@
|
|
|
502
502
|
"default": true
|
|
503
503
|
}
|
|
504
504
|
},
|
|
505
|
-
"description": "Validates the pull request description
|
|
505
|
+
"description": "Validates the pull request description \u2014 minimum length, ticket reference."
|
|
506
506
|
},
|
|
507
507
|
"cpp": {
|
|
508
508
|
"$ref": "#/$defs/toggle"
|
|
@@ -573,7 +573,7 @@
|
|
|
573
573
|
"enum": ["auto", "always", "never"]
|
|
574
574
|
},
|
|
575
575
|
"onDegradedScope": {
|
|
576
|
-
"description": "What to do when a CI run wanted a diff range, could not build one, and fell back to a full scan
|
|
576
|
+
"description": "What to do when a CI run wanted a diff range, could not build one, and fell back to a full scan \u2014 which silently drops every diff-only check. Never triggers outside CI.",
|
|
577
577
|
"enum": ["warn", "error", "off"]
|
|
578
578
|
},
|
|
579
579
|
"concurrency": {
|
|
@@ -622,7 +622,7 @@
|
|
|
622
622
|
"type": "number"
|
|
623
623
|
},
|
|
624
624
|
"retries": {
|
|
625
|
-
"description": "Attempts per request for retryable failures
|
|
625
|
+
"description": "Attempts per request for retryable failures \u2014 5xx, 429, network (default 3).",
|
|
626
626
|
"type": "number"
|
|
627
627
|
},
|
|
628
628
|
"maxPages": {
|
|
@@ -654,12 +654,12 @@
|
|
|
654
654
|
}
|
|
655
655
|
},
|
|
656
656
|
"commands": {
|
|
657
|
-
"description": "Quick CLI reference written by init. Informational only
|
|
657
|
+
"description": "Quick CLI reference written by init. Informational only \u2014 ignored at runtime.",
|
|
658
658
|
"type": "object",
|
|
659
659
|
"additionalProperties": true
|
|
660
660
|
},
|
|
661
661
|
"documentation": {
|
|
662
|
-
"description": "Documentation links written by init. Informational only
|
|
662
|
+
"description": "Documentation links written by init. Informational only \u2014 ignored at runtime.",
|
|
663
663
|
"type": "object",
|
|
664
664
|
"additionalProperties": true
|
|
665
665
|
},
|
|
@@ -727,7 +727,7 @@
|
|
|
727
727
|
"default": 1
|
|
728
728
|
},
|
|
729
729
|
"reuseLocal": {
|
|
730
|
-
"description": "Reuse a tool already in the
|
|
730
|
+
"description": "Reuse a tool already present in the repository's node_modules instead of our copy. \"compatible\" (default) reuses when the major matches ours, or when the tool reads the repository's own config (a legacy .eslintrc can only be read by the ESLint that wrote it, and a tsconfig by its own compiler). \"always\" reuses across a major gap at your own risk. \"off\" always uses our pinned copy, for reproducibility.",
|
|
731
731
|
"type": "string",
|
|
732
732
|
"enum": ["compatible", "always", "off"],
|
|
733
733
|
"default": "compatible"
|
|
@@ -761,7 +761,7 @@
|
|
|
761
761
|
"default": "~/.cache/pr-checkmate"
|
|
762
762
|
},
|
|
763
763
|
"prewarm": {
|
|
764
|
-
"description": "
|
|
764
|
+
"description": "NOT IMPLEMENTED \u2014 accepted and ignored. Warming the cache would need a postinstall hook, which would run npm inside npm on every install of this package; for a supply-chain tool that is not a trade worth making. Pre-warm with \"npx pr-checkmate install --all\" instead. Documented as inert rather than quietly doing nothing.",
|
|
765
765
|
"type": "boolean",
|
|
766
766
|
"default": true
|
|
767
767
|
},
|
|
@@ -1011,7 +1011,7 @@
|
|
|
1011
1011
|
}
|
|
1012
1012
|
},
|
|
1013
1013
|
"log": {
|
|
1014
|
-
"description": "Diagnostic output
|
|
1014
|
+
"description": "Diagnostic output \u2014 the running commentary around the run, as opposed to the summary it produces.",
|
|
1015
1015
|
"type": "object",
|
|
1016
1016
|
"properties": {
|
|
1017
1017
|
"level": {
|
|
@@ -1042,6 +1042,28 @@
|
|
|
1042
1042
|
"type": "number"
|
|
1043
1043
|
}
|
|
1044
1044
|
}
|
|
1045
|
+
},
|
|
1046
|
+
"packageSize": {
|
|
1047
|
+
"description": "Growth of the published npm package since the last release. Advisory by default.",
|
|
1048
|
+
"type": "object",
|
|
1049
|
+
"additionalProperties": false,
|
|
1050
|
+
"properties": {
|
|
1051
|
+
"enabled": {
|
|
1052
|
+
"type": "boolean",
|
|
1053
|
+
"default": true
|
|
1054
|
+
},
|
|
1055
|
+
"maxGrowthPercent": {
|
|
1056
|
+
"description": "Growth above this, in percent of the previous release's unpacked size, is reported.",
|
|
1057
|
+
"type": "number",
|
|
1058
|
+
"minimum": 0,
|
|
1059
|
+
"default": 20
|
|
1060
|
+
},
|
|
1061
|
+
"compareWith": {
|
|
1062
|
+
"description": "dist-tag or version to compare against. Default \"latest\".",
|
|
1063
|
+
"type": "string",
|
|
1064
|
+
"default": "latest"
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1045
1067
|
}
|
|
1046
1068
|
},
|
|
1047
1069
|
"$defs": {
|
|
@@ -1137,7 +1159,7 @@
|
|
|
1137
1159
|
}
|
|
1138
1160
|
},
|
|
1139
1161
|
"disablePatterns": {
|
|
1140
|
-
"description": "Built-in rules to switch off by label substring
|
|
1162
|
+
"description": "Built-in rules to switch off by label substring \u2014 the rule never runs.",
|
|
1141
1163
|
"type": "array",
|
|
1142
1164
|
"items": {
|
|
1143
1165
|
"type": "string"
|
|
@@ -1165,7 +1187,7 @@
|
|
|
1165
1187
|
"enum": ["error", "warn"]
|
|
1166
1188
|
},
|
|
1167
1189
|
"view": {
|
|
1168
|
-
"description": "\"code\" matches with string literals blanked out
|
|
1190
|
+
"description": "\"code\" matches with string literals blanked out \u2014 use it to find a call, not text inside a string.",
|
|
1169
1191
|
"enum": ["raw", "code"]
|
|
1170
1192
|
},
|
|
1171
1193
|
"flags": {
|
|
@@ -1174,6 +1196,12 @@
|
|
|
1174
1196
|
}
|
|
1175
1197
|
}
|
|
1176
1198
|
}
|
|
1199
|
+
},
|
|
1200
|
+
"dataflowWindow": {
|
|
1201
|
+
"type": "integer",
|
|
1202
|
+
"minimum": 0,
|
|
1203
|
+
"default": 10,
|
|
1204
|
+
"description": "Added lines a value stays tainted for, connecting an interpolated string assigned on one line to a query on a later line. 0 disables the cross-line heuristic. Advisory only \u2014 it has no scopes and no reassignment tracking, so it never blocks a run."
|
|
1177
1205
|
}
|
|
1178
1206
|
}
|
|
1179
1207
|
},
|
|
@@ -1,13 +0,0 @@
|
|
|
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;
|
|
@@ -1,52 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -1,8 +0,0 @@
|
|
|
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;
|
|
@@ -1,48 +0,0 @@
|
|
|
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,42 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.kotlinLintCheck = 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 KOTLIN_GLOBS = ['*.kt', '*.kts'];
|
|
9
|
-
exports.kotlinLintCheck = {
|
|
10
|
-
name: 'ktlint',
|
|
11
|
-
phase: 'informational',
|
|
12
|
-
applies(ctx) {
|
|
13
|
-
return ctx.config.kotlin?.enabled !== false && ctx.languages.includes('kotlin');
|
|
14
|
-
},
|
|
15
|
-
async run(ctx) {
|
|
16
|
-
const targets = await (0, targets_1.resolveTargetFiles)(ctx, KOTLIN_GLOBS);
|
|
17
|
-
if (targets === null)
|
|
18
|
-
return (0, types_1.skip)('git unavailable');
|
|
19
|
-
if (targets.length === 0)
|
|
20
|
-
return (0, types_1.pass)('no Kotlin files changed');
|
|
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');
|
|
30
|
-
const output = [result.stdout, result.stderr].filter(Boolean).join('\n').trim();
|
|
31
|
-
if (result.exitCode === 0 || !output) {
|
|
32
|
-
utils_1.logger.info('[ktlint]: ✅ No issues found');
|
|
33
|
-
return (0, types_1.pass)();
|
|
34
|
-
}
|
|
35
|
-
const lines = output.split('\n').filter(Boolean);
|
|
36
|
-
utils_1.logger.warn(`[ktlint]: ⚠️ ${lines.length} issue(s):`);
|
|
37
|
-
lines.slice(0, 10).forEach(l => utils_1.logger.warn(` ${l}`));
|
|
38
|
-
if (lines.length > 10)
|
|
39
|
-
utils_1.logger.warn(` ... and ${lines.length - 10} more`);
|
|
40
|
-
return (0, types_1.warn)(`${lines.length} issue(s)`);
|
|
41
|
-
},
|
|
42
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
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;
|
|
@@ -1,49 +0,0 @@
|
|
|
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,8 +0,0 @@
|
|
|
1
|
-
import { Check } from '../../types';
|
|
2
|
-
/**
|
|
3
|
-
* Lints changed Ruby files with RuboCop (which covers both style and layout, so
|
|
4
|
-
* it doubles as the formatting signal). Runner-dependency: needs `rubocop` on
|
|
5
|
-
* the runner, gracefully skipping when absent. Uses the repo's own `.rubocop.yml`
|
|
6
|
-
* when present.
|
|
7
|
-
*/
|
|
8
|
-
export declare const rubyLintCheck: Check;
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.rubyLintCheck = 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 RUBY_GLOBS = ['*.rb', '*.rake'];
|
|
9
|
-
/**
|
|
10
|
-
* Lints changed Ruby files with RuboCop (which covers both style and layout, so
|
|
11
|
-
* it doubles as the formatting signal). Runner-dependency: needs `rubocop` on
|
|
12
|
-
* the runner, gracefully skipping when absent. Uses the repo's own `.rubocop.yml`
|
|
13
|
-
* when present.
|
|
14
|
-
*/
|
|
15
|
-
exports.rubyLintCheck = {
|
|
16
|
-
name: 'RuboCop',
|
|
17
|
-
phase: 'informational',
|
|
18
|
-
applies(ctx) {
|
|
19
|
-
return ctx.config.ruby?.enabled !== false && ctx.languages.includes('ruby');
|
|
20
|
-
},
|
|
21
|
-
async run(ctx) {
|
|
22
|
-
const targets = await (0, targets_1.resolveTargetFiles)(ctx, RUBY_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 Ruby files changed');
|
|
27
|
-
const result = await (0, execa_1.execa)('rubocop', ['--format', 'simple', ...targets], {
|
|
28
|
-
cwd: ctx.cwd,
|
|
29
|
-
reject: false,
|
|
30
|
-
});
|
|
31
|
-
if (result.code === 'ENOENT')
|
|
32
|
-
return (0, types_1.skip)('rubocop not installed');
|
|
33
|
-
if (result.exitCode === 0) {
|
|
34
|
-
utils_1.logger.info('[RuboCop]: ✅ No offenses found');
|
|
35
|
-
return (0, types_1.pass)();
|
|
36
|
-
}
|
|
37
|
-
const lines = [result.stdout, result.stderr]
|
|
38
|
-
.filter(Boolean)
|
|
39
|
-
.join('\n')
|
|
40
|
-
.split('\n')
|
|
41
|
-
.filter(l => l.trim());
|
|
42
|
-
utils_1.logger.warn('[RuboCop]: ⚠️ offenses detected:');
|
|
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 line(s)`);
|
|
46
|
-
// RuboCop's summary line looks like "N offenses detected".
|
|
47
|
-
const summary = lines.find(l => /offense/i.test(l)) ?? `${lines.length} line(s) of output`;
|
|
48
|
-
return (0, types_1.warn)(summary.trim());
|
|
49
|
-
},
|
|
50
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Check } from '../../types';
|
|
2
|
-
/**
|
|
3
|
-
* Formats changed Rust code with `cargo fmt` (which respects the crate's edition
|
|
4
|
-
* from Cargo.toml, unlike a bare `rustfmt`). Runner-dependency, gracefully
|
|
5
|
-
* skipping when `cargo` is absent. Read-only in check mode (`cargo fmt --check`);
|
|
6
|
-
* rewrites in place with `cargo fmt` when `write`, so CI can auto-commit —
|
|
7
|
-
* mirrors the Prettier/C++/Go format checks.
|
|
8
|
-
*/
|
|
9
|
-
export declare const rustFormatCheck: Check;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.rustFormatCheck = 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 RUST_GLOBS = ['*.rs'];
|
|
9
|
-
/**
|
|
10
|
-
* Formats changed Rust code with `cargo fmt` (which respects the crate's edition
|
|
11
|
-
* from Cargo.toml, unlike a bare `rustfmt`). Runner-dependency, gracefully
|
|
12
|
-
* skipping when `cargo` is absent. Read-only in check mode (`cargo fmt --check`);
|
|
13
|
-
* rewrites in place with `cargo fmt` when `write`, so CI can auto-commit —
|
|
14
|
-
* mirrors the Prettier/C++/Go format checks.
|
|
15
|
-
*/
|
|
16
|
-
exports.rustFormatCheck = {
|
|
17
|
-
name: 'Rustfmt',
|
|
18
|
-
phase: 'format',
|
|
19
|
-
applies(ctx) {
|
|
20
|
-
return ctx.config.rust?.enabled !== false && ctx.languages.includes('rust');
|
|
21
|
-
},
|
|
22
|
-
async run(ctx) {
|
|
23
|
-
const targets = await (0, targets_1.resolveTargetFiles)(ctx, RUST_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 Rust files changed');
|
|
28
|
-
const check = await (0, execa_1.execa)('cargo', ['fmt', '--check'], { cwd: ctx.cwd, reject: false });
|
|
29
|
-
if (check.code === 'ENOENT')
|
|
30
|
-
return (0, types_1.skip)('cargo not installed');
|
|
31
|
-
if (check.exitCode === 0)
|
|
32
|
-
return (0, types_1.pass)();
|
|
33
|
-
if (!ctx.write) {
|
|
34
|
-
utils_1.logger.warn('[Rustfmt]: ⚠️ Rust code is not formatted (cargo fmt --check failed)');
|
|
35
|
-
return (0, types_1.warn)('Rust code needs formatting (run with write to fix)');
|
|
36
|
-
}
|
|
37
|
-
const fix = await (0, execa_1.execa)('cargo', ['fmt'], { cwd: ctx.cwd, reject: false });
|
|
38
|
-
if (fix.exitCode !== 0) {
|
|
39
|
-
utils_1.logger.warn(`[Rustfmt]: ⚠️ cargo fmt failed\n${fix.stderr}`);
|
|
40
|
-
return (0, types_1.warn)('cargo fmt failed to rewrite files');
|
|
41
|
-
}
|
|
42
|
-
utils_1.logger.info('[Rustfmt]: ✅ Reformatted Rust code');
|
|
43
|
-
return (0, types_1.pass)('reformatted Rust code');
|
|
44
|
-
},
|
|
45
|
-
};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { Check } from '../../types';
|
|
2
|
-
/**
|
|
3
|
-
* Lints changed Rust code with Clippy (`cargo clippy -- -D warnings`).
|
|
4
|
-
* Runner-dependency: needs the Rust toolchain + clippy on the runner, and
|
|
5
|
-
* gracefully skips when absent. Clippy compiles the whole crate, so it runs over
|
|
6
|
-
* the crate rather than a file list; the delta check only gates whether it runs.
|
|
7
|
-
*/
|
|
8
|
-
export declare const rustLintCheck: Check;
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.rustLintCheck = 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 RUST_GLOBS = ['*.rs'];
|
|
9
|
-
/**
|
|
10
|
-
* Lints changed Rust code with Clippy (`cargo clippy -- -D warnings`).
|
|
11
|
-
* Runner-dependency: needs the Rust toolchain + clippy on the runner, and
|
|
12
|
-
* gracefully skips when absent. Clippy compiles the whole crate, so it runs over
|
|
13
|
-
* the crate rather than a file list; the delta check only gates whether it runs.
|
|
14
|
-
*/
|
|
15
|
-
exports.rustLintCheck = {
|
|
16
|
-
name: 'Clippy',
|
|
17
|
-
phase: 'informational',
|
|
18
|
-
applies(ctx) {
|
|
19
|
-
return ctx.config.rust?.enabled !== false && ctx.languages.includes('rust');
|
|
20
|
-
},
|
|
21
|
-
async run(ctx) {
|
|
22
|
-
const targets = await (0, targets_1.resolveTargetFiles)(ctx, RUST_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 Rust files changed');
|
|
27
|
-
const result = await (0, execa_1.execa)('cargo', ['clippy', '--quiet', '--', '-D', 'warnings'], {
|
|
28
|
-
cwd: ctx.cwd,
|
|
29
|
-
reject: false,
|
|
30
|
-
});
|
|
31
|
-
// execa v9 with reject:false resolves (not throws) with `code: 'ENOENT'` when
|
|
32
|
-
// the binary is absent — detect the missing toolchain on the result.
|
|
33
|
-
if (result.code === 'ENOENT')
|
|
34
|
-
return (0, types_1.skip)('cargo/clippy not installed');
|
|
35
|
-
if (result.exitCode === 0) {
|
|
36
|
-
utils_1.logger.info('[Clippy]: ✅ No issues found');
|
|
37
|
-
return (0, types_1.pass)();
|
|
38
|
-
}
|
|
39
|
-
// Clippy writes diagnostics to stderr.
|
|
40
|
-
const lines = result.stderr
|
|
41
|
-
.split('\n')
|
|
42
|
-
.filter(l => /\b(warning|error)\b/.test(l))
|
|
43
|
-
.filter(Boolean);
|
|
44
|
-
utils_1.logger.warn(`[Clippy]: ⚠️ ${lines.length} diagnostic line(s):`);
|
|
45
|
-
lines.slice(0, 10).forEach(l => utils_1.logger.warn(` ${l}`));
|
|
46
|
-
if (lines.length > 10)
|
|
47
|
-
utils_1.logger.warn(` ... and ${lines.length - 10} more`);
|
|
48
|
-
return (0, types_1.warn)(`${lines.length || 'unknown'} clippy diagnostic(s)`);
|
|
49
|
-
},
|
|
50
|
-
};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { Check } from '../../types';
|
|
2
|
-
/**
|
|
3
|
-
* Lints changed shell scripts with ShellCheck. Runner-dependency: needs the
|
|
4
|
-
* `shellcheck` binary on the runner (like Go Vet/Clippy/RuboCop), gracefully
|
|
5
|
-
* skipping when it's absent. `-f gcc` gives one line per finding, ending in
|
|
6
|
-
* an `[SC…]` rule code, which both a human and the count below can read directly.
|
|
7
|
-
*/
|
|
8
|
-
export declare const shellcheckCheck: Check;
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.shellcheckCheck = 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 SHELL_GLOBS = ['*.sh', '*.bash', '*.ksh'];
|
|
9
|
-
/**
|
|
10
|
-
* Lints changed shell scripts with ShellCheck. Runner-dependency: needs the
|
|
11
|
-
* `shellcheck` binary on the runner (like Go Vet/Clippy/RuboCop), gracefully
|
|
12
|
-
* skipping when it's absent. `-f gcc` gives one line per finding, ending in
|
|
13
|
-
* an `[SC…]` rule code, which both a human and the count below can read directly.
|
|
14
|
-
*/
|
|
15
|
-
exports.shellcheckCheck = {
|
|
16
|
-
name: 'ShellCheck',
|
|
17
|
-
phase: 'informational',
|
|
18
|
-
applies(ctx) {
|
|
19
|
-
return ctx.config.shellcheck?.enabled !== false;
|
|
20
|
-
},
|
|
21
|
-
async run(ctx) {
|
|
22
|
-
const targets = await (0, targets_1.resolveTargetFiles)(ctx, SHELL_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 shell scripts changed');
|
|
27
|
-
const minSeverity = ctx.config.shellcheck?.minSeverity;
|
|
28
|
-
const ignore = ctx.config.shellcheck?.ignore ?? [];
|
|
29
|
-
const args = ['-f', 'gcc'];
|
|
30
|
-
if (minSeverity)
|
|
31
|
-
args.push('-S', minSeverity);
|
|
32
|
-
if (ignore.length > 0)
|
|
33
|
-
args.push('-e', ignore.join(','));
|
|
34
|
-
args.push(...targets);
|
|
35
|
-
const result = await (0, execa_1.execa)('shellcheck', args, { cwd: ctx.cwd, reject: false });
|
|
36
|
-
// execa v9 with reject:false does NOT throw on a missing binary — it resolves
|
|
37
|
-
// with `code: 'ENOENT'`. Detect that on the result, not via try/catch.
|
|
38
|
-
if (result.code === 'ENOENT')
|
|
39
|
-
return (0, types_1.skip)('shellcheck not installed');
|
|
40
|
-
if (result.exitCode === 0) {
|
|
41
|
-
utils_1.logger.info('[ShellCheck]: ✅ No issues found');
|
|
42
|
-
return (0, types_1.pass)();
|
|
43
|
-
}
|
|
44
|
-
const lines = [result.stdout, result.stderr]
|
|
45
|
-
.filter(Boolean)
|
|
46
|
-
.join('\n')
|
|
47
|
-
.split('\n')
|
|
48
|
-
.filter(Boolean);
|
|
49
|
-
utils_1.logger.warn(`[ShellCheck]: ⚠️ ${lines.length} issue(s):`);
|
|
50
|
-
lines.slice(0, 10).forEach(l => utils_1.logger.warn(` ${l}`));
|
|
51
|
-
if (lines.length > 10)
|
|
52
|
-
utils_1.logger.warn(` ... and ${lines.length - 10} more`);
|
|
53
|
-
return (0, types_1.warn)(`${lines.length} issue(s) in ${targets.length} file(s)`);
|
|
54
|
-
},
|
|
55
|
-
};
|