From e09fef633bd676d562b227f1408abc98b6abb648 Mon Sep 17 00:00:00 2001 From: gadhagod <69025547+gadhagod@users.noreply.github.com> Date: Wed, 16 Jun 2021 23:27:09 -0700 Subject: [PATCH 1/5] Add support for configuration in `package.json` --- .spellcheckerrc.yml | 5 ----- CHANGELOG.md | 2 ++ README.md | 2 ++ lib/config/index.ts | 4 +++- lib/config/package.ts | 22 ++++++++++++++++++++++ package.json | 9 +++++++++ test/cli-test.ts | 4 ++++ 7 files changed, 42 insertions(+), 6 deletions(-) delete mode 100644 .spellcheckerrc.yml create mode 100644 lib/config/package.ts diff --git a/.spellcheckerrc.yml b/.spellcheckerrc.yml deleted file mode 100644 index 749260f..0000000 --- a/.spellcheckerrc.yml +++ /dev/null @@ -1,5 +0,0 @@ -files: - - "**/*.md" - - "!test/**/*.md" -dictionaries: - - dictionary.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 0470abb..f188716 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +- Add support for configuration in `package.json` ([@gadhagod](https://github.com/gadhagod)). + ## [4.8.0] - 2021-06-13 - Convert project to TypeScript. diff --git a/README.md b/README.md index 634c1cb..d7dc199 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,8 @@ Spellchecker CLI can also read configuration from a JSON or YAML file. By defaul You can specify any command line option in a config file. Just make sure to use camelcase option names in the config file, _e.g._ `frontmatterKeys` instead of `frontmatter-keys`. +Also, you can specify command line options in your `package.json`. All keys under `spellchecker` in `package.json` are rendered the sayme way as other configuration-from-file methods. + Command line arguments will override any configuration read from a file. ### Globs diff --git a/lib/config/index.ts b/lib/config/index.ts index 023f50d..1629679 100644 --- a/lib/config/index.ts +++ b/lib/config/index.ts @@ -8,6 +8,7 @@ import { defaultPlugins, getUsage, readArgs, supportedLanguages, supportedPlugins, } from './command-line'; import { readConfigFile } from './file'; +import { readFromPackage } from './package'; import { InternalConfig } from './types'; const defaultValues = { @@ -23,7 +24,8 @@ const defaultValues = { export const parseConfig = (): InternalConfig => { const args = readArgs(); const configFile = readConfigFile(args.config); - const parsedArgs = merge({}, defaultValues, configFile, args); + const packageFile = readFromPackage(); + const parsedArgs = merge({}, defaultValues, packageFile, configFile, args); const { files, diff --git a/lib/config/package.ts b/lib/config/package.ts new file mode 100644 index 0000000..13886ed --- /dev/null +++ b/lib/config/package.ts @@ -0,0 +1,22 @@ +import { readFileSync } from 'fs'; + +import { printError } from '../print-error'; + +import { ExternalConfig } from './types'; + +export function readFromPackage(): ExternalConfig { + let config; + try { + config = JSON.parse(readFileSync('package.json') as unknown as string); + } catch (err) { + if ((err as Error).name === 'SyntaxError') { + printError('Unable to parse package.json'); + } else { + printError(`Unable to parse package.json. Error: ${(err as Error).message}`); + } + } + if ('spellchecker' in config) { + return config.spellchecker; + } + return {}; +} diff --git a/package.json b/package.json index 8364f38..6765812 100644 --- a/package.json +++ b/package.json @@ -74,5 +74,14 @@ "mocha.parallel": "0.15.5", "ts-node": "^10.0.0", "typescript": "^4.3.2" + }, + "spellchecker": { + "files": [ + "**/*.md", + "!test/**/*.md" + ], + "dictionaries": [ + "dictionary.txt" + ] } } diff --git a/test/cli-test.ts b/test/cli-test.ts index 8e7cfe0..113706e 100644 --- a/test/cli-test.ts +++ b/test/cli-test.ts @@ -477,4 +477,8 @@ parallel('Spellchecker CLI', function testSpellcheckerCLI(this: { timeout(n: num const result = await runWithArguments('--config test/fixtures/config/basic.jsonc'); result.should.not.have.property('code'); }); + it ('can read options from `package.json`', async () => { + const result = await runCommand("node build/index.js"); + result.should.not.have.property('code'); + }) }); From c1148f4a0f8df9682b428ed68b3f676383125f94 Mon Sep 17 00:00:00 2001 From: gadhagod <69025547+gadhagod@users.noreply.github.com> Date: Thu, 17 Jun 2021 17:35:11 -0700 Subject: [PATCH 2/5] Fix bug where error was raised when no package.json is present --- README.md | 2 +- lib/config/package.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d7dc199..f7d16c8 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ Spellchecker CLI can also read configuration from a JSON or YAML file. By defaul You can specify any command line option in a config file. Just make sure to use camelcase option names in the config file, _e.g._ `frontmatterKeys` instead of `frontmatter-keys`. -Also, you can specify command line options in your `package.json`. All keys under `spellchecker` in `package.json` are rendered the sayme way as other configuration-from-file methods. +Also, you can specify command line options in your `package.json`. All keys under `spellchecker` in `package.json` are rendered the same way as other configuration-from-file methods. Command line arguments will override any configuration read from a file. diff --git a/lib/config/package.ts b/lib/config/package.ts index 13886ed..880e990 100644 --- a/lib/config/package.ts +++ b/lib/config/package.ts @@ -11,9 +11,9 @@ export function readFromPackage(): ExternalConfig { } catch (err) { if ((err as Error).name === 'SyntaxError') { printError('Unable to parse package.json'); - } else { - printError(`Unable to parse package.json. Error: ${(err as Error).message}`); + process.exit(1); } + return {}; } if ('spellchecker' in config) { return config.spellchecker; From 8825f8e462321a296e20dee38b4896caedde8d25 Mon Sep 17 00:00:00 2001 From: gadhagod <69025547+gadhagod@users.noreply.github.com> Date: Thu, 17 Jun 2021 17:36:58 -0700 Subject: [PATCH 3/5] Fix bug with configuration files --- lib/config/file.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/config/file.ts b/lib/config/file.ts index 9482ce9..fb0cdb7 100644 --- a/lib/config/file.ts +++ b/lib/config/file.ts @@ -33,12 +33,11 @@ export const readConfigFile = (filePathFromArgs: string|undefined): ExternalConf if (filePathFromArgs) { return tryLoad(filePathFromArgs); } - const filePath = [ '/.spellcheckerrc.yaml', '/.spellcheckerrc.yml', - './spellcheckerrc.json', - './spellcheckerrc.jsonc', + '/.spellcheckerrc.json', + '/.spellcheckerrc.jsonc', ] .map(path => appRootPath.resolve(path)) .find((path) => { From 2bc20ffb6278bda4c727549657742937f53af7df Mon Sep 17 00:00:00 2001 From: gadhagod <69025547+gadhagod@users.noreply.github.com> Date: Sat, 19 Jun 2021 18:15:54 -0700 Subject: [PATCH 4/5] Print all errors in package.json configuration --- lib/config/package.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/config/package.ts b/lib/config/package.ts index 880e990..448fad3 100644 --- a/lib/config/package.ts +++ b/lib/config/package.ts @@ -1,19 +1,28 @@ -import { readFileSync } from 'fs'; +import { accessSync, readFileSync } from 'fs'; + +import appRootPath from 'app-root-path'; import { printError } from '../print-error'; import { ExternalConfig } from './types'; export function readFromPackage(): ExternalConfig { + const path = appRootPath.resolve('package.json'); + try { + accessSync(path); + } catch { + return {}; + } let config; try { - config = JSON.parse(readFileSync('package.json') as unknown as string); + config = JSON.parse(readFileSync(path, 'utf-8')); } catch (err) { if ((err as Error).name === 'SyntaxError') { printError('Unable to parse package.json'); - process.exit(1); + } else { + printError(`Unable to parse package.json: ${(err as Error).message}`); } - return {}; + process.exit(1); } if ('spellchecker' in config) { return config.spellchecker; From 50639f0b74134fc749d99680c880376bf12d4a6b Mon Sep 17 00:00:00 2001 From: gadhagod <69025547+gadhagod@users.noreply.github.com> Date: Sat, 19 Jun 2021 18:49:29 -0700 Subject: [PATCH 5/5] Use package.json from `test/fixtures/config/package.json` in `package.json\ configuration test` --- test/cli-test.ts | 15 ++++++++------- test/fixtures/config/package.json | 11 +++++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 test/fixtures/config/package.json diff --git a/test/cli-test.ts b/test/cli-test.ts index 113706e..c9fe23e 100644 --- a/test/cli-test.ts +++ b/test/cli-test.ts @@ -21,12 +21,12 @@ chai.should(); type CommandResult = { stdout: string, stderr: string } & Partial -function runCommand(command: string): Promise { +function runCommand(command: string, appRootPath?: string): Promise { return new Promise((resolve) => { exec( command, // Prevent Spellchecker from picking up .spellcheckerrc.yml in these tests. - { env: Object.assign({}, process.env, { APP_ROOT_PATH: __dirname }) }, + { env: Object.assign({}, process.env, { APP_ROOT_PATH: appRootPath ?? __dirname }) }, (error, stdout, stderr) => { if (error) { resolve(merge({}, error, { stdout, stderr })); @@ -37,8 +37,8 @@ function runCommand(command: string): Promise { }); } -function runWithArguments(args: string) { - return runCommand(`node build/index.js ${args}`); +function runWithArguments(args: string, appRootPath?: string) { + return runCommand(`node build/index.js ${args}`, appRootPath); } const notSpell = (plugin: string) => plugin !== 'spell'; @@ -477,8 +477,9 @@ parallel('Spellchecker CLI', function testSpellcheckerCLI(this: { timeout(n: num const result = await runWithArguments('--config test/fixtures/config/basic.jsonc'); result.should.not.have.property('code'); }); - it ('can read options from `package.json`', async () => { - const result = await runCommand("node build/index.js"); + + it('can read options from `package.json`', async () => { + const result = await runWithArguments('', `${__dirname}/fixtures/config`); result.should.not.have.property('code'); - }) + }); }); diff --git a/test/fixtures/config/package.json b/test/fixtures/config/package.json new file mode 100644 index 0000000..2a0539d --- /dev/null +++ b/test/fixtures/config/package.json @@ -0,0 +1,11 @@ +{ + "name": "spellchecker-cli-test-fixtures", + "version": "1.0.0", + "description": "", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "MIT" +}