From bed9127fda3c74795a3cb6de49f6c4000b7df6db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Sat, 29 Jun 2019 23:29:45 +0300 Subject: [PATCH] refactor: use execa's shell option to run commands BREAKING CHANGE: Local commands are no longer resolved by lint-staged, but execa will do this instead. In effect, there are no longer pretty error messages when commands are not found. --- README.md | 2 +- package.json | 4 +- src/checkPkgScripts.js | 46 ----------- src/findBin.js | 54 ------------- src/resolveTaskFn.js | 32 +++----- .../checkPkgScripts.spec.js.snap | 19 ----- test/__snapshots__/findBin.spec.js.snap | 10 --- test/checkPkgScripts.spec.js | 50 ------------ test/findBin.spec.js | 56 -------------- test/makeCmdTasks.spec.js | 4 +- test/resolveTaskFn.spec.js | 45 ++++++----- yarn.lock | 76 +++++++++++++------ 12 files changed, 95 insertions(+), 303 deletions(-) delete mode 100644 src/checkPkgScripts.js delete mode 100644 src/findBin.js delete mode 100644 test/__snapshots__/checkPkgScripts.spec.js.snap delete mode 100644 test/__snapshots__/findBin.spec.js.snap delete mode 100644 test/checkPkgScripts.spec.js delete mode 100644 test/findBin.spec.js diff --git a/README.md b/README.md index 79fd1785f..9b1002064 100644 --- a/README.md +++ b/README.md @@ -214,7 +214,7 @@ Supported are any executables installed locally or globally via `npm` as well as > Using globally installed scripts is discouraged, since lint-staged may not work for someone who doesn’t have it installed. -`lint-staged` is using [npm-which](https://github.com/timoxley/npm-which) to locate locally installed scripts. So in your `.lintstagedrc` you can write: +`lint-staged` uses [execa](https://github.com/sindresorhus/execa#preferlocal) to locate locally installed scripts. So in your `.lintstagedrc` you can write: ```json { diff --git a/package.json b/package.json index bd25a3e76..ea5152c94 100644 --- a/package.json +++ b/package.json @@ -33,17 +33,15 @@ "debug": "^3.1.0", "dedent": "^0.7.0", "del": "^4.1.1", - "execa": "^1.0.0", + "execa": "^2.0.1", "is-glob": "^4.0.0", "listr": "^0.14.2", "listr-update-renderer": "^0.5.0", "lodash": "^4.17.11", "log-symbols": "^2.2.0", "micromatch": "^3.1.8", - "npm-which": "^3.0.1", "path-is-inside": "^1.0.2", "please-upgrade-node": "^3.0.2", - "string-argv": "^0.0.2", "stringify-object": "^3.2.2", "yup": "^0.27.0" }, diff --git a/src/checkPkgScripts.js b/src/checkPkgScripts.js deleted file mode 100644 index 63dffa527..000000000 --- a/src/checkPkgScripts.js +++ /dev/null @@ -1,46 +0,0 @@ -'use strict' - -const chalk = require('chalk') -const dedent = require('dedent') -const has = require('lodash/has') - -const warn = msg => { - console.warn(chalk.yellowBright.bold(msg)) -} - -/** - * Checks if the given command or binary name is present in the package.json scripts. This would be - * called if and when resolving a binary fails in `findBin`. - * - * @param {Object} pkg package.json - * @param {string} cmd - * @param {string} binName - * @param {Array} args - * @throws {Error} If a script is found in the pkg for the given `cmd` or `binName`. - */ -module.exports = function checkPkgScripts(pkg, cmd, binName, args) { - if (pkg && pkg.scripts) { - const { scripts } = pkg - let scriptName - let script - if (has(scripts, cmd)) { - scriptName = cmd - script = scripts[cmd] - } else if (has(scripts, binName)) { - scriptName = binName - script = scripts[binName] - } else { - return - } - - const argsStr = args && args.length ? args.join(' ') : '' - warn(dedent` - \`lint-staged\` no longer supports running scripts defined in package.json. - - The same behavior can be achieved by changing the command to any of the following: - - \`npm run ${scriptName} -- ${argsStr}\` - - \`${script} ${argsStr}\` - `) - throw new Error(`Could not resolve binary for \`${cmd}\``) - } -} diff --git a/src/findBin.js b/src/findBin.js deleted file mode 100644 index 55cd85c6a..000000000 --- a/src/findBin.js +++ /dev/null @@ -1,54 +0,0 @@ -'use strict' - -const parse = require('string-argv') -const npmWhich = require('npm-which')(process.cwd()) -const checkPkgScripts = require('./checkPkgScripts') - -const debug = require('debug')('lint-staged:find-bin') - -// Find and load the package.json at the root of the project. -let pkg -try { - // eslint-disable-next-line import/no-dynamic-require, global-require - pkg = require(`${process.cwd()}/package.json`) - debug('Loaded package.json using `process.cwd()`') -} catch (ignore) { - debug('Could not load package.json using `process.cwd()`') - pkg = {} -} - -const cache = new Map() - -module.exports = function findBin(cmd) { - debug('Resolving binary for command `%s`', cmd) - - /* - * Try to locate the binary in node_modules/.bin and if this fails, in - * $PATH. - * - * This allows to use linters installed for the project: - * - * "lint-staged": { - * "*.js": "eslint" - * } - */ - const [binName, ...args] = parse(cmd) - - if (cache.has(binName)) { - debug('Resolving binary for `%s` from cache', binName) - return { bin: cache.get(binName), args } - } - - try { - /* npm-which tries to resolve the bin in local node_modules/.bin */ - /* and if this fails it look in $PATH */ - const bin = npmWhich.sync(binName) - debug('Binary for `%s` resolved to `%s`', cmd, bin) - cache.set(binName, bin) - return { bin, args } - } catch (err) { - // throw helpful error if matching script is present in package.json - checkPkgScripts(pkg, cmd, binName, args) - throw new Error(`${binName} could not be found. Try \`npm install ${binName}\`.`) - } -} diff --git a/src/resolveTaskFn.js b/src/resolveTaskFn.js index bd93bd31e..0a1bc37ae 100644 --- a/src/resolveTaskFn.js +++ b/src/resolveTaskFn.js @@ -5,25 +5,19 @@ const dedent = require('dedent') const execa = require('execa') const symbols = require('log-symbols') -const findBin = require('./findBin') - const debug = require('debug')('lint-staged:task') /** - * Execute the given linter binary with arguments using execa and + * Execute the given linter cmd using execa and * return the promise. * - * @param {string} bin - * @param {Array} args - * @param {Object} execaOptions + * @param {string} cmd * @return {Promise} child_process */ -function execLinter(bin, args, execaOptions) { - debug('bin:', bin) - debug('args: %O', args) - debug('opts: %o', execaOptions) - - return execa(bin, args, { ...execaOptions }) +const execLinter = (cmd, execaOptions = {}) => { + debug('cmd:', cmd) + debug('execaOptions:', execaOptions) + return execa(cmd, execaOptions) } const successMsg = linter => `${symbols.success} ${linter} passed!` @@ -84,7 +78,7 @@ function makeErr(linter, result, context = {}) { * @returns {function(): Promise>} */ module.exports = function resolveTaskFn(options) { - const { linter, gitDir, pathsToLint } = options + const { gitDir, linter, pathsToLint } = options // If `linter` is a function, it should return a string when evaluated with `pathsToLint`. // Else, it's a already a string @@ -94,20 +88,18 @@ module.exports = function resolveTaskFn(options) { const linters = Array.isArray(linterString) ? linterString : [linterString] const tasks = linters.map(command => { - const { bin, args } = findBin(command) - - // If `linter` is a function, args already include `pathsToLint`. - const argsWithPaths = fnLinter ? args : args.concat(pathsToLint) + // If `linter` is a function, cmd already includes `pathsToLint`. + const cmdWithPaths = fnLinter ? command : `${command} ${pathsToLint.join(' ')}` - const execaOptions = { reject: false } // Only use gitDir as CWD if we are using the git binary // e.g `npm` should run tasks in the actual CWD - if (/git(\.exe)?$/i.test(bin) && gitDir !== process.cwd()) { + const execaOptions = { preferLocal: true, reject: false, shell: true } + if (/^git(\.exe)?/i.test(command) && gitDir !== process.cwd()) { execaOptions.cwd = gitDir } return ctx => - execLinter(bin, argsWithPaths, execaOptions).then(result => { + execLinter(cmdWithPaths, execaOptions).then(result => { if (result.failed || result.killed || result.signal != null) { throw makeErr(linter, result, ctx) } diff --git a/test/__snapshots__/checkPkgScripts.spec.js.snap b/test/__snapshots__/checkPkgScripts.spec.js.snap deleted file mode 100644 index 7434cccf1..000000000 --- a/test/__snapshots__/checkPkgScripts.spec.js.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`checkPkgScripts throws if the binary name is defined in script 1`] = ` -" -WARN \`lint-staged\` no longer supports running scripts defined in package.json. - -The same behavior can be achieved by changing the command to any of the following: - - \`npm run lint -- --fix\` - - \`eslint . --fix\`" -`; - -exports[`checkPkgScripts throws if the cmd is defined in script 1`] = ` -" -WARN \`lint-staged\` no longer supports running scripts defined in package.json. - -The same behavior can be achieved by changing the command to any of the following: - - \`npm run lint -- \` - - \`eslint . \`" -`; diff --git a/test/__snapshots__/findBin.spec.js.snap b/test/__snapshots__/findBin.spec.js.snap deleted file mode 100644 index fa4989def..000000000 --- a/test/__snapshots__/findBin.spec.js.snap +++ /dev/null @@ -1,10 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`findBin should throw a helpful error if the cmd is present in pkg scripts 1`] = ` -" -WARN \`lint-staged\` no longer supports running scripts defined in package.json. - -The same behavior can be achieved by changing the command to any of the following: - - \`npm run lint -- \` - - \`npm run lint:base -- . \`" -`; diff --git a/test/checkPkgScripts.spec.js b/test/checkPkgScripts.spec.js deleted file mode 100644 index 4f2bf3557..000000000 --- a/test/checkPkgScripts.spec.js +++ /dev/null @@ -1,50 +0,0 @@ -import makeConsoleMock from 'consolemock' -import checkPkgScripts from '../src/checkPkgScripts' - -describe('checkPkgScripts', () => { - describe('does not throw', () => { - it('if there are no scripts defined', () => { - expect(() => checkPkgScripts(null)).not.toThrow() - expect(() => checkPkgScripts({})).not.toThrow() - }) - - it('if the script cannot be found', () => { - expect(() => checkPkgScripts({ scripts: {} }, 'fmt')).not.toThrow() - }) - }) - - describe('throws', () => { - const originalConsole = global.console - beforeAll(() => { - global.console = makeConsoleMock() - }) - - beforeEach(() => { - global.console.clearHistory() - }) - - afterAll(() => { - global.console = originalConsole - }) - - const pkg = { - scripts: { - lint: 'eslint .' - } - } - - it('if the cmd is defined in script', () => { - expect(() => { - checkPkgScripts(pkg, 'lint', 'lint') - }).toThrow('Could not resolve binary for `lint`') - expect(console.printHistory()).toMatchSnapshot() - }) - - it('if the binary name is defined in script', () => { - expect(() => { - checkPkgScripts(pkg, 'lint --fix', 'lint', ['--fix']) - }).toThrow('Could not resolve binary for `lint --fix`') - expect(console.printHistory()).toMatchSnapshot() - }) - }) -}) diff --git a/test/findBin.spec.js b/test/findBin.spec.js deleted file mode 100644 index 31f87cd38..000000000 --- a/test/findBin.spec.js +++ /dev/null @@ -1,56 +0,0 @@ -import makeConsoleMock from 'consolemock' -import npmWhichMock from 'npm-which' - -import findBin from '../src/findBin' - -describe('findBin', () => { - it('should return path to bin', () => { - const { bin, args } = findBin('my-linter') - expect(bin).toEqual('my-linter') - expect(args).toEqual([]) - }) - - it('should resolve path to bin from cache for subsequent invocations', () => { - npmWhichMock.mockFn.mockClear() - findBin('my-cmd') - expect(npmWhichMock.mockFn).toHaveBeenCalledTimes(1) - findBin('my-cmd --arg') - expect(npmWhichMock.mockFn).toHaveBeenCalledTimes(1) - }) - - it('should throw an error if bin not found', () => { - expect(() => { - findBin('my-missing-linter') - }).toThrow('my-missing-linter could not be found. Try `npm install my-missing-linter`.') - }) - - it('should throw a helpful error if the cmd is present in pkg scripts', () => { - const originalConsole = global.console - global.console = makeConsoleMock() - npmWhichMock.mockFn.mockImplementationOnce(() => { - throw new Error() - }) - - expect(() => { - findBin('lint') - }).toThrow('Could not resolve binary for `lint`') - expect(console.printHistory()).toMatchSnapshot() - - global.console = originalConsole - }) - - it('should parse cmd and add arguments to args', () => { - const { bin, args } = findBin( - 'my-linter task --fix --rule \'quotes: [2, double]\' --another "[complex:argument]"' - ) - expect(bin).toEqual('my-linter') - expect(args).toEqual([ - 'task', - '--fix', - '--rule', - 'quotes: [2, double]', - '--another', - '[complex:argument]' - ]) - }) -}) diff --git a/test/makeCmdTasks.spec.js b/test/makeCmdTasks.spec.js index 4d4a94e6d..dc33cf2f7 100644 --- a/test/makeCmdTasks.spec.js +++ b/test/makeCmdTasks.spec.js @@ -37,11 +37,11 @@ describe('makeCmdTasks', () => { expect(taskPromise).toBeInstanceOf(Promise) await taskPromise expect(execa).toHaveBeenCalledTimes(1) - expect(execa).lastCalledWith('test', ['test.js'], { reject: false }) + expect(execa).lastCalledWith('test test.js', { preferLocal: true, reject: false, shell: true }) taskPromise = linter2.task() expect(taskPromise).toBeInstanceOf(Promise) await taskPromise expect(execa).toHaveBeenCalledTimes(2) - expect(execa).lastCalledWith('test2', ['test.js'], { reject: false }) + expect(execa).lastCalledWith('test2 test.js', { preferLocal: true, reject: false, shell: true }) }) }) diff --git a/test/resolveTaskFn.spec.js b/test/resolveTaskFn.spec.js index cb6aeca90..f3a4ed45d 100644 --- a/test/resolveTaskFn.spec.js +++ b/test/resolveTaskFn.spec.js @@ -8,15 +8,6 @@ describe('resolveTaskFn', () => { execa.mockClear() }) - it('should throw for non-existent script', () => { - expect(() => { - resolveTaskFn({ - ...defaultOpts, - linter: 'missing-module' - }) - }).toThrow() - }) - it('should support non npm scripts', async () => { expect.assertions(2) const taskFn = resolveTaskFn({ @@ -26,8 +17,10 @@ describe('resolveTaskFn', () => { await taskFn() expect(execa).toHaveBeenCalledTimes(1) - expect(execa).lastCalledWith('node', ['--arg=true', './myscript.js', 'test.js'], { - reject: false + expect(execa).lastCalledWith('node --arg=true ./myscript.js test.js', { + preferLocal: true, + reject: false, + shell: true }) }) @@ -40,8 +33,10 @@ describe('resolveTaskFn', () => { await taskFn() expect(execa).toHaveBeenCalledTimes(1) - expect(execa).lastCalledWith('node', ['--arg=true', './myscript.js', 'test.js'], { - reject: false + expect(execa).lastCalledWith('node --arg=true ./myscript.js test.js', { + preferLocal: true, + reject: false, + shell: true }) }) @@ -55,11 +50,15 @@ describe('resolveTaskFn', () => { await taskFn() expect(execa).toHaveBeenCalledTimes(2) - expect(execa).nthCalledWith(1, 'node', ['--arg=true', './myscript.js', 'foo.js'], { - reject: false + expect(execa).nthCalledWith(1, 'node --arg=true ./myscript.js foo.js', { + preferLocal: true, + reject: false, + shell: true }) - expect(execa).nthCalledWith(2, 'node', ['--arg=true', './myscript.js', 'bar.js'], { - reject: false + expect(execa).nthCalledWith(2, 'node --arg=true ./myscript.js bar.js', { + preferLocal: true, + reject: false, + shell: true }) }) @@ -73,9 +72,11 @@ describe('resolveTaskFn', () => { await taskFn() expect(execa).toHaveBeenCalledTimes(1) - expect(execa).lastCalledWith('git', ['add', 'test.js'], { + expect(execa).lastCalledWith('git add test.js', { cwd: '../', - reject: false + preferLocal: true, + reject: false, + shell: true }) }) @@ -85,7 +86,11 @@ describe('resolveTaskFn', () => { await taskFn() expect(execa).toHaveBeenCalledTimes(1) - expect(execa).lastCalledWith('jest', ['test.js'], { reject: false }) + expect(execa).lastCalledWith('jest test.js', { + preferLocal: true, + reject: false, + shell: true + }) }) it('should throw error for failed linters', async () => { diff --git a/yarn.lock b/yarn.lock index 51f9db617..0704320e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1220,7 +1220,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^2.11.0, commander@^2.14.1, commander@^2.9.0, commander@~2.20.0: +commander@^2.11.0, commander@^2.14.1, commander@~2.20.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== @@ -1330,7 +1330,7 @@ cross-spawn@^5.0.1, cross-spawn@^5.1.0: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^6.0.0: +cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -1894,6 +1894,20 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-2.0.1.tgz#546a5be56388953409cbf24972d2fd1bb36dbfcd" + integrity sha512-pHGXlV7S7ilDda3eaCTcr6zmFTMA3wJo7j+RtNg0uH9sbAasJfVug5RkYOTBLj5g4MOqlsaPUn3HKa/UfTDw8w== + dependencies: + cross-spawn "^6.0.5" + get-stream "^5.0.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^3.0.0" + p-finally "^2.0.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + exit-hook@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" @@ -2300,6 +2314,13 @@ get-stream@^4.0.0: dependencies: pump "^3.0.0" +get-stream@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" + integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== + dependencies: + pump "^3.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -2943,6 +2964,11 @@ is-stream@^1.0.1, is-stream@^1.1.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + is-symbol@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" @@ -3789,6 +3815,11 @@ merge-stream@^1.0.1: dependencies: readable-stream "^2.0.1" +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + merge@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" @@ -4053,13 +4084,6 @@ npm-packlist@^1.1.6: ignore-walk "^3.0.1" npm-bundled "^1.0.1" -npm-path@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64" - integrity sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw== - dependencies: - which "^1.2.10" - npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -4067,14 +4091,12 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npm-which@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa" - integrity sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo= +npm-run-path@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-3.1.0.tgz#7f91be317f6a466efed3c9f2980ad8a4ee8b0fa5" + integrity sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg== dependencies: - commander "^2.9.0" - npm-path "^2.0.2" - which "^1.2.10" + path-key "^3.0.0" npmlog@^4.0.2: version "4.1.2" @@ -4256,6 +4278,11 @@ p-finally@^1.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= +p-finally@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" + integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== + p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -4373,6 +4400,11 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= +path-key@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.0.tgz#99a10d870a803bdd5ee6f0470e58dfcd2f9a54d3" + integrity sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg== + path-parse@^1.0.5, path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" @@ -5198,11 +5230,6 @@ stealthy-require@^1.1.1: resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= -string-argv@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" - integrity sha1-2sMECGkMIfPDYwo/86BYd73L1zY= - string-length@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" @@ -5280,6 +5307,11 @@ strip-eof@^1.0.0: resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + strip-json-comments@2.0.1, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -5631,7 +5663,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^1.2.10, which@^1.2.12, which@^1.2.9, which@^1.3.0: +which@^1.2.12, which@^1.2.9, which@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==