diff --git a/.travis.yml b/.travis.yml index d43663a4..96acd5c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ node_js: script: - echo "Smoke testing d2 executable" - ./packages/main/bin/d2 debug system + - yarn test deploy: - provider: script skip_cleanup: true diff --git a/package.json b/package.json index 432c676d..44600217 100644 --- a/package.json +++ b/package.json @@ -12,12 +12,16 @@ "license": "BSD-3-Clause", "devDependencies": { "@dhis2/cli-style": "3.2.2", - "husky": "^2.0.0" + "husky": "^2.0.0", + "tape": "^4.10.1" }, "husky": { "hooks": { "commit-msg": "d2-style commit check", "pre-commit": "d2-style js apply" } + }, + "scripts": { + "test": "tape packages/**/tests/*.js" } } diff --git a/packages/cluster/src/commands/down.js b/packages/cluster/src/commands/down.js index 0cc36601..e9053e21 100644 --- a/packages/cluster/src/commands/down.js +++ b/packages/cluster/src/commands/down.js @@ -1,11 +1,7 @@ const chalk = require('chalk') const path = require('path') const { exec, reporter } = require('@dhis2/cli-helpers-engine') -const { - initDockerComposeCache, - makeComposeProject, - makeDockerImage, -} = require('../common') +const { initDockerComposeCache, makeComposeProject } = require('../common') const defaults = require('../defaults') diff --git a/packages/cluster/src/commands/logs.js b/packages/cluster/src/commands/logs.js index 9ccb435e..4b9b691b 100644 --- a/packages/cluster/src/commands/logs.js +++ b/packages/cluster/src/commands/logs.js @@ -1,11 +1,7 @@ const chalk = require('chalk') const path = require('path') const { reporter, exec, tryCatchAsync } = require('@dhis2/cli-helpers-engine') -const { - initDockerComposeCache, - makeComposeProject, - makeDockerImage, -} = require('../common') +const { initDockerComposeCache, makeComposeProject } = require('../common') const defaults = require('../defaults') const run = async function({ service, name, ...argv }) { diff --git a/packages/cluster/src/commands/restart.js b/packages/cluster/src/commands/restart.js index 27836d4b..008f29cc 100644 --- a/packages/cluster/src/commands/restart.js +++ b/packages/cluster/src/commands/restart.js @@ -1,11 +1,7 @@ const chalk = require('chalk') const path = require('path') const { reporter, exec, tryCatchAsync } = require('@dhis2/cli-helpers-engine') -const { - initDockerComposeCache, - makeComposeProject, - makeDockerImage, -} = require('../common') +const { initDockerComposeCache, makeComposeProject } = require('../common') const defaults = require('../defaults') @@ -53,9 +49,10 @@ module.exports = { builder: { port: { alias: 'p', - desc: 'Specify the port on which to expose the DHIS2 instance', + desc: `Specify the port on which to expose the DHIS2 instance (default: ${ + defaults.port + })`, type: 'integer', - default: defaults.port, }, }, handler: run, diff --git a/packages/cluster/src/commands/seed.js b/packages/cluster/src/commands/seed.js index 22570475..a0fb3317 100644 --- a/packages/cluster/src/commands/seed.js +++ b/packages/cluster/src/commands/seed.js @@ -41,7 +41,6 @@ module.exports = { dhis2Version: { desc: 'DHIS2 version to use', type: 'string', - default: '', }, }, handler: run, diff --git a/packages/cluster/src/commands/up.js b/packages/cluster/src/commands/up.js index 62653acd..6a0c4c7c 100644 --- a/packages/cluster/src/commands/up.js +++ b/packages/cluster/src/commands/up.js @@ -4,42 +4,21 @@ const { reporter, exec, tryCatchAsync } = require('@dhis2/cli-helpers-engine') const { initDockerComposeCache, makeComposeProject, - makeDockerImage, - substituteVersion, + makeEnvironment, } = require('../common') const defaults = require('../defaults') const { seed: doSeed } = require('../db') -const run = async function({ - name, - port, - seed, - seedFile, - update, - image, - dhis2Version, - customContext, - ...argv -}) { - const { cluster } = argv +const run = async function(argv) { + const { cluster, name, seed, seedFile, update } = argv - const resolvedVersion = dhis2Version || name - const resolvedImage = substituteVersion( - image || cluster.image || defaults.image, - resolvedVersion - ) - - const resolvedPort = port || cluster.port || defaults.port - const resolvedContext = - customContext || cluster.customContext || defaults.customContext - const resolvedContextPath = resolvedContext ? `/${name}` : '' + const runtime = makeEnvironment(argv, {}, cluster) const cacheLocation = await initDockerComposeCache({ cache: argv.getCache(), dockerComposeRepository: - argv.cluster.dockerComposeRepository || - defaults.dockerComposeRepository, + cluster.dockerComposeRepository || defaults.dockerComposeRepository, force: update, }) @@ -51,7 +30,7 @@ const run = async function({ if (seed || seedFile) { await doSeed({ cacheLocation, - dbVersion: resolvedVersion, + dbVersion: runtime.DHIS2_CORE_DB_VERSION, name, path: seedFile, update, @@ -64,6 +43,7 @@ const run = async function({ const res = await tryCatchAsync( 'exec(docker-compose)', exec({ + env: runtime, cmd: 'docker-compose', args: [ '-p', @@ -73,13 +53,6 @@ const run = async function({ 'up', '-d', ], - env: { - DHIS2_CORE_NAME: name, - DHIS2_CORE_CONTEXT_PATH: resolvedContextPath, - DHIS2_CORE_IMAGE: resolvedImage, - DHIS2_CORE_VERSION: resolvedVersion, - DHIS2_CORE_PORT: resolvedPort, - }, pipe: true, }) ) @@ -96,15 +69,15 @@ module.exports = { builder: { port: { alias: 'p', - desc: 'Specify the port on which to expose the DHIS2 instance', + desc: `Specify the port on which to expose the DHIS2 instance (default: ${ + defaults.port + })`, type: 'integer', - default: defaults.port, }, seed: { alias: 's', desc: 'Seed the detabase from a sql dump', type: 'boolean', - default: defaults.seed, }, seedFile: { desc: @@ -115,24 +88,34 @@ module.exports = { alias: 'u', desc: 'Indicate that d2 cluster should re-download cached files', type: 'boolean', - default: defaults.update, }, image: { alias: 'i', desc: 'Specify the Docker image to use', type: 'string', - default: defaults.image, }, dhis2Version: { desc: 'Set the DHIS2 version', type: 'string', - default: defaults.dhis2Version, + }, + dbVersion: { + desc: 'Set the database version', + type: 'string', + }, + channel: { + desc: `Set the release channel to use (default: ${ + defaults.channel + })`, + type: 'string', }, customContext: { alias: 'c', desc: 'Serve on a custom context path', type: 'boolean', - default: defaults.customContext, + }, + variant: { + desc: 'Append variant options to the image', + type: 'string', }, }, handler: run, diff --git a/packages/cluster/src/common.js b/packages/cluster/src/common.js index 87f81618..6b237e72 100644 --- a/packages/cluster/src/common.js +++ b/packages/cluster/src/common.js @@ -1,5 +1,7 @@ const { reporter } = require('@dhis2/cli-helpers-engine') +const defaults = require('./defaults') + const dockerComposeCacheName = 'd2-cluster-docker-compose-v2' module.exports.initDockerComposeCache = async ({ @@ -33,8 +35,80 @@ module.exports.initDockerComposeCache = async ({ } module.exports.makeComposeProject = version => `d2-cluster-${version}` -module.exports.makeDockerImage = version => `${version}-alpine` + module.exports.substituteVersion = (string, version) => - string.replace(/{version}/g, version) + replacer(string, 'version', version) + +function makeDockerImage(string = '', substitutes = {}, variant = '') { + let res = string + + // the stable channel is just dhis2/core, so if the channel is + // unspecified or 'stable', we should just strip it out from the + // image tag + if (!substitutes.channel || substitutes.channel === 'stable') { + res = replacer(res, 'channel', '') + } + + for (const token in substitutes) { + const value = + token === 'channel' + ? `-${substitutes[token]}` // add a leading '-' to channel + : substitutes[token] + + res = replacer(res, token, value) + } + + if (variant) { + res = `${res}-${variant}` + } + return res +} + +function replacer(string, token, value) { + const regexp = new RegExp(`{${token}}`, 'g') + return string.replace(regexp, value) +} + +function resolveConfiguration(argv = {}, cache = {}, config = {}) { + const resolved = Object.assign({}, defaults, config, cache, argv) + + // resolve specials... + resolved.dhis2Version = resolved.dhis2Version || resolved.name + resolved.dbVersion = resolved.dbVersion || resolved.dhis2Version + resolved.contextPath = resolved.customContext ? `/${resolved.name}` : '' + + resolved.dockerImage = makeDockerImage( + resolved.image, + { + channel: resolved.channel, + version: resolved.dhis2Version, + }, + resolved.variant + ) + + reporter.debug('Resolved configuration\n', resolved) + + return resolved +} + +module.exports.makeEnvironment = (argv = {}, cache = {}, config = {}) => { + const cfg = resolveConfiguration(argv, cache, config) + + const env = { + DHIS2_CORE_NAME: cfg.name, + DHIS2_CORE_IMAGE: cfg.dockerImage, + DHIS2_CORE_CONTEXT_PATH: cfg.contextPath, + DHIS2_CORE_VERSION: cfg.dhis2Version, + DHIS2_CORE_DB_VERSION: cfg.dbVersion, + DHIS2_CORE_PORT: cfg.port, + } + + reporter.debug('Runtime environment\n', env) + + return env +} module.exports.getLocalClusters = async () => {} + +module.exports.makeDockerImage = makeDockerImage +module.exports.resolveConfiguration = resolveConfiguration diff --git a/packages/cluster/src/defaults.js b/packages/cluster/src/defaults.js index 583ab19f..367f0512 100644 --- a/packages/cluster/src/defaults.js +++ b/packages/cluster/src/defaults.js @@ -1,6 +1,8 @@ module.exports = { dhis2Version: '', - image: 'amcgee/dhis2-core:{version}-alpine', + dbVersion: '', + channel: 'stable', + image: 'dhis2/core{channel}:{version}', port: 8080, customContext: false, update: false, diff --git a/packages/cluster/src/index.js b/packages/cluster/src/index.js index 04880392..d16814ca 100644 --- a/packages/cluster/src/index.js +++ b/packages/cluster/src/index.js @@ -3,9 +3,10 @@ const { namespace } = require('@dhis2/cli-helpers-engine') const command = namespace('cluster', { desc: 'Manage DHIS2 Docker clusters', aliases: 'c', - builder: yargs => { - yargs.commandDir('commands') - }, + builder: yargs => + yargs.commandDir('commands').parserConfiguration({ + 'parse-numbers': false, + }), }) module.exports = command diff --git a/packages/cluster/tests/setup-environment.js b/packages/cluster/tests/setup-environment.js new file mode 100644 index 00000000..58c7c5bd --- /dev/null +++ b/packages/cluster/tests/setup-environment.js @@ -0,0 +1,119 @@ +const test = require('tape') + +const { makeEnvironment } = require('../src/common.js') + +const defaults = require('../src/defaults.js') + +test('build runtime environment based on defaults', function(t) { + t.plan(1) + + const argv = { + name: 'dev', + } + const cache = {} + const config = {} + + const actual = makeEnvironment(argv, cache, config) + + const expected = { + DHIS2_CORE_NAME: 'dev', + DHIS2_CORE_CONTEXT_PATH: '', + DHIS2_CORE_IMAGE: 'dhis2/core:dev', + DHIS2_CORE_VERSION: 'dev', + DHIS2_CORE_DB_VERSION: 'dev', + DHIS2_CORE_PORT: defaults.port, + } + + t.deepEqual(actual, expected, 'default environment') +}) + +test('build runtime environment based on args', function(t) { + t.plan(1) + + const argv = { + name: 'dev', + customContext: true, + dhis2Version: '2.33', + dbVersion: '2.32', + channel: 'canary', + variant: 'jetty-slackware', + port: 8233, + } + const cache = {} + const config = {} + + const actual = makeEnvironment(argv, cache, config) + + const expected = { + DHIS2_CORE_NAME: 'dev', + DHIS2_CORE_CONTEXT_PATH: '/dev', + DHIS2_CORE_IMAGE: 'dhis2/core-canary:2.33-jetty-slackware', + DHIS2_CORE_VERSION: '2.33', + DHIS2_CORE_DB_VERSION: '2.32', + DHIS2_CORE_PORT: 8233, + } + + t.deepEqual(actual, expected, 'args environment') +}) + +test('build runtime environment based on mixed args and config', function(t) { + t.plan(1) + + const argv = { + name: 'mydev', + customContext: true, + } + + const cache = {} + + const config = { + dhis2Version: 'master', + port: 8233, + channel: 'dev', + dbVersion: 'dev', + } + + const actual = makeEnvironment(argv, cache, config) + + const expected = { + DHIS2_CORE_NAME: 'mydev', + DHIS2_CORE_CONTEXT_PATH: '/mydev', + DHIS2_CORE_IMAGE: 'dhis2/core-dev:master', + DHIS2_CORE_VERSION: 'master', + DHIS2_CORE_DB_VERSION: 'dev', + DHIS2_CORE_PORT: 8233, + } + + t.deepEqual(actual, expected, 'args and config environment') +}) + +test('build runtime environment based on mixed args, cache, config and defaults', function(t) { + t.plan(1) + + const argv = { + name: 'mydev', + } + + const cache = { + customContext: true, + image: 'dhis2/core-canary:master-20190523-alpine', + } + + const config = { + port: 8233, + dhis2Version: 'dev', + } + + const actual = makeEnvironment(argv, cache, config) + + const expected = { + DHIS2_CORE_NAME: 'mydev', + DHIS2_CORE_CONTEXT_PATH: '/mydev', + DHIS2_CORE_IMAGE: 'dhis2/core-canary:master-20190523-alpine', + DHIS2_CORE_VERSION: 'dev', + DHIS2_CORE_DB_VERSION: 'dev', + DHIS2_CORE_PORT: 8233, + } + + t.deepEqual(actual, expected, 'merged environment') +}) diff --git a/packages/cluster/tests/substitute-string-keys.js b/packages/cluster/tests/substitute-string-keys.js new file mode 100644 index 00000000..792814fe --- /dev/null +++ b/packages/cluster/tests/substitute-string-keys.js @@ -0,0 +1,179 @@ +const test = require('tape') + +const { makeDockerImage, substituteVersion } = require('../src/common.js') + +const defaults = require('../src/defaults') + +const template = defaults.image + +test('replace {version} key with a value', function(t) { + t.plan(1) + + const string = 'somethingwitha{version}key' + const version = '2.31.1' + + const result = substituteVersion(string, version) + + t.equal(result, 'somethingwitha2.31.1key', 'replace {version} with 2.31.1') +}) + +test('stable and 2.31.4', function(t) { + t.plan(2) + + const expected = 'dhis2/core:2.31.4' + + t.equal( + makeDockerImage(template, { + version: '2.31.4', + channel: 'stable', + }), + expected, + expected + ) + + t.equal( + makeDockerImage(template, { + version: '2.31.4', + }), + expected, + expected + ) +}) + +test('stable and 2.32.0 with alpine variant', function(t) { + t.plan(1) + + const expected = 'dhis2/core:2.32.0-alpine' + + t.equal( + makeDockerImage( + template, + { + version: '2.32.0', + }, + 'alpine' + ), + expected, + expected + ) +}) + +test('stable and master with tomcat9 and debian-slim variant', function(t) { + t.plan(1) + + const expected = 'dhis2/core:master-tomcat9-debian-slim' + + t.equal( + makeDockerImage( + template, + { + version: 'master', + }, + 'tomcat9-debian-slim' + ), + expected, + expected + ) +}) + +test('stable and 2.32.0', function(t) { + t.plan(2) + + const expected = 'dhis2/core:2.32.0' + + t.equal( + makeDockerImage(template, { + version: '2.32.0', + channel: 'stable', + }), + expected, + expected + ) + + t.equal( + makeDockerImage(template, { + version: '2.32.0', + }), + expected, + expected + ) +}) + +test('dev and master', function(t) { + t.plan(1) + + const expected = 'dhis2/core-dev:master' + + t.equal( + makeDockerImage(template, { + version: 'master', + channel: 'dev', + }), + expected, + expected + ) +}) + +test('dev and 2.32', function(t) { + t.plan(1) + + const expected = 'dhis2/core-dev:2.32' + + t.equal( + makeDockerImage(template, { + version: '2.32', + channel: 'dev', + }), + expected, + expected + ) +}) + +test('canary and master', function(t) { + t.plan(1) + + const expected = 'dhis2/core-canary:master' + + t.equal( + makeDockerImage(template, { + version: 'master', + channel: 'canary', + }), + expected, + expected + ) +}) + +test('canary and 2.32', function(t) { + t.plan(1) + + const expected = 'dhis2/core-canary:2.32' + + t.equal( + makeDockerImage(template, { + version: '2.32', + channel: 'canary', + }), + expected, + expected + ) +}) + +test('canary and 2.32 from date', function(t) { + t.plan(1) + + const expected = 'dhis2/core-canary:2.32-20190523' + + t.equal( + makeDockerImage( + template, + { + version: '2.32', + channel: 'canary', + }, + '20190523' + ), + expected, + expected + ) +}) diff --git a/yarn.lock b/yarn.lock index d7577fa2..0eefe623 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1256,6 +1256,11 @@ decompress-response@^3.3.0: dependencies: mimic-response "^1.0.0" +deep-equal@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -1278,6 +1283,13 @@ defer-to-connect@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.0.2.tgz#4bae758a314b034ae33902b5aac25a8dd6a8633e" +define-properties@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" @@ -1297,6 +1309,11 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +defined@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -1433,6 +1450,27 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +es-abstract@^1.5.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" + integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== + dependencies: + es-to-primitive "^1.2.0" + function-bind "^1.1.1" + has "^1.0.3" + is-callable "^1.1.4" + is-regex "^1.0.4" + object-keys "^1.0.12" + +es-to-primitive@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + es6-promise@^4.0.3: version "4.2.6" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.6.tgz#b685edd8258886365ea62b57d30de28fadcd974f" @@ -1714,6 +1752,13 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" +for-each@~0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -1802,6 +1847,11 @@ fstream@^1.0.0, fstream@^1.0.12: mkdirp ">=0.5 0" rimraf "2" +function-bind@^1.0.2, function-bind@^1.1.1, function-bind@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" @@ -1906,7 +1956,7 @@ glob-to-regexp@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" -glob@^7.0.3, glob@^7.1.1: +glob@^7.0.3, glob@^7.1.1, glob@~7.1.3: version "7.1.4" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" dependencies: @@ -2016,6 +2066,11 @@ has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= + has-unicode@^2.0.0, has-unicode@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -2051,6 +2106,13 @@ has-yarn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" +has@^1.0.1, has@^1.0.3, has@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + hook-std@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/hook-std/-/hook-std-2.0.0.tgz#ff9aafdebb6a989a354f729bb6445cf4a3a7077c" @@ -2255,6 +2317,11 @@ is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" +is-callable@^1.1.3, is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== + is-ci@^1.0.10: version "1.2.1" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" @@ -2285,6 +2352,11 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -2396,6 +2468,13 @@ is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= + dependencies: + has "^1.0.1" + is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" @@ -2408,6 +2487,13 @@ is-subset@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== + dependencies: + has-symbols "^1.0.0" + is-text-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" @@ -3023,7 +3109,7 @@ minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -minimist@^1.1.3, minimist@^1.2.0: +minimist@^1.1.3, minimist@^1.2.0, minimist@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" @@ -3449,6 +3535,16 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-inspect@~1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" + integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ== + +object-keys@^1.0.12: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" @@ -4128,6 +4224,13 @@ resolve@^1.10.0: dependencies: path-parse "^1.0.6" +resolve@~1.10.0: + version "1.10.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.1.tgz#664842ac960795bbe758221cdccda61fb64b5f18" + integrity sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA== + dependencies: + path-parse "^1.0.6" + responselike@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" @@ -4141,6 +4244,13 @@ restore-cursor@^2.0.0: onetime "^2.0.0" signal-exit "^3.0.2" +resumer@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" + integrity sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k= + dependencies: + through "~2.3.4" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -4538,6 +4648,15 @@ string-width@^3.0.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" +string.prototype.trim@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea" + integrity sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.0" + function-bind "^1.0.2" + string_decoder@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" @@ -4614,6 +4733,25 @@ table@^5.2.3: slice-ansi "^2.1.0" string-width "^3.0.0" +tape@^4.10.1: + version "4.10.1" + resolved "https://registry.yarnpkg.com/tape/-/tape-4.10.1.tgz#f73be60888dcb120f08b57f947af65a829506a5f" + integrity sha512-G0DywYV1jQeY3axeYnXUOt6ktnxS9OPJh97FGR3nrua8lhWi1zPflLxcAHavZ7Jf3qUfY7cxcVIVFa4mY2IY1w== + dependencies: + deep-equal "~1.0.1" + defined "~1.0.0" + for-each "~0.3.3" + function-bind "~1.1.1" + glob "~7.1.3" + has "~1.0.3" + inherits "~2.0.3" + minimist "~1.2.0" + object-inspect "~1.6.0" + resolve "~1.10.0" + resumer "~0.0.0" + string.prototype.trim "~1.1.2" + through "~2.3.8" + tar@^2.0.0: version "2.2.2" resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" @@ -4655,7 +4793,7 @@ through2@^2.0.0, through2@^2.0.2, through2@~2.0.0: readable-stream "~2.3.6" xtend "~4.0.1" -through@2, "through@>=2.2.7 <3", through@^2.3.6: +through@2, "through@>=2.2.7 <3", through@^2.3.6, through@~2.3.4, through@~2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"