diff --git a/README.md b/README.md index dd40853e4..47d6b4c40 100644 --- a/README.md +++ b/README.md @@ -114,9 +114,7 @@ Starting with v3.1 you can now use different ways of configuring lint-staged: whether your project's _package.json_ contains the `"type": "module"` option or not. - Pass a configuration file using the `--config` or `-c` flag -See [cosmiconfig](https://github.com/davidtheclark/cosmiconfig) for more details on what formats are supported. - -Configuration should be an object where each value is a command to run and its key is a glob pattern to use for this command. This package uses [micromatch](https://github.com/micromatch/micromatch) for glob patterns. +Configuration should be an object where each value is a command to run and its key is a glob pattern to use for this command. This package uses [micromatch](https://github.com/micromatch/micromatch) for glob patterns. JavaScript files can also export advanced configuration as a function. See [Using JS configuration files](#using-js-configuration-files) for more info. #### `package.json` example: @@ -202,7 +200,7 @@ For example: going to execute `eslint` and if it exits with `0` code, it will execute `prettier --write` on all staged `*.js` files. -## Using JS configuration file +## Using JS configuration files Writing the configuration file in JavaScript is the most powerful way to configure lint-staged (`lint-staged.config.js`, [similar](https://github.com/okonet/lint-staged/README.md#configuration), or passed via `--config`). From the configuration file, you can export either a single function or an object. diff --git a/lib/index.js b/lib/index.js index 84f5c168f..838489892 100644 --- a/lib/index.js +++ b/lib/index.js @@ -58,21 +58,19 @@ const lintStaged = async ( ) => { await validateOptions({ shell }, logger) - debugLog('Loading config using `cosmiconfig`') + debugLog('Loading config using `lilconfig`') const resolved = configObject ? { config: configObject, filepath: '(input)' } : await loadConfig(configPath) - if (resolved == null) { + if (!resolved) { logger.error(`${ConfigNotFoundError.message}.`) throw ConfigNotFoundError } debugLog('Successfully loaded config from `%s`:\n%O', resolved.filepath, resolved.config) - // resolved.config is the parsed configuration object - // resolved.filepath is the path to the config file that was found const config = validateConfig(resolved.config, logger) if (debug) { diff --git a/lib/loadConfig.js b/lib/loadConfig.js index e79c4b339..80b7c10b5 100644 --- a/lib/loadConfig.js +++ b/lib/loadConfig.js @@ -1,9 +1,44 @@ -import { cosmiconfig } from 'cosmiconfig' +import { lilconfig } from 'lilconfig' +import YAML from 'yaml' + +/** + * The list of files `lint-staged` will read configuration + * from, in the declared order. + */ +const searchPlaces = [ + 'package.json', + '.lintstagedrc', + '.lintstagedrc.json', + '.lintstagedrc.yaml', + '.lintstagedrc.yml', + '.lintstagedrc.mjs', + '.lintstagedrc.js', + '.lintstagedrc.cjs', + 'lint-staged.config.mjs', + 'lint-staged.config.js', + 'lint-staged.config.cjs', +] const dynamicImport = (path) => import(path).then((module) => module.default) const jsonParse = (path, content) => JSON.parse(content) +/** + * `lilconfig` doesn't support yaml files by default, + * so we add custom loaders for those. Files without + * an extensions are assumed to be yaml — this + * assumption is in `cosmiconfig` as well. + */ +const loaders = { + '.js': dynamicImport, + '.json': jsonParse, + '.mjs': dynamicImport, + '.cjs': dynamicImport, + '.yaml': YAML.parse, + '.yml': YAML.parse, + noExt: YAML.parse, +} + const resolveConfig = (configPath) => { try { return require.resolve(configPath) @@ -16,27 +51,6 @@ const resolveConfig = (configPath) => { * @param {string} [configPath] */ export const loadConfig = (configPath) => { - const explorer = cosmiconfig('lint-staged', { - searchPlaces: [ - 'package.json', - '.lintstagedrc', - '.lintstagedrc.json', - '.lintstagedrc.yaml', - '.lintstagedrc.yml', - '.lintstagedrc.mjs', - '.lintstagedrc.js', - '.lintstagedrc.cjs', - 'lint-staged.config.mjs', - 'lint-staged.config.js', - 'lint-staged.config.cjs', - ], - loaders: { - '.cjs': dynamicImport, - '.js': dynamicImport, - '.json': jsonParse, - '.mjs': dynamicImport, - }, - }) - + const explorer = lilconfig('lint-staged', { searchPlaces, loaders }) return configPath ? explorer.load(resolveConfig(configPath)) : explorer.search() } diff --git a/lib/symbols.js b/lib/symbols.js index e904b3b56..dc832a311 100644 --- a/lib/symbols.js +++ b/lib/symbols.js @@ -1,6 +1,10 @@ export const ApplyEmptyCommitError = Symbol('ApplyEmptyCommitError') -export const ConfigNotFoundError = new Error('Config could not be found') +export const ConfigNotFoundError = new Error('Configuration could not be found') + +export const ConfigFormatError = new Error('Configuration should be an object or a function') + +export const ConfigEmptyError = new Error('Configuration should not be empty') export const GetBackupStashError = Symbol('GetBackupStashError') diff --git a/lib/validateConfig.js b/lib/validateConfig.js index 19c0a9704..11e1ceea0 100644 --- a/lib/validateConfig.js +++ b/lib/validateConfig.js @@ -1,6 +1,7 @@ import debug from 'debug' import { configurationError } from './messages.js' +import { ConfigEmptyError, ConfigFormatError } from './symbols.js' import { validateBraces } from './validateBraces.js' const debugLog = debug('lint-staged:validateConfig') @@ -27,7 +28,7 @@ export const validateConfig = (config, logger) => { debugLog('Validating config') if (!config || (typeof config !== 'object' && typeof config !== 'function')) { - throw new Error('Configuration should be an object or a function!') + throw ConfigFormatError } /** @@ -42,7 +43,7 @@ export const validateConfig = (config, logger) => { } if (Object.entries(config).length === 0) { - throw new Error('Configuration should not be empty!') + throw ConfigEmptyError } const errors = [] diff --git a/package-lock.json b/package-lock.json index c5add3b0d..3c2cd33c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,16 +12,17 @@ "cli-truncate": "^3.1.0", "colorette": "^2.0.16", "commander": "^8.3.0", - "cosmiconfig": "^7.0.1", "debug": "^4.3.2", "enquirer": "^2.3.6", "execa": "^5.1.1", + "lilconfig": "2.0.4", "listr2": "^3.13.3", "micromatch": "^4.0.4", "normalize-path": "^3.0.0", "object-inspect": "^1.11.0", "string-argv": "^0.3.1", - "supports-color": "^9.0.2" + "supports-color": "^9.0.2", + "yaml": "^1.10.2" }, "bin": { "lint-staged": "bin/lint-staged.js" @@ -55,6 +56,7 @@ "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", + "dev": true, "dependencies": { "@babel/highlight": "^7.16.0" }, @@ -414,6 +416,7 @@ "version": "7.15.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -460,6 +463,7 @@ "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", + "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.15.7", "chalk": "^2.0.0", @@ -2505,11 +2509,6 @@ "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==", "dev": true }, - "node_modules/@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" - }, "node_modules/@types/prettier": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", @@ -2670,6 +2669,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -3047,6 +3047,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, "engines": { "node": ">=6" } @@ -3074,6 +3075,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -3087,6 +3089,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, "engines": { "node": ">=4" } @@ -3095,6 +3098,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -3225,6 +3229,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -3232,7 +3237,8 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true }, "node_modules/colorette": { "version": "2.0.16", @@ -3338,21 +3344,6 @@ "semver": "bin/semver.js" } }, - "node_modules/cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3553,14 +3544,6 @@ "node": ">=8.6" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, "node_modules/es-abstract": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", @@ -3625,6 +3608,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, "engines": { "node": ">=0.8.0" } @@ -4870,6 +4854,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -4885,6 +4870,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, "engines": { "node": ">=4" } @@ -4964,11 +4950,6 @@ "node": ">= 0.4" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -7032,7 +7013,8 @@ "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "node_modules/js-yaml": { "version": "3.14.1", @@ -7105,11 +7087,6 @@ "node": ">=4" } }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -7180,10 +7157,13 @@ "node": ">= 0.8.0" } }, - "node_modules/lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" + "node_modules/lilconfig": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz", + "integrity": "sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==", + "engines": { + "node": ">=10" + } }, "node_modules/listr2": { "version": "3.13.3", @@ -7725,6 +7705,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -7732,23 +7713,6 @@ "node": ">=6" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", @@ -7787,14 +7751,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "engines": { - "node": ">=8" - } - }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -9152,6 +9108,7 @@ "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", + "dev": true, "requires": { "@babel/highlight": "^7.16.0" } @@ -9418,7 +9375,8 @@ "@babel/helper-validator-identifier": { "version": "7.15.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==" + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true }, "@babel/helper-validator-option": { "version": "7.14.5", @@ -9453,6 +9411,7 @@ "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.15.7", "chalk": "^2.0.0", @@ -10929,11 +10888,6 @@ "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==", "dev": true }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" - }, "@types/prettier": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", @@ -11057,6 +11011,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -11347,7 +11302,8 @@ "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true }, "camelcase": { "version": "5.3.1", @@ -11365,6 +11321,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -11374,12 +11331,14 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -11483,6 +11442,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, "requires": { "color-name": "1.1.3" } @@ -11490,7 +11450,8 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true }, "colorette": { "version": "2.0.16", @@ -11578,18 +11539,6 @@ } } }, - "cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } - }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -11744,14 +11693,6 @@ "ansi-colors": "^4.1.1" } }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, "es-abstract": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", @@ -11800,7 +11741,8 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true }, "escodegen": { "version": "2.0.0", @@ -12710,6 +12652,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -12718,7 +12661,8 @@ "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true } } }, @@ -12781,11 +12725,6 @@ "side-channel": "^1.0.4" } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, "is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -14309,7 +14248,8 @@ "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "js-yaml": { "version": "3.14.1", @@ -14362,11 +14302,6 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -14420,10 +14355,10 @@ "type-check": "~0.4.0" } }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" + "lilconfig": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz", + "integrity": "sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==" }, "listr2": { "version": "3.13.3", @@ -14828,21 +14763,11 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, "requires": { "callsites": "^3.0.0" } }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, "parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", @@ -14872,11 +14797,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" - }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", diff --git a/package.json b/package.json index c9d46bc4c..7f63a0123 100644 --- a/package.json +++ b/package.json @@ -32,16 +32,17 @@ "cli-truncate": "^3.1.0", "colorette": "^2.0.16", "commander": "^8.3.0", - "cosmiconfig": "^7.0.1", "debug": "^4.3.2", "enquirer": "^2.3.6", "execa": "^5.1.1", + "lilconfig": "2.0.4", "listr2": "^3.13.3", "micromatch": "^4.0.4", "normalize-path": "^3.0.0", "object-inspect": "^1.11.0", "string-argv": "^0.3.1", - "supports-color": "^9.0.2" + "supports-color": "^9.0.2", + "yaml": "^1.10.2" }, "devDependencies": { "@babel/core": "^7.16.0", diff --git a/test/__mocks__/cosmiconfig.js b/test/__mocks__/cosmiconfig.js deleted file mode 100644 index 2a485c317..000000000 --- a/test/__mocks__/cosmiconfig.js +++ /dev/null @@ -1,7 +0,0 @@ -const actual = jest.requireActual('cosmiconfig') - -function cosmiconfig(name, options) { - return actual.cosmiconfig(name, options) -} - -module.exports.cosmiconfig = jest.fn(cosmiconfig) diff --git a/test/__mocks__/lilconfig.js b/test/__mocks__/lilconfig.js new file mode 100644 index 000000000..da03c4a60 --- /dev/null +++ b/test/__mocks__/lilconfig.js @@ -0,0 +1,7 @@ +const actual = jest.requireActual('lilconfig') + +function lilconfig(name, options) { + return actual.lilconfig(name, options) +} + +module.exports.lilconfig = jest.fn(lilconfig) diff --git a/test/__snapshots__/validateConfig.spec.js.snap b/test/__snapshots__/validateConfig.spec.js.snap index 32de00026..38bf1af6a 100644 --- a/test/__snapshots__/validateConfig.spec.js.snap +++ b/test/__snapshots__/validateConfig.spec.js.snap @@ -8,7 +8,7 @@ exports[`validateConfig should throw and should print validation errors for inva Should be a string, a function, or an array of strings and functions." `; -exports[`validateConfig should throw and should print validation errors for invalid config 1 1`] = `"Configuration should be an object or a function!"`; +exports[`validateConfig should throw and should print validation errors for invalid config 1 1`] = `"Configuration should be an object or a function"`; exports[`validateConfig should throw when detecting deprecated advanced configuration 1`] = ` "✖ Validation Error: diff --git a/test/index.spec.js b/test/index.spec.js index 19979233c..4f2b77922 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -1,6 +1,6 @@ import path from 'path' -import { cosmiconfig } from 'cosmiconfig' +import { lilconfig } from 'lilconfig' import makeConsoleMock from 'consolemock' jest.unmock('execa') @@ -12,8 +12,8 @@ import { validateOptions } from '../lib/validateOptions' import { replaceSerializer } from './utils/replaceSerializer' -const mockCosmiconfigWith = (result) => { - cosmiconfig.mockImplementationOnce(() => ({ +const mockLilConfig = (result) => { + lilconfig.mockImplementationOnce(() => ({ search: () => Promise.resolve(result), })) } @@ -33,11 +33,11 @@ describe('lintStaged', () => { logger.clearHistory() }) - it('should use cosmiconfig if no params are passed', async () => { + it('should use lilconfig if no params are passed', async () => { expect.assertions(1) const config = { '*': 'mytask' } - mockCosmiconfigWith({ config }) + mockLilConfig({ config }) await lintStaged(undefined, logger) @@ -60,14 +60,14 @@ describe('lintStaged', () => { it('should use use the console if no logger is passed', async () => { expect.assertions(2) - mockCosmiconfigWith({ config: {} }) + mockLilConfig({ config: {} }) const previousConsole = console const mockedConsole = makeConsoleMock() console = mockedConsole await expect(lintStaged()).rejects.toMatchInlineSnapshot( - `[Error: Configuration should not be empty!]` + `[Error: Configuration should not be empty]` ) expect(mockedConsole.printHistory()).toMatchInlineSnapshot(`""`) @@ -79,7 +79,7 @@ describe('lintStaged', () => { expect.assertions(1) const config = { '*': 'mytask' } - mockCosmiconfigWith({ config }) + mockLilConfig({ config }) await lintStaged({ debug: true, quiet: true }, logger) @@ -96,7 +96,7 @@ describe('lintStaged', () => { expect.assertions(1) const config = { '*': 'mytask' } - mockCosmiconfigWith({ config }) + mockLilConfig({ config }) await lintStaged({ quiet: true }, logger) @@ -119,10 +119,10 @@ describe('lintStaged', () => { it('should throw when invalid config is provided', async () => { const config = {} - mockCosmiconfigWith({ config }) + mockLilConfig({ config }) await expect(lintStaged({ quiet: true }, logger)).rejects.toMatchInlineSnapshot( - `[Error: Configuration should not be empty!]` + `[Error: Configuration should not be empty]` ) expect(logger.printHistory()).toMatchInlineSnapshot(`""`) @@ -285,15 +285,15 @@ describe('lintStaged', () => { it('should print helpful error message when config file is not found', async () => { expect.assertions(2) - mockCosmiconfigWith(null) + mockLilConfig(null) await expect(lintStaged({ quiet: true }, logger)).rejects.toMatchInlineSnapshot( - `[Error: Config could not be found]` + `[Error: Configuration could not be found]` ) expect(logger.printHistory()).toMatchInlineSnapshot(` " - ERROR Config could not be found." + ERROR Configuration could not be found." `) }) diff --git a/test/integration.test.js b/test/integration.test.js index dfec7a743..cc9c2da11 100644 --- a/test/integration.test.js +++ b/test/integration.test.js @@ -5,7 +5,7 @@ import fs from 'fs-extra' import ansiSerializer from 'jest-snapshot-serializer-ansi' import normalize from 'normalize-path' -jest.unmock('cosmiconfig') +jest.unmock('lilconfig') jest.unmock('execa') import { execGit as execGitBase } from '../lib/execGit'