pr-checkmate 1.23.19 → 1.23.20
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/cspell.json +17 -17
- package/dist/core/checks/quality/spellcheck.d.ts +25 -0
- package/dist/core/checks/quality/spellcheck.js +71 -11
- package/dist/init.js +7 -1
- package/dist/interfaces/index.d.ts +11 -0
- package/package.json +1 -1
- package/pr-checkmate.schema.json +12 -0
- package/src/config/cspell.json +17 -17
- package/src/config/pr-checkmate.schema.json +12 -0
package/cspell.json
CHANGED
|
@@ -1237,23 +1237,23 @@
|
|
|
1237
1237
|
"רטינול"
|
|
1238
1238
|
],
|
|
1239
1239
|
"ignorePaths": [
|
|
1240
|
-
"
|
|
1241
|
-
"
|
|
1242
|
-
"
|
|
1243
|
-
"
|
|
1244
|
-
"
|
|
1245
|
-
"
|
|
1246
|
-
"
|
|
1247
|
-
"
|
|
1248
|
-
"
|
|
1249
|
-
"
|
|
1250
|
-
"
|
|
1251
|
-
"
|
|
1252
|
-
"
|
|
1253
|
-
"
|
|
1254
|
-
"
|
|
1255
|
-
"
|
|
1256
|
-
"
|
|
1240
|
+
"/**/node_modules/**",
|
|
1241
|
+
"/**/dist/**",
|
|
1242
|
+
"/**/.git/**",
|
|
1243
|
+
"/**/build/**",
|
|
1244
|
+
"/**/coverage/**",
|
|
1245
|
+
"/**/.next/**",
|
|
1246
|
+
"/**/.nuxt/**",
|
|
1247
|
+
"/**/out/**",
|
|
1248
|
+
"/**/__pycache__/**",
|
|
1249
|
+
"/**/.pytest_cache/**",
|
|
1250
|
+
"/**/.venv/**",
|
|
1251
|
+
"/**/venv/**",
|
|
1252
|
+
"/**/package-lock.json",
|
|
1253
|
+
"/**/yarn.lock",
|
|
1254
|
+
"/**/pnpm-lock.yaml",
|
|
1255
|
+
"/**/*.min.js",
|
|
1256
|
+
"/**/*.min.css"
|
|
1257
1257
|
],
|
|
1258
1258
|
"enableFiletypes": ["typescript", "javascript", "markdown", "json"],
|
|
1259
1259
|
"ignoreRegExpList": ["/https?:\\/\\/[^\\s]+/g", "/\\b[0-9a-f]{7,40}\\b/gi"]
|
|
@@ -1,2 +1,27 @@
|
|
|
1
|
+
import { CspellConfig } from '../../../interfaces';
|
|
1
2
|
import { Check } from '../../types';
|
|
3
|
+
/**
|
|
4
|
+
* Anchors an ignore glob to the repository root.
|
|
5
|
+
*
|
|
6
|
+
* cspell matches `ignorePaths` against each file's ABSOLUTE path, so an unanchored
|
|
7
|
+
* `**\/build/**` also matches every ancestor directory of the workspace. On Bitbucket
|
|
8
|
+
* Pipelines the clone lives in `/opt/atlassian/pipelines/agent/build`, so that one
|
|
9
|
+
* pattern excluded the entire repository and the check silently spellchecked nothing.
|
|
10
|
+
* A leading `/` anchors the pattern to the config's directory (the repo root) while
|
|
11
|
+
* `/**\/dir/**` still matches at any depth INSIDE the repo — verified against cspell 10.
|
|
12
|
+
*
|
|
13
|
+
* Patterns that are already anchored (`/…`) or plainly relative (`dir/**`,
|
|
14
|
+
* `CHANGELOG.md`) are left untouched: they cannot match an ancestor.
|
|
15
|
+
*/
|
|
16
|
+
export declare function anchorIgnoreGlob(pattern: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Folds the client's `cspell` block from pr-checkmate.json into the bundled
|
|
19
|
+
* defaults. `enabled` is deliberately not carried over — it gates the check
|
|
20
|
+
* itself (see `applies`) and is not a cspell setting.
|
|
21
|
+
*
|
|
22
|
+
* Lists are appended so a client extends the curated vocabulary instead of
|
|
23
|
+
* replacing it; `language` is the one exception and replaces the default, because
|
|
24
|
+
* a client writing `"en"` means exactly that and appending would be meaningless.
|
|
25
|
+
*/
|
|
26
|
+
export declare function mergeCspellConfig(defaultConfig: CspellConfig, userConfig: Partial<CspellConfig>): CspellConfig;
|
|
2
27
|
export declare const spellcheckCheck: Check;
|
|
@@ -4,6 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.spellcheckCheck = void 0;
|
|
7
|
+
exports.anchorIgnoreGlob = anchorIgnoreGlob;
|
|
8
|
+
exports.mergeCspellConfig = mergeCspellConfig;
|
|
7
9
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
10
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
11
|
const config_1 = require("../../../config");
|
|
@@ -23,6 +25,47 @@ function loadUserCspellConfig(cwd) {
|
|
|
23
25
|
return {};
|
|
24
26
|
}
|
|
25
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Anchors an ignore glob to the repository root.
|
|
30
|
+
*
|
|
31
|
+
* cspell matches `ignorePaths` against each file's ABSOLUTE path, so an unanchored
|
|
32
|
+
* `**\/build/**` also matches every ancestor directory of the workspace. On Bitbucket
|
|
33
|
+
* Pipelines the clone lives in `/opt/atlassian/pipelines/agent/build`, so that one
|
|
34
|
+
* pattern excluded the entire repository and the check silently spellchecked nothing.
|
|
35
|
+
* A leading `/` anchors the pattern to the config's directory (the repo root) while
|
|
36
|
+
* `/**\/dir/**` still matches at any depth INSIDE the repo — verified against cspell 10.
|
|
37
|
+
*
|
|
38
|
+
* Patterns that are already anchored (`/…`) or plainly relative (`dir/**`,
|
|
39
|
+
* `CHANGELOG.md`) are left untouched: they cannot match an ancestor.
|
|
40
|
+
*/
|
|
41
|
+
function anchorIgnoreGlob(pattern) {
|
|
42
|
+
return pattern.startsWith('**/') ? `/${pattern}` : pattern;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Folds the client's `cspell` block from pr-checkmate.json into the bundled
|
|
46
|
+
* defaults. `enabled` is deliberately not carried over — it gates the check
|
|
47
|
+
* itself (see `applies`) and is not a cspell setting.
|
|
48
|
+
*
|
|
49
|
+
* Lists are appended so a client extends the curated vocabulary instead of
|
|
50
|
+
* replacing it; `language` is the one exception and replaces the default, because
|
|
51
|
+
* a client writing `"en"` means exactly that and appending would be meaningless.
|
|
52
|
+
*/
|
|
53
|
+
function mergeCspellConfig(defaultConfig, userConfig) {
|
|
54
|
+
const dictionaries = [...(defaultConfig.dictionaries ?? []), ...(userConfig.dictionaries ?? [])];
|
|
55
|
+
return {
|
|
56
|
+
...defaultConfig,
|
|
57
|
+
language: userConfig.language || defaultConfig.language,
|
|
58
|
+
words: [...defaultConfig.words, ...(userConfig.words || [])],
|
|
59
|
+
// Client globs are anchored too — a repo's own pattern is meant to be relative
|
|
60
|
+
// to that repo, never to whatever directories sit above the checkout.
|
|
61
|
+
ignorePaths: [...defaultConfig.ignorePaths, ...(userConfig.ignorePaths || [])].map(anchorIgnoreGlob),
|
|
62
|
+
ignoreRegExpList: [...defaultConfig.ignoreRegExpList, ...(userConfig.ignoreRegExpList || [])],
|
|
63
|
+
// The bundled dictionaries arrive through `import`, so there is nothing to
|
|
64
|
+
// override here. cspell ignores names it cannot resolve, so a client typo
|
|
65
|
+
// costs coverage but never fails the run.
|
|
66
|
+
...(dictionaries.length > 0 ? { dictionaries } : {}),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
26
69
|
function createTempCspellConfig(cwd) {
|
|
27
70
|
const packageConfigPath = (0, config_1.getPackageConfigPath)('cspell.json');
|
|
28
71
|
const packageConfigDir = node_path_1.default.dirname(packageConfigPath);
|
|
@@ -40,11 +83,8 @@ function createTempCspellConfig(cwd) {
|
|
|
40
83
|
}
|
|
41
84
|
});
|
|
42
85
|
const mergedConfig = {
|
|
43
|
-
...defaultConfig,
|
|
86
|
+
...mergeCspellConfig(defaultConfig, userConfig),
|
|
44
87
|
import: resolvedImports,
|
|
45
|
-
words: [...defaultConfig.words, ...(userConfig.words || [])],
|
|
46
|
-
ignorePaths: [...defaultConfig.ignorePaths, ...(userConfig.ignorePaths || [])],
|
|
47
|
-
ignoreRegExpList: [...defaultConfig.ignoreRegExpList, ...(userConfig.ignoreRegExpList || [])],
|
|
48
88
|
};
|
|
49
89
|
const tempConfigPath = node_path_1.default.join(cwd, '.cspell.temp.json');
|
|
50
90
|
node_fs_1.default.writeFileSync(tempConfigPath, JSON.stringify(mergedConfig, null, 2));
|
|
@@ -53,26 +93,46 @@ function createTempCspellConfig(cwd) {
|
|
|
53
93
|
exports.spellcheckCheck = {
|
|
54
94
|
name: 'Spellcheck',
|
|
55
95
|
phase: 'informational',
|
|
56
|
-
|
|
57
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Clients turn the check off with `cspell.enabled: false` (or the `spellcheck`
|
|
98
|
+
* alias the config interface uses). The universal `severity: { Spellcheck: "off" }`
|
|
99
|
+
* switch keeps working too — this is the per-check flag every other check exposes.
|
|
100
|
+
*/
|
|
101
|
+
applies(ctx) {
|
|
102
|
+
return ctx.config.cspell?.enabled !== false && ctx.config.spellcheck?.enabled !== false;
|
|
58
103
|
},
|
|
59
104
|
async run(ctx) {
|
|
60
|
-
const
|
|
61
|
-
if (
|
|
105
|
+
const targets = await (0, targets_1.resolveScopedTargetFiles)(ctx, ['*.ts', '*.tsx', '*.js', '*.jsx', '*.md', '*.mdx', '*.json'], (0, config_1.getSourcePaths)());
|
|
106
|
+
if (targets === null)
|
|
62
107
|
return (0, types_1.skip)('git unavailable');
|
|
108
|
+
// Committed build output and test reports are dropped here, in JS, against
|
|
109
|
+
// repo-RELATIVE paths — a client cannot fix a typo in a generated file, so
|
|
110
|
+
// reporting one is noise that buries the real findings. Neither cspell
|
|
111
|
+
// mechanism can do this safely: `--exclude` ignores glob anchoring outright
|
|
112
|
+
// (`--exclude=/**/build/**` still matches an ancestor `build` dir, which on
|
|
113
|
+
// Bitbucket Pipelines is the checkout itself), and `ignorePaths` only reaches
|
|
114
|
+
// repos that have no cspell config of their own. Filtering the list keeps one
|
|
115
|
+
// rule for every repo. `ignoreDirs` already covers plain directory names via
|
|
116
|
+
// `resolveTargetFiles`; this adds the composite globs it cannot express
|
|
117
|
+
// (`**/cypress/videos/**`, `**/jest-html-reporters-*/**`).
|
|
118
|
+
const files = targets.filter(f => !(0, utils_1.matchesAnyGlob)(f, config_1.IGNORE_PATTERNS));
|
|
63
119
|
if (files.length === 0)
|
|
64
120
|
return (0, types_1.pass)('no files to spellcheck');
|
|
65
|
-
const patterns = [...files, ...config_1.IGNORE_PATTERNS.map(p => `--exclude=${p}`)];
|
|
66
121
|
const hasLocal = (0, config_1.hasLocalConfig)(['cspell.json', '.cspell.json', 'cspell.config.json']);
|
|
67
122
|
let tempConfigPath = null;
|
|
68
123
|
const cspellBin = (0, utils_1.resolvePackageBin)('cspell', 'bin.mjs');
|
|
124
|
+
// `--no-must-find-files`: cspell exits 1 when it checked nothing, which the
|
|
125
|
+
// exit-code mapping below would report as "spelling issues found" — a warning
|
|
126
|
+
// about problems that do not exist. Every file being excluded is a pass, not a
|
|
127
|
+
// finding.
|
|
128
|
+
const baseArgs = [...files, '--no-progress', '--no-must-find-files'];
|
|
69
129
|
let args;
|
|
70
130
|
if (hasLocal) {
|
|
71
|
-
args =
|
|
131
|
+
args = baseArgs;
|
|
72
132
|
}
|
|
73
133
|
else {
|
|
74
134
|
tempConfigPath = createTempCspellConfig(ctx.cwd);
|
|
75
|
-
args = [...
|
|
135
|
+
args = [...baseArgs, '--config', tempConfigPath];
|
|
76
136
|
}
|
|
77
137
|
try {
|
|
78
138
|
const result = await (0, execa_1.execa)(process.execPath, [cspellBin, ...args], {
|
package/dist/init.js
CHANGED
|
@@ -58,8 +58,14 @@ const DEFAULT_CONFIG = {
|
|
|
58
58
|
prettier: {
|
|
59
59
|
rules: {},
|
|
60
60
|
},
|
|
61
|
-
//
|
|
61
|
+
// Spellcheck (cspell). `enabled: false` turns the check off — that part always
|
|
62
|
+
// applies. The lists feed the cspell config pr-checkmate generates, so they are
|
|
63
|
+
// ignored when the repo has a cspell.json of its own; all of them are appended to
|
|
64
|
+
// the bundled defaults. `ignorePaths` takes globs to skip (e.g. "CHANGELOG.md",
|
|
65
|
+
// "generated/**"), anchored to the repo root so a pattern never matches a
|
|
66
|
+
// directory above the checkout.
|
|
62
67
|
cspell: {
|
|
68
|
+
enabled: true,
|
|
63
69
|
words: [],
|
|
64
70
|
ignorePaths: [],
|
|
65
71
|
ignoreRegExpList: [],
|
|
@@ -19,6 +19,8 @@ export interface CspellConfig {
|
|
|
19
19
|
ignorePaths: string[];
|
|
20
20
|
enableFiletypes: string[];
|
|
21
21
|
ignoreRegExpList: string[];
|
|
22
|
+
dictionaries?: string[];
|
|
23
|
+
enabled?: boolean;
|
|
22
24
|
}
|
|
23
25
|
export interface PRCheckMateConfig {
|
|
24
26
|
sourcePath: string | string[];
|
|
@@ -42,10 +44,19 @@ export interface PRCheckMateConfig {
|
|
|
42
44
|
config?: Record<string, any>;
|
|
43
45
|
};
|
|
44
46
|
spellcheck?: {
|
|
47
|
+
enabled?: boolean;
|
|
45
48
|
words?: string[];
|
|
46
49
|
ignoreWords?: string[];
|
|
47
50
|
ignorePaths?: string[];
|
|
48
51
|
};
|
|
52
|
+
cspell?: {
|
|
53
|
+
enabled?: boolean;
|
|
54
|
+
words?: string[];
|
|
55
|
+
ignorePaths?: string[];
|
|
56
|
+
ignoreRegExpList?: string[];
|
|
57
|
+
dictionaries?: string[];
|
|
58
|
+
language?: string;
|
|
59
|
+
};
|
|
49
60
|
security?: {
|
|
50
61
|
gitleaks?: {
|
|
51
62
|
enabled?: boolean;
|
package/package.json
CHANGED
package/pr-checkmate.schema.json
CHANGED
|
@@ -149,6 +149,18 @@
|
|
|
149
149
|
"caseCollision": { "$ref": "#/$defs/toggle" },
|
|
150
150
|
"sensitiveFileGuard": { "$ref": "#/$defs/toggle" },
|
|
151
151
|
"configValidation": { "$ref": "#/$defs/toggle" },
|
|
152
|
+
"cspell": {
|
|
153
|
+
"description": "Spellcheck control. 'enabled: false' turns the check off. The other fields configure the cspell config pr-checkmate generates, so they apply only when the repository has no cspell.json of its own: 'words', 'ignorePaths', 'ignoreRegExpList' and 'dictionaries' are appended to the bundled defaults, 'language' replaces it. Ignore globs are anchored to the repository root, so '**/dist/**' never matches a directory above the checkout.",
|
|
154
|
+
"type": "object",
|
|
155
|
+
"properties": {
|
|
156
|
+
"enabled": { "type": "boolean" },
|
|
157
|
+
"language": { "type": "string" },
|
|
158
|
+
"words": { "type": "array", "items": { "type": "string" } },
|
|
159
|
+
"dictionaries": { "type": "array", "items": { "type": "string" } },
|
|
160
|
+
"ignorePaths": { "type": "array", "items": { "type": "string" } },
|
|
161
|
+
"ignoreRegExpList": { "type": "array", "items": { "type": "string" } }
|
|
162
|
+
}
|
|
163
|
+
},
|
|
152
164
|
"yamlLint": {
|
|
153
165
|
"type": "object",
|
|
154
166
|
"properties": {
|
package/src/config/cspell.json
CHANGED
|
@@ -1237,23 +1237,23 @@
|
|
|
1237
1237
|
"רטינול"
|
|
1238
1238
|
],
|
|
1239
1239
|
"ignorePaths": [
|
|
1240
|
-
"
|
|
1241
|
-
"
|
|
1242
|
-
"
|
|
1243
|
-
"
|
|
1244
|
-
"
|
|
1245
|
-
"
|
|
1246
|
-
"
|
|
1247
|
-
"
|
|
1248
|
-
"
|
|
1249
|
-
"
|
|
1250
|
-
"
|
|
1251
|
-
"
|
|
1252
|
-
"
|
|
1253
|
-
"
|
|
1254
|
-
"
|
|
1255
|
-
"
|
|
1256
|
-
"
|
|
1240
|
+
"/**/node_modules/**",
|
|
1241
|
+
"/**/dist/**",
|
|
1242
|
+
"/**/.git/**",
|
|
1243
|
+
"/**/build/**",
|
|
1244
|
+
"/**/coverage/**",
|
|
1245
|
+
"/**/.next/**",
|
|
1246
|
+
"/**/.nuxt/**",
|
|
1247
|
+
"/**/out/**",
|
|
1248
|
+
"/**/__pycache__/**",
|
|
1249
|
+
"/**/.pytest_cache/**",
|
|
1250
|
+
"/**/.venv/**",
|
|
1251
|
+
"/**/venv/**",
|
|
1252
|
+
"/**/package-lock.json",
|
|
1253
|
+
"/**/yarn.lock",
|
|
1254
|
+
"/**/pnpm-lock.yaml",
|
|
1255
|
+
"/**/*.min.js",
|
|
1256
|
+
"/**/*.min.css"
|
|
1257
1257
|
],
|
|
1258
1258
|
"enableFiletypes": ["typescript", "javascript", "markdown", "json"],
|
|
1259
1259
|
"ignoreRegExpList": ["/https?:\\/\\/[^\\s]+/g", "/\\b[0-9a-f]{7,40}\\b/gi"]
|
|
@@ -149,6 +149,18 @@
|
|
|
149
149
|
"caseCollision": { "$ref": "#/$defs/toggle" },
|
|
150
150
|
"sensitiveFileGuard": { "$ref": "#/$defs/toggle" },
|
|
151
151
|
"configValidation": { "$ref": "#/$defs/toggle" },
|
|
152
|
+
"cspell": {
|
|
153
|
+
"description": "Spellcheck control. 'enabled: false' turns the check off. The other fields configure the cspell config pr-checkmate generates, so they apply only when the repository has no cspell.json of its own: 'words', 'ignorePaths', 'ignoreRegExpList' and 'dictionaries' are appended to the bundled defaults, 'language' replaces it. Ignore globs are anchored to the repository root, so '**/dist/**' never matches a directory above the checkout.",
|
|
154
|
+
"type": "object",
|
|
155
|
+
"properties": {
|
|
156
|
+
"enabled": { "type": "boolean" },
|
|
157
|
+
"language": { "type": "string" },
|
|
158
|
+
"words": { "type": "array", "items": { "type": "string" } },
|
|
159
|
+
"dictionaries": { "type": "array", "items": { "type": "string" } },
|
|
160
|
+
"ignorePaths": { "type": "array", "items": { "type": "string" } },
|
|
161
|
+
"ignoreRegExpList": { "type": "array", "items": { "type": "string" } }
|
|
162
|
+
}
|
|
163
|
+
},
|
|
152
164
|
"yamlLint": {
|
|
153
165
|
"type": "object",
|
|
154
166
|
"properties": {
|