diff --git a/.lintstagedrc.json b/.lintstagedrc.json index 533a7f58a..135ddb1bf 100644 --- a/.lintstagedrc.json +++ b/.lintstagedrc.json @@ -1,7 +1,5 @@ { - "linters": { - "*.{js,json,md}": ["prettier --write", "git add"], - "*.js": ["npm run lint:base --fix", "git add"], - ".*{rc, json}": ["jsonlint", "git add"] - } + "*.{js,json,md}": ["prettier --write", "git add"], + "*.js": ["npm run lint:base --fix", "git add"], + ".*{rc, json}": ["jsonlint", "git add"] } diff --git a/README.md b/README.md index 9b1002064..1cd061737 100644 --- a/README.md +++ b/README.md @@ -72,11 +72,7 @@ Starting with v3.1 you can now use different ways of configuring it: See [cosmiconfig](https://github.com/davidtheclark/cosmiconfig) for more details on what formats are supported. -Lint-staged supports simple and advanced config formats. - -### Simple config format - -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. #### `package.json` example: @@ -102,34 +98,6 @@ So, considering you did `git add file1.ext file2.ext`, lint-staged will run the `your-cmd file1.ext file2.ext` -### Advanced config format - -To extend and customise lint-staged, advanced options are available. To use these options the format should be as the following: - -#### `package.json` example with `ignore` option: - -```json -{ - "lint-staged": { - "linters": { - "*.{js,scss}": ["some command", "git add"] - }, - "ignore": ["**/dist/*.min.js"] - } -} -``` - -Notice that the linting commands now are nested into the `linters` object. The following options are available for advanced configuration: - -#### Options - -* `concurrent` — _true_ — runs linters for each glob pattern simultaneously. If you don’t want this, you can set `concurrent: false` -* `globOptions` — `{ matchBase: true, dot: true }` — [micromatch options](https://github.com/micromatch/micromatch#options) to - customize how glob patterns match files. -* `ignore` - `['**/docs/**/*.js']` - array of glob patterns to entirely ignore from any task. -* `linters` — `Object` — keys (`String`) are glob patterns, values (`Array | String`) are commands to execute. -* `relative` — `false` — if `true` it will give the relative path from your `package.json` directory to your linter arguments. - ## Using JS functions to customize linter commands When supplying configuration in JS format it is possible to define the linter command as a function which receives an array of staged filenames/paths and returns the complete linter command as a string. It is also possible to return an array of complete command strings, for example when the linter command supports only a single file input. @@ -178,36 +146,6 @@ module.exports = { } ``` -## Filtering files - -It is possible to run linters for certain paths only by using glob patterns. [micromatch](https://github.com/micromatch/micromatch) is used to filter the staged files according to these patterns. File patterns should be specified _relative to the `package.json` location_ (i.e. where `lint-staged` is installed). - -**NOTE:** If you're using `lint-staged<5` globs have to be _relative to the git root_. - -```js -{ - // .js files anywhere in the root directory of the project - "*.js": "eslint", - // .js files anywhere in the project - "**/*.js": "eslint", - // .js file in the src directory - "src/*.js": "eslint", - // .js file anywhere within and below the src directory - "src/**/*.js": "eslint", -} -``` - -When matching, `lint-staged` will do the following - -* Resolve the git root automatically, no configuration needed. -* Pick the staged files which are present inside the project directory. -* Filter them using the specified glob patterns. -* Pass absolute paths to the linters as arguments. - -**NOTE:** `lint-staged` will pass _absolute_ paths to the linters to avoid any confusion in case they're executed in a different working directory (i.e. when your `.git` directory isn't the same as your `package.json` directory). - -Also see [How to use `lint-staged` in a multi package monorepo?](#how-to-use-lint-staged-in-a-multi-package-monorepo) - ## What commands are supported? Supported are any executables installed locally or globally via `npm` as well as any executable from your $PATH. @@ -328,17 +266,6 @@ For example, here is `jest` running on all `.js` files with the `NODE_ENV` varia } ``` -### Use ng lint with angular cli >= 7.0.0 - -```json -{ - "linters": { - "*.ts": "ng lint myProjectName --files" - }, - "relative": true -} -``` - ### Stylelint for CSS with defaults and for SCSS with SCSS syntax ```json diff --git a/package.json b/package.json index ea5152c94..cf2604a35 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,6 @@ "dedent": "^0.7.0", "del": "^4.1.1", "execa": "^2.0.1", - "is-glob": "^4.0.0", "listr": "^0.14.2", "listr-update-renderer": "^0.5.0", "lodash": "^4.17.11", @@ -42,8 +41,7 @@ "micromatch": "^3.1.8", "path-is-inside": "^1.0.2", "please-upgrade-node": "^3.0.2", - "stringify-object": "^3.2.2", - "yup": "^0.27.0" + "stringify-object": "^3.2.2" }, "devDependencies": { "babel-core": "^6.26.3", diff --git a/src/generateTasks.js b/src/generateTasks.js index 885a651bb..41dc401ae 100644 --- a/src/generateTasks.js +++ b/src/generateTasks.js @@ -4,16 +4,11 @@ const micromatch = require('micromatch') const pathIsInside = require('path-is-inside') const path = require('path') -const { getConfig } = require('./getConfig') - const debug = require('debug')('lint-staged:gen-tasks') -module.exports = async function generateTasks(config, gitDir, stagedRelFiles) { +module.exports = async function generateTasks(linters, gitDir, stagedRelFiles) { debug('Generating linter tasks') - const normalizedConfig = getConfig(config) // Ensure we have a normalized config - const { linters, globOptions, ignore } = normalizedConfig - const cwd = process.cwd() const stagedFiles = stagedRelFiles.map(file => path.resolve(gitDir, file)) @@ -30,17 +25,13 @@ module.exports = async function generateTasks(config, gitDir, stagedRelFiles) { .map(file => path.relative(cwd, file)), pattern, { - ...globOptions, - ignore - } - ).map(file => { - // if you set relative option, then the file path will be relative to your package.json - if (config.relative) { - return path.normalize(file) + matchBase: true, + dot: true } + ).map(file => // Return absolute path after the filter is run - return path.resolve(cwd, file) - }) + path.resolve(cwd, file) + ) const task = { pattern, commands, fileList } debug('Generated task: \n%O', task) diff --git a/src/getConfig.js b/src/getConfig.js deleted file mode 100644 index 86bfdec4c..000000000 --- a/src/getConfig.js +++ /dev/null @@ -1,224 +0,0 @@ -/* eslint no-prototype-builtins: 0 */ - -'use strict' - -const chalk = require('chalk') -const format = require('stringify-object') -const intersection = require('lodash/intersection') -const defaultsDeep = require('lodash/defaultsDeep') -const isArray = require('lodash/isArray') -const isFunction = require('lodash/isFunction') -const isObject = require('lodash/isObject') -const isString = require('lodash/isString') -const isGlob = require('is-glob') -const yup = require('yup') - -const debug = require('debug')('lint-staged:cfg') - -/** - * Default config object - * - * @type {{concurrent: boolean, globOptions: {matchBase: boolean, dot: boolean}, linters: {}, renderer: string}} - */ -const defaultConfig = { - concurrent: true, - globOptions: { - matchBase: true, - dot: true - }, - linters: {}, - ignore: [], - renderer: 'update', - relative: false -} - -/** - * Configuration schema to validate configuration - */ -const schema = yup.object().shape({ - concurrent: yup.boolean().default(defaultConfig.concurrent), - globOptions: yup.object().shape({ - matchBase: yup.boolean().default(defaultConfig.globOptions.matchBase), - dot: yup.boolean().default(defaultConfig.globOptions.dot) - }), - linters: yup.object(), - ignore: yup.array().of(yup.string()), - renderer: yup - .mixed() - .test( - 'renderer', - "Should be 'update', 'verbose' or a function.", - value => value === 'update' || value === 'verbose' || isFunction(value) - ), - relative: yup.boolean().default(defaultConfig.relative) -}) - -/** - * Check if the config is "simple" i.e. doesn't contains any of full config keys - * - * @param config - * @returns {boolean} - */ -function isSimple(config) { - return ( - isObject(config) && - !config.hasOwnProperty('linters') && - intersection(Object.keys(defaultConfig), Object.keys(config)).length === 0 - ) -} - -const logDeprecation = (opt, helpMsg) => - console.warn(`● Deprecation Warning: - - Option ${chalk.bold(opt)} was removed. - - ${helpMsg} - - Please remove ${chalk.bold(opt)} from your configuration. - -Please refer to https://github.com/okonet/lint-staged#configuration for more information...`) - -const logUnknown = (opt, helpMsg, value) => - console.warn(`● Validation Warning: - - Unknown option ${chalk.bold(`"${opt}"`)} with value ${chalk.bold( - format(value, { inlineCharacterLimit: Number.POSITIVE_INFINITY }) - )} was found in the config root. - - ${helpMsg} - -Please refer to https://github.com/okonet/lint-staged#configuration for more information...`) - -const formatError = helpMsg => `● Validation Error: - - ${helpMsg} - -Please refer to https://github.com/okonet/lint-staged#configuration for more information...` - -const createError = (opt, helpMsg, value) => - formatError(`Invalid value for '${chalk.bold(opt)}'. - - ${helpMsg}. - - Configured value is: ${chalk.bold( - format(value, { inlineCharacterLimit: Number.POSITIVE_INFINITY }) - )}`) - -/** - * Reporter for unknown options - * @param config - * @param option - * @returns {void} - */ -function unknownValidationReporter(config, option) { - /** - * If the unkonwn property is a glob this is probably - * a typical mistake of mixing simple and advanced configs - */ - if (isGlob(option)) { - // prettier-ignore - const message = `You are probably trying to mix simple and advanced config formats. Adding - - ${chalk.bold(`"linters": { - "${option}": ${JSON.stringify(config[option])} - }`)} - - will fix it and remove this message.` - - return logUnknown(option, message, config[option]) - } - - // If it is not glob pattern, simply notify of unknown value - return logUnknown(option, '', config[option]) -} - -/** - * For a given configuration object that we retrive from .lintstagedrc or package.json - * construct a full configuration with all options set. - * - * This is a bit tricky since we support 2 different syntxes: simple and full - * For simple config, only the `linters` configuration is provided. - * - * @param {Object} sourceConfig - * @returns {{ - * concurrent: boolean, globOptions: {matchBase: boolean, dot: boolean}, linters: {}, renderer: string - * }} - */ -function getConfig(sourceConfig, debugMode) { - debug('Normalizing config') - const config = defaultsDeep( - {}, // Do not mutate sourceConfig!!! - isSimple(sourceConfig) ? { linters: sourceConfig } : sourceConfig, - defaultConfig - ) - - // Check if renderer is set in sourceConfig and if not, set accordingly to verbose - if (isObject(sourceConfig) && !sourceConfig.hasOwnProperty('renderer')) { - config.renderer = debugMode ? 'verbose' : 'update' - } - - return config -} - -/** - * Runs config validation. Throws error if the config is not valid. - * @param config {Object} - * @returns config {Object} - */ -function validateConfig(config) { - debug('Validating config') - - const deprecatedConfig = { - gitDir: "lint-staged now automatically resolves '.git' directory.", - verbose: `Use the command line flag ${chalk.bold('--debug')} instead.` - } - - const errors = [] - - try { - schema.validateSync(config, { abortEarly: false, strict: true }) - } catch (error) { - error.errors.forEach(message => errors.push(formatError(message))) - } - - if (isObject(config.linters)) { - Object.keys(config.linters).forEach(key => { - if ( - (!isArray(config.linters[key]) || - config.linters[key].some(item => !isString(item) && !isFunction(item))) && - !isString(config.linters[key]) && - !isFunction(config.linters[key]) - ) { - errors.push( - createError( - `linters[${key}]`, - 'Should be a string, a function, or an array of strings and functions', - key - ) - ) - } - }) - } - - Object.keys(config) - .filter(key => !defaultConfig.hasOwnProperty(key)) - .forEach(option => { - if (deprecatedConfig.hasOwnProperty(option)) { - logDeprecation(option, deprecatedConfig[option]) - return - } - - unknownValidationReporter(config, option) - }) - - if (errors.length) { - throw new Error(errors.join('\n')) - } - - return config -} - -module.exports = { - getConfig, - validateConfig -} diff --git a/src/index.js b/src/index.js index 11cb2ec0b..3f017a210 100644 --- a/src/index.js +++ b/src/index.js @@ -3,9 +3,9 @@ const dedent = require('dedent') const cosmiconfig = require('cosmiconfig') const stringifyObject = require('stringify-object') -const { getConfig, validateConfig } = require('./getConfig') const printErrors = require('./printErrors') const runAll = require('./runAll') +const validateConfig = require('./validateConfig') const debug = require('debug')('lint-staged') @@ -55,7 +55,7 @@ module.exports = function lintStaged(logger = console, configPath, debugMode) { debug('Successfully loaded config from `%s`:\n%O', result.filepath, result.config) // result.config is the parsed configuration object // result.filepath is the path to the config file that was found - const config = validateConfig(getConfig(result.config, debugMode)) + const config = validateConfig(result.config) if (debugMode) { // Log using logger to be able to test through `consolemock`. logger.log('Running lint-staged with the following config:') @@ -66,7 +66,7 @@ module.exports = function lintStaged(logger = console, configPath, debugMode) { debug('Normalized config:\n%O', config) } - return runAll(config) + return runAll(config, debugMode) .then(() => { debug('linters were executed successfully!') // No errors, exiting with 0 diff --git a/src/runAll.js b/src/runAll.js index 3c66abcf1..668153066 100644 --- a/src/runAll.js +++ b/src/runAll.js @@ -3,7 +3,6 @@ const chalk = require('chalk') const dedent = require('dedent') const Listr = require('listr') -const has = require('lodash/has') const symbols = require('log-symbols') const generateTasks = require('./generateTasks') @@ -27,14 +26,9 @@ const MAX_ARG_LENGTH = * @param config {Object} * @returns {Promise} */ -module.exports = async function runAll(config) { +module.exports = async function runAll(config, debugMode) { debug('Running all linter scripts') - // Config validation - if (!config || !has(config, 'concurrent') || !has(config, 'renderer')) { - throw new Error('Invalid config provided to runAll! Use getConfig instead.') - } - const { concurrent, renderer } = config const gitDir = await resolveGitDir(config) if (!gitDir) { @@ -81,9 +75,9 @@ https://github.com/okonet/lint-staged#using-js-functions-to-customize-linter-com } })) - const listrBaseOptions = { + const listrOptions = { dateFormat: false, - renderer + renderer: debugMode ? 'verbose' : 'update' } // If all of the configured "linters" should be skipped @@ -114,12 +108,7 @@ https://github.com/okonet/lint-staged#using-js-functions-to-customize-linter-com }, { title: 'Running linters...', - task: () => - new Listr(tasks, { - ...listrBaseOptions, - concurrent, - exitOnError: !concurrent - }) + task: () => new Listr(tasks, { ...listrOptions, concurrent: true, exitOnError: false }) }, { title: 'Updating stash...', @@ -133,6 +122,6 @@ https://github.com/okonet/lint-staged#using-js-functions-to-customize-linter-com task: () => git.gitStashPop({ cwd: gitDir }) } ], - listrBaseOptions + listrOptions ).run() } diff --git a/src/validateConfig.js b/src/validateConfig.js new file mode 100644 index 000000000..eca9e4072 --- /dev/null +++ b/src/validateConfig.js @@ -0,0 +1,70 @@ +/* eslint no-prototype-builtins: 0 */ + +'use strict' + +const chalk = require('chalk') +const format = require('stringify-object') +const isArray = require('lodash/isArray') +const isFunction = require('lodash/isFunction') +const isObject = require('lodash/isObject') +const isString = require('lodash/isString') + +const debug = require('debug')('lint-staged:cfg') + +const formatError = helpMsg => `● Validation Error: + + ${helpMsg} + +Please refer to https://github.com/okonet/lint-staged#configuration for more information...` + +const createError = (opt, helpMsg, value) => + formatError(`Invalid value for '${chalk.bold(opt)}'. + + ${helpMsg}. + + Configured value is: ${chalk.bold( + format(value, { inlineCharacterLimit: Number.POSITIVE_INFINITY }) + )}`) + +/** + * Runs config validation. Throws error if the config is not valid. + * @param config {Object} + * @returns config {Object} + */ +module.exports = function validateConfig(config) { + debug('Validating config') + + const errors = [] + + if (!isObject(config)) { + errors.push('Configuration should be an object!') + } else { + const globs = Object.keys(config) + + if (globs.length === 0) { + errors.push('Configuration should not be empty!') + } + + globs.forEach(key => { + if ( + (!isArray(config[key]) || config[key].some(item => !isString(item) && !isFunction(item))) && + !isString(config[key]) && + !isFunction(config[key]) + ) { + errors.push( + createError( + key, + 'Should be a string, a function, or an array of strings and functions', + key + ) + ) + } + }) + } + + if (errors.length) { + throw new Error(errors.join('\n')) + } + + return config +} diff --git a/test/__mocks__/my-config.json b/test/__mocks__/my-config.json index cb997df03..227fc84e3 100644 --- a/test/__mocks__/my-config.json +++ b/test/__mocks__/my-config.json @@ -1,5 +1,3 @@ { - "linters": { - "*": "mytask" - } + "*": "mytask" } diff --git a/test/__snapshots__/getConfig.spec.js.snap b/test/__snapshots__/getConfig.spec.js.snap deleted file mode 100644 index d54c5c4de..000000000 --- a/test/__snapshots__/getConfig.spec.js.snap +++ /dev/null @@ -1,132 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`getConfig should return config with defaults 1`] = ` -Object { - "concurrent": true, - "globOptions": Object { - "dot": true, - "matchBase": true, - }, - "ignore": Array [], - "linters": Object {}, - "relative": false, - "renderer": "update", -} -`; - -exports[`getConfig should return config with defaults for undefined 1`] = ` -Object { - "concurrent": true, - "globOptions": Object { - "dot": true, - "matchBase": true, - }, - "ignore": Array [], - "linters": Object {}, - "relative": false, - "renderer": "update", -} -`; - -exports[`getConfig should set linters 1`] = ` -Object { - "concurrent": true, - "globOptions": Object { - "dot": true, - "matchBase": true, - }, - "ignore": Array [], - "linters": Object { - "*.js": Array [ - "eslint --fix", - "git add", - ], - ".*rc": "jsonlint", - }, - "relative": false, - "renderer": "update", -} -`; - -exports[`getConfig should set linters 2`] = ` -Object { - "concurrent": true, - "globOptions": Object { - "dot": true, - "matchBase": true, - }, - "ignore": Array [], - "linters": Object { - "*.js": [Function], - }, - "relative": false, - "renderer": "update", -} -`; - -exports[`validateConfig should not throw and should print nothing for advanced valid config 1`] = `""`; - -exports[`validateConfig should not throw and should print nothing for custom renderer 1`] = `""`; - -exports[`validateConfig should not throw and should print nothing for function linter 1`] = `""`; - -exports[`validateConfig should not throw and should print nothing for simple valid config 1`] = `""`; - -exports[`validateConfig should not throw and should print validation warnings for mixed config 1`] = ` -" -WARN ● Validation Warning: - - Unknown option \\"*.js\\" with value ['eslint --fix', 'git add'] was found in the config root. - - You are probably trying to mix simple and advanced config formats. Adding - - \\"linters\\": { - \\"*.js\\": [\\"eslint --fix\\",\\"git add\\"] - } - - will fix it and remove this message. - -Please refer to https://github.com/okonet/lint-staged#configuration for more information..." -`; - -exports[`validateConfig should print deprecation warning for deprecated options 1`] = ` -" -WARN ● Deprecation Warning: - - Option gitDir was removed. - - lint-staged now automatically resolves '.git' directory. - - Please remove gitDir from your configuration. - -Please refer to https://github.com/okonet/lint-staged#configuration for more information... -WARN ● Deprecation Warning: - - Option verbose was removed. - - Use the command line flag --debug instead. - - Please remove verbose from your configuration. - -Please refer to https://github.com/okonet/lint-staged#configuration for more information..." -`; - -exports[`validateConfig should throw and should print validation errors for invalid config 1`] = ` -"● Validation Error: - - ignore must be a \`array\` type, but the final value was: \`false\`. - -Please refer to https://github.com/okonet/lint-staged#configuration for more information..." -`; - -exports[`validateConfig should throw and should print validation errors for invalid linter config 1`] = ` -"● Validation Error: - - Invalid value for 'linters[*.js]'. - - Should be a string, a function, or an array of strings and functions. - - Configured value is: '*.js' - -Please refer to https://github.com/okonet/lint-staged#configuration for more information..." -`; diff --git a/test/__snapshots__/index.spec.js.snap b/test/__snapshots__/index.spec.js.snap index 54a94a342..975ff6b64 100644 --- a/test/__snapshots__/index.spec.js.snap +++ b/test/__snapshots__/index.spec.js.snap @@ -4,17 +4,7 @@ exports[`lintStaged should load an npm config package when specified 1`] = ` " LOG Running lint-staged with the following config: LOG { - linters: { - '*': 'mytask' - }, - concurrent: true, - globOptions: { - matchBase: true, - dot: true - }, - ignore: [], - renderer: 'verbose', - relative: false + '*': 'mytask' }" `; @@ -22,17 +12,7 @@ exports[`lintStaged should load config file when specified 1`] = ` " LOG Running lint-staged with the following config: LOG { - linters: { - '*': 'mytask' - }, - concurrent: true, - globOptions: { - matchBase: true, - dot: true - }, - ignore: [], - renderer: 'verbose', - relative: false + '*': 'mytask' }" `; @@ -42,17 +22,7 @@ exports[`lintStaged should output config in debug mode 1`] = ` " LOG Running lint-staged with the following config: LOG { - linters: { - '*': 'mytask' - }, - concurrent: true, - globOptions: { - matchBase: true, - dot: true - }, - ignore: [], - renderer: 'verbose', - relative: false + '*': 'mytask' }" `; @@ -60,18 +30,8 @@ exports[`lintStaged should parse function linter from js config 1`] = ` " LOG Running lint-staged with the following config: LOG { - linters: { - '*.css': filenames => \`echo \${filenames.join(' ')}\`, - '*.js': filenames => filenames.map(filename => \`echo \${filename}\`) - }, - concurrent: true, - globOptions: { - matchBase: true, - dot: true - }, - ignore: [], - renderer: 'verbose', - relative: false + '*.css': filenames => \`echo \${filenames.join(' ')}\`, + '*.js': filenames => filenames.map(filename => \`echo \${filename}\`) }" `; @@ -92,3 +52,13 @@ ERROR ERROR Please make sure you have created it correctly. See https://github.com/okonet/lint-staged#configuration. `; + +exports[`lintStaged should throw when invalid config is provided 1`] = ` +" +ERROR Could not parse lint-staged config. + +Error: Configuration should not be empty! +ERROR +ERROR Please make sure you have created it correctly. +See https://github.com/okonet/lint-staged#configuration." +`; diff --git a/test/__snapshots__/runAll.spec.js.snap b/test/__snapshots__/runAll.spec.js.snap index 38c413186..9364d3668 100644 --- a/test/__snapshots__/runAll.spec.js.snap +++ b/test/__snapshots__/runAll.spec.js.snap @@ -111,7 +111,3 @@ LOG { context: {hasStash: true, hasErrors: true} }" `; - -exports[`runAll should throw when invalid config is provided 1`] = `"Invalid config provided to runAll! Use getConfig instead."`; - -exports[`runAll should throw when invalid config is provided 2`] = `"Invalid config provided to runAll! Use getConfig instead."`; diff --git a/test/__snapshots__/validateConfig.spec.js.snap b/test/__snapshots__/validateConfig.spec.js.snap new file mode 100644 index 000000000..28be0a280 --- /dev/null +++ b/test/__snapshots__/validateConfig.spec.js.snap @@ -0,0 +1,19 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`validateConfig should not throw and should print nothing for function linter 1`] = `""`; + +exports[`validateConfig should not throw and should print nothing for valid config 1`] = `""`; + +exports[`validateConfig should throw and should print validation errors for invalid config 1`] = ` +"● Validation Error: + + Invalid value for 'foo'. + + Should be a string, a function, or an array of strings and functions. + + Configured value is: 'foo' + +Please refer to https://github.com/okonet/lint-staged#configuration for more information..." +`; + +exports[`validateConfig should throw and should print validation errors for invalid config 1 1`] = `"Configuration should be an object!"`; diff --git a/test/generateTasks.spec.js b/test/generateTasks.spec.js index c3072c675..ec9ae21ba 100644 --- a/test/generateTasks.spec.js +++ b/test/generateTasks.spec.js @@ -29,14 +29,12 @@ const workDir = path.join(os.tmpdir(), 'tmp-lint-staged') resolveGitDir.mockResolvedValue(workDir) const config = { - linters: { - '*.js': 'root-js', - '**/*.js': 'any-js', - 'deeper/*.js': 'deeper-js', - '.hidden/*.js': 'hidden-js', - 'unknown/*.js': 'unknown-js', - '*.{css,js}': 'root-css-or-js' - } + '*.js': 'root-js', + '**/*.js': 'any-js', + 'deeper/*.js': 'deeper-js', + '.hidden/*.js': 'hidden-js', + 'unknown/*.js': 'unknown-js', + '*.{css,js}': 'root-css-or-js' } describe('generateTasks', () => { @@ -48,38 +46,10 @@ describe('generateTasks', () => { process.cwd.mockRestore() }) - it('should work with simple configuration', async () => { - const result = await generateTasks( - { - '*.js': 'lint' - }, - workDir, - ['test.js'] - ) - const commands = result.map(match => match.commands) - expect(commands).toEqual(['lint']) - }) - - it('should work with advanced configuration', async () => { - const result = await generateTasks( - { - linters: { - '*.js': 'lint' - } - }, - workDir, - ['test.js'] - ) - const commands = result.map(match => match.commands) - expect(commands).toEqual(['lint']) - }) - it('should return absolute paths', async () => { const [task] = await generateTasks( { - linters: { - '*': 'lint' - } + '*': 'lint' }, workDir, files @@ -89,22 +59,6 @@ describe('generateTasks', () => { }) }) - it('should return relative paths', async () => { - const [task] = await generateTasks( - { - linters: { - '*': 'lint' - }, - relative: true - }, - workDir, - files - ) - task.fileList.forEach(file => { - expect(path.isAbsolute(file)).toBe(false) - }) - }) - it('should not match non-children files', async () => { const relPath = path.join(process.cwd(), '..') const result = await generateTasks({ ...config }, relPath, files) @@ -144,26 +98,6 @@ describe('generateTasks', () => { }) }) - it('should match pattern "*.js" and return relative path', async () => { - const result = await generateTasks( - Object.assign({}, config, { relative: true }), - workDir, - files - ) - const linter = result.find(item => item.pattern === '*.js') - expect(linter).toEqual({ - pattern: '*.js', - commands: 'root-js', - fileList: [ - `test.js`, - `deeper/test.js`, - `deeper/test2.js`, - `even/deeper/test.js`, - `.hidden/test.js` - ].map(path.normalize) - }) - }) - it('should match pattern "**/*.js"', async () => { const result = await generateTasks(config, workDir, files) const linter = result.find(item => item.pattern === '**/*.js') @@ -180,26 +114,6 @@ describe('generateTasks', () => { }) }) - it('should match pattern "**/*.js" with relative path', async () => { - const result = await generateTasks( - Object.assign({}, config, { relative: true }), - workDir, - files - ) - const linter = result.find(item => item.pattern === '**/*.js') - expect(linter).toEqual({ - pattern: '**/*.js', - commands: 'any-js', - fileList: [ - `test.js`, - `deeper/test.js`, - `deeper/test2.js`, - `even/deeper/test.js`, - `.hidden/test.js` - ].map(path.normalize) - }) - }) - it('should match pattern "deeper/*.js"', async () => { const result = await generateTasks(config, workDir, files) const linter = result.find(item => item.pattern === 'deeper/*.js') @@ -240,74 +154,4 @@ describe('generateTasks', () => { ].map(path.normalize) }) }) - - it('should support globOptions specified in advanced configuration', async () => { - const result = await generateTasks( - { - globOptions: { - matchBase: false, - nocase: true - }, - linters: { - 'TeSt.*': 'lint' - } - }, - workDir, - files - ) - const linter = result.find(item => item.pattern === 'TeSt.*') - expect(linter).toEqual({ - pattern: 'TeSt.*', - commands: 'lint', - fileList: [`${workDir}/test.js`, `${workDir}/test.css`, `${workDir}/test.txt`].map( - path.normalize - ) - }) - }) - - it('should ignore patterns in the ignore array of configuration', async () => { - const pattern = '**/*.js' - const commands = 'lint' - const result = await generateTasks( - { - ignore: ['**/ignore/**', '**/ignore.*'], - linters: { [pattern]: commands } - }, - workDir, - ['ignore/me.js', 'ignore.me.js', 'cool/js.js'] - ) - expect(result[0]).toEqual({ - pattern, - commands, - fileList: [`${workDir}/cool/js.js`].map(path.normalize) - }) - }) - - it('should not filter files for pattern which begins with `..`', async () => { - jest.spyOn(process, 'cwd').mockReturnValueOnce(path.join(workDir, 'prj')) - const result = await generateTasks( - { - linters: { - '*.js': 'my-cmd', - '../outside/*.js': 'my-cmd' - } - }, - workDir, - ['root.js', 'prj/test.js', 'outside/test.js', 'outside/test2.js'] - ) - - const prjTask = result.find(item => item.pattern === '*.js') - expect(prjTask).toEqual({ - pattern: '*.js', - commands: 'my-cmd', - fileList: [`${workDir}/prj/test.js`].map(path.normalize) - }) - - const parentFolderTask = result.find(item => item.pattern === '../outside/*.js') - expect(parentFolderTask).toEqual({ - pattern: '../outside/*.js', - commands: 'my-cmd', - fileList: [`${workDir}/outside/test.js`, `${workDir}/outside/test2.js`].map(path.normalize) - }) - }) }) diff --git a/test/getConfig.spec.js b/test/getConfig.spec.js deleted file mode 100644 index 0c1ff281e..000000000 --- a/test/getConfig.spec.js +++ /dev/null @@ -1,230 +0,0 @@ -import makeConsoleMock from 'consolemock' -import { cloneDeep } from 'lodash' -import { getConfig, validateConfig } from '../src/getConfig' - -describe('getConfig', () => { - it('should return config with defaults for undefined', () => { - expect(getConfig()).toMatchSnapshot() - }) - - it('should return config with defaults', () => { - expect(getConfig({})).toMatchSnapshot() - }) - - it('should set renderer based on debug mode', () => { - expect(getConfig({})).toEqual( - expect.objectContaining({ - renderer: 'update' - }) - ) - - expect( - getConfig({ - '*.js': ['eslint', 'git add'] - }) - ).toEqual( - expect.objectContaining({ - renderer: 'update' - }) - ) - - expect(getConfig({}, true)).toEqual( - expect.objectContaining({ - renderer: 'verbose' - }) - ) - }) - - it('should set linters', () => { - expect(getConfig()).toEqual( - expect.objectContaining({ - linters: {} - }) - ) - - expect(getConfig({})).toEqual( - expect.objectContaining({ - linters: {} - }) - ) - - expect( - getConfig({ - '*.js': 'eslint' - }) - ).toEqual( - expect.objectContaining({ - linters: { - '*.js': 'eslint' - } - }) - ) - - expect( - getConfig({ - linters: { - '*.js': ['eslint --fix', 'git add'], - '.*rc': 'jsonlint' - } - }) - ).toMatchSnapshot() - - expect( - getConfig({ - linters: { - '*.js': filenames => { - const files = filenames.join(' ') - return `eslint --fix ${files} && git add ${files}` - } - } - }) - ).toMatchSnapshot() - }) - - it('should deeply merge configs', () => { - expect( - getConfig({ - globOptions: { - nocase: true - } - }) - ).toEqual( - expect.objectContaining({ - globOptions: { - nocase: true, - matchBase: true, - dot: true - } - }) - ) - }) - - it('should not add plain linters object to the full config', () => { - expect( - getConfig({ - '*.js': 'eslint' - }) - ).not.toEqual( - expect.objectContaining({ - '*.js': 'eslint' - }) - ) - }) - - it('should not change config if the whole config was passed', () => { - const src = { - concurrent: true, - globOptions: { - matchBase: false, - dot: true - }, - linters: { - '*.js': 'eslint' - }, - ignore: ['docs/**/*.js'], - renderer: 'custom', - relative: true - } - expect(getConfig(cloneDeep(src))).toEqual(src) - }) -}) - -describe('validateConfig', () => { - const originalConsole = global.console - beforeAll(() => { - global.console = makeConsoleMock() - }) - - beforeEach(() => { - global.console.clearHistory() - }) - - afterAll(() => { - global.console = originalConsole - }) - - it('should throw and should print validation errors for invalid config', () => { - const invalidAdvancedConfig = { - foo: false, - ignore: false - } - expect(() => validateConfig(getConfig(invalidAdvancedConfig))).toThrowErrorMatchingSnapshot() - }) - - it('should throw and should print validation errors for invalid linter config', () => { - const invalidAdvancedConfig = { - foo: false, - linters: { - '*.js': 1 - } - } - expect(() => validateConfig(getConfig(invalidAdvancedConfig))).toThrowErrorMatchingSnapshot() - }) - - it('should not throw and should print validation warnings for mixed config', () => { - const invalidMixedConfig = { - ignore: ['**/*.test.js'], - '*.js': ['eslint --fix', 'git add'] - } - expect(() => validateConfig(getConfig(invalidMixedConfig))).not.toThrow() - expect(console.printHistory()).toMatchSnapshot() - }) - - it('should print deprecation warning for deprecated options', () => { - const baseConfig = { - linters: { - '*.js': ['eslint --fix', 'git add'] - } - } - const opts = [{ gitDir: '../' }, { verbose: true }] - opts.forEach(opt => { - const configWithDeprecatedOpt = Object.assign(opt, baseConfig) - expect(() => validateConfig(getConfig(configWithDeprecatedOpt))).not.toThrow() - }) - expect(console.printHistory()).toMatchSnapshot() - }) - - it('should not throw and should print nothing for simple valid config', () => { - const validSimpleConfig = { - '*.js': ['eslint --fix', 'git add'] - } - expect(() => validateConfig(getConfig(validSimpleConfig))).not.toThrow() - expect(console.printHistory()).toMatchSnapshot() - }) - - it('should not throw and should print nothing for advanced valid config', () => { - const validAdvancedConfig = { - ignore: ['**/*.test.js'], - linters: { - '*.js': ['eslint --fix', 'git add'] - } - } - expect(() => validateConfig(getConfig(validAdvancedConfig))).not.toThrow() - expect(console.printHistory()).toMatchSnapshot() - }) - - it('should not throw and should print nothing for custom renderer', () => { - const validAdvancedConfig = { - renderer: () => {} - } - expect(() => validateConfig(getConfig(validAdvancedConfig))).not.toThrow() - expect(console.printHistory()).toMatchSnapshot() - }) - - it('should not throw and should print nothing for function linter', () => { - expect(() => - validateConfig( - getConfig({ - linters: { - '*.js': filenames => { - const files = filenames.join(' ') - return `eslint --fix ${files} && git add ${files}` - }, - '*.css': [filenames => filenames.map(filename => `eslint --fix ${filename}`)] - } - }) - ) - ).not.toThrow() - expect(console.printHistory()).toMatchSnapshot() - }) -}) diff --git a/test/index.spec.js b/test/index.spec.js index 8dadeb795..65fe75674 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -40,9 +40,7 @@ describe('lintStaged', () => { it('should output config in debug mode', async () => { expect.assertions(1) const config = { - linters: { - '*': 'mytask' - } + '*': 'mytask' } mockCosmiconfigWith({ config }) await lintStaged(logger, undefined, true) @@ -59,6 +57,13 @@ describe('lintStaged', () => { expect(logger.printHistory()).toMatchSnapshot() }) + it('should throw when invalid config is provided', async () => { + const config = {} + mockCosmiconfigWith({ config }) + await lintStaged(logger) + expect(logger.printHistory()).toMatchSnapshot() + }) + it('should load config file when specified', async () => { expect.assertions(1) await lintStaged(logger, path.join(__dirname, '__mocks__', 'my-config.json'), true) @@ -105,9 +110,7 @@ describe('lintStaged', () => { it('should exit with code 1 on linter errors', async () => { const config = { - linters: { - '*': 'node -e "process.exit(1)"' - } + '*': 'node -e "process.exit(1)"' } mockCosmiconfigWith({ config }) getStagedFiles.mockImplementationOnce(async () => ['sample.java']) diff --git a/test/runAll.2.spec.js b/test/runAll.2.spec.js index 09cf2a1d9..136673366 100644 --- a/test/runAll.2.spec.js +++ b/test/runAll.2.spec.js @@ -1,11 +1,10 @@ -import { getConfig } from '../src/getConfig' import runAll from '../src/runAll' jest.unmock('execa') describe('runAll', () => { it('should throw when not in a git directory', async () => { - const config = getConfig({ renderer: 'update', cwd: '/' }) + const config = { cwd: '/' } await expect(runAll(config)).rejects.toThrowErrorMatchingSnapshot() }) }) diff --git a/test/runAll.spec.js b/test/runAll.spec.js index 23fbff4c3..3250d1aef 100644 --- a/test/runAll.spec.js +++ b/test/runAll.spec.js @@ -1,7 +1,6 @@ import makeConsoleMock from 'consolemock' import execa from 'execa' -import { getConfig } from '../src/getConfig' import getStagedFiles from '../src/getStagedFiles' import runAll from '../src/runAll' import { hasPartiallyStagedFiles, gitStashSave, gitStashPop, updateStash } from '../src/gitWorkflow' @@ -29,37 +28,31 @@ describe('runAll', () => { global.console = globalConsoleTemp }) - it('should throw when invalid config is provided', async () => { - await expect(runAll({})).rejects.toThrowErrorMatchingSnapshot() - await expect(runAll()).rejects.toThrowErrorMatchingSnapshot() - }) - it('should not throw when a valid config is provided', () => { - const config = getConfig({}) - expect(() => runAll(config)).not.toThrow() + expect(() => runAll({})).not.toThrow() }) it('should return a promise', () => { - expect(runAll(getConfig({}))).toBeInstanceOf(Promise) + expect(runAll({})).toBeInstanceOf(Promise) }) it('should resolve the promise with no tasks', async () => { expect.assertions(1) - const res = await runAll(getConfig({})) + const res = await runAll({}) expect(res).toEqual('No tasks to run.') }) it('should resolve the promise with no files', async () => { expect.assertions(1) - await runAll(getConfig({ linters: { '*.js': ['echo "sample"'] } })) + await runAll({ '*.js': ['echo "sample"'] }) expect(console.printHistory()).toMatchSnapshot() }) it('should not skip tasks if there are files', async () => { expect.assertions(1) getStagedFiles.mockImplementationOnce(async () => ['sample.js']) - await runAll(getConfig({ linters: { '*.js': ['echo "sample"'] } })) + await runAll({ '*.js': ['echo "sample"'] }) expect(console.printHistory()).toMatchSnapshot() }) @@ -67,7 +60,7 @@ describe('runAll', () => { expect.assertions(4) hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(true)) getStagedFiles.mockImplementationOnce(async () => ['sample.js']) - await runAll(getConfig({ linters: { '*.js': ['echo "sample"'] } })) + await runAll({ '*.js': ['echo "sample"'] }) expect(gitStashSave).toHaveBeenCalledTimes(1) expect(updateStash).toHaveBeenCalledTimes(1) expect(gitStashPop).toHaveBeenCalledTimes(1) @@ -78,7 +71,7 @@ describe('runAll', () => { expect.assertions(4) hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(false)) getStagedFiles.mockImplementationOnce(async () => ['sample.js']) - await runAll(getConfig({ linters: { '*.js': ['echo "sample"'] } })) + await runAll({ '*.js': ['echo "sample"'] }) expect(gitStashSave).toHaveBeenCalledTimes(0) expect(updateStash).toHaveBeenCalledTimes(0) expect(gitStashPop).toHaveBeenCalledTimes(0) @@ -100,7 +93,7 @@ describe('runAll', () => { ) try { - await runAll(getConfig({ linters: { '*.js': ['echo "sample"'] } })) + await runAll({ '*.js': ['echo "sample"'] }) } catch (err) { console.log(err) } @@ -127,7 +120,7 @@ describe('runAll', () => { ) try { - await runAll(getConfig({ linters: { '*.js': ['echo "sample"'] } })) + await runAll({ '*.js': ['echo "sample"'] }) } catch (err) { console.log(err) } @@ -140,7 +133,7 @@ describe('runAll', () => { it('should reject promise when error during getStagedFiles', async () => { expect.assertions(1) getStagedFiles.mockImplementationOnce(async () => null) - await expect(runAll(getConfig({}))).rejects.toThrowErrorMatchingSnapshot() + await expect(runAll({})).rejects.toThrowErrorMatchingSnapshot() }) it('should skip stashing changes if no lint-staged files are changed', async () => { @@ -158,7 +151,7 @@ describe('runAll', () => { ) try { - await runAll(getConfig({ linters: { '*.js': ['echo "sample"'] } })) + await runAll({ '*.js': ['echo "sample"'] }) } catch (err) { console.log(err) } diff --git a/test/validateConfig.spec.js b/test/validateConfig.spec.js new file mode 100644 index 000000000..f682278af --- /dev/null +++ b/test/validateConfig.spec.js @@ -0,0 +1,51 @@ +import makeConsoleMock from 'consolemock' + +import validateConfig from '../src/validateConfig' + +describe('validateConfig', () => { + const originalConsole = global.console + beforeAll(() => { + global.console = makeConsoleMock() + }) + + beforeEach(() => { + global.console.clearHistory() + }) + + afterAll(() => { + global.console = originalConsole + }) + + it('should throw and should print validation errors for invalid config 1', () => { + const invalidConfig = 'test' + expect(() => validateConfig(invalidConfig)).toThrowErrorMatchingSnapshot() + }) + + it('should throw and should print validation errors for invalid config', () => { + const invalidConfig = { + foo: false + } + expect(() => validateConfig(invalidConfig)).toThrowErrorMatchingSnapshot() + }) + + it('should not throw and should print nothing for valid config', () => { + const validSimpleConfig = { + '*.js': ['eslint --fix', 'git add'] + } + expect(() => validateConfig(validSimpleConfig)).not.toThrow() + expect(console.printHistory()).toMatchSnapshot() + }) + + it('should not throw and should print nothing for function linter', () => { + expect(() => + validateConfig({ + '*.js': filenames => { + const files = filenames.join(' ') + return `eslint --fix ${files} && git add ${files}` + }, + '*.css': [filenames => filenames.map(filename => `eslint --fix ${filename}`)] + }) + ).not.toThrow() + expect(console.printHistory()).toMatchSnapshot() + }) +}) diff --git a/yarn.lock b/yarn.lock index 0704320e4..60fbb96b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18,13 +18,6 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/runtime@^7.0.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.4.tgz#dc2e34982eb236803aa27a07fea6857af1b9171d" - integrity sha512-w0+uT71b6Yi7i5SE0co4NioIpSYS6lLiXvCzWzGSKvpK5vdQtCbICHMj+gbAKAOtxiV6HsVh/MBdaF9EQ6faSg== - dependencies: - regenerator-runtime "^0.13.2" - "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" @@ -2177,11 +2170,6 @@ flat-cache@^1.2.1: rimraf "~2.6.2" write "^0.2.1" -fn-name@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fn-name/-/fn-name-2.0.1.tgz#5214d7537a4d06a4a301c0cc262feb84188002e7" - integrity sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc= - for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -2827,11 +2815,6 @@ is-extglob@^1.0.0: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - is-finite@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" @@ -2863,13 +2846,6 @@ is-glob@^2.0.0, is-glob@^2.0.1: dependencies: is-extglob "^1.0.0" -is-glob@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - is-number@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" @@ -4549,11 +4525,6 @@ prop-types@^15.7.2: object-assign "^4.1.1" react-is "^16.8.1" -property-expr@^1.5.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-1.5.1.tgz#22e8706894a0c8e28d58735804f6ba3a3673314f" - integrity sha512-CGuc0VUTGthpJXL36ydB6jnbyOf/rAHFvmVrJlH+Rg0DqqLFQGAP6hIaxD/G0OAmBJPhXDHuEJigrp0e0wFV6g== - pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" @@ -4696,11 +4667,6 @@ regenerator-runtime@^0.11.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== -regenerator-runtime@^0.13.2: - version "0.13.2" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447" - integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA== - regenerator-transform@^0.10.0: version "0.10.1" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" @@ -5346,11 +5312,6 @@ symbol-tree@^3.2.2: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" integrity sha1-rifbOPZgp64uHDt9G8KQgZuFGeY= -synchronous-promise@^2.0.6: - version "2.0.7" - resolved "https://registry.yarnpkg.com/synchronous-promise/-/synchronous-promise-2.0.7.tgz#3574b3d2fae86b145356a4b89103e1577f646fe3" - integrity sha512-16GbgwTmFMYFyQMLvtQjvNWh30dsFe1cAW5Fg1wm5+dg84L9Pe36mftsIRU95/W2YsISxsz/xq4VB23sqpgb/A== - table@4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" @@ -5451,11 +5412,6 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -toposort@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" - integrity sha1-riF2gXXRVZ1IvvNUILL0li8JwzA= - tough-cookie@^2.3.3, tough-cookie@^2.3.4: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" @@ -5780,15 +5736,3 @@ yargs@^11.0.0: which-module "^2.0.0" y18n "^3.2.1" yargs-parser "^9.0.2" - -yup@^0.27.0: - version "0.27.0" - resolved "https://registry.yarnpkg.com/yup/-/yup-0.27.0.tgz#f8cb198c8e7dd2124beddc2457571329096b06e7" - integrity sha512-v1yFnE4+u9za42gG/b/081E7uNW9mUj3qtkmelLbW5YPROZzSH/KUUyJu9Wt8vxFJcT9otL/eZopS0YK1L5yPQ== - dependencies: - "@babel/runtime" "^7.0.0" - fn-name "~2.0.1" - lodash "^4.17.11" - property-expr "^1.5.0" - synchronous-promise "^2.0.6" - toposort "^2.0.2"