cspell 7.3.9 → 8.1.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/dist/esm/application.js +3 -3
- package/dist/esm/application.mjs +3 -3
- package/dist/esm/cli-reporter.d.mts +2 -2
- package/dist/esm/cli-reporter.d.ts +2 -2
- package/dist/esm/cli-reporter.js +9 -3
- package/dist/esm/cli-reporter.mjs +9 -3
- package/dist/esm/commandLink.js +6 -6
- package/dist/esm/commandLink.mjs +6 -6
- package/dist/esm/commandLint.js +21 -15
- package/dist/esm/commandLint.mjs +21 -15
- package/dist/esm/lint/LintRequest.js +13 -2
- package/dist/esm/lint/LintRequest.mjs +13 -2
- package/dist/esm/lint/lint.js +33 -16
- package/dist/esm/lint/lint.mjs +33 -16
- package/dist/esm/options.d.mts +8 -0
- package/dist/esm/options.d.ts +8 -0
- package/dist/esm/repl/index.js +5 -0
- package/dist/esm/repl/index.mjs +5 -0
- package/dist/esm/util/InMemoryReporter.js +36 -37
- package/dist/esm/util/InMemoryReporter.mjs +36 -37
- package/dist/esm/util/cache/DiskCache.js +11 -4
- package/dist/esm/util/cache/DiskCache.mjs +11 -4
- package/dist/esm/util/cache/ObjectCollection.js +2 -6
- package/dist/esm/util/cache/ObjectCollection.mjs +2 -6
- package/dist/esm/util/constants.d.mts +4 -5
- package/dist/esm/util/constants.d.ts +4 -5
- package/dist/esm/util/errors.js +4 -0
- package/dist/esm/util/errors.mjs +4 -0
- package/dist/esm/util/fileHelper.d.mts +4 -2
- package/dist/esm/util/fileHelper.d.ts +4 -2
- package/dist/esm/util/fileHelper.js +0 -21
- package/dist/esm/util/fileHelper.mjs +0 -21
- package/dist/esm/util/timer.d.mts +2 -6
- package/dist/esm/util/timer.d.ts +2 -6
- package/dist/esm/util/timer.js +5 -7
- package/dist/esm/util/timer.mjs +5 -7
- package/package.json +14 -14
package/dist/esm/application.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { opMap, opTap, pipeAsync, toAsyncIterable } from '@cspell/cspell-pipe';
|
|
2
|
-
import { checkTextDocument, getDefaultSettings,
|
|
2
|
+
import { checkTextDocument, getDefaultSettings, getGlobalSettingsAsync, mergeSettings, SuggestionError, suggestionsForWords, traceWordsAsync, } from 'cspell-lib';
|
|
3
3
|
import { getReporter } from './cli-reporter.js';
|
|
4
4
|
import { getFeatureFlags, parseFeatureFlags } from './featureFlags/index.js';
|
|
5
5
|
import { LintRequest, runLint } from './lint/index.js';
|
|
@@ -13,7 +13,7 @@ import * as util from './util/util.js';
|
|
|
13
13
|
export { IncludeExcludeFlag } from 'cspell-lib';
|
|
14
14
|
export function lint(fileGlobs, options, reporter) {
|
|
15
15
|
options = fixLegacy(options);
|
|
16
|
-
const cfg = new LintRequest(fileGlobs, options, finalizeReporter(reporter) ?? getReporter({ ...options, fileGlobs }));
|
|
16
|
+
const cfg = new LintRequest(fileGlobs, options, finalizeReporter(reporter) ?? getReporter({ ...options, fileGlobs }, options));
|
|
17
17
|
return runLint(cfg);
|
|
18
18
|
}
|
|
19
19
|
export async function* trace(words, options) {
|
|
@@ -22,7 +22,7 @@ export async function* trace(words, options) {
|
|
|
22
22
|
const { languageId, locale, allowCompoundWords, ignoreCase } = options;
|
|
23
23
|
const configFile = await readConfig(options.config, undefined);
|
|
24
24
|
const loadDefault = options.defaultConfiguration ?? configFile.config.loadDefaultConfiguration ?? true;
|
|
25
|
-
const config = mergeSettings(getDefaultSettings(loadDefault),
|
|
25
|
+
const config = mergeSettings(await getDefaultSettings(loadDefault), await getGlobalSettingsAsync(), configFile.config);
|
|
26
26
|
yield* traceWordsAsync(iWords, config, util.clean({ languageId, locale, ignoreCase, allowCompoundWords }));
|
|
27
27
|
}
|
|
28
28
|
export async function checkText(filename, options) {
|
package/dist/esm/application.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { opMap, opTap, pipeAsync, toAsyncIterable } from '@cspell/cspell-pipe';
|
|
2
|
-
import { checkTextDocument, getDefaultSettings,
|
|
2
|
+
import { checkTextDocument, getDefaultSettings, getGlobalSettingsAsync, mergeSettings, SuggestionError, suggestionsForWords, traceWordsAsync, } from 'cspell-lib';
|
|
3
3
|
import { getReporter } from './cli-reporter.mjs';
|
|
4
4
|
import { getFeatureFlags, parseFeatureFlags } from './featureFlags/index.mjs';
|
|
5
5
|
import { LintRequest, runLint } from './lint/index.mjs';
|
|
@@ -13,7 +13,7 @@ import * as util from './util/util.mjs';
|
|
|
13
13
|
export { IncludeExcludeFlag } from 'cspell-lib';
|
|
14
14
|
export function lint(fileGlobs, options, reporter) {
|
|
15
15
|
options = fixLegacy(options);
|
|
16
|
-
const cfg = new LintRequest(fileGlobs, options, finalizeReporter(reporter) ?? getReporter({ ...options, fileGlobs }));
|
|
16
|
+
const cfg = new LintRequest(fileGlobs, options, finalizeReporter(reporter) ?? getReporter({ ...options, fileGlobs }, options));
|
|
17
17
|
return runLint(cfg);
|
|
18
18
|
}
|
|
19
19
|
export async function* trace(words, options) {
|
|
@@ -22,7 +22,7 @@ export async function* trace(words, options) {
|
|
|
22
22
|
const { languageId, locale, allowCompoundWords, ignoreCase } = options;
|
|
23
23
|
const configFile = await readConfig(options.config, undefined);
|
|
24
24
|
const loadDefault = options.defaultConfiguration ?? configFile.config.loadDefaultConfiguration ?? true;
|
|
25
|
-
const config = mergeSettings(getDefaultSettings(loadDefault),
|
|
25
|
+
const config = mergeSettings(await getDefaultSettings(loadDefault), await getGlobalSettingsAsync(), configFile.config);
|
|
26
26
|
yield* traceWordsAsync(iWords, config, util.clean({ languageId, locale, ignoreCase, allowCompoundWords }));
|
|
27
27
|
}
|
|
28
28
|
export async function checkText(filename, options) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Issue } from '@cspell/cspell-types';
|
|
1
|
+
import type { Issue, ReporterConfiguration } from '@cspell/cspell-types';
|
|
2
2
|
import type { LinterCliOptions } from './options.mjs';
|
|
3
3
|
import type { FinalizedReporter } from './util/reporters.mjs';
|
|
4
4
|
export interface ReporterIssue extends Issue {
|
|
@@ -7,7 +7,7 @@ export interface ReporterIssue extends Issue {
|
|
|
7
7
|
export interface ReporterOptions extends Pick<LinterCliOptions, 'debug' | 'issues' | 'legacy' | 'progress' | 'relative' | 'root' | 'showContext' | 'showSuggestions' | 'silent' | 'summary' | 'verbose' | 'wordsOnly'> {
|
|
8
8
|
fileGlobs: string[];
|
|
9
9
|
}
|
|
10
|
-
export declare function getReporter(options: ReporterOptions): FinalizedReporter;
|
|
10
|
+
export declare function getReporter(options: ReporterOptions, config?: ReporterConfiguration): FinalizedReporter;
|
|
11
11
|
declare function formatIssue(templateStr: string, issue: ReporterIssue, maxIssueTextWidth: number): string;
|
|
12
12
|
export declare const __testing__: {
|
|
13
13
|
formatIssue: typeof formatIssue;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Issue } from '@cspell/cspell-types';
|
|
1
|
+
import type { Issue, ReporterConfiguration } from '@cspell/cspell-types';
|
|
2
2
|
import type { LinterCliOptions } from './options.js';
|
|
3
3
|
import type { FinalizedReporter } from './util/reporters.js';
|
|
4
4
|
export interface ReporterIssue extends Issue {
|
|
@@ -7,7 +7,7 @@ export interface ReporterIssue extends Issue {
|
|
|
7
7
|
export interface ReporterOptions extends Pick<LinterCliOptions, 'debug' | 'issues' | 'legacy' | 'progress' | 'relative' | 'root' | 'showContext' | 'showSuggestions' | 'silent' | 'summary' | 'verbose' | 'wordsOnly'> {
|
|
8
8
|
fileGlobs: string[];
|
|
9
9
|
}
|
|
10
|
-
export declare function getReporter(options: ReporterOptions): FinalizedReporter;
|
|
10
|
+
export declare function getReporter(options: ReporterOptions, config?: ReporterConfiguration): FinalizedReporter;
|
|
11
11
|
declare function formatIssue(templateStr: string, issue: ReporterIssue, maxIssueTextWidth: number): string;
|
|
12
12
|
export declare const __testing__: {
|
|
13
13
|
formatIssue: typeof formatIssue;
|
package/dist/esm/cli-reporter.js
CHANGED
|
@@ -3,6 +3,7 @@ import chalkTemplate from 'chalk-template';
|
|
|
3
3
|
import { isSpellingDictionaryLoadError } from 'cspell-lib';
|
|
4
4
|
import * as path from 'path';
|
|
5
5
|
import { URI } from 'vscode-uri';
|
|
6
|
+
import { uniqueFilterFnGenerator } from './util/util.js';
|
|
6
7
|
const templateIssue = `{green $filename}:{yellow $row:$col} - $message ({red $text}) $quickFix`;
|
|
7
8
|
const templateIssueNoFix = `{green $filename}:{yellow $row:$col} - $message ({red $text})`;
|
|
8
9
|
const templateIssueWithSuggestions = `{green $filename}:{yellow $row:$col} - $message ({red $text}) Suggestions: {yellow [$suggestions]}`;
|
|
@@ -10,11 +11,14 @@ const templateIssueWithContext = `{green $filename}:{yellow $row:$col} $padRowCo
|
|
|
10
11
|
const templateIssueWithContextWithSuggestions = `{green $filename}:{yellow $row:$col} $padRowCol- $message ({red $text})$padContext -- {gray $contextLeft}{red {underline $text}}{gray $contextRight}\n\t Suggestions: {yellow [$suggestions]}`;
|
|
11
12
|
const templateIssueLegacy = `${chalk.green('$filename')}[$row, $col]: $message: ${chalk.red('$text')}`;
|
|
12
13
|
const templateIssueWordsOnly = '$text';
|
|
13
|
-
function genIssueEmitter(template) {
|
|
14
|
+
function genIssueEmitter(template, uniqueIssues) {
|
|
15
|
+
const uniqueFilter = uniqueIssues ? uniqueFilterFnGenerator((issue) => issue.text) : () => true;
|
|
14
16
|
const defaultWidth = 10;
|
|
15
17
|
let maxWidth = defaultWidth;
|
|
16
18
|
let uri;
|
|
17
19
|
return function issueEmitter(issue) {
|
|
20
|
+
if (!uniqueFilter(issue))
|
|
21
|
+
return;
|
|
18
22
|
if (uri !== issue.uri) {
|
|
19
23
|
maxWidth = defaultWidth;
|
|
20
24
|
uri = issue.uri;
|
|
@@ -74,7 +78,8 @@ function reportTime(elapsedTimeMs, cached) {
|
|
|
74
78
|
const color = elapsedTimeMs < 1000 ? chalk.white : elapsedTimeMs < 2000 ? chalk.yellow : chalk.redBright;
|
|
75
79
|
return color(elapsedTimeMs.toFixed(2) + 'ms');
|
|
76
80
|
}
|
|
77
|
-
export function getReporter(options) {
|
|
81
|
+
export function getReporter(options, config) {
|
|
82
|
+
const uniqueIssues = config?.unique || false;
|
|
78
83
|
const issueTemplate = options.wordsOnly
|
|
79
84
|
? templateIssueWordsOnly
|
|
80
85
|
: options.legacy
|
|
@@ -120,7 +125,7 @@ export function getReporter(options) {
|
|
|
120
125
|
console.error('CSpell\x3a Files checked: %d, Issues found: %d in %d files', result.files, result.issues, result.filesWithIssues.size);
|
|
121
126
|
};
|
|
122
127
|
return {
|
|
123
|
-
issue: relativeIssue(silent || !issues ? nullEmitter : genIssueEmitter(issueTemplate)),
|
|
128
|
+
issue: relativeIssue(silent || !issues ? nullEmitter : genIssueEmitter(issueTemplate, uniqueIssues)),
|
|
124
129
|
error: silent ? nullEmitter : errorEmitter,
|
|
125
130
|
info: infoEmitter,
|
|
126
131
|
debug: emitters.Debug,
|
|
@@ -185,6 +190,7 @@ function formatQuickFix(issue) {
|
|
|
185
190
|
return `fix: (${fixes.join(', ')})`;
|
|
186
191
|
}
|
|
187
192
|
class TS extends Array {
|
|
193
|
+
raw;
|
|
188
194
|
constructor(s) {
|
|
189
195
|
super(s);
|
|
190
196
|
this.raw = [s];
|
|
@@ -3,6 +3,7 @@ import chalkTemplate from 'chalk-template';
|
|
|
3
3
|
import { isSpellingDictionaryLoadError } from 'cspell-lib';
|
|
4
4
|
import * as path from 'path';
|
|
5
5
|
import { URI } from 'vscode-uri';
|
|
6
|
+
import { uniqueFilterFnGenerator } from './util/util.mjs';
|
|
6
7
|
const templateIssue = `{green $filename}:{yellow $row:$col} - $message ({red $text}) $quickFix`;
|
|
7
8
|
const templateIssueNoFix = `{green $filename}:{yellow $row:$col} - $message ({red $text})`;
|
|
8
9
|
const templateIssueWithSuggestions = `{green $filename}:{yellow $row:$col} - $message ({red $text}) Suggestions: {yellow [$suggestions]}`;
|
|
@@ -10,11 +11,14 @@ const templateIssueWithContext = `{green $filename}:{yellow $row:$col} $padRowCo
|
|
|
10
11
|
const templateIssueWithContextWithSuggestions = `{green $filename}:{yellow $row:$col} $padRowCol- $message ({red $text})$padContext -- {gray $contextLeft}{red {underline $text}}{gray $contextRight}\n\t Suggestions: {yellow [$suggestions]}`;
|
|
11
12
|
const templateIssueLegacy = `${chalk.green('$filename')}[$row, $col]: $message: ${chalk.red('$text')}`;
|
|
12
13
|
const templateIssueWordsOnly = '$text';
|
|
13
|
-
function genIssueEmitter(template) {
|
|
14
|
+
function genIssueEmitter(template, uniqueIssues) {
|
|
15
|
+
const uniqueFilter = uniqueIssues ? uniqueFilterFnGenerator((issue) => issue.text) : () => true;
|
|
14
16
|
const defaultWidth = 10;
|
|
15
17
|
let maxWidth = defaultWidth;
|
|
16
18
|
let uri;
|
|
17
19
|
return function issueEmitter(issue) {
|
|
20
|
+
if (!uniqueFilter(issue))
|
|
21
|
+
return;
|
|
18
22
|
if (uri !== issue.uri) {
|
|
19
23
|
maxWidth = defaultWidth;
|
|
20
24
|
uri = issue.uri;
|
|
@@ -74,7 +78,8 @@ function reportTime(elapsedTimeMs, cached) {
|
|
|
74
78
|
const color = elapsedTimeMs < 1000 ? chalk.white : elapsedTimeMs < 2000 ? chalk.yellow : chalk.redBright;
|
|
75
79
|
return color(elapsedTimeMs.toFixed(2) + 'ms');
|
|
76
80
|
}
|
|
77
|
-
export function getReporter(options) {
|
|
81
|
+
export function getReporter(options, config) {
|
|
82
|
+
const uniqueIssues = config?.unique || false;
|
|
78
83
|
const issueTemplate = options.wordsOnly
|
|
79
84
|
? templateIssueWordsOnly
|
|
80
85
|
: options.legacy
|
|
@@ -120,7 +125,7 @@ export function getReporter(options) {
|
|
|
120
125
|
console.error('CSpell\x3a Files checked: %d, Issues found: %d in %d files', result.files, result.issues, result.filesWithIssues.size);
|
|
121
126
|
};
|
|
122
127
|
return {
|
|
123
|
-
issue: relativeIssue(silent || !issues ? nullEmitter : genIssueEmitter(issueTemplate)),
|
|
128
|
+
issue: relativeIssue(silent || !issues ? nullEmitter : genIssueEmitter(issueTemplate, uniqueIssues)),
|
|
124
129
|
error: silent ? nullEmitter : errorEmitter,
|
|
125
130
|
info: infoEmitter,
|
|
126
131
|
debug: emitters.Debug,
|
|
@@ -185,6 +190,7 @@ function formatQuickFix(issue) {
|
|
|
185
190
|
return `fix: (${fixes.join(', ')})`;
|
|
186
191
|
}
|
|
187
192
|
class TS extends Array {
|
|
193
|
+
raw;
|
|
188
194
|
constructor(s) {
|
|
189
195
|
super(s);
|
|
190
196
|
this.raw = [s];
|
package/dist/esm/commandLink.js
CHANGED
|
@@ -9,8 +9,8 @@ export function commandLink(prog) {
|
|
|
9
9
|
.command('list', { isDefault: true })
|
|
10
10
|
.alias('ls')
|
|
11
11
|
.description('List currently linked configurations.')
|
|
12
|
-
.action(() => {
|
|
13
|
-
const imports = listGlobalImports();
|
|
12
|
+
.action(async () => {
|
|
13
|
+
const imports = await listGlobalImports();
|
|
14
14
|
const table = listGlobalImportsResultToTable(imports.list);
|
|
15
15
|
tableToLines(table).forEach((line) => console.log(line));
|
|
16
16
|
return;
|
|
@@ -19,8 +19,8 @@ export function commandLink(prog) {
|
|
|
19
19
|
.command('add <dictionaries...>')
|
|
20
20
|
.alias('a')
|
|
21
21
|
.description('Add dictionaries any other settings to the cspell global config.')
|
|
22
|
-
.action((dictionaries) => {
|
|
23
|
-
const r = addPathsToGlobalImports(dictionaries);
|
|
22
|
+
.action(async (dictionaries) => {
|
|
23
|
+
const r = await addPathsToGlobalImports(dictionaries);
|
|
24
24
|
const table = addPathsToGlobalImportsResultToTable(r);
|
|
25
25
|
console.log('Adding:');
|
|
26
26
|
tableToLines(table).forEach((line) => console.log(line));
|
|
@@ -33,8 +33,8 @@ export function commandLink(prog) {
|
|
|
33
33
|
.command('remove <paths...>')
|
|
34
34
|
.alias('r')
|
|
35
35
|
.description('Remove matching paths / packages from the global config.')
|
|
36
|
-
.action((dictionaries) => {
|
|
37
|
-
const r = removePathsFromGlobalImports(dictionaries);
|
|
36
|
+
.action(async (dictionaries) => {
|
|
37
|
+
const r = await removePathsFromGlobalImports(dictionaries);
|
|
38
38
|
console.log('Removing:');
|
|
39
39
|
if (r.error) {
|
|
40
40
|
throw new CheckFailed(r.error, 1);
|
package/dist/esm/commandLink.mjs
CHANGED
|
@@ -9,8 +9,8 @@ export function commandLink(prog) {
|
|
|
9
9
|
.command('list', { isDefault: true })
|
|
10
10
|
.alias('ls')
|
|
11
11
|
.description('List currently linked configurations.')
|
|
12
|
-
.action(() => {
|
|
13
|
-
const imports = listGlobalImports();
|
|
12
|
+
.action(async () => {
|
|
13
|
+
const imports = await listGlobalImports();
|
|
14
14
|
const table = listGlobalImportsResultToTable(imports.list);
|
|
15
15
|
tableToLines(table).forEach((line) => console.log(line));
|
|
16
16
|
return;
|
|
@@ -19,8 +19,8 @@ export function commandLink(prog) {
|
|
|
19
19
|
.command('add <dictionaries...>')
|
|
20
20
|
.alias('a')
|
|
21
21
|
.description('Add dictionaries any other settings to the cspell global config.')
|
|
22
|
-
.action((dictionaries) => {
|
|
23
|
-
const r = addPathsToGlobalImports(dictionaries);
|
|
22
|
+
.action(async (dictionaries) => {
|
|
23
|
+
const r = await addPathsToGlobalImports(dictionaries);
|
|
24
24
|
const table = addPathsToGlobalImportsResultToTable(r);
|
|
25
25
|
console.log('Adding:');
|
|
26
26
|
tableToLines(table).forEach((line) => console.log(line));
|
|
@@ -33,8 +33,8 @@ export function commandLink(prog) {
|
|
|
33
33
|
.command('remove <paths...>')
|
|
34
34
|
.alias('r')
|
|
35
35
|
.description('Remove matching paths / packages from the global config.')
|
|
36
|
-
.action((dictionaries) => {
|
|
37
|
-
const r = removePathsFromGlobalImports(dictionaries);
|
|
36
|
+
.action(async (dictionaries) => {
|
|
37
|
+
const r = await removePathsFromGlobalImports(dictionaries);
|
|
38
38
|
console.log('Removing:');
|
|
39
39
|
if (r.error) {
|
|
40
40
|
throw new CheckFailed(r.error, 1);
|
package/dist/esm/commandLint.js
CHANGED
|
@@ -107,27 +107,33 @@ export function commandLint(prog) {
|
|
|
107
107
|
.addOption(new CommanderOption('--no-default-configuration', 'Do not load the default configuration and dictionaries.'))
|
|
108
108
|
.option('--debug', 'Output information useful for debugging cspell.json files.')
|
|
109
109
|
.option('--reporter <module|path>', 'Specify one or more reporters to use.', collect)
|
|
110
|
+
.addOption(new CommanderOption('--skip-validation', 'Collect and process documents, but do not spell check.')
|
|
111
|
+
.implies({ cache: false })
|
|
112
|
+
.hideHelp())
|
|
113
|
+
.addOption(new CommanderOption('--issues-summary-report', 'Output a summary of issues found.').hideHelp())
|
|
110
114
|
.usage(usage)
|
|
111
115
|
.addHelpText('after', advanced)
|
|
112
116
|
.arguments('[globs...]')
|
|
113
|
-
.action((fileGlobs, options) => {
|
|
117
|
+
.action(async (fileGlobs, options) => {
|
|
114
118
|
const useExitCode = options.exitCode ?? true;
|
|
119
|
+
if (options.skipValidation) {
|
|
120
|
+
options.cache = false;
|
|
121
|
+
}
|
|
115
122
|
App.parseApplicationFeatureFlags(options.flag);
|
|
116
123
|
const { mustFindFiles, fileList } = options;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
});
|
|
124
|
+
const result = await App.lint(fileGlobs, options);
|
|
125
|
+
if (!fileGlobs.length && !result.files && !result.errors && !fileList) {
|
|
126
|
+
spellCheckCommand.outputHelp();
|
|
127
|
+
throw new CheckFailed('outputHelp', 1);
|
|
128
|
+
}
|
|
129
|
+
if (result.errors || (mustFindFiles && !result.files)) {
|
|
130
|
+
throw new CheckFailed('check failed', 1);
|
|
131
|
+
}
|
|
132
|
+
if (result.issues) {
|
|
133
|
+
const exitCode = useExitCode ? 1 : 0;
|
|
134
|
+
throw new CheckFailed('check failed', exitCode);
|
|
135
|
+
}
|
|
136
|
+
return;
|
|
131
137
|
});
|
|
132
138
|
return spellCheckCommand;
|
|
133
139
|
}
|
package/dist/esm/commandLint.mjs
CHANGED
|
@@ -107,27 +107,33 @@ export function commandLint(prog) {
|
|
|
107
107
|
.addOption(new CommanderOption('--no-default-configuration', 'Do not load the default configuration and dictionaries.'))
|
|
108
108
|
.option('--debug', 'Output information useful for debugging cspell.json files.')
|
|
109
109
|
.option('--reporter <module|path>', 'Specify one or more reporters to use.', collect)
|
|
110
|
+
.addOption(new CommanderOption('--skip-validation', 'Collect and process documents, but do not spell check.')
|
|
111
|
+
.implies({ cache: false })
|
|
112
|
+
.hideHelp())
|
|
113
|
+
.addOption(new CommanderOption('--issues-summary-report', 'Output a summary of issues found.').hideHelp())
|
|
110
114
|
.usage(usage)
|
|
111
115
|
.addHelpText('after', advanced)
|
|
112
116
|
.arguments('[globs...]')
|
|
113
|
-
.action((fileGlobs, options) => {
|
|
117
|
+
.action(async (fileGlobs, options) => {
|
|
114
118
|
const useExitCode = options.exitCode ?? true;
|
|
119
|
+
if (options.skipValidation) {
|
|
120
|
+
options.cache = false;
|
|
121
|
+
}
|
|
115
122
|
App.parseApplicationFeatureFlags(options.flag);
|
|
116
123
|
const { mustFindFiles, fileList } = options;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
});
|
|
124
|
+
const result = await App.lint(fileGlobs, options);
|
|
125
|
+
if (!fileGlobs.length && !result.files && !result.errors && !fileList) {
|
|
126
|
+
spellCheckCommand.outputHelp();
|
|
127
|
+
throw new CheckFailed('outputHelp', 1);
|
|
128
|
+
}
|
|
129
|
+
if (result.errors || (mustFindFiles && !result.files)) {
|
|
130
|
+
throw new CheckFailed('check failed', 1);
|
|
131
|
+
}
|
|
132
|
+
if (result.issues) {
|
|
133
|
+
const exitCode = useExitCode ? 1 : 0;
|
|
134
|
+
throw new CheckFailed('check failed', exitCode);
|
|
135
|
+
}
|
|
136
|
+
return;
|
|
131
137
|
});
|
|
132
138
|
return spellCheckCommand;
|
|
133
139
|
}
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import * as path from 'path';
|
|
2
2
|
import { calcExcludeGlobInfo } from '../util/glob.js';
|
|
3
|
-
import * as util from '../util/util.js';
|
|
4
3
|
const defaultContextRange = 20;
|
|
5
4
|
export class LintRequest {
|
|
5
|
+
fileGlobs;
|
|
6
|
+
options;
|
|
7
|
+
reporter;
|
|
8
|
+
uniqueFilter;
|
|
9
|
+
locale;
|
|
10
|
+
configFile;
|
|
11
|
+
excludes;
|
|
12
|
+
root;
|
|
13
|
+
showContext;
|
|
14
|
+
enableGlobDot;
|
|
15
|
+
fileLists;
|
|
6
16
|
constructor(fileGlobs, options, reporter) {
|
|
7
17
|
this.fileGlobs = fileGlobs;
|
|
8
18
|
this.options = options;
|
|
@@ -12,7 +22,8 @@ export class LintRequest {
|
|
|
12
22
|
this.excludes = calcExcludeGlobInfo(this.root, options.exclude);
|
|
13
23
|
this.locale = options.locale || '';
|
|
14
24
|
this.enableGlobDot = options.dot;
|
|
15
|
-
this.uniqueFilter = options.unique ? util.uniqueFilterFnGenerator((issue) => issue.text) : () => true;
|
|
25
|
+
// this.uniqueFilter = options.unique ? util.uniqueFilterFnGenerator((issue: Issue) => issue.text) : () => true;
|
|
26
|
+
this.uniqueFilter = () => true;
|
|
16
27
|
this.showContext =
|
|
17
28
|
options.showContext === true ? defaultContextRange : options.showContext ? options.showContext : 0;
|
|
18
29
|
this.fileLists = (options.fileList ?? options.fileLists) || [];
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import * as path from 'path';
|
|
2
2
|
import { calcExcludeGlobInfo } from '../util/glob.mjs';
|
|
3
|
-
import * as util from '../util/util.mjs';
|
|
4
3
|
const defaultContextRange = 20;
|
|
5
4
|
export class LintRequest {
|
|
5
|
+
fileGlobs;
|
|
6
|
+
options;
|
|
7
|
+
reporter;
|
|
8
|
+
uniqueFilter;
|
|
9
|
+
locale;
|
|
10
|
+
configFile;
|
|
11
|
+
excludes;
|
|
12
|
+
root;
|
|
13
|
+
showContext;
|
|
14
|
+
enableGlobDot;
|
|
15
|
+
fileLists;
|
|
6
16
|
constructor(fileGlobs, options, reporter) {
|
|
7
17
|
this.fileGlobs = fileGlobs;
|
|
8
18
|
this.options = options;
|
|
@@ -12,7 +22,8 @@ export class LintRequest {
|
|
|
12
22
|
this.excludes = calcExcludeGlobInfo(this.root, options.exclude);
|
|
13
23
|
this.locale = options.locale || '';
|
|
14
24
|
this.enableGlobDot = options.dot;
|
|
15
|
-
this.uniqueFilter = options.unique ? util.uniqueFilterFnGenerator((issue) => issue.text) : () => true;
|
|
25
|
+
// this.uniqueFilter = options.unique ? util.uniqueFilterFnGenerator((issue: Issue) => issue.text) : () => true;
|
|
26
|
+
this.uniqueFilter = () => true;
|
|
16
27
|
this.showContext =
|
|
17
28
|
options.showContext === true ? defaultContextRange : options.showContext ? options.showContext : 0;
|
|
18
29
|
this.fileLists = (options.fileList ?? options.fileLists) || [];
|
package/dist/esm/lint/lint.js
CHANGED
|
@@ -4,7 +4,7 @@ import { MessageTypes } from '@cspell/cspell-types';
|
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import { findRepoRoot, GitIgnore } from 'cspell-gitignore';
|
|
6
6
|
import { GlobMatcher } from 'cspell-glob';
|
|
7
|
-
import
|
|
7
|
+
import { ENV_CSPELL_GLOB_ROOT, extractDependencies, extractImportErrors, getDictionary, isBinaryFile as cspellIsBinaryFile, setLogger, shouldCheckDocument, spellCheckDocument, Text as cspellText, } from 'cspell-lib';
|
|
8
8
|
import * as path from 'path';
|
|
9
9
|
import { format } from 'util';
|
|
10
10
|
import { URI } from 'vscode-uri';
|
|
@@ -23,7 +23,7 @@ const BATCH_SIZE = 8;
|
|
|
23
23
|
const { opFilterAsync } = operators;
|
|
24
24
|
export async function runLint(cfg) {
|
|
25
25
|
let { reporter } = cfg;
|
|
26
|
-
|
|
26
|
+
setLogger(getLoggerFromReporter(reporter));
|
|
27
27
|
const configErrors = new Set();
|
|
28
28
|
const timer = getTimeMeasurer();
|
|
29
29
|
const lintResult = await run();
|
|
@@ -45,7 +45,7 @@ export async function runLint(cfg) {
|
|
|
45
45
|
return { fileResult };
|
|
46
46
|
}
|
|
47
47
|
const uri = filenameToUri(filename, cfg.root);
|
|
48
|
-
const checkResult = await
|
|
48
|
+
const checkResult = await shouldCheckDocument({ uri }, {}, configInfo.config);
|
|
49
49
|
if (!checkResult.shouldCheck)
|
|
50
50
|
return { skip: true };
|
|
51
51
|
const fileInfo = await readFileInfo(filename, undefined, true);
|
|
@@ -88,13 +88,20 @@ export async function runLint(cfg) {
|
|
|
88
88
|
let spellResult = {};
|
|
89
89
|
reporter.info(`Checking: ${filename}, File type: ${doc.languageId ?? 'auto'}, Language: ${doc.locale ?? 'default'}`, MessageTypes.Info);
|
|
90
90
|
try {
|
|
91
|
-
const { showSuggestions: generateSuggestions, validateDirectives } = cfg.options;
|
|
91
|
+
const { showSuggestions: generateSuggestions, validateDirectives, skipValidation } = cfg.options;
|
|
92
92
|
const numSuggestions = configInfo.config.numSuggestions ?? 5;
|
|
93
|
-
const validateOptions = util.clean({
|
|
94
|
-
|
|
93
|
+
const validateOptions = util.clean({
|
|
94
|
+
generateSuggestions,
|
|
95
|
+
numSuggestions,
|
|
96
|
+
validateDirectives,
|
|
97
|
+
skipValidation,
|
|
98
|
+
});
|
|
99
|
+
const r = await spellCheckDocument(doc, validateOptions, configInfo.config);
|
|
100
|
+
// console.warn('filename: %o %o', path.relative(process.cwd(), filename), r.perf);
|
|
95
101
|
spellResult = r;
|
|
96
102
|
result.processed = r.checked;
|
|
97
|
-
result.
|
|
103
|
+
result.perf = r.perf ? { ...r.perf } : undefined;
|
|
104
|
+
result.issues = cspellText.calculateTextDocumentOffsets(doc.uri, text, r.issues).map(mapIssue);
|
|
98
105
|
}
|
|
99
106
|
catch (e) {
|
|
100
107
|
reporter.error(`Failed to process "${filename}"`, toError(e));
|
|
@@ -103,9 +110,9 @@ export async function runLint(cfg) {
|
|
|
103
110
|
result.elapsedTimeMs = getElapsedTimeMs();
|
|
104
111
|
const config = spellResult.settingsUsed ?? {};
|
|
105
112
|
result.configErrors += await reportConfigurationErrors(config);
|
|
106
|
-
const elapsed = result.elapsedTimeMs
|
|
113
|
+
const elapsed = result.elapsedTimeMs;
|
|
107
114
|
const dictionaries = config.dictionaries || [];
|
|
108
|
-
reporter.info(`Checked: ${filename}, File type: ${config.languageId}, Language: ${config.language} ... Issues: ${result.issues.length} ${elapsed}
|
|
115
|
+
reporter.info(`Checked: ${filename}, File type: ${config.languageId}, Language: ${config.language} ... Issues: ${result.issues.length} ${elapsed.toFixed(2)}ms`, MessageTypes.Info);
|
|
109
116
|
reporter.info(`Config file Used: ${spellResult.localConfigFilepath || configInfo.source}`, MessageTypes.Info);
|
|
110
117
|
reporter.info(`Dictionaries Used: ${dictionaries.join(', ')}`, MessageTypes.Info);
|
|
111
118
|
if (cfg.options.debug) {
|
|
@@ -193,8 +200,18 @@ export async function runLint(cfg) {
|
|
|
193
200
|
else {
|
|
194
201
|
for (const pf of prefetchFiles(files)) {
|
|
195
202
|
await pf.result;
|
|
196
|
-
yield
|
|
203
|
+
yield processPrefetchFileResult(pf, ++i);
|
|
197
204
|
}
|
|
205
|
+
// const iter = prefetchIterable(
|
|
206
|
+
// pipe(
|
|
207
|
+
// prefetchFiles(files),
|
|
208
|
+
// opMap(async (pf) => {
|
|
209
|
+
// return processPrefetchFileResult(pf, ++i);
|
|
210
|
+
// }),
|
|
211
|
+
// ),
|
|
212
|
+
// BATCH_SIZE,
|
|
213
|
+
// );
|
|
214
|
+
// yield* iter;
|
|
198
215
|
}
|
|
199
216
|
}
|
|
200
217
|
for await (const fileP of loadAndProcessFiles()) {
|
|
@@ -218,11 +235,11 @@ export async function runLint(cfg) {
|
|
|
218
235
|
return status;
|
|
219
236
|
}
|
|
220
237
|
function calcDependencies(config) {
|
|
221
|
-
const { configFiles, dictionaryFiles } =
|
|
238
|
+
const { configFiles, dictionaryFiles } = extractDependencies(config);
|
|
222
239
|
return { files: configFiles.concat(dictionaryFiles) };
|
|
223
240
|
}
|
|
224
241
|
async function reportConfigurationErrors(config) {
|
|
225
|
-
const errors =
|
|
242
|
+
const errors = extractImportErrors(config);
|
|
226
243
|
let count = 0;
|
|
227
244
|
errors.forEach((ref) => {
|
|
228
245
|
const key = ref.error.toString();
|
|
@@ -232,7 +249,7 @@ export async function runLint(cfg) {
|
|
|
232
249
|
count += 1;
|
|
233
250
|
reporter.error('Configuration', ref.error);
|
|
234
251
|
});
|
|
235
|
-
const dictCollection = await
|
|
252
|
+
const dictCollection = await getDictionary(config);
|
|
236
253
|
dictCollection.dictionaries.forEach((dict) => {
|
|
237
254
|
const dictErrors = dict.getErrors?.() || [];
|
|
238
255
|
const msg = `Dictionary Error with (${dict.name})`;
|
|
@@ -252,7 +269,7 @@ export async function runLint(cfg) {
|
|
|
252
269
|
}
|
|
253
270
|
async function run() {
|
|
254
271
|
if (cfg.options.root) {
|
|
255
|
-
process.env[
|
|
272
|
+
process.env[ENV_CSPELL_GLOB_ROOT] = cfg.root;
|
|
256
273
|
}
|
|
257
274
|
const configInfo = await readConfig(cfg.configFile, cfg.root);
|
|
258
275
|
if (cfg.options.defaultConfiguration !== undefined) {
|
|
@@ -266,7 +283,7 @@ export async function runLint(cfg) {
|
|
|
266
283
|
});
|
|
267
284
|
const reporters = cfg.options.reporter ?? configInfo.config.reporters;
|
|
268
285
|
reporter = mergeReporters(...(await loadReporters(reporters, cfg.reporter, reporterConfig)));
|
|
269
|
-
|
|
286
|
+
setLogger(getLoggerFromReporter(reporter));
|
|
270
287
|
const globInfo = await determineGlobs(configInfo, cfg);
|
|
271
288
|
const { fileGlobs, excludeGlobs } = globInfo;
|
|
272
289
|
const hasFileLists = !!cfg.fileLists.length;
|
|
@@ -361,7 +378,7 @@ async function determineFilesToCheck(configInfo, cfg, reporter, globInfo) {
|
|
|
361
378
|
return files;
|
|
362
379
|
}
|
|
363
380
|
function isExcluded(filename, globMatcherExclude) {
|
|
364
|
-
if (
|
|
381
|
+
if (cspellIsBinaryFile(URI.file(filename))) {
|
|
365
382
|
return true;
|
|
366
383
|
}
|
|
367
384
|
const { root } = cfg;
|