Improve prestart and tests (#1610)

* screenshotter: replace promisify(fs) and mkdirp with fs-extra

* screenshotter: replace selenium.promise with builtin Promise

* Lint all JavaScript files in the root

* unicodeMake: replace console.log with writeFile(string)

* unicodeMake: check timestamp, do not build if up-to-date

* Replace check-dependencies with yarn check

* Exclude src/unicodeMake.js from coverage

* Add (missing) dependencies

* Skip CircleCI if only unrelated has been changed

* Fix commit range

* Use fs-extra in update-sri
This commit is contained in:
ylemkimon
2018-08-17 16:29:27 +09:00
committed by GitHub
parent e8f2ecdd39
commit f829ebc692
7 changed files with 120 additions and 197 deletions

View File

@@ -1,9 +1,21 @@
checkout_submodule: &checkout_submodule
post_checkout: &post_checkout
run:
name: Checkout submodule
name: Checkout submodule and get changed files
command: |
git submodule sync
git submodule update --init --recursive
if [[ $CIRCLE_PULL_REQUEST ]]; then
BASE_COMMIT=$(curl -s -H "Authorization: token a61ecb2fc5b72da54431""1b3db3875c96854958a8" \
https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/pulls/$CIRCLE_PR_NUMBER \
| jq -r ".base.sha | select(. != null)")...
else
BASE_COMMIT=HEAD^
fi
if [[ $BASE_COMMIT ]]; then
CHANGED=$(git diff --name-only $BASE_COMMIT)
echo $CHANGED
echo 'export CHANGED="$CHANGED"' >> $BASH_ENV
fi
node_modules_cache_key: &node_modules_cache_key
yarn-deps-v1-{{ checksum "yarn.lock" }}
@@ -22,7 +34,13 @@ yarn_install: &yarn_install
screenshotter: &screenshotter
steps:
- checkout
- *checkout_submodule
- *post_checkout
- run:
name: Skip screenshotter if no KaTeX code has been changed
command: |
if [[ $CHANGED ]]; then
echo $CHANGED | grep -qvE '^contrib/|^docs/|^static/|^website/|^LICENSE|\.md$' || circleci step halt
fi
- *restore_node_modules_cache
- *yarn_install
@@ -53,7 +71,13 @@ jobs:
fi
- checkout
- *checkout_submodule
- *post_checkout
- run:
name: Skip screenshotter if only documentation has been changed
command: |
if [[ $CHANGED ]]; then
echo $CHANGED | grep -qvE '^docs/|^LICENSE|\.md$' || circleci step halt
fi
- *restore_node_modules_cache
- *yarn_install

View File

@@ -1,16 +1,10 @@
"use strict";
var v = process.version;
v = v.replace(/^v/,"");
v = v.split(".");
v = v.map(function(s){
return parseInt(s);
});
var a = v[0], b = v[1], c = v[2];
if (a < 6 || (a == 6 && b < 9)) {
const v = process.version
.replace(/^v/, "")
.split(".")
.map(parseInt);
if (v[0] < 6 || (v[0] === 6 && v[1] < 9)) {
// eslint-disable-next-line no-console
console.error("Node 6.9 or later required for development. " +
"Version " + process.version + " found");
process.exit(1);
} else {
console.log("OK");
}

View File

@@ -2,8 +2,7 @@
"use strict";
const childProcess = require("child_process");
const fs = require("fs");
const mkdirp = require("mkdirp");
const fs = require("fs-extra");
const jspngopt = require("jspngopt");
const net = require("net");
const os = require("os");
@@ -352,7 +351,7 @@ function takeScreenshot(key) {
let retry = 0;
let loadExpected = null;
if (opts.verify) {
loadExpected = promisify(fs.readFile, file);
loadExpected = fs.readFile(file);
}
const url = katexURL + "test/screenshotter/test.html?" + itm.query;
@@ -400,7 +399,7 @@ function takeScreenshot(key) {
key += "_alt";
file = path.join(dstDir, key + "-" + opts.browser + ".png");
if (loadExpected) {
loadExpected = promisify(fs.readFile, file);
loadExpected = fs.readFile(file);
}
}
const opt = new jspngopt.Optimizer({
@@ -430,7 +429,7 @@ function takeScreenshot(key) {
}
});
} else {
return promisify(fs.writeFile, file, buf).then(function() {
return fs.writeFile(file, buf).then(function() {
console.log(key);
});
}
@@ -443,16 +442,11 @@ function takeScreenshot(key) {
const diffFile = path.join(diffDir, filenamePrefix + "-diff.png");
const bufFile = path.join(outputDir, filenamePrefix + ".png");
let promise = promisify(mkdirp, outputDir)
.then(function() {
return promisify(fs.writeFile, bufFile, buf);
});
let promise = fs.ensureDir(outputDir)
.then(fs.writeFile(bufFile, buf));
if (opts.diff) {
promise = promise.then(function() {
return promisify(mkdirp, diffDir);
})
.then(function() {
return execFile("convert", [
promise = promise.then(fs.ensureDir(diffDir))
.then(execFile("convert", [
"-fill", "white",
// First image: saved screenshot in red
"(", baseFile, "-colorize", "100,0,0", ")",
@@ -463,13 +457,10 @@ function takeScreenshot(key) {
"-trim", // remove everything with the same color as the
// corners
diffFile, // output file name
]);
});
]));
}
if (!opts.new) {
promise = promise.then(function() {
return promisify(fs.unlink, bufFile);
});
promise = promise.then(fs.unlink(bufFile));
}
return promise;
}
@@ -500,38 +491,19 @@ function browserSideWait(milliseconds) {
milliseconds);
}
// Turn node callback style into a call returning a promise,
// like Q.nfcall but using Selenium promises instead of Q ones.
// Second and later arguments are passed to the function named in the
// first argument, and a callback is added as last argument.
function promisify(f) {
const args = Array.prototype.slice.call(arguments, 1);
const deferred = new selenium.promise.Deferred();
args.push(function(err, val) {
if (err) {
deferred.reject(err);
} else {
deferred.fulfill(val);
}
});
f.apply(null, args);
return deferred.promise;
}
// Execute a given command, and return a promise to its output.
// Don't denodeify here, since fail branch needs access to stderr.
function execFile(cmd, args, opts) {
const deferred = new selenium.promise.Deferred();
childProcess.execFile(cmd, args, opts, function(err, stdout, stderr) {
if (err) {
console.error("Error executing " + cmd + " " + args.join(" "));
console.error(stdout + stderr);
err.stdout = stdout;
err.stderr = stderr;
deferred.reject(err);
} else {
deferred.fulfill(stdout);
}
return new Promise(function(resolve, reject) {
childProcess.execFile(cmd, args, opts, function(err, stdout, stderr) {
if (err) {
console.error("Error executing " + cmd + " " + args.join(" "));
console.error(stdout + stderr);
err.stdout = stdout;
err.stderr = stderr;
reject(err);
} else {
resolve(stdout);
}
});
});
return deferred.promise;
}

View File

@@ -17,6 +17,7 @@
],
"license": "MIT",
"devDependencies": {
"babel-core": "^6.26.3",
"babel-eslint": "^8.1.2",
"babel-jest": "^23.0.1",
"babel-loader": "^7.1.4",
@@ -27,7 +28,6 @@
"babel-preset-flow": "^6.23.0",
"babel-register": "^6.26.0",
"benchmark": "^2.1.4",
"check-dependencies": "^1.1.0",
"codecov": "^3.0.4",
"css-loader": "^1.0.0",
"cssnano": "^4.0.1",
@@ -37,6 +37,7 @@
"eslint-plugin-transform-runtime-aliasing": "^1.0.0",
"file-loader": "^1.1.11",
"flow-bin": "^0.78.0",
"fs-extra": "^7.0.0",
"greenkeeper-lockfile": "^1.15.1",
"husky": "^1.0.0-rc.8",
"jest": "^23.0.1",
@@ -69,7 +70,7 @@
"scripts": {
"test": "yarn prestart && yarn test:lint && yarn test:flow && yarn test:jest",
"test:lint": "yarn test:lint:js && yarn test:lint:css",
"test:lint:js": "eslint katex.js katex.webpack.js cli.js webpack.*.js src static test contrib dockers website",
"test:lint:js": "eslint *.js src static test contrib dockers website",
"test:lint:css": "stylelint src/katex.less static/main.css contrib/**/*.css website/static/**/*.css",
"test:flow": "flow",
"test:jest": "jest",
@@ -81,7 +82,7 @@
"test:perf": "yarn prestart && NODE_ENV=test node test/perf-test.js",
"clean": "rm -rf dist/ node_modules/",
"clean-install": "yarn clean && yarn",
"prestart": "node check-node-version.js && check-dependencies && node src/unicodeMake.js > src/unicodeSymbols.js",
"prestart": "node check-node-version.js && yarn check && node src/unicodeMake.js",
"start": "webpack-dev-server --hot --config webpack.dev.js",
"analyze": "webpack --config webpack.analyze.js",
"build": "yarn prestart && rimraf dist/ && mkdirp dist && cp README.md dist && rollup -c && webpack",
@@ -102,7 +103,8 @@
"jest": {
"collectCoverageFrom": [
"src/**/*.js",
"contrib/**/*.js"
"contrib/**/*.js",
"!src/unicodeMake.js"
],
"setupTestFrameworkScriptFile": "<rootDir>/test/setup.js",
"snapshotSerializers": [

View File

@@ -4,14 +4,19 @@
// whose purpose is to generate unicodeSymbols.js in this directory.
// In this way, only this tool, and not the distribution/browser,
// needs String's normalize function.
const path = require('path');
const fs = require('fs');
const target = path.join(__dirname, 'unicodeSymbols.js');
const targetMtime = fs.statSync(target).mtime;
if (fs.statSync(__filename).mtime <= targetMtime && fs.statSync(
path.join(__dirname, 'unicodeAccents.js')).mtime <= targetMtime) {
return;
}
require('babel-register')({plugins: ["transform-es2015-modules-commonjs"]});
const accents = require('./unicodeAccents').default;
console.log("// @flow");
console.log("// This file is GENERATED by unicodeMake.js. DO NOT MODIFY.");
console.log("");
const encode = function(string) {
let output = '"';
for (let i = 0; i < string.length; i++) {
@@ -25,7 +30,12 @@ const encode = function(string) {
return output;
};
console.log("export default {");
let unicodeSymbols =
`// @flow
// This file is GENERATED by unicodeMake.js. DO NOT MODIFY.
export default {
`;
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"αβγδεϵζηθϑικλμνξοπϖρϱςστυφϕχψωΓΔΘΛΞΠΣΥΦΨΩ";
@@ -34,9 +44,9 @@ for (const letter of letters) {
const combined = letter + accent;
const normalized = combined.normalize('NFC');
if (normalized.length === 1) {
console.log(
unicodeSymbols +=
` ${encode(normalized)}: ${encode(combined)},`
+ ` // ${normalized} = ${accents[accent].text}{${letter}}`);
+ ` // ${normalized} = ${accents[accent].text}{${letter}}\n`;
}
for (const accent2 of Object.getOwnPropertyNames(accents)) {
if (accent === accent2) {
@@ -45,13 +55,16 @@ for (const letter of letters) {
const combined2 = combined + accent2;
const normalized2 = combined2.normalize('NFC');
if (normalized2.length === 1) {
console.log(
unicodeSymbols +=
` ${encode(normalized2)}: ${encode(combined2)},`
+ ` // ${normalized2} = ${accents[accent].text}`
+ `${accents[accent2].text}{${letter}}`);
+ `${accents[accent2].text}{${letter}}\n`;
}
}
}
}
console.log("};");
unicodeSymbols += `};
`;
fs.writeFileSync(target, unicodeSymbols);

View File

@@ -1,31 +1,14 @@
const fs = require("fs");
const path = require("path");
const fs = require("fs-extra");
const sriToolbox = require("sri-toolbox");
const version = process.argv[2];
function read(file, encoding) {
return new Promise((resolve, reject) =>
fs.readFile(file, encoding, (err, body) =>
err ? reject(err) : resolve(body)));
}
function write(file, data) {
return new Promise((resolve, reject) =>
fs.writeFile(file, data, (err) =>
err ? reject(err) : resolve()));
}
Promise.all(process.argv.slice(3).map(file =>
read(file, "utf8")
fs.readFile(file, "utf8")
.then(body => {
// Replace size badge url
// 1 - url prefix: https://img.badgesize.io/Khan/KaTeX/
// 2 - url suffix: /dist/katex.min.js?compression=gzip
const badgeRe = /(https:\/\/img\.badgesize\.io\/Khan\/KaTeX\/v)(?:.+)(\/dist\/katex\.min\.js\?compression=gzip)/g;
body = body.replace(badgeRe, (m, pre, post) => {
return pre + version + post;
});
// eslint-disable-next-line max-len
body = body.replace(/(https:\/\/img\.badgesize\.io\/Khan\/KaTeX\/v)(?:.+)(\/dist\/katex\.min\.js\?compression=gzip)/g, `$1${version}$2`);
// Replace CDN urls
// 1 - url prefix: "http…/KaTeX/
@@ -35,24 +18,26 @@ Promise.all(process.argv.slice(3).map(file =>
// 5 - integrity opening quote: "
// 6 - old hash: sha384-…
// 7 - integrity hash algorithm: sha384
const cdnRe = /((["'])https?:\/\/cdn\.jsdelivr\.net\/npm\/katex@)[^\/"']+(\/([^"']+)\2(?:\s+integrity=(["'])(([^-]+)-[^"']+)\5)?)/g;
// eslint-disable-next-line max-len
const cdnRe = /((["'])https?:\/\/cdn\.jsdelivr\.net\/npm\/katex@)[^/"']+(\/([^"']+)\2(?:\s+integrity=(["'])(([^-]+)-[^"']+)\5)?)/g;
const hashes = {};
body = body.replace(cdnRe, (m, pre, oq1, post, file, oq2, old, algo) => {
if (old) {
hashes[old] = { file, algo };
hashes[old] = {file, algo};
}
return pre + version + post;
});
return Promise.all(Object.keys(hashes).map(hash =>
read(hashes[hash].file, null)
fs.readFile(hashes[hash].file, null)
.then(data => {
body = body.replace(hash, sriToolbox.generate({
algorithms: [hashes[hash].algo],
}, data));
})
)).then(() => write(file, body));
)).then(() => fs.writeFile(file, body));
})
)).then(() => process.exit(0), err => {
// eslint-disable-next-line no-console
console.error(err.stack);
process.exit(1);
});

117
yarn.lock
View File

@@ -555,7 +555,7 @@ babel-code-frame@^6.26.0:
esutils "^2.0.2"
js-tokens "^3.0.2"
babel-core@^6.0.0, babel-core@^6.26.0:
babel-core@^6.0.0, babel-core@^6.26.0, babel-core@^6.26.3:
version "6.26.3"
resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207"
dependencies:
@@ -1134,16 +1134,6 @@ boolbase@^1.0.0, boolbase@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
bower-config@^1.4.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/bower-config/-/bower-config-1.4.1.tgz#85fd9df367c2b8dbbd0caa4c5f2bad40cd84c2cc"
dependencies:
graceful-fs "^4.1.3"
mout "^1.0.0"
optimist "^0.6.1"
osenv "^0.1.3"
untildify "^2.1.0"
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -1444,17 +1434,6 @@ chardet@^0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.5.0.tgz#fe3ac73c00c3d865ffcc02a0682e2c20b6a06029"
check-dependencies@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/check-dependencies/-/check-dependencies-1.1.0.tgz#3aa2df4061770179d8e88e8bf9315c53722ddff4"
dependencies:
bower-config "^1.4.0"
chalk "^2.1.0"
findup-sync "^2.0.0"
lodash.camelcase "^4.3.0"
minimist "^1.2.0"
semver "^5.4.1"
check-types@^7.3.0:
version "7.4.0"
resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.4.0.tgz#0378ec1b9616ec71f774931a3c6516fad8c152f4"
@@ -2134,10 +2113,6 @@ destroy@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
detect-file@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7"
detect-indent@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
@@ -2613,12 +2588,6 @@ expand-range@^1.8.1:
dependencies:
fill-range "^2.1.0"
expand-tilde@^2.0.0, expand-tilde@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502"
dependencies:
homedir-polyfill "^1.0.1"
expect@^23.4.0:
version "23.4.0"
resolved "https://registry.yarnpkg.com/expect/-/expect-23.4.0.tgz#6da4ecc99c1471253e7288338983ad1ebadb60c3"
@@ -2867,15 +2836,6 @@ find-up@^3.0.0:
dependencies:
locate-path "^3.0.0"
findup-sync@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc"
dependencies:
detect-file "^1.0.0"
is-glob "^3.1.0"
micromatch "^3.0.4"
resolve-dir "^1.0.1"
flat-cache@^1.2.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481"
@@ -2953,6 +2913,14 @@ from2@^2.1.0:
inherits "^2.0.1"
readable-stream "^2.0.0"
fs-extra@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.0.tgz#8cc3f47ce07ef7b3593a11b9fb245f7e34c041d6"
dependencies:
graceful-fs "^4.1.2"
jsonfile "^4.0.0"
universalify "^0.1.0"
fs-minipass@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d"
@@ -3065,24 +3033,6 @@ global-modules-path@^2.1.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/global-modules-path/-/global-modules-path-2.3.0.tgz#b0e2bac6beac39745f7db5c59d26a36a0b94f7dc"
global-modules@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea"
dependencies:
global-prefix "^1.0.1"
is-windows "^1.0.1"
resolve-dir "^1.0.0"
global-prefix@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe"
dependencies:
expand-tilde "^2.0.2"
homedir-polyfill "^1.0.1"
ini "^1.3.4"
is-windows "^1.0.1"
which "^1.2.14"
globals@^11.1.0, globals@^11.7.0:
version "11.7.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673"
@@ -3134,7 +3084,7 @@ gonzales-pe@4.2.3:
dependencies:
minimist "1.1.x"
graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3:
graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
@@ -3270,12 +3220,6 @@ home-or-tmp@^2.0.0:
os-homedir "^1.0.0"
os-tmpdir "^1.0.1"
homedir-polyfill@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc"
dependencies:
parse-passwd "^1.0.0"
hosted-git-info@^2.1.4:
version "2.7.1"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047"
@@ -3506,7 +3450,7 @@ inherits@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
ini@^1.3.4, ini@~1.3.0:
ini@~1.3.0:
version "1.3.5"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
@@ -3862,7 +3806,7 @@ is-whitespace-character@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.2.tgz#ede53b4c6f6fb3874533751ec9280d01928d03ed"
is-windows@^1.0.1, is-windows@^1.0.2:
is-windows@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
@@ -4365,6 +4309,12 @@ json5@^0.5.0, json5@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
optionalDependencies:
graceful-fs "^4.1.6"
jsonify@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
@@ -4760,7 +4710,7 @@ micromatch@^2.3.11:
parse-glob "^3.0.4"
regex-cache "^0.4.2"
micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8, micromatch@^3.1.9:
micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8, micromatch@^3.1.9:
version "3.1.10"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
dependencies:
@@ -4897,10 +4847,6 @@ mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
dependencies:
minimist "0.0.8"
mout@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/mout/-/mout-1.1.0.tgz#0b29d41e6a80fa9e2d4a5be9d602e1d9d02177f6"
move-concurrently@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
@@ -5267,7 +5213,7 @@ os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
osenv@^0.1.3, osenv@^0.1.4:
osenv@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
dependencies:
@@ -5369,10 +5315,6 @@ parse-json@^4.0.0:
error-ex "^1.3.1"
json-parse-better-errors "^1.0.1"
parse-passwd@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
parse5@4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
@@ -6385,13 +6327,6 @@ resolve-cwd@^2.0.0:
dependencies:
resolve-from "^3.0.0"
resolve-dir@^1.0.0, resolve-dir@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43"
dependencies:
expand-tilde "^2.0.0"
global-modules "^1.0.0"
resolve-from@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
@@ -7490,6 +7425,10 @@ unist-util-visit@^1.1.0:
dependencies:
unist-util-visit-parents "^2.0.0"
universalify@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
unpipe@1.0.0, unpipe@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
@@ -7505,12 +7444,6 @@ unset-value@^1.0.0:
has-value "^0.3.1"
isobject "^3.0.0"
untildify@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0"
dependencies:
os-homedir "^1.0.0"
upath@^1.0.5:
version "1.1.0"
resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd"
@@ -7828,7 +7761,7 @@ which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
which@^1.2.12, which@^1.2.14, 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"
dependencies: