From ee5fcc03dfefde42bf761928cbb3f59b20b392f9 Mon Sep 17 00:00:00 2001 From: Steven Vachon Date: Tue, 3 Mar 2020 18:12:52 -0500 Subject: [PATCH] @grafana/e2e: added support for plugin repositories (#22546) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Minor changes * Include Cypress support files in published package * Added CLI … with support for custom configurations (which Cypress does not currently support by default): * Loads cypress.json from @grafana/e2e as a base config (via a custom Cypress plugin) * Sets default values for project-level Cypress files (tests, etc) * Optionally loads a cypress.json from the current working directory as overrides * Updated lockfile --- packages/grafana-e2e/bin/grafana-e2e.js | 10 ++ .../cypress/plugins/cy-extend-config.js | 60 +++++++++ packages/grafana-e2e/cypress/plugins/index.js | 13 +- packages/grafana-e2e/package.json | 12 +- packages/grafana-e2e/rollup.config.ts | 55 ++++---- packages/grafana-e2e/src/bin/grafana-e2e.ts | 5 + packages/grafana-e2e/src/cli/index.ts | 40 ++++++ packages/grafana-e2e/tsconfig.json | 1 + yarn.lock | 124 ++++++++++++++++++ 9 files changed, 289 insertions(+), 31 deletions(-) create mode 100755 packages/grafana-e2e/bin/grafana-e2e.js create mode 100644 packages/grafana-e2e/cypress/plugins/cy-extend-config.js create mode 100644 packages/grafana-e2e/src/bin/grafana-e2e.ts create mode 100644 packages/grafana-e2e/src/cli/index.ts diff --git a/packages/grafana-e2e/bin/grafana-e2e.js b/packages/grafana-e2e/bin/grafana-e2e.js new file mode 100755 index 00000000000..1d4d474a768 --- /dev/null +++ b/packages/grafana-e2e/bin/grafana-e2e.js @@ -0,0 +1,10 @@ +#!/usr/bin/env node + +// This file is used only for internal executions + +require('ts-node').register({ + project: `${__dirname}/../tsconfig.json`, + transpileOnly: true, +}); + +require('../src/cli/index.ts').default(); diff --git a/packages/grafana-e2e/cypress/plugins/cy-extend-config.js b/packages/grafana-e2e/cypress/plugins/cy-extend-config.js new file mode 100644 index 00000000000..db56ae16782 --- /dev/null +++ b/packages/grafana-e2e/cypress/plugins/cy-extend-config.js @@ -0,0 +1,60 @@ +'use strict'; +const { + promises: { readFile }, +} = require('fs'); +const { resolve } = require('path'); + +module.exports = async baseConfig => { + // From CLI + const { + env: { CWD }, + } = baseConfig; + + if (CWD) { + const projectConfig = { + integrationFolder: `${CWD}/cypress/integration`, + screenshotsFolder: `${CWD}/cypress/screenshots`, + videosFolder: `${CWD}/cypress/videos`, + }; + + const customProjectConfig = await readFile(`${CWD}/cypress.json`, 'utf8') + .then(JSON.parse) + .then(config => { + const pathKeys = [ + 'fileServerFolder', + 'fixturesFolder', + 'ignoreTestFiles', + 'integrationFolder', + 'pluginsFile', + 'screenshotsFolder', + 'supportFile', + 'testFiles', + 'videosFolder', + ]; + + return Object.fromEntries( + Object.entries(config).map(([key, value]) => { + if (pathKeys.includes(key)) { + return [key, resolve(CWD, value)]; + } else { + return [key, value]; + } + }) + ); + }) + .catch(error => { + if (error.code === 'ENOENT') { + // File is optional + return null; + } else { + // Unexpected error + throw error; + } + }); + + return { ...baseConfig, ...projectConfig, ...customProjectConfig }; + } else { + // Temporary legacy support for Grafana core (using `yarn start`) + return baseConfig; + } +}; diff --git a/packages/grafana-e2e/cypress/plugins/index.js b/packages/grafana-e2e/cypress/plugins/index.js index 937cf2c8cd2..6dc9773ed72 100644 --- a/packages/grafana-e2e/cypress/plugins/index.js +++ b/packages/grafana-e2e/cypress/plugins/index.js @@ -1,7 +1,8 @@ -const cypressTypeScriptPreprocessor = require('./cy-ts-preprocessor'); const compareSnapshotsPlugin = require('./cy-compare-images'); +const cypressTypeScriptPreprocessor = require('./cy-ts-preprocessor'); +const extendConfigPlugin = require('./cy-extend-config'); -module.exports = on => { +module.exports = (on, config) => { // yarn build fails with: // >> /Users/hugo/go/src/github.com/grafana/grafana/node_modules/stringmap/stringmap.js:99 // >> throw new Error("StringMap expected string key"); @@ -13,9 +14,13 @@ module.exports = on => { compareSnapshotsPlugin, }); on('task', { - log(args) { - args.optional ? console.log(args.message, args.optional) : console.log(args.message); + log({ message, optional }) { + optional ? console.log(message, optional) : console.log(message); return null; }, }); + + // Always extend with this library's config and return for diffing + // @todo remove this when possible: https://github.com/cypress-io/cypress/issues/5674 + return extendConfigPlugin(config); }; diff --git a/packages/grafana-e2e/package.json b/packages/grafana-e2e/package.json index 1d15fd7cf81..65e79e9b579 100644 --- a/packages/grafana-e2e/package.json +++ b/packages/grafana-e2e/package.json @@ -15,6 +15,9 @@ "directory": "packages/grafana-e2e" }, "main": "src/index.ts", + "bin": { + "grafana-e2e": "bin/grafana-e2e.js" + }, "scripts": { "build": "grafana-toolkit package:build --scope=e2e", "bundle": "rollup -c rollup.config.ts", @@ -28,19 +31,24 @@ "devDependencies": { "@cypress/webpack-preprocessor": "4.1.1", "@grafana/tsconfig": "^1.0.0-rc1", - "blink-diff": "1.0.13", + "@types/node": "13.7.7", "rollup": "1.6.0", "rollup-plugin-commonjs": "9.2.1", + "rollup-plugin-copy": "3.3.0", "rollup-plugin-node-resolve": "4.0.1", "rollup-plugin-sourcemaps": "0.4.2", "rollup-plugin-terser": "4.0.4", "rollup-plugin-typescript2": "0.19.3", "rollup-plugin-visualizer": "0.9.2", "ts-loader": "6.2.1", + "ts-node": "8.5.0", "typescript": "3.7.2" }, "types": "src/index.ts", "dependencies": { - "cypress": "3.7.0" + "blink-diff": "1.0.13", + "commander": "4.1.1", + "cypress": "3.7.0", + "execa": "4.0.0" } } diff --git a/packages/grafana-e2e/rollup.config.ts b/packages/grafana-e2e/rollup.config.ts index caeb03a28cf..d18f81e37f7 100644 --- a/packages/grafana-e2e/rollup.config.ts +++ b/packages/grafana-e2e/rollup.config.ts @@ -1,33 +1,38 @@ import resolve from 'rollup-plugin-node-resolve'; import commonjs from 'rollup-plugin-commonjs'; +import copy from 'rollup-plugin-copy'; import sourceMaps from 'rollup-plugin-sourcemaps'; import { terser } from 'rollup-plugin-terser'; -const pkg = require('./package.json'); +const { name } = require('./package.json'); -const libraryName = pkg.name; +const buildCjsPackage = ({ env }) => ({ + input: 'compiled/index.js', + output: { + file: `dist/index.${env}.js`, + name, + format: 'cjs', + sourcemap: true, + exports: 'named', + globals: {}, + }, + plugins: [ + copy({ + flatten: false, + targets: [ + { src: 'compiled/bin/**/*.*', dest: 'dist/' }, + { src: 'compiled/cli/**/*.*', dest: 'dist/' }, + { src: 'cypress.json', dest: 'dist/' }, + { src: 'cypress/**/*.+(js|ts)', dest: 'dist/cypress/' }, + ], + }), + commonjs({ + include: /node_modules/, + }), + resolve(), + sourceMaps(), + env === 'production' && terser(), + ], +}); -const buildCjsPackage = ({ env }) => { - return { - input: `compiled/index.js`, - output: [ - { - file: `dist/index.${env}.js`, - name: libraryName, - format: 'cjs', - sourcemap: true, - exports: 'named', - globals: {}, - }, - ], - plugins: [ - commonjs({ - include: /node_modules/, - }), - resolve(), - sourceMaps(), - env === 'production' && terser(), - ], - }; -}; export default [buildCjsPackage({ env: 'development' }), buildCjsPackage({ env: 'production' })]; diff --git a/packages/grafana-e2e/src/bin/grafana-e2e.ts b/packages/grafana-e2e/src/bin/grafana-e2e.ts new file mode 100644 index 00000000000..6542c3ba318 --- /dev/null +++ b/packages/grafana-e2e/src/bin/grafana-e2e.ts @@ -0,0 +1,5 @@ +#!/usr/bin/env node + +import cli from '../cli/index'; + +cli(); diff --git a/packages/grafana-e2e/src/cli/index.ts b/packages/grafana-e2e/src/cli/index.ts new file mode 100644 index 00000000000..1d7c38fcc5f --- /dev/null +++ b/packages/grafana-e2e/src/cli/index.ts @@ -0,0 +1,40 @@ +import { resolve, sep } from 'path'; +import execa, { Options } from 'execa'; +import program from 'commander'; + +const cypress = (commandName: string) => { + // Support running an unpublished dev build + const parentPath = resolve(`${__dirname}/../`); + const parentDirname = parentPath.split(sep).pop(); + const projectPath = resolve(`${parentPath}${parentDirname === 'dist' ? '/..' : ''}`); + + const cypressOptions = [commandName, '--env', `CWD=${process.cwd()}`, `--project=${projectPath}`]; + + const execaOptions: Options = { + cwd: __dirname, + stdio: 'inherit', + }; + + return execa(`${projectPath}/node_modules/.bin/cypress`, cypressOptions, execaOptions) + .then(() => {}) // no return value + .catch(error => console.error(error.message)); +}; + +export default () => { + const configOption = '-c, --config '; + const configDescription = 'path to JSON file where configuration values are set; defaults to "cypress.json"'; + + program + .command('open') + .description('runs tests within the interactive GUI') + .option(configOption, configDescription) + .action(() => cypress('open')); + + program + .command('run') + .description('runs tests from the CLI without the GUI') + .option(configOption, configDescription) + .action(() => cypress('run')); + + program.parse(process.argv); +}; diff --git a/packages/grafana-e2e/tsconfig.json b/packages/grafana-e2e/tsconfig.json index 7e51e9fbda7..997a3817e55 100644 --- a/packages/grafana-e2e/tsconfig.json +++ b/packages/grafana-e2e/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { "declarationDir": "dist", + "module": "commonjs", "outDir": "compiled", "rootDirs": ["."], "typeRoots": ["node_modules/@types"], diff --git a/yarn.lock b/yarn.lock index f582804bb08..b92155764fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5178,6 +5178,13 @@ resolved "https://registry.yarnpkg.com/@types/flatbuffers/-/flatbuffers-1.9.1.tgz#1910bebfc15c8f67a287fae07bfc061f94e9d291" integrity sha512-TC3X0Nkj5wgvuY217VkodBtjbD3Yr0JNApDY1GW9IU5Mzm5ie1IJErqe4vRm+wy08IRz3bemaDATrdEw1CJlVQ== +"@types/fs-extra@^8.0.1": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-8.1.0.tgz#1114834b53c3914806cd03b3304b37b3bd221a4d" + integrity sha512-UoOfVEzAUpeSPmjm7h1uk5MH6KZma2z2O7a75onTGjnNvAvMVrPzPL/vBbT65iIGHWj6rokwfmYcmxmlSf2uwg== + dependencies: + "@types/node" "*" + "@types/geojson@*": version "7946.0.7" resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.7.tgz#c8fa532b60a0042219cdf173ca21a975ef0666ad" @@ -5402,6 +5409,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.0.tgz#b417deda18cf8400f278733499ad5547ed1abec4" integrity sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ== +"@types/node@13.7.7": + version "13.7.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.7.tgz#1628e6461ba8cc9b53196dfeaeec7b07fa6eea99" + integrity sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg== + "@types/node@^11.9.5": version "11.13.22" resolved "https://registry.yarnpkg.com/@types/node/-/node-11.13.22.tgz#91ee88ebfa25072433497f6f3150f84fa8c3a91b" @@ -8690,6 +8702,11 @@ color@^3.0.0: color-convert "^1.9.1" color-string "^1.5.2" +colorette@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.1.0.tgz#1f943e5a357fac10b4e0f5aaef3b14cdc1af6ec7" + integrity sha512-6S062WDQUXi6hOfkO/sBPVwE5ASXY4G2+b4atvhJfSsuUUhIaUKlkjLe9692Ipyt5/a+IPF5aVTu3V5gvXq5cg== + colors@^1.1.2: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" @@ -8785,6 +8802,11 @@ commander@2.9.x: dependencies: graceful-readlink ">= 1.0.0" +commander@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + commander@^4.0.1: version "4.1.0" resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.0.tgz#545983a0603fe425bc672d66c9e3c89c42121a83" @@ -9321,6 +9343,15 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" + integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypt@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" @@ -11411,6 +11442,21 @@ execa@0.10.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.0.0.tgz#7f37d6ec17f09e6b8fc53288611695b6d12b9daf" + integrity sha512-JbDUxwV3BoT5ZVXQrSVbAiaXhXUkIwvbhPIwZ0N13kX+5yCzOhUNdocxB/UQRuYOHRYYwAxKYwJYc0T4D12pDA== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" @@ -12547,6 +12593,13 @@ get-stream@^4.0.0, get-stream@^4.1.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-user-locale@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/get-user-locale/-/get-user-locale-1.3.0.tgz#21ea740e413541281ae7b2b42e70ee523b7725b2" @@ -12817,6 +12870,20 @@ globalthis@^1.0.0: function-bind "^1.1.1" object-keys "^1.0.12" +globby@10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.1.tgz#4782c34cb75dd683351335c5829cc3420e606b22" + integrity sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A== + dependencies: + "@types/glob" "^7.1.1" + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.0.3" + glob "^7.1.3" + ignore "^5.1.1" + merge2 "^1.2.3" + slash "^3.0.0" + globby@8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.2.tgz#5697619ccd95c5275dbb2d6faa42087c1a941d8d" @@ -13650,6 +13717,11 @@ https-proxy-agent@^4.0.0: agent-base "5" debug "4" +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + humanize-ms@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" @@ -14586,6 +14658,11 @@ is-stream@^1.0.0, 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-string@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" @@ -17667,6 +17744,13 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" +npm-run-path@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + npm-user-validate@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-1.0.0.tgz#8ceca0f5cea04d4e93519ef72d0557a75122e951" @@ -18619,6 +18703,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, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + 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" @@ -21870,6 +21959,17 @@ rollup-plugin-commonjs@9.2.1: resolve "^1.10.0" rollup-pluginutils "^2.3.3" +rollup-plugin-copy@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-copy/-/rollup-plugin-copy-3.3.0.tgz#5ba230047f86b9f703a29288f242948a5580e7b9" + integrity sha512-euDjCUSBXZa06nqnwCNADbkAcYDfzwowfZQkto9K/TFhiH+QG7I4PUsEMwM9tDgomGWJc//z7KLW8t+tZwxADA== + dependencies: + "@types/fs-extra" "^8.0.1" + colorette "^1.1.0" + fs-extra "^8.1.0" + globby "10.0.1" + is-plain-object "^3.0.0" + rollup-plugin-node-resolve@4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-4.0.1.tgz#f95765d174e5daeef9ea6268566141f53aa9d422" @@ -22453,11 +22553,23 @@ shebang-command@^1.2.0: dependencies: shebang-regex "^1.0.0" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + shell-quote@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" @@ -23394,6 +23506,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-indent@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" @@ -25363,6 +25480,13 @@ which@1, which@1.3.1, which@^1.2.10, which@^1.2.14, which@^1.2.4, which@^1.2.9, dependencies: isexe "^2.0.0" +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + wide-align@1.1.3, wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"