pr-checkmate 2.1.0 → 3.0.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 +63 -267
- package/cspell.json +155 -133
- package/dist/config/constants.d.ts +13 -1
- package/dist/config/constants.js +20 -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 +2 -2
- package/dist/core/checks/dependencies/grype-scan.js +2 -1
- package/dist/core/checks/dependencies/license-check.js +1 -6
- package/dist/core/checks/dependencies/npm-audit.js +1 -1
- package/dist/core/checks/dependencies/outdated-deps.js +1 -6
- 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/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/duplicate-check.js +86 -28
- 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/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/context.js +9 -1
- package/dist/core/install/cache.js +42 -11
- package/dist/core/install/doctor.d.ts +2 -2
- package/dist/core/install/doctor.js +17 -16
- package/dist/core/install/ensure.js +22 -3
- package/dist/core/install/lock.d.ts +2 -1
- package/dist/core/install/prepare.d.ts +75 -0
- package/dist/core/install/prepare.js +151 -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 +10 -18
- package/dist/core/reporters.js +8 -2
- 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 +26 -2
- package/dist/core/types.js +28 -0
- package/dist/init.js +21 -1
- package/dist/interfaces/index.d.ts +1 -0
- package/dist/utils/detect-language.js +11 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/package-version.d.ts +4 -0
- package/dist/utils/package-version.js +41 -0
- package/dist/utils/resolve-bin.d.ts +56 -6
- package/dist/utils/resolve-bin.js +136 -26
- package/dist/utils/update-notifier.js +5 -7
- package/gitleaks.toml +14 -0
- package/install-manifests/go/package-lock.json +24 -0
- package/install-manifests/go/package.json +8 -0
- package/install-manifests/pytypes/package-lock.json +45 -0
- package/install-manifests/pytypes/package.json +8 -0
- package/package.json +4 -2
- package/pr-checkmate.schema.json +8 -2
- package/src/config/cspell.json +155 -133
- package/src/config/pr-checkmate.schema.json +8 -2
- 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
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.packageVersion = packageVersion;
|
|
7
|
+
exports.packageName = packageName;
|
|
8
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
/**
|
|
11
|
+
* Our own name and version, read from the manifest that ships inside the package.
|
|
12
|
+
*
|
|
13
|
+
* Read from disk rather than baked in at build time so it is the *running* copy
|
|
14
|
+
* that answers. That distinction is the whole point: a stale global install
|
|
15
|
+
* (`npm i -g pr-checkmate`) shadows the project's own copy on `PATH`, and a repo
|
|
16
|
+
* pinned to the latest version can still be checked by a year-old binary without
|
|
17
|
+
* anything in the log saying so. One client spent a while reading an upgrade
|
|
18
|
+
* notice for a version they had already installed, because nothing printed which
|
|
19
|
+
* version was speaking.
|
|
20
|
+
*
|
|
21
|
+
* Falls back to placeholders rather than throwing: no caller here is important
|
|
22
|
+
* enough to fail a run over a manifest it could not read.
|
|
23
|
+
*/
|
|
24
|
+
function readManifest() {
|
|
25
|
+
try {
|
|
26
|
+
const manifest = node_path_1.default.resolve(__dirname, '../..', 'package.json');
|
|
27
|
+
const parsed = JSON.parse(node_fs_1.default.readFileSync(manifest, 'utf-8'));
|
|
28
|
+
return { name: parsed.name ?? 'pr-checkmate', version: parsed.version ?? '0.0.0' };
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return { name: 'pr-checkmate', version: '0.0.0' };
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** The version of pr-checkmate that is executing right now. */
|
|
35
|
+
function packageVersion() {
|
|
36
|
+
return readManifest().version;
|
|
37
|
+
}
|
|
38
|
+
/** The package name that is executing right now — the one to query npm for. */
|
|
39
|
+
function packageName() {
|
|
40
|
+
return readManifest().name;
|
|
41
|
+
}
|
|
@@ -1,16 +1,66 @@
|
|
|
1
|
+
/** Where a tool was found, in the order the candidates are tried. */
|
|
2
|
+
export type ToolSource = 'client' | 'profile' | 'bundled';
|
|
3
|
+
/** A resolved tool binary, and which copy of it answered. */
|
|
4
|
+
export interface ResolvedTool {
|
|
5
|
+
bin: string;
|
|
6
|
+
source: ToolSource;
|
|
7
|
+
/** The search root that produced it; `undefined` for module-relative resolution. */
|
|
8
|
+
root?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Point tool resolution at the profile directories fetched for this run.
|
|
12
|
+
*
|
|
13
|
+
* Called by the install layer once the cache is known. Passing an empty list —
|
|
14
|
+
* or never calling it at all — leaves resolution exactly as it was before
|
|
15
|
+
* profiles existed, which is what keeps a run that needs no fetching identical
|
|
16
|
+
* to a run from before there was anything to fetch.
|
|
17
|
+
*/
|
|
18
|
+
export declare function registerToolPaths(dirs: string[]): void;
|
|
19
|
+
/** Drop every registered profile root. For tests, and for a second run in-process. */
|
|
20
|
+
export declare function clearToolPaths(): void;
|
|
21
|
+
/** The root of the installed pr-checkmate package — where our own tooling lives. */
|
|
22
|
+
export declare function ownPackageRoot(): string;
|
|
23
|
+
/**
|
|
24
|
+
* Whether a package is physically present in our own dependency tree.
|
|
25
|
+
*
|
|
26
|
+
* Checked by walking `node_modules` upwards rather than by `require.resolve`,
|
|
27
|
+
* because a package that restricts its `exports` map resolves for neither its
|
|
28
|
+
* main entry nor its `package.json` while being perfectly well installed —
|
|
29
|
+
* `cspell` is one. The question here is only "is it there", and the directory
|
|
30
|
+
* answers that without an opinion about what it chooses to export.
|
|
31
|
+
*
|
|
32
|
+
* Walking up matters as much as the check itself: installed as a dependency, our
|
|
33
|
+
* own packages are hoisted to the client's `node_modules`, one level above ours.
|
|
34
|
+
*/
|
|
35
|
+
export declare function packagePresent(pkgName: string, from?: string): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Resolve a tool's binary and say which copy answered.
|
|
38
|
+
*
|
|
39
|
+
* Use this over {@link resolvePackageBin} when the answer is worth logging — the
|
|
40
|
+
* source is the difference between "the client's ESLint 8 ran" and "ours did",
|
|
41
|
+
* and that is the first thing anyone asks when a lint result looks wrong.
|
|
42
|
+
*
|
|
43
|
+
* @param pkgName Package whose binary to resolve (e.g. `eslint`).
|
|
44
|
+
* @param binRelPath Bin path relative to the package root (e.g. `bin/eslint.js`).
|
|
45
|
+
* @param options Resolution options.
|
|
46
|
+
* @param options.paths Roots to prefer ahead of everything else. Use
|
|
47
|
+
* `[process.cwd()]` to prefer the consumer project's copy.
|
|
48
|
+
*/
|
|
49
|
+
export declare function resolveTool(pkgName: string, binRelPath: string, options?: {
|
|
50
|
+
paths?: string[];
|
|
51
|
+
}): ResolvedTool | null;
|
|
1
52
|
/**
|
|
2
53
|
* Resolves a binary path for a bundled package, bypassing exports map restrictions.
|
|
3
54
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* 3. Walk up from main entry — for packages that export neither (e.g. cspell)
|
|
55
|
+
* Throws when no copy can be found anywhere, which is the honest outcome: a check
|
|
56
|
+
* that cannot find its tool has nothing to report, and the install layer turns
|
|
57
|
+
* that into a skip with a reason rather than letting it surface as a stack trace.
|
|
8
58
|
*
|
|
9
59
|
* @param pkgName - The package whose binary to resolve (e.g. `eslint`).
|
|
10
60
|
* @param binRelPath - The bin path relative to the package root (e.g. `bin/eslint.js`).
|
|
11
61
|
* @param options - Resolution options.
|
|
12
|
-
* @param options.paths - Directories to resolve from
|
|
13
|
-
* Use `[process.cwd()]` to prefer the consumer project's copy
|
|
62
|
+
* @param options.paths - Directories to resolve from, preferred over everything
|
|
63
|
+
* else. Use `[process.cwd()]` to prefer the consumer project's copy.
|
|
14
64
|
*/
|
|
15
65
|
export declare function resolvePackageBin(pkgName: string, binRelPath: string, options?: {
|
|
16
66
|
paths?: string[];
|
|
@@ -3,51 +3,161 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.registerToolPaths = registerToolPaths;
|
|
7
|
+
exports.clearToolPaths = clearToolPaths;
|
|
8
|
+
exports.ownPackageRoot = ownPackageRoot;
|
|
9
|
+
exports.packagePresent = packagePresent;
|
|
10
|
+
exports.resolveTool = resolveTool;
|
|
6
11
|
exports.resolvePackageBin = resolvePackageBin;
|
|
7
12
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
13
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
14
|
/**
|
|
10
|
-
*
|
|
15
|
+
* Extra roots to search, registered once per run by the install layer.
|
|
11
16
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
17
|
+
* Module state rather than a parameter threaded through fifteen call sites: a
|
|
18
|
+
* profile directory is a property of the *run*, not of any one check, and every
|
|
19
|
+
* check that resolves a binary would otherwise have to be handed a value it has
|
|
20
|
+
* no opinion about. `registerToolPaths` is called before the first check starts
|
|
21
|
+
* and never during one, so nothing observes it changing underneath.
|
|
22
|
+
*/
|
|
23
|
+
let profileRoots = [];
|
|
24
|
+
/**
|
|
25
|
+
* Point tool resolution at the profile directories fetched for this run.
|
|
16
26
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* Use `[process.cwd()]` to prefer the consumer project's copy of the package.
|
|
27
|
+
* Called by the install layer once the cache is known. Passing an empty list —
|
|
28
|
+
* or never calling it at all — leaves resolution exactly as it was before
|
|
29
|
+
* profiles existed, which is what keeps a run that needs no fetching identical
|
|
30
|
+
* to a run from before there was anything to fetch.
|
|
22
31
|
*/
|
|
23
|
-
function
|
|
24
|
-
|
|
25
|
-
|
|
32
|
+
function registerToolPaths(dirs) {
|
|
33
|
+
profileRoots = [...dirs];
|
|
34
|
+
}
|
|
35
|
+
/** Drop every registered profile root. For tests, and for a second run in-process. */
|
|
36
|
+
function clearToolPaths() {
|
|
37
|
+
profileRoots = [];
|
|
38
|
+
}
|
|
39
|
+
/** The root of the installed pr-checkmate package — where our own tooling lives. */
|
|
40
|
+
function ownPackageRoot() {
|
|
41
|
+
return node_path_1.default.resolve(__dirname, '../..');
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Whether a package is physically present in our own dependency tree.
|
|
45
|
+
*
|
|
46
|
+
* Checked by walking `node_modules` upwards rather than by `require.resolve`,
|
|
47
|
+
* because a package that restricts its `exports` map resolves for neither its
|
|
48
|
+
* main entry nor its `package.json` while being perfectly well installed —
|
|
49
|
+
* `cspell` is one. The question here is only "is it there", and the directory
|
|
50
|
+
* answers that without an opinion about what it chooses to export.
|
|
51
|
+
*
|
|
52
|
+
* Walking up matters as much as the check itself: installed as a dependency, our
|
|
53
|
+
* own packages are hoisted to the client's `node_modules`, one level above ours.
|
|
54
|
+
*/
|
|
55
|
+
function packagePresent(pkgName, from = ownPackageRoot()) {
|
|
56
|
+
let dir = from;
|
|
57
|
+
while (dir !== node_path_1.default.dirname(dir)) {
|
|
58
|
+
if (node_fs_1.default.existsSync(node_path_1.default.join(dir, 'node_modules', pkgName, 'package.json')))
|
|
59
|
+
return true;
|
|
60
|
+
dir = node_path_1.default.dirname(dir);
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
/** One resolution attempt against a single set of search paths. */
|
|
65
|
+
function tryResolve(pkgName, binRelPath, paths) {
|
|
66
|
+
const resolveOpts = paths ? { paths } : undefined;
|
|
67
|
+
// 1. Direct subpath — the fast path for packages that export their bin.
|
|
26
68
|
try {
|
|
27
69
|
return require.resolve(`${pkgName}/${binRelPath}`, resolveOpts);
|
|
28
70
|
}
|
|
29
71
|
catch { }
|
|
30
|
-
// 2. Via package.json
|
|
72
|
+
// 2. Via package.json — for packages that export `./package.json` but not the
|
|
73
|
+
// bin subpath (eslint).
|
|
31
74
|
try {
|
|
32
75
|
const pkgJsonPath = require.resolve(`${pkgName}/package.json`, resolveOpts);
|
|
33
76
|
return node_path_1.default.join(node_path_1.default.dirname(pkgJsonPath), binRelPath);
|
|
34
77
|
}
|
|
35
78
|
catch { }
|
|
36
|
-
// 3. Walk up from main entry
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
79
|
+
// 3. Walk up from the main entry, matching the package name — for packages
|
|
80
|
+
// that export neither (cspell).
|
|
81
|
+
try {
|
|
82
|
+
let dir = node_path_1.default.dirname(require.resolve(pkgName, resolveOpts));
|
|
83
|
+
while (dir !== node_path_1.default.dirname(dir)) {
|
|
84
|
+
const pkgJsonPath = node_path_1.default.join(dir, 'package.json');
|
|
85
|
+
if (node_fs_1.default.existsSync(pkgJsonPath)) {
|
|
86
|
+
try {
|
|
87
|
+
const pkg = JSON.parse(node_fs_1.default.readFileSync(pkgJsonPath, 'utf-8'));
|
|
88
|
+
if (pkg.name === pkgName)
|
|
89
|
+
return node_path_1.default.join(dir, binRelPath);
|
|
46
90
|
}
|
|
91
|
+
catch { }
|
|
47
92
|
}
|
|
48
|
-
|
|
93
|
+
dir = node_path_1.default.dirname(dir);
|
|
49
94
|
}
|
|
50
|
-
dir = node_path_1.default.dirname(dir);
|
|
51
95
|
}
|
|
96
|
+
catch { }
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The roots to try, in order, and what finding a tool in each one means.
|
|
101
|
+
*
|
|
102
|
+
* The order is the policy, and it is deliberate:
|
|
103
|
+
*
|
|
104
|
+
* 1. **The client's own copy**, when a caller asked for it. A repository pinned
|
|
105
|
+
* to ESLint 8 with a legacy `.eslintrc` must keep working, and only its copy
|
|
106
|
+
* can do that.
|
|
107
|
+
* 2. **A fetched profile**, for tooling that does not ship inside the package.
|
|
108
|
+
* 3. **Our bundle** — module-relative, exactly as resolution worked before
|
|
109
|
+
* profiles existed.
|
|
110
|
+
*
|
|
111
|
+
* Branch 3 is passed `undefined` rather than our package root on purpose: that is
|
|
112
|
+
* literally the previous behaviour, so a run with nothing registered resolves
|
|
113
|
+
* every tool along the identical path it always did.
|
|
114
|
+
*/
|
|
115
|
+
function candidates(optPaths) {
|
|
116
|
+
const list = [];
|
|
117
|
+
if (optPaths && optPaths.length > 0)
|
|
118
|
+
list.push({ paths: optPaths, source: 'client' });
|
|
119
|
+
for (const root of profileRoots)
|
|
120
|
+
list.push({ paths: [root], source: 'profile' });
|
|
121
|
+
list.push({ source: 'bundled' });
|
|
122
|
+
return list;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Resolve a tool's binary and say which copy answered.
|
|
126
|
+
*
|
|
127
|
+
* Use this over {@link resolvePackageBin} when the answer is worth logging — the
|
|
128
|
+
* source is the difference between "the client's ESLint 8 ran" and "ours did",
|
|
129
|
+
* and that is the first thing anyone asks when a lint result looks wrong.
|
|
130
|
+
*
|
|
131
|
+
* @param pkgName Package whose binary to resolve (e.g. `eslint`).
|
|
132
|
+
* @param binRelPath Bin path relative to the package root (e.g. `bin/eslint.js`).
|
|
133
|
+
* @param options Resolution options.
|
|
134
|
+
* @param options.paths Roots to prefer ahead of everything else. Use
|
|
135
|
+
* `[process.cwd()]` to prefer the consumer project's copy.
|
|
136
|
+
*/
|
|
137
|
+
function resolveTool(pkgName, binRelPath, options) {
|
|
138
|
+
for (const candidate of candidates(options?.paths)) {
|
|
139
|
+
const bin = tryResolve(pkgName, binRelPath, candidate.paths);
|
|
140
|
+
if (bin)
|
|
141
|
+
return { bin, source: candidate.source, root: candidate.paths?.[0] };
|
|
142
|
+
}
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Resolves a binary path for a bundled package, bypassing exports map restrictions.
|
|
147
|
+
*
|
|
148
|
+
* Throws when no copy can be found anywhere, which is the honest outcome: a check
|
|
149
|
+
* that cannot find its tool has nothing to report, and the install layer turns
|
|
150
|
+
* that into a skip with a reason rather than letting it surface as a stack trace.
|
|
151
|
+
*
|
|
152
|
+
* @param pkgName - The package whose binary to resolve (e.g. `eslint`).
|
|
153
|
+
* @param binRelPath - The bin path relative to the package root (e.g. `bin/eslint.js`).
|
|
154
|
+
* @param options - Resolution options.
|
|
155
|
+
* @param options.paths - Directories to resolve from, preferred over everything
|
|
156
|
+
* else. Use `[process.cwd()]` to prefer the consumer project's copy.
|
|
157
|
+
*/
|
|
158
|
+
function resolvePackageBin(pkgName, binRelPath, options) {
|
|
159
|
+
const resolved = resolveTool(pkgName, binRelPath, options);
|
|
160
|
+
if (resolved)
|
|
161
|
+
return resolved.bin;
|
|
52
162
|
throw new Error(`Cannot resolve binary "${binRelPath}" for package "${pkgName}"`);
|
|
53
163
|
}
|
|
@@ -1,16 +1,12 @@
|
|
|
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.isMajorUpgrade = isMajorUpgrade;
|
|
7
4
|
exports.getUpdateNotice = getUpdateNotice;
|
|
8
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
10
5
|
// Imported from the module rather than the `../config` barrel on purpose:
|
|
11
6
|
// `config/index.ts` imports `../utils`, so going through the barrel would make
|
|
12
7
|
// utils ⇄ config circular. `constants.ts` itself pulls in nothing from utils.
|
|
13
8
|
const constants_1 = require("../config/constants");
|
|
9
|
+
const package_version_1 = require("./package-version");
|
|
14
10
|
// Same widths as the run summary in `reporters.ts`, so the two boxes line up
|
|
15
11
|
// when both are printed at the end of a run.
|
|
16
12
|
const NOTICE_BORDER = '═'.repeat(63);
|
|
@@ -72,8 +68,10 @@ async function getUpdateNotice(timeoutMs = 2500) {
|
|
|
72
68
|
if (process.env.PR_CHECKMATE_NO_UPDATE_CHECK)
|
|
73
69
|
return null;
|
|
74
70
|
try {
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
// The *running* copy's identity, not the project's declared dependency. A
|
|
72
|
+
// stale global install shadows the local one on `PATH`, and it is the stale
|
|
73
|
+
// copy that must own the notice it prints.
|
|
74
|
+
const pkg = { name: (0, package_version_1.packageName)(), version: (0, package_version_1.packageVersion)() };
|
|
77
75
|
const controller = new AbortController();
|
|
78
76
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
79
77
|
let latest;
|
package/gitleaks.toml
CHANGED
|
@@ -3,6 +3,20 @@ title = "pr-checkmate gitleaks config"
|
|
|
3
3
|
[extend]
|
|
4
4
|
useDefault = true
|
|
5
5
|
|
|
6
|
+
# THIS FILE SHIPS, AND IT IS APPLIED TO EVERY CLIENT WITHOUT A GITLEAKS CONFIG OF
|
|
7
|
+
# THEIR OWN. Read `src/core/checks/security/security.ts`: `--config` points here
|
|
8
|
+
# whenever `hasLocalConfig` finds nothing in the repository being scanned.
|
|
9
|
+
#
|
|
10
|
+
# So an entry added here to quieten OUR OWN corpus silences it for everybody. That
|
|
11
|
+
# was measured, not imagined: adding `tests/` to the paths below removed six real
|
|
12
|
+
# `Generic API Key` findings from a client repository — under
|
|
13
|
+
# `packages/commons/tests/`, `packages/node/tests/`, and three more — in a check
|
|
14
|
+
# that BLOCKS. Our own noise is never a reason to widen this list; use
|
|
15
|
+
# `.gitleaksignore` in this repository instead, which does not ship.
|
|
16
|
+
#
|
|
17
|
+
# `__tests__` predates that and is left alone: it is a convention for a directory
|
|
18
|
+
# of test files specifically, not a whole path segment named `test`.
|
|
19
|
+
|
|
6
20
|
[allowlist]
|
|
7
21
|
description = "pr-checkmate global allowlist"
|
|
8
22
|
paths = [
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pr-checkmate-profile-go",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"lockfileVersion": 3,
|
|
5
|
+
"requires": true,
|
|
6
|
+
"packages": {
|
|
7
|
+
"": {
|
|
8
|
+
"name": "pr-checkmate-profile-go",
|
|
9
|
+
"version": "1.0.0",
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@wasm-fmt/gofmt": "0.7.3"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"node_modules/@wasm-fmt/gofmt": {
|
|
15
|
+
"version": "0.7.3",
|
|
16
|
+
"resolved": "https://registry.npmjs.org/@wasm-fmt/gofmt/-/gofmt-0.7.3.tgz",
|
|
17
|
+
"integrity": "sha512-nzVTwMxHDOYrHonT7DzjqicbaTYOYPNYeXKPJnDrVUbJjx67Sg/LS1uzlOTWKToGMF8Y8l0u7G5/5Q3/8nHMMA==",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=16.17.0"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pr-checkmate-profile-pytypes",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"lockfileVersion": 3,
|
|
5
|
+
"requires": true,
|
|
6
|
+
"packages": {
|
|
7
|
+
"": {
|
|
8
|
+
"name": "pr-checkmate-profile-pytypes",
|
|
9
|
+
"version": "1.0.0",
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"pyright": "1.1.413"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"node_modules/fsevents": {
|
|
15
|
+
"version": "2.3.3",
|
|
16
|
+
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
|
17
|
+
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
|
18
|
+
"hasInstallScript": true,
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"optional": true,
|
|
21
|
+
"os": [
|
|
22
|
+
"darwin"
|
|
23
|
+
],
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"node_modules/pyright": {
|
|
29
|
+
"version": "1.1.413",
|
|
30
|
+
"resolved": "https://registry.npmjs.org/pyright/-/pyright-1.1.413.tgz",
|
|
31
|
+
"integrity": "sha512-1lpxKrh0DHHpfAQOfciZo2ojua2jase3wwO9at8kldc+F/p1PBscxA5CQ3G1qg5lMOMhXo6ZaiMLMXEAqADIAg==",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"bin": {
|
|
34
|
+
"pyright": "index.js",
|
|
35
|
+
"pyright-langserver": "langserver.index.js"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=14.0.0"
|
|
39
|
+
},
|
|
40
|
+
"optionalDependencies": {
|
|
41
|
+
"fsevents": "~2.3.3"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pr-checkmate",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Security-first PR gate for CI: secret scanning, grype dependency scanning, SBOM — plus linting and formatting across 11 languages",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"github-actions",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"spellcheck": "cspell '**/*.{ts,tsx,js,jsx,md,json}' --no-progress",
|
|
53
53
|
"docs": "typedoc",
|
|
54
54
|
"scan:secrets": "gitleaks-secret-scanner --diff-mode ci --html-report gitleaks-report.html",
|
|
55
|
-
"test": "node --require ts-node/register --test --test-timeout=60000
|
|
55
|
+
"test": "node --require ts-node/register --test --test-timeout=60000 \"tests/**/*.test.ts\"",
|
|
56
56
|
"test:ci": "bash scripts/test-per-file.sh",
|
|
57
57
|
"verify:tarball": "bash scripts/verify-tarball.sh",
|
|
58
58
|
"security-scan": "npx pr-checkmate security",
|
|
@@ -82,6 +82,7 @@
|
|
|
82
82
|
"@typescript-eslint/eslint-plugin": "^8.62.1",
|
|
83
83
|
"@typescript-eslint/parser": "^8.62.1",
|
|
84
84
|
"@wasm-fmt/clang-format": "^22.1.8",
|
|
85
|
+
"@wasm-fmt/gofmt": "^0.7.3",
|
|
85
86
|
"cspell": "^10.0.1",
|
|
86
87
|
"dpdm": "^4.2.0",
|
|
87
88
|
"eslint": "^10.6.0",
|
|
@@ -106,6 +107,7 @@
|
|
|
106
107
|
"devDependencies": {
|
|
107
108
|
"conventional-commits-filter": "^5.0.0",
|
|
108
109
|
"conventional-commits-parser": "^6.4.0",
|
|
110
|
+
"pyright": "^1.1.413",
|
|
109
111
|
"standard-version": "^9.5.0",
|
|
110
112
|
"typedoc": "^0.28.20"
|
|
111
113
|
},
|
package/pr-checkmate.schema.json
CHANGED
|
@@ -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 YET IMPLEMENTED — accepted and ignored. Warming the cache needs a postinstall hook, and there is nothing to warm while every profile's tooling ships inside the package; the hook lands with the dependency extraction (ticket 064, release 2). Documented as inert rather than quietly doing nothing.",
|
|
765
765
|
"type": "boolean",
|
|
766
766
|
"default": true
|
|
767
767
|
},
|
|
@@ -1174,6 +1174,12 @@
|
|
|
1174
1174
|
}
|
|
1175
1175
|
}
|
|
1176
1176
|
}
|
|
1177
|
+
},
|
|
1178
|
+
"dataflowWindow": {
|
|
1179
|
+
"type": "integer",
|
|
1180
|
+
"minimum": 0,
|
|
1181
|
+
"default": 10,
|
|
1182
|
+
"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 — it has no scopes and no reassignment tracking, so it never blocks a run."
|
|
1177
1183
|
}
|
|
1178
1184
|
}
|
|
1179
1185
|
},
|