From d85ffecd1364c3e11a5c72639f4b3050322bad58 Mon Sep 17 00:00:00 2001 From: Jason Dent Date: Sat, 14 Nov 2020 11:11:56 +0100 Subject: [PATCH] fix: fail on missing files (#575) cspell will now exit with code 1 if there are any errors in config files. Added an optional flag to fail if no files are checked. --- packages/cspell/src/app.test.ts | 6 ++++-- packages/cspell/src/app.ts | 27 +++++++++++++++++---------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/packages/cspell/src/app.test.ts b/packages/cspell/src/app.test.ts index 5d6c46bb43a..09ca3047a1e 100644 --- a/packages/cspell/src/app.test.ts +++ b/packages/cspell/src/app.test.ts @@ -27,18 +27,20 @@ type Test = [string, string[], ErrorCheck, boolean, boolean, boolean]; const tests: Test[] = [ t('test app no-args', [], 'outputHelp', true, true, false), t('test app current_file', [__filename], undefined, true, false, false), + t('test app current_file languageId', [__filename, '--languageId=typescript'], undefined, true, false, false), t('test app trace hello', ['trace', 'hello'], undefined, false, true, false), t('test app check LICENSE', ['check', pathRoot('LICENSE')], undefined, false, true, false), t('test app check missing', ['check', pathRoot('missing-file.txt')], undefined, true, true, false), t('test app LICENSE', [pathRoot('LICENSE')], undefined, true, false, false), t('test app samples/Dutch.txt', [pathSamples('Dutch.txt')], app.CheckFailed, true, true, false), t('test app current_file --verbose', ['--verbose', __filename], undefined, true, false, true), - t('test app bad config', ['-c', __filename, __filename], undefined, true, false, false), + t('test app bad config', ['-c', __filename, __filename], app.CheckFailed, true, false, false), + t('test app must find', ['*.not', '--must-find-files'], app.CheckFailed, true, false, false), t('test app cspell-bad.json', ['-c', pathSamples('cspell-bad.json'), __filename], undefined, true, false, false), t( 'test app cspell-import-missing.json', ['-c', pathSamples('linked/cspell-import-missing.json'), __filename], - undefined, + app.CheckFailed, true, false, false diff --git a/packages/cspell/src/app.ts b/packages/cspell/src/app.ts index 3bf5e9d7ee9..98eebf5c0fc 100644 --- a/packages/cspell/src/app.ts +++ b/packages/cspell/src/app.ts @@ -11,6 +11,7 @@ interface Options extends CSpellApplicationOptions { summary: boolean; issues: boolean; silent: boolean; + mustFindFiles: boolean; } type TraceOptions = App.TraceOptions; // interface InitOptions extends Options {} @@ -75,6 +76,8 @@ export async function run(program?: commander.Command, argv?: string[]): Promise const prog = program || commander; const args = argv || process.argv; + prog.passCommandToAction(false); + return new Promise((resolve, rejects) => { let showHelp = true; @@ -94,7 +97,10 @@ export async function run(program?: commander.Command, argv?: string[]): Promise '--local ', 'Set language locals. i.e. "en,fr" for English and French, or "en-GB" for British English.' ) - .option('--legacy', 'Legacy output') + .option( + '--language-id ', + 'Force programming language for unknown extensions. i.e. "php" or "scala"' + ) .option( '--languageId ', 'Force programming language for unknown extensions. i.e. "php" or "scala"' @@ -107,11 +113,15 @@ export async function run(program?: commander.Command, argv?: string[]): Promise .option('--no-summary', 'Turn off summary message in console') .option('-s, --silent', 'Silent mode, suppress error messages') .option('-r, --root ', 'Root directory, defaults to current directory.') + .option('--must-find-files', 'Error if no files are found', false) + .option('--no-must-find-files', 'Do not error is no files are found') // The following options are planned features // .option('-w, --watch', 'Watch for any changes to the matching files and report any errors') // .option('--force', 'Force the exit value to always be 0') + .option('--legacy', 'Legacy output') .arguments('') .action((files: string[] | undefined, options: Options) => { + const { mustFindFiles } = options; const emitters: App.Emitters = getEmitters(options); if (!files || !files.length) { return; @@ -126,15 +136,14 @@ export async function run(program?: commander.Command, argv?: string[]): Promise result.filesWithIssues.size ); } - if (result.issues) { + if (result.issues || result.errors || (mustFindFiles && !result.files)) { throw new CheckFailed('check failed', 1); } }); }); - interface TraceCommandOptions { - parent: TraceOptions; - } + type TraceCommandOptions = TraceOptions; + prog.command('trace') .description('Trace words') .option( @@ -154,14 +163,12 @@ export async function run(program?: commander.Command, argv?: string[]): Promise .arguments('') .action((words: string[], options: TraceCommandOptions) => { showHelp = false; - return App.trace(words, options.parent).then((result) => { + return App.trace(words, options).then((result) => { result.forEach(emitTraceResult); }); }); - interface CheckCommandOptions { - parent: BaseOptions; - } + type CheckCommandOptions = BaseOptions; prog.command('check ') .description('Spell check file(s) and display the result. The full file is displayed in color.') @@ -178,7 +185,7 @@ export async function run(program?: commander.Command, argv?: string[]): Promise console.log(chalk.yellowBright(`Check file: ${filename}`)); console.log(); try { - const result = await checkText(filename, options.parent); + const result = await checkText(filename, options); for (const item of result.items) { const fn = item.flagIE === App.IncludeExcludeFlag.EXCLUDE