diff --git a/generators/_init-hybrid/templates/_gitignore b/generators/_init-hybrid/templates/_gitignore index 4651a11f..0c09b7db 100644 --- a/generators/_init-hybrid/templates/_gitignore +++ b/generators/_init-hybrid/templates/_gitignore @@ -2,6 +2,7 @@ /.tscache /.idea /build/ +/dist/tsBuildInfoFile /lib/ *.egg-info/ *.py[cod] diff --git a/generators/_init-web/templates/_gitignore b/generators/_init-web/templates/_gitignore index 0de78b39..b0a18c9a 100644 --- a/generators/_init-web/templates/_gitignore +++ b/generators/_init-web/templates/_gitignore @@ -1,6 +1,7 @@ /.tscache /.idea /build/ +/dist/tsBuildInfoFile /lib/ node_modules/ /src/**/*.js diff --git a/generators/_init-web/templates/plain/tsconfig.json b/generators/_init-web/templates/plain/tsconfig.json index e7bc9b2d..e1cadbab 100644 --- a/generators/_init-web/templates/plain/tsconfig.json +++ b/generators/_init-web/templates/plain/tsconfig.json @@ -11,6 +11,8 @@ "declarationDir": "dist", "outDir": "dist", "experimentalDecorators": true, + "incremental": true, + "tsBuildInfoFile": "dist/tsBuildInfoFile", "noImplicitAny": false, "skipLibCheck": true, "esModuleInterop": false, diff --git a/generators/auto-update/AutoUpdateUtils.js b/generators/auto-update/AutoUpdateUtils.js new file mode 100644 index 00000000..451b12c9 --- /dev/null +++ b/generators/auto-update/AutoUpdateUtils.js @@ -0,0 +1,98 @@ +const fse = require('fs-extra'); +const path = require('path'); +const NpmUtils = require('../../utils/NpmUtils'); +const glob = require('glob').sync; +const semver = require('semver'); + +class AutoUpdateUtils { + static async autoUpdate(repo, pluginType, currentVersion, targetVersion, cwd, parent) { + const updatesDir = path.join(__dirname, 'updates'); + const excecuteUpdates = AutoUpdateUtils.getAvailableUpdates(updatesDir).filter((version) => semver.gtr(version, currentVersion)); + return parent.newListr( + [...excecuteUpdates.map((version) => { + return { + title: 'update ' + version, + options: { + bottomBar: Infinity, + persistentOutput: true + }, + task: async (ctx, task) => AutoUpdateUtils.updateLogic(version, targetVersion, pluginType, cwd, task, ctx) + }; + })], { exitOnError: true, concurrent: false, rendererOptions: { showErrorMessage: true, collapseErrors: false, collapse: false } } + ); + } + + /** + * Runs a single update and writes version to yo-rc.json if successful. + * @param {*} nextVersion + * @param {*} targetVersion + * @param {*} pluginType + * @param {*} cwd + * @param {*} task + * @param {*} ctx + */ + static async updateLogic(nextVersion, targetVersion, pluginType, cwd, task, ctx) { + const filePath = `./updates/update-${nextVersion}.js`; + const repo = path.basename(cwd); + const { update, description } = require(filePath); + + const log = (text) => task.output = text; + const currentVersion = AutoUpdateUtils.readConfig('localVersion', cwd) || NpmUtils.decrementVersion(targetVersion); + + if (currentVersion === nextVersion) { + throw new Error(`${repo}: Duplicate version tag "${currentVersion}"`); + } + return update(repo, pluginType, cwd, log) + .then(async () => { + AutoUpdateUtils.setConfig('localVersion', nextVersion, cwd); + return ctx[repo].descriptions.push(`#### ${currentVersion} to ${nextVersion}\n ${description}`); + }) + + .catch((e) => { + const msg = `${repo}: Update ${currentVersion} to ${nextVersion} failed with ${e.message}`; + e.message = msg; + throw e; + }); + } + + /** + * Reads and sorts all available updates by their versions. + * @param {string} updatesDir Absolute path to the updates dir. + * @returns {string[]} The versions in ascending order. + */ + static getAvailableUpdates(updatesDir) { + const files = glob('update-*.js', { + cwd: updatesDir + }) || []; + const versions = files.map((file) => file.match(/(?<=update-).*?(?=.js)/)[0]); + return semver.sort(versions); + } + + /** + * Sets a key in `.yo-rc.json`. + * @param {string} key Key name + * @param {string} value Value + * @param {string} cwd Path to the current repo + */ + static setConfig(key, value, cwd) { + const target = path.join(cwd + '/.yo-rc.json'); + const file = fse.readJSONSync(target); + file['generator-phovea'][key] = value; + fse.writeJSONSync(target, file, { spaces: 2 }); + } + + static readConfig(key, cwd) { + const file = fse.readJSONSync(path.join(cwd + '/.yo-rc.json')); + return file['generator-phovea'][key]; + } + + static getCredentials(org) { + org = org.toUpperCase(); + return { + username: process.env[`${org}_USER`], + token: process.env[`${org}_TOKEN`] + }; + } +} + +module.exports = AutoUpdateUtils; \ No newline at end of file diff --git a/generators/auto-update/GithubRestUtils.js b/generators/auto-update/GithubRestUtils.js new file mode 100644 index 00000000..91465d50 --- /dev/null +++ b/generators/auto-update/GithubRestUtils.js @@ -0,0 +1,42 @@ +const rp = require('request-promise'); +const _ = require('lodash'); + +class GithubRestUtils { + static commonPostOptions() { + return { + method: 'POST', + headers: { + 'User-Agent': 'request' + }, + body: { + accept: 'application/vnd.github.v3+json', + }, + json: true + }; + } + static createPullRequest(baseName, data = {}, {username, token}) { + const config = _.merge({}, + GithubRestUtils.commonPostOptions(), + { + uri: `https://${username}:${token}@api.github.com/repos/${baseName}/pulls`, + body: { + ...data + }, + }); + return rp(config); + } + + static setAssignees(baseName, prNumber, assignees, {username, token}) { + const config = _.merge({}, + GithubRestUtils.commonPostOptions(), + { + uri: `https://${username}:${token}@api.github.com/repos/${baseName}/issues/${prNumber}/assignees`, + body: { + assignees + }, + }); + return rp(config); + } +} + +module.exports = GithubRestUtils; \ No newline at end of file diff --git a/generators/auto-update/index.js b/generators/auto-update/index.js new file mode 100644 index 00000000..c70e7700 --- /dev/null +++ b/generators/auto-update/index.js @@ -0,0 +1,260 @@ +'use strict'; +const Base = require('yeoman-generator'); +const fse = require('fs-extra'); +const AutoUpdateUtils = require('./AutoUpdateUtils'); +const path = require('path'); +const parse = require('csv-parse/lib/sync'); +const SpawnUtils = require('../../utils/SpawnUtils'); +const RepoUtils = require('../../utils/RepoUtils'); +const GithubRestUtils = require('./GithubRestUtils'); +const { decrementVersion } = require('../../utils/NpmUtils'); +const { Listr } = require('listr2'); +const tmp = require('tmp'); +const { chunk } = require('lodash'); +const chalk = require('chalk'); + +class Generator extends Base { + constructor(args, options) { + super(args, Object.assign(options, { + skipLocalCache: true // prevents store prompts from being saved in the local `.yo-rc.json` + })); + this.option('test-run', { + default: false, + required: false, + type: Boolean + }); + } + + initializing() { + this.composeWith(['phovea:_check-own-version', 'phovea:check-node-version']); + } + + async prompting() { + return this.prompt([ + { + type: 'input', + name: 'knownReposFile', + message: 'Path to the known repos file', + default: '/workspaces/releases/repositories.csv', + required: true, + store: true, + when: this.args.length === 0, + validate: (d) => d.trim().length > 0 + } + ]).then(({ knownReposFile }) => { + this.knownRepos = this._readKnownReposFile(knownReposFile); + this.generatorVersion = require('../../package.json').version.replace('-SNAPSHOT', ''); + }); + } + + _readKnownReposFile(file) { + const repoName = 'Repository name'; + const repoLink = 'Repository link'; + const owner = 'Owner'; + const type = 'Type'; + + if (!fse.existsSync(file)) { + this.env.error('Given file cannot be read: ' + file); + } + const records = parse(fse.readFileSync(file), { + columns: true, + skip_empty_lines: true + }); + const parsedRecords = records + .filter((r) => r[repoName] && r[repoName] !== 'lineupjs' && r[repoLink] && r[owner] && r[type] && r[type] !== '-'); + return Object.assign({}, ...parsedRecords.map((item) => ( + { + [item[repoName]]: { + org: RepoUtils.getOrganization(item[repoLink]), + ...item + } + }))); + } + + _taskWraper(chunk) { + return new Listr( + [ + ...chunk.map((repo) => { + const { org } = this.knownRepos[repo]; + const { token } = AutoUpdateUtils.getCredentials(org); + const repoUrl = `https://${token}@github.com/${org}/${repo}.git`; + const repoDir = path.join(this.cwd, repo); + const baseName = `${org}/${repo}`; + const enablePredicate = (ctx) => !this.options['test-run'] && ctx[repo] && !ctx[repo].skipNext; + return { + title: chalk.bold(repo), + task: async (ctx, parent) => { + return parent.newListr([ + { + title: 'Clone repo ' + repo, + options: { + persistentOutput: false, + bottomBar: Infinity, + }, + task: async () => await SpawnUtils.spawnPromise('git', 'clone -b develop ' + repoUrl, this.cwd) + }, + { + title: 'Check if yo-rc.json exists', + options: { + persistentOutput: false, + }, + task: async (ctx) => { + const [currentVersion = decrementVersion(this.generatorVersion), type] = [ + AutoUpdateUtils.readConfig('localVersion', repoDir), + AutoUpdateUtils.readConfig('type', repoDir) + ]; + ctx[repo] = {}; + ctx[repo].currentVersion = currentVersion; + ctx[repo].type = type; + } + }, + { + title: 'Checkout working branch', + options: { + persistentOutput: false, + }, + task: async (ctx, task) => { + const branch = `generator_update/${ctx[repo].currentVersion}_to_${this.generatorVersion}`; + ctx[repo].branch = branch; + task.title = 'Checkout branch ' + branch; + await SpawnUtils.spawnOrAbort('git', ['checkout', '-b', branch], repoDir, this.options.verbose); + } + }, + { + title: 'Run updates', + task: async (ctx, task) => { + ctx[repo].descriptions = []; + return AutoUpdateUtils.autoUpdate(repo, ctx[repo].type, ctx[repo].currentVersion, this.generatorVersion, repoDir, task); + } + }, + { + task: (ctx, task) => { + ctx[repo].fileChanges = SpawnUtils.spawnWithOutput('git', ['status', '--porcelain'], repoDir); + if (!ctx[repo].fileChanges) { + task.title = 'No file changes detected, aborting '; + ctx[repo].skipNext = true; + task.skip(); + parent.skip(); + } + } + }, + { + title: 'Commit changes', + enabled: (ctx) => enablePredicate(ctx), + task: async (ctx) => { + ctx[repo].title = `Generator updates from ${ctx[repo].currentVersion} to ${this.generatorVersion}`; + await SpawnUtils.spawnPromise('git', ['add', '.'], repoDir); + await SpawnUtils.spawnPromise('git', ['commit', '-am', ctx[repo].title], repoDir); + } + }, + { + title: 'Push changes', + enabled: (ctx) => enablePredicate(ctx), + task: async (ctx) => { + await SpawnUtils.spawnPromise('git', ['push', repoUrl, ctx[repo].branch], repoDir); + } + }, + { + title: 'Draft pull request', + enabled: (ctx) => enablePredicate(ctx), + task: async (ctx) => { + const { title, branch, descriptions } = ctx[repo]; + const data = { + title, + head: branch, + body: descriptions.join('\n'), + base: 'develop' + }; + const credentials = AutoUpdateUtils.chooseCredentials(org); + const { number } = await GithubRestUtils.createPullRequest(baseName, data, credentials); + const assignees = [SpawnUtils.spawnWithOutput('git', ['config', 'user.name'], repoDir)]; + await GithubRestUtils.setAssignees(baseName, number, assignees, credentials); + }, + } + ], { concurrent: false, rendererOptions: { collapseErrors: false, showErrorMessage: true, collapse: false } }); + } + }; + }), + ], { concurrent: true, exitOnError: false, rendererOptions: { showErrorMessage: true, collapseErrors: false } }); + + } + + /** + * Checks if the required environment variables are set in the system. + * For each organization the `${org}_TOKEN` and `${org}_USER` are required. + * @param {Set} orgs + */ + _checkEnvironmentVars(orgs) { + let missingEnvs = []; + orgs.forEach((org) => { + org = org.toUpperCase(); + const { token, username } = AutoUpdateUtils.getCredentials(org); + if (!token) { + missingEnvs.push(`${org}_TOKEN`); + } + if (!username) { + missingEnvs.push(`${org}_USER`); + } + }); + + if (missingEnvs.length) { + this.env.error(`${chalk.red('Missing required environment variable(s):')}\n${missingEnvs.join('\n')}`); + } + } + + async writing() { + this.cwd = tmp.dirSync({ unsafeCleanup: true }).name; + const repos = Object.keys(this.knownRepos).slice(0, 10); + const orgs = new Set(repos.map((r) => this.knownRepos[r].org)); + this._checkEnvironmentVars(orgs); + + // seperate repos in chunks to make logging more managable + const chunkSize = 8; + const [...chunks] = chunk(repos, chunkSize); + const groups = chunks.map((chunk) => this._taskWraper(chunk)); + + await groups.reduce(async (updateChain, group) => { + return updateChain + .then(() => group.run()); + }, Promise.resolve([])); + + this.errorLog = this._composeErrorLog(groups); + if (this.options['test-run']) { + await this._reviewChanges(); + } + } + + /** + * Formats all silent error messages + * @param {Listr[]} taskGroups + */ + _composeErrorLog(taskGroups) { + const errorGroups = taskGroups.filter((taskGroup) => taskGroup.err[0]); + if (errorGroups.length) { + return errorGroups + .map((group) => group.err[0].errors.map(({ stack }) => stack).join('\n')) + .join('\n'); + } + } + + _reviewChanges() { + return this.prompt([ + { + type: 'confirm', + name: 'review', + message: 'Review changes in vscode?', + }]).then(({ review }) => { + if (review) { + SpawnUtils.spawnSync('code', ['.'], this.cwd); + } + }); + } + + end() { + if (this.errorLog) { + this.fs.write(this.destinationPath('error.log'), this.errorLog); + } + } +} + +module.exports = Generator; diff --git a/generators/auto-update/templates/update-template.js b/generators/auto-update/templates/update-template.js new file mode 100644 index 00000000..52672c8f --- /dev/null +++ b/generators/auto-update/templates/update-template.js @@ -0,0 +1,31 @@ +'use strict'; + +const fse = require('fs-extra'); + + + +/** + * Outputs text to the console. + * @typedef {function(string): void} Log + */ + +/** + * Update implementation. + * @param {string} repo Name of the current repo. + * @param {string} pluginType Type of plugin i.e., `lib-slib`. + * @param {string} cwd The path to the current cloned repo files. + * @param {Log} log Logging function, `console.log` will not work. + * @example log('Message'). + * @returns {Promise} + */ +async function update(repo, pluginType, cwd, log) { + // use asynchronous functions to write to the filesystem + // i.e., `await fse.promises.writeFile(path)` instead of fse.writeJSONSync +} + + +module.exports = { + update, + /** Description of what the update does. Will be used in PR body.*/ + description: 'Add description' +}; \ No newline at end of file diff --git a/generators/auto-update/updates/update-6.0.0.js b/generators/auto-update/updates/update-6.0.0.js new file mode 100644 index 00000000..cfe0da77 --- /dev/null +++ b/generators/auto-update/updates/update-6.0.0.js @@ -0,0 +1,48 @@ +'use strict'; + +const fse = require('fs-extra'); +const { merge } = require('lodash'); +const path = require('path'); +const { lib, plugin } = require('../../../utils/types'); + + + +/** + * Outputs text to the console. + * @typedef {function(string): void} Log + */ + +/** + * Update 6.0.0 implementation. + * @param {string} repo Name of the current repo. + * @param {string} pluginType Type of plugin i.e., `lib-slib`. + * @param {string} cwd The path to the current cloned repo files. + * @param {Log} log Logging function, `console.log` will not work. + * @returns {Promise} + */ +async function update(repo, pluginType, cwd, log) { + const type = { type: pluginType }; + const updateCondition = lib.isTypeHybrid(type) || lib.isTypeWeb(type) || plugin.isTypeHybrid(type) || plugin.isTypeWeb(type); + if (!updateCondition) { + return; + } + const gitignore = (await fse.promises.readFile(path.join(cwd, '.gitignore'))).toString(); + const newGitignore = gitignore.replace('/build/', '/build/\n/dist/tsBuildInfoFile'); + + await fse.promises.writeFile(path.join(cwd, '.gitignore'), newGitignore); + const tsConfig = await fse.readJson(path.join(cwd, 'tsconfig.json')); + merge(tsConfig, { + compilerOptions: { + incremental: true, + tsBuildInfoFile: 'dist/tsBuildInfoFile' + } + }); + await fse.writeJSON(path.join(cwd, 'tsconfig.json'), tsConfig, { spaces: 2 }); +} + + +module.exports = { + update, + /** Description of what the update does. Will be used in PR body. */ + description: 'Add `--incremental` build flag for ts compiler ' +}; \ No newline at end of file diff --git a/generators/init-app-slib/templates/package.tmpl.json b/generators/init-app-slib/templates/package.tmpl.json index ce483dce..ba6e75a8 100644 --- a/generators/init-app-slib/templates/package.tmpl.json +++ b/generators/init-app-slib/templates/package.tmpl.json @@ -6,7 +6,7 @@ "copy": "npm run copy-assets && npm run copy-styles && npm run copy-app-assets", "copy-assets": "if [ -d src/assets ]; then shx --verbose cp -R src/assets/. dist/assets/; fi", "copy-styles": "if [ -d src/scss ]; then shx --verbose cp -R src/scss/. dist/scss/; fi", - "copy-app-assets": "shx --verbose cp src/.txt dist/ | true && shx --verbose cp src/.html dist/ | true && shx --verbose cp src/*.ejs dist/ | true", + "copy-app-assets": "shx --verbose cp src/*.txt dist/ | true && shx --verbose cp src/*.html dist/ | true && shx --verbose cp src/*.ejs dist/ | true", "dist": "mkdir lib && cd dist && tar cvzf ../lib/<%-name.toLowerCase()%>.tar.gz *", "predist": "npm run build", "predocker": "npm run build", diff --git a/generators/init-app/templates/package.tmpl.json b/generators/init-app/templates/package.tmpl.json index ce483dce..ba6e75a8 100644 --- a/generators/init-app/templates/package.tmpl.json +++ b/generators/init-app/templates/package.tmpl.json @@ -6,7 +6,7 @@ "copy": "npm run copy-assets && npm run copy-styles && npm run copy-app-assets", "copy-assets": "if [ -d src/assets ]; then shx --verbose cp -R src/assets/. dist/assets/; fi", "copy-styles": "if [ -d src/scss ]; then shx --verbose cp -R src/scss/. dist/scss/; fi", - "copy-app-assets": "shx --verbose cp src/.txt dist/ | true && shx --verbose cp src/.html dist/ | true && shx --verbose cp src/*.ejs dist/ | true", + "copy-app-assets": "shx --verbose cp src/*.txt dist/ | true && shx --verbose cp src/*.html dist/ | true && shx --verbose cp src/*.ejs dist/ | true", "dist": "mkdir lib && cd dist && tar cvzf ../lib/<%-name.toLowerCase()%>.tar.gz *", "predist": "npm run build", "predocker": "npm run build", diff --git a/generators/setup-workspace/index.js b/generators/setup-workspace/index.js index f43e76c8..86623e9a 100644 --- a/generators/setup-workspace/index.js +++ b/generators/setup-workspace/index.js @@ -104,8 +104,8 @@ class Generator extends Base { fs.unlinkSync(this.cwd + '/.yo-rc.json'); } - fs.rmdirSync(this.cwd + '/.git', { recursive: true }); // TODO look into git submodules - fs.renameSync(this.cwd + '/package.json', this.cwd + '/package_product.json'); + fs.rmdirSync(this.cwd + '/.git', { recursive: true }); + fs.renameSync(this.cwd + '/package.json', this.cwd + '/package_product.json'); } /** diff --git a/generators/workspace/templates/package.tmpl.json b/generators/workspace/templates/package.tmpl.json index ec76a9ea..f9a6e434 100644 --- a/generators/workspace/templates/package.tmpl.json +++ b/generators/workspace/templates/package.tmpl.json @@ -35,7 +35,7 @@ "devDependencies": { "clean-webpack-plugin": "~3.0.0", "copy-webpack-plugin": "~6.3.2", - "css-loader": "~4.3.0", + "css-loader": "~3.6.0", "css-minimizer-webpack-plugin": "^1.1.5", "dotenv-webpack": "^5.0.0", "expose-loader": "~1.0.3", @@ -46,7 +46,7 @@ "ifdef-loader": "~2.1.5", "imports-loader": "~1.2.0", "mini-css-extract-plugin": "~1.3.2", - "node-sass": "~4.13.1", + "node-sass": "~4.13.1", "npm-run-all": "~4.1.5", "npm-watch": "^0.7.0", "raw-loader": "~4.0.2", diff --git a/generators/workspace/templates/plain_initialize_once/config/webpack.dev.js b/generators/workspace/templates/plain_initialize_once/config/webpack.dev.js index d59f3f10..6913539f 100644 --- a/generators/workspace/templates/plain_initialize_once/config/webpack.dev.js +++ b/generators/workspace/templates/plain_initialize_once/config/webpack.dev.js @@ -1,6 +1,7 @@ const {CleanWebpackPlugin} = require('clean-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); +const Dotenv = require('dotenv-webpack'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); //for debugging issues //const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; @@ -272,6 +273,14 @@ const config = { 'process.env.__APP_CONTEXT__': JSON.stringify('/'), 'process.env.__DEBUG__': JSON.stringify(isDev) }), + new Dotenv({ + path: base + '/.env', // load this now instead of the ones in '.env' + safe: false, // load '.env.example' to verify the '.env' variables are all set. Can also be a string to a different file. + allowEmptyValues: true, // allow empty variables (e.g. `FOO=`) (treat it as empty string, rather than missing) + systemvars: true, // load all the predefined 'process.env' variables which will trump anything local per dotenv specs. + silent: true, // hide any errors + defaults: false // load '.env.defaults' as the default values if empty. + }), new CopyWebpackPlugin({ patterns: [ { diff --git a/generators/workspace/templates/plain_initialize_once/config/webpack.prod.js b/generators/workspace/templates/plain_initialize_once/config/webpack.prod.js index 8b8e4ccd..f22de838 100644 --- a/generators/workspace/templates/plain_initialize_once/config/webpack.prod.js +++ b/generators/workspace/templates/plain_initialize_once/config/webpack.prod.js @@ -1,6 +1,7 @@ const {CleanWebpackPlugin} = require('clean-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); +const Dotenv = require('dotenv-webpack'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); //for debugging issues @@ -231,6 +232,14 @@ const config = { 'process.env.__APP_CONTEXT__': JSON.stringify('/'), 'process.env.__DEBUG__': JSON.stringify(isDev) }), + new Dotenv({ + path: base + '/.env', // load this now instead of the ones in '.env' + safe: false, // load '.env.example' to verify the '.env' variables are all set. Can also be a string to a different file. + allowEmptyValues: true, // allow empty variables (e.g. `FOO=`) (treat it as empty string, rather than missing) + systemvars: true, // load all the predefined 'process.env' variables which will trump anything local per dotenv specs. + silent: true, // hide any errors + defaults: false // load '.env.defaults' as the default values if empty. + }), new CopyWebpackPlugin({ patterns: [ { diff --git a/package-lock.json b/package-lock.json index dddaa96b..e418ac2f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,19 +13,19 @@ } }, "@babel/core": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.1.tgz", - "integrity": "sha512-XqF7F6FWQdKGGWAzGELL+aCO1p+lRY5Tj5/tbT3St1G8NaH70jhhDIKknIZaDans0OQBG5wRAldROLHSt44BgQ==", + "version": "7.11.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.6.tgz", + "integrity": "sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.0", + "@babel/generator": "^7.11.6", "@babel/helper-module-transforms": "^7.11.0", "@babel/helpers": "^7.10.4", - "@babel/parser": "^7.11.1", + "@babel/parser": "^7.11.5", "@babel/template": "^7.10.4", - "@babel/traverse": "^7.11.0", - "@babel/types": "^7.11.0", + "@babel/traverse": "^7.11.5", + "@babel/types": "^7.11.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", @@ -37,12 +37,12 @@ }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "semver": { @@ -60,12 +60,12 @@ } }, "@babel/generator": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz", - "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==", + "version": "7.11.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.6.tgz", + "integrity": "sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA==", "dev": true, "requires": { - "@babel/types": "^7.11.0", + "@babel/types": "^7.11.5", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -250,9 +250,9 @@ } }, "@babel/parser": { - "version": "7.11.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz", - "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz", + "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==", "dev": true }, "@babel/plugin-syntax-object-rest-spread": { @@ -276,29 +276,29 @@ } }, "@babel/traverse": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", - "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.5.tgz", + "integrity": "sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.0", + "@babel/generator": "^7.11.5", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.11.0", - "@babel/types": "^7.11.0", + "@babel/parser": "^7.11.5", + "@babel/types": "^7.11.5", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "globals": { @@ -310,9 +310,9 @@ } }, "@babel/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", - "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -844,9 +844,9 @@ } }, "@types/babel__core": { - "version": "7.1.9", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", - "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", + "version": "7.1.10", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.10.tgz", + "integrity": "sha512-x8OM8XzITIMyiwl5Vmo2B1cR1S1Ipkyv4mdlbJjMa1lmuKvKY9FrBbEANIaMlnWn5Rf7uO+rC/VgYabNkE17Hw==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -857,18 +857,18 @@ } }, "@types/babel__generator": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", - "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", + "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", "dev": true, "requires": { "@babel/types": "^7.0.0" } }, "@types/babel__template": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", - "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.3.tgz", + "integrity": "sha512-uCoznIPDmnickEi6D0v11SBpW0OuVqHJCa7syXqQHy5uktSCreIlt0iglsCnmvz8yCb38hGcWeseA8cWJSwv5Q==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -876,9 +876,9 @@ } }, "@types/babel__traverse": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.13.tgz", - "integrity": "sha512-i+zS7t6/s9cdQvbqKDARrcbrPvtJGlbYsMkazo03nTAK3RX9FNrLllXys22uiTGJapPOTZTQ35nHh4ISph4SLQ==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.15.tgz", + "integrity": "sha512-Pzh9O3sTK8V6I1olsXpCfj2k/ygO2q1X0vhhnDrEQyYLHZesWz+zMZMVcwXLCYf0U36EtmyYaFGPfXlTtDHe3A==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -899,9 +899,9 @@ } }, "@types/inquirer": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-7.3.0.tgz", - "integrity": "sha512-wcPs5jTrZYQBzzPlvUEzBcptzO4We2sijSvkBq8oAKRMJoH8PvrmP6QQnxLB5RScNUmRfujxA+ngxD4gk4xe7Q==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-7.3.1.tgz", + "integrity": "sha512-osD38QVIfcdgsPCT0V3lD7eH0OFurX71Jft18bZrsVQWVRt6TuxRzlr0GJLrxoHZR2V5ph7/qP8se/dcnI7o0g==", "requires": { "@types/through": "*", "rxjs": "^6.4.0" @@ -938,9 +938,9 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "14.6.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.6.0.tgz", - "integrity": "sha512-mikldZQitV94akrc4sCcSjtJfsTKt4p+e/s0AGscVA6XArQ9kFclP+ZiYUMnq987rc6QlYxXv/EivqlfSLxpKA==" + "version": "14.11.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.2.tgz", + "integrity": "sha512-jiE3QIxJ8JLNcb1Ps6rDbysDhN4xa8DJJvuC9prr6w+1tIh+QAbYyNF3tyiZNLDBIuBCf4KEcV2UvQm/V60xfA==" }, "@types/normalize-package-data": { "version": "2.4.0", @@ -962,9 +962,9 @@ } }, "@types/yargs": { - "version": "13.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.10.tgz", - "integrity": "sha512-MU10TSgzNABgdzKvQVW1nuuT+sgBMWeXNc3XOs5YXV5SDAK+PPja2eUuBNB9iqElu03xyEDqlnGw0jgl4nbqGQ==", + "version": "13.0.11", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.11.tgz", + "integrity": "sha512-NRqD6T4gktUrDi1o1wLH3EKC1o2caCr7/wR87ODcbVITQF106OM3sFN92ysZ++wqelOd1CTzatnOBRDYYG6wGQ==", "dev": true, "requires": { "@types/yargs-parser": "*" @@ -995,9 +995,9 @@ } }, "abab": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.4.tgz", - "integrity": "sha512-Eu9ELJWCz/c1e9gTiCY+FceWxcqzjYEbqMgtndnuSqZSUCOL73TWNK2mHfIj4Cw2E/ongOp+JISVNCmovt2KYQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", "dev": true }, "acorn": { @@ -1025,9 +1025,9 @@ } }, "acorn-jsx": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", - "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", "dev": true }, "acorn-walk": { @@ -1036,10 +1036,19 @@ "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", "dev": true }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, "ajv": { - "version": "6.12.4", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz", - "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==", + "version": "6.12.5", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", + "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1642,6 +1651,11 @@ "file-uri-to-path": "1.0.0" } }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, "boxen": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", @@ -1855,6 +1869,35 @@ } } }, + "child-process-promise": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/child-process-promise/-/child-process-promise-2.2.1.tgz", + "integrity": "sha1-RzChHvYQ+tRQuPIjx50x172tgHQ=", + "requires": { + "cross-spawn": "^4.0.2", + "node-version": "^1.0.0", + "promise-polyfill": "^6.0.1" + }, + "dependencies": { + "cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "chokidar": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", @@ -1901,10 +1944,15 @@ } } }, - "cli-boxes": { + "clean-stack": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", - "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==" + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" }, "cli-cursor": { "version": "3.1.0", @@ -1922,6 +1970,32 @@ "colors": "1.0.3" } }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + } + } + }, "cli-width": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", @@ -2203,6 +2277,11 @@ "cssom": "0.3.x" } }, + "csv-parse": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.12.0.tgz", + "integrity": "sha512-wPQl3H79vWLPI8cgKFcQXl0NBgYYEqVnT1i6/So7OjMpsI540oD7p93r3w6fDSyPvwkTepG05F69/7AViX2lXg==" + }, "d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", @@ -2422,9 +2501,9 @@ } }, "dot-prop": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", - "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "requires": { "is-obj": "^2.0.0" } @@ -2531,20 +2610,21 @@ } }, "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", + "object.assign": "^4.1.1", "string.prototype.trimend": "^1.0.1", "string.prototype.trimstart": "^1.0.1" } @@ -2734,12 +2814,12 @@ } }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "glob-parent": { @@ -2841,12 +2921,12 @@ } }, "eslint-scope": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", - "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { - "esrecurse": "^4.1.0", + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, @@ -2904,12 +2984,20 @@ } }, "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { - "estraverse": "^4.1.0" + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, "estraverse": { @@ -3064,9 +3152,9 @@ }, "dependencies": { "type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", - "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", + "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==", "dev": true } } @@ -3103,6 +3191,16 @@ "chardet": "^0.7.0", "iconv-lite": "^0.4.24", "tmp": "^0.0.33" + }, + "dependencies": { + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + } } }, "extglob": { @@ -4232,6 +4330,11 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -4369,9 +4472,9 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", "dev": true }, "is-ci": { @@ -4472,6 +4575,12 @@ "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", "dev": true }, + "is-negative-zero": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", + "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", + "dev": true + }, "is-npm": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", @@ -4734,12 +4843,12 @@ }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "make-dir": { @@ -6431,7 +6540,13 @@ "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "json-schema": { "version": "0.2.3", @@ -6494,9 +6609,9 @@ "dev": true }, "just-extend": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.0.tgz", - "integrity": "sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.1.tgz", + "integrity": "sha512-aWgeGFW67BP3e5181Ep1Fv2v8z//iBJfrvyTnq8wG86vEESwmonn1zPBJ0VfmT9CJq2FIT0VsETtrNFm2a+SHA==", "dev": true }, "keyv": { @@ -6622,6 +6737,32 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" }, + "listr2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.2.2.tgz", + "integrity": "sha512-AajqcZEUikF2ioph6PfH3dIuxJclhr3i3kHgTOP0xeXdWQohrvJAAmqVcV43/GI987HFY/vzT73jYXoa4esDHg==", + "requires": { + "chalk": "^4.1.0", + "cli-truncate": "^2.1.0", + "figures": "^3.2.0", + "indent-string": "^4.0.0", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rxjs": "^6.6.3", + "through": "^2.3.8" + }, + "dependencies": { + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", @@ -6737,6 +6878,44 @@ } } }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -6751,6 +6930,15 @@ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -7007,9 +7195,9 @@ } }, "moment": { - "version": "2.27.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz", - "integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==" + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.0.tgz", + "integrity": "sha512-z6IJ5HXYiuxvFTI6eiQ9dm77uE0gyy1yXNApVHqTcnIKfY9tIwEjlzsZ6u1LQXvVgKeTnv9Xm7NDvJ7lso3MtA==" }, "ms": { "version": "2.1.2", @@ -7154,6 +7342,11 @@ } } }, + "node-version": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/node-version/-/node-version-1.2.0.tgz", + "integrity": "sha512-ma6oU4Sk0qOoKEAymVoTvk8EdXEobdS7m/mAGhDJ8Rouugho48crHBORAmy5BoOcv8wraPM6xumapQp5hl4iIQ==" + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -7305,15 +7498,15 @@ } }, "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", + "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.0", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" } }, "object.defaults": { @@ -7336,6 +7529,27 @@ "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } } }, "object.map": { @@ -7383,9 +7597,9 @@ } }, "open": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/open/-/open-7.1.0.tgz", - "integrity": "sha512-lLPI5KgOwEYCDKXf4np7y1PBEkj7HYIyP2DY8mVDRnx0VIIu6bNrRB0R66TuO7Mack6EnTNLm4uvcl1UoklTpA==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/open/-/open-7.3.0.tgz", + "integrity": "sha512-mgLwQIx2F/ye9SmbrUkurZCnkoXyXyu9EbHtJZrICjVAJfyMArdHp3KkixGdZx1ZHFPNIwl0DDM1dFFqXbTLZw==", "requires": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" @@ -7467,6 +7681,14 @@ "p-limit": "^2.0.0" } }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "requires": { + "aggregate-error": "^3.0.0" + } + }, "p-reduce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", @@ -7624,13 +7846,13 @@ } }, "parse-json": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.1.tgz", - "integrity": "sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, @@ -7799,9 +8021,9 @@ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" }, "pretty-bytes": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz", - "integrity": "sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==" + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.4.1.tgz", + "integrity": "sha512-s1Iam6Gwz3JI5Hweaz4GoCD1WUNUIyzePFy5+Js2hjwGVt2Z79wNN+ZKOZ2vB6C+Xs6njyB84Z1IthQg8d9LxA==" }, "pretty-format": { "version": "24.9.0", @@ -7864,6 +8086,11 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "promise-polyfill": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz", + "integrity": "sha1-36lpQ+qcEh/KTem1hoyznTRy4Fc=" + }, "prompts": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", @@ -7874,6 +8101,11 @@ "sisteransi": "^1.0.4" } }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -8170,11 +8402,21 @@ "uuid": "^3.3.2" } }, + "request-promise": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz", + "integrity": "sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==", + "requires": { + "bluebird": "^3.5.0", + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, "request-promise-core": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, "requires": { "lodash": "^4.17.19" } @@ -8283,7 +8525,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -8305,9 +8546,9 @@ "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==" }, "rxjs": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", - "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", + "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", "requires": { "tslib": "^1.9.0" } @@ -8570,9 +8811,9 @@ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, "sinon": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.0.3.tgz", - "integrity": "sha512-IKo9MIM111+smz9JGwLmw5U1075n1YXeAq8YeSFlndCLhAL5KGn6bLgu7b/4AYHTV/LcEMcRm2wU2YiL55/6Pg==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.1.0.tgz", + "integrity": "sha512-9zQShgaeylYH6qtsnNXlTvv0FGTTckuDfHBi+qhgj5PvW2r2WslHZpgc3uy3e/ZAoPkqaOASPi+juU6EdYRYxA==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.2", @@ -8831,9 +9072,9 @@ } }, "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz", + "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==" }, "split-string": { "version": "3.1.0", @@ -8898,8 +9139,7 @@ "stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "dev": true + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" }, "stream-exhaust": { "version": "1.0.2", @@ -8968,6 +9208,27 @@ "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } } }, "string.prototype.trimstart": { @@ -8978,6 +9239,27 @@ "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } } }, "string_decoder": { @@ -9045,9 +9327,9 @@ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } @@ -9258,11 +9540,11 @@ "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" }, "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", "requires": { - "os-tmpdir": "~1.0.2" + "rimraf": "^3.0.0" } }, "tmpl": { @@ -9551,9 +9833,9 @@ "dev": true }, "update-notifier": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.1.tgz", - "integrity": "sha512-9y+Kds0+LoLG6yN802wVXoIfxYEwh3FlZwzMwpCZp62S2i1/Jzeqb9Eeeju3NSHccGGasfGlK5/vEHbAifYRDg==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", "requires": { "boxen": "^4.2.0", "chalk": "^3.0.0", @@ -9584,9 +9866,9 @@ } }, "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", "requires": { "punycode": "^2.1.0" } @@ -9629,6 +9911,27 @@ "es-abstract": "^1.17.2", "has-symbols": "^1.0.1", "object.getownpropertydescriptors": "^2.1.0" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } } }, "uuid": { @@ -9685,9 +9988,9 @@ } }, "vinyl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", - "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", + "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", "requires": { "clone": "^2.1.1", "clone-buffer": "^1.0.0", @@ -9977,6 +10280,11 @@ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", "dev": true }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, "yamljs": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", @@ -10217,9 +10525,9 @@ } }, "yeoman-generator": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/yeoman-generator/-/yeoman-generator-4.11.0.tgz", - "integrity": "sha512-++t6t2Z6HjL5F1/UM7+uNvGknKmQdF8tstJx8WKzsUSEpB+19kLVtapSfQIh9uWqm0L59fLWDzUui//WXoynPw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/yeoman-generator/-/yeoman-generator-4.12.0.tgz", + "integrity": "sha512-lozwklVQHwUXMM1o8BgxEB8F5BB7vkHW4pjAo1Zt5sJ7FOlWhd6DJ4ZxJ2OK0w+gNYkY/ocPMkUV7DTz/uqEEg==", "requires": { "async": "^2.6.2", "chalk": "^2.4.2", @@ -10301,11 +10609,11 @@ } }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "diff": { @@ -10442,99 +10750,16 @@ } }, "yeoman-test": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/yeoman-test/-/yeoman-test-2.7.0.tgz", - "integrity": "sha512-NNH3XYaeiYO9gWdQ2B02kZuLZnbYZhGqcqrUjyS5VW/r1xOuJ9t6FIzw7uE35/yCx+U9R0kzeTbxkQ6Iwsv3DA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/yeoman-test/-/yeoman-test-3.0.0.tgz", + "integrity": "sha512-L8+m6u3enXxL2czVAN/+M2oCuVgDuNqAlegY4+RcO4xD8Fd9/9hdMfoMd83YtVXNUBJvvMdYBRSYj4kd7nsp3A==", "dev": true, "requires": { - "inquirer": "^7.1.0", - "lodash": "^4.17.15", - "mem-fs": "^1.2.0", - "mem-fs-editor": "^7.0.1", - "mkdirp": "^1.0.3", - "rimraf": "^3.0.2", - "sinon": "^9.0.1", - "yeoman-environment": "^2.10.0", - "yeoman-generator": "^4.10.0" - }, - "dependencies": { - "dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "requires": { - "path-type": "^3.0.0" - } - }, - "ejs": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.5.tgz", - "integrity": "sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w==", - "dev": true, - "requires": { - "jake": "^10.6.1" - } - }, - "globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "mem-fs-editor": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/mem-fs-editor/-/mem-fs-editor-7.0.1.tgz", - "integrity": "sha512-eD8r4/d2ayp9HHIgBPHB6Ds0ggA8F9cf9HxcNtbqrwqJXfIDrOSMG5K4fV3+Ib3B+HIdrWqkeDDDvrO7i9EbvQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "deep-extend": "^0.6.0", - "ejs": "^3.0.1", - "glob": "^7.1.4", - "globby": "^9.2.0", - "isbinaryfile": "^4.0.0", - "mkdirp": "^1.0.0", - "multimatch": "^4.0.0", - "rimraf": "^3.0.0", - "through2": "^3.0.1", - "vinyl": "^2.2.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - } + "inquirer": "^7.3.3", + "lodash": "^4.17.19", + "sinon": "^9.0.2", + "yeoman-environment": "^2.10.3", + "yeoman-generator": "^4.11.0" } } } diff --git a/package.json b/package.json index e8014f93..4baaa474 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,8 @@ "@types/yeoman-generator": "^3.1.4", "chalk": "^3.0.0", "check-node-version": "^4.0.2", + "child-process-promise": "^2.2.1", + "csv-parse": "^4.11.1", "escodegen": "^1.14.1", "esprima": "^4.0.1", "esprima-walk": "0.1.0", @@ -44,11 +46,14 @@ "glob": "^7.1.6", "inquirer": "^7.0.5", "inquirer-npm-name": "^3.0.0", + "listr2": "^3.2.2", "lodash": "^4.17.15", "open": "^7.0.2", "parse-author": "^2.0.0", + "request-promise": "^4.2.6", "semver": "^7.1.3", "semver-intersect": "^1.4.0", + "tmp": "^0.2.1", "update-notifier": "^4.1.0", "yamljs": "^0.3.0", "yeoman-environment": "^2.8.0", @@ -66,7 +71,7 @@ "gulp-plumber": "^1.2.1", "jest-cli": "^24.9.0", "yeoman-assert": "^3.1.1", - "yeoman-test": "^2.2.0", + "yeoman-test": "^3.0.0", "rimraf": "^3.0.2" }, "eslintConfig": { diff --git a/test/AutoUpdateUtils.test.js b/test/AutoUpdateUtils.test.js new file mode 100644 index 00000000..ad2476b0 --- /dev/null +++ b/test/AutoUpdateUtils.test.js @@ -0,0 +1,12 @@ +'use strict'; + +const AutoUpdateUtils = require("../generators/auto-update/AutoUpdateUtils"); + + +describe('Current', () => { + + it('it runs', () => { + AutoUpdateUtils.autoUpdate('app-slib', '6.0.0', '6.0.1', ''); + expect(1).toBe(1); + }); +}); \ No newline at end of file diff --git a/test/auto-update.test.js b/test/auto-update.test.js new file mode 100644 index 00000000..7838a587 --- /dev/null +++ b/test/auto-update.test.js @@ -0,0 +1,201 @@ + +'use strict'; +const path = require('path'); +const assert = require('yeoman-assert'); +const helpers = require('yeoman-test'); +const rimraf = require('rimraf'); +const fse = require('fs-extra'); +const dependencies = require('./test-utils/generator-dependencies'); +const WorkspaceUtils = require('../utils/WorkspaceUtils'); +const parse = require('csv-parse/lib/sync'); +const tmp = require('tmp'); +const AutoUpdateUtils = require('../generators/auto-update/AutoUpdateUtils'); +const RepoUtils = require('../utils/RepoUtils'); +const NpmUtils = require('../utils/NpmUtils'); +const SpawnUtils = require('../utils/SpawnUtils'); +const GithubRestUtils = require('../generators/auto-update/GithubRestUtils'); +const targetVersion = require('../package.json').version.replace('-SNAPSHOT', ''); + +const target = '../update'; +const dummyToken = '********************'; + +// describe('auto-update generator runs sequentially', () => { + +// const knownReposFile = 'repositories.csv'; +// const tmpDir = 'tmp/tmp-xxxxx'; +// const pluginType = 'lib-slib'; + +// const records = parse(fse.readFileSync(path.join(__dirname, './test-utils/templates/repositories.csv')), { +// columns: true, +// skip_empty_lines: true +// }); + +// beforeAll(async () => { +// // mocks +// WorkspaceUtils.cloneRepo = jest.fn() +// .mockImplementationOnce((_repo, _branch, _extras, _dir, cwd) => { +// const dirs = records.map(({name}) => path.join(cwd, name)); +// dirs.forEach((dir) => { + +// fse.mkdirSync(dir, {recursive: true}); +// fse.writeJSONSync(dir + '/.yo-rc.json', { +// "generator-phovea": { +// type: pluginType +// } +// }); +// }); +// return Promise.resolve(null); +// }) +// .mockImplementation(() => Promise.resolve(null)); +// tmp.dirSync = jest.fn(() => ({name: tmpDir})); +// SpawnUtils.spawnOrAbort = jest.fn(); +// AutoUpdateUtils.autoUpdate = jest.fn(); +// SpawnUtils.spawnSync = jest.fn((_cmd, argline) => { +// if (argline[0] === 'config') { +// return {stdout: 'dummy_user'}; +// } +// return {stdout: 'package.json'}; + +// }); +// GithubRestUtils.createPullRequest = jest.fn(() => Promise.resolve({number: 5})); +// GithubRestUtils.setAssignees = jest.fn(() => Promise.resolve(null)); +// return helpers +// .run(path.join(__dirname, '../generators/auto-update')) +// .withGenerators(dependencies.COMMON) +// .withPrompts({ +// githubToken: dummyToken, +// knownReposFile: 'repositories.csv' +// }) +// .inTmpDir((dir) => { +// fse.copyFileSync(path.join(__dirname, './test-utils/templates/repositories.csv'), path.join(dir, knownReposFile)); +// }); +// }); + +// it('clones all repos with the correct args (calls `cloneRepo()`)', () => { +// const calls = WorkspaceUtils.cloneRepo.mock.calls; +// expect(calls.length).toBe(records.length); + +// records.forEach((record, i) => { +// const args = calls[i]; +// expect(args).toMatchObject([record.link, 'develop', null, '', tmpDir]); +// }); +// }); + +// it('checks out update branch for each repository (calls `spawnOrAbort()`)', () => { +// records.forEach((record, i) => { +// const args = SpawnUtils.spawnOrAbort.mock.calls[i]; +// const branch = `generator_update/${NpmUtils.decrementVersionByOne(targetVersion)}_to_${targetVersion}`; +// const cwd = `${tmpDir}/${record.name}`; +// expect(args).toMatchObject(['git', ['checkout', '-b', branch], cwd, false]); +// }); +// }); + +// it('runs the updates for each repository (calls `autoUpdate()`)', () => { +// const calls = AutoUpdateUtils.autoUpdate.mock.calls; +// expect(calls.length).toBe(records.length); +// records.forEach((record, i) => { +// const args = calls[i]; +// const localVersion = NpmUtils.decrementVersionByOne(targetVersion); +// const cwd = `${tmpDir}/${record.name}`; +// expect(args).toMatchObject([pluginType, localVersion, targetVersion, cwd]); +// }); +// }); + +// it('checks for each repository if any file changes were made (calls `spawnSync()`)', () => { +// const calls = SpawnUtils.spawnSync.mock.calls; +// records.forEach((record, i) => { +// const args = calls[i]; +// const cwd = `${tmpDir}/${record.name}`; +// expect(args).toMatchObject(['git', ['diff', '--name-only'], cwd, false]); +// }); +// }); + +// it('commits changes for each repository if any file changes were made (calls `spawnOrAbort()`)', () => { +// const calls = SpawnUtils.spawnOrAbort.mock.calls; +// records.forEach((record, i) => { +// const localVersion = NpmUtils.decrementVersionByOne(targetVersion); +// const title = `Generator updates from version ${localVersion} to ${targetVersion}`; +// const args = calls[records.length + i]; +// const cwd = `${tmpDir}/${record.name}`; +// expect(args).toMatchObject(['git', ['commit', '-am', title], cwd, false]); +// }); +// }); + +// it('pushes branch for each repository (calls `spawnOrAbort()`)', () => { +// const calls = SpawnUtils.spawnOrAbort.mock.calls; +// records.forEach((record, i) => { +// const localVersion = NpmUtils.decrementVersionByOne(targetVersion); +// const branch = `generator_update/${localVersion}_to_${targetVersion}`; +// const args = calls[records.length * 2 + i]; +// const cwd = `${tmpDir}/${record.name}`; +// expect(args).toMatchObject(['git', ['push', 'origin', branch], cwd, false]); +// }); +// }); + +// it('creates pull request for each repository (calls `createPullRequest()`)', () => { +// const calls = GithubRestUtils.createPullRequest.mock.calls; +// expect(calls.length).toBe(records.length); + +// records.forEach((record, i) => { + +// const args = calls[i]; +// const credentials = { +// username: 'oltionchampari', +// token: '************************************', +// }; +// const localVersion = NpmUtils.decrementVersionByOne(targetVersion); +// const title = `Generator updates from version ${localVersion} to ${targetVersion}`; +// const branch = `generator_update/${localVersion}_to_${targetVersion}`; +// const data = { +// title, +// head: branch, +// body: `Description`, +// base: 'develop' +// }; +// const baseName = `${RepoUtils.getOrganization(record.link)}/${record.name}`; +// expect(args).toMatchObject([baseName, data, credentials]); +// }); +// }); + +// it('adds assignee to pull request (calls `setAssignees()`)', () => { +// const calls = GithubRestUtils.setAssignees.mock.calls; +// expect(calls.length).toBe(records.length); + +// records.forEach((record, i) => { + +// const args = calls[i]; +// const credentials = { +// username: 'oltionchampari', +// token: '************************************', +// }; +// const baseName = `${RepoUtils.getOrganization(record.link)}/${record.name}`; +// expect(args).toMatchObject([baseName, 5, ['dummy_user'], credentials]); +// }); +// }); + +// }); + + +describe('auto-update generator fails', () => { + + afterAll(() => { + rimraf.sync(path.join(__dirname, target)); + }); + + + it('throws error if `knownReposFile` does not exist', async () => { + await helpers + .run(path.join(__dirname, '../generators/auto-update')) + .inDir(path.join(__dirname, target), () => null) + .withGenerators(dependencies.COMMON) + .withPrompts({ + githubToken: dummyToken + }) + .catch((e) => { + expect(e.message.includes('Given file cannot be read: ' + '/workspaces/releases/repositories.csv')).toBeTruthy(); + }); + }); + +}); + +// TODO test when update fails for a repo \ No newline at end of file diff --git a/test/setup-workspace.test.js b/test/setup-workspace.test.js index 1c81b507..bf1b7769 100644 --- a/test/setup-workspace.test.js +++ b/test/setup-workspace.test.js @@ -50,9 +50,9 @@ describe('generator setup-workspace', () => { return setupWorkspace(); }); - afterAll(() => { - rimraf.sync(path.join(__dirname, target)); - }); + // afterAll(() => { + // rimraf.sync(path.join(__dirname, target)); + // }); it('calls WorkspaceUtils.cloneRepo(...args) 13 times (1 product + 12 plugins)', () => { expect(WorkspaceUtils.cloneRepo.mock.calls.length).toBe(13); diff --git a/test/test-utils/templates/repositories.csv b/test/test-utils/templates/repositories.csv new file mode 100644 index 00000000..519300c1 --- /dev/null +++ b/test/test-utils/templates/repositories.csv @@ -0,0 +1,7 @@ +name,link,owner,version,pip,npm +phovea_clue_dummy,https://github.com/phovea/phovea_clue_dummy,John,v6.0.0,x,x +phovea_core_dummy,https://github.com/phovea/phovea_core_dummy,John,v5.0.1,,x +phovea_d3_dummy,https://github.com/phovea/phovea_d3_dummy,John,v5.0.0,,x +phovea_data_hdf_dummy,https://github.com/phovea/phovea_data_hdf_dummy,John,v6.0.0,x, +tdp_matomo_dummy,https://github.com/datavisyn/tdp_matomo_dummy,John,v5.0.0,x, +gapminder_dummy,https://github.com/Caleydo/gapminder,John,v4.0.0,, \ No newline at end of file diff --git a/utils/GeneratorUtils.js b/utils/GeneratorUtils.js index ee7f8ae4..947cf9b2 100644 --- a/utils/GeneratorUtils.js +++ b/utils/GeneratorUtils.js @@ -39,7 +39,6 @@ module.exports = class GeneratorUtils { const _args = Array.isArray(args) ? args.join(' ') : args || ''; return new Promise((resolve, reject) => { try { - console.log(`Running: yo phovea:${generator} ${_args}`); env.lookup(() => { env.run(`phovea:${generator} ${_args}`, options || {}, () => { // wait a second after running yo to commit the files correctly diff --git a/utils/NpmUtils.js b/utils/NpmUtils.js index 9be0bdfa..47737ba7 100644 --- a/utils/NpmUtils.js +++ b/utils/NpmUtils.js @@ -248,4 +248,10 @@ module.exports = class NpmUtils { static useDevVersion(version) { return (version || '').includes('-'); } + + static decrementVersion(version) { + version = semver.parse(version, {loose: true}); + version.major -= 1; + return version.format(); + } }; \ No newline at end of file diff --git a/utils/RepoUtils.js b/utils/RepoUtils.js index 1a9a8138..a2c9f191 100644 --- a/utils/RepoUtils.js +++ b/utils/RepoUtils.js @@ -183,4 +183,10 @@ module.exports = class RepoUtils { }); return Array.from(new Set(r)); } + + static getOrganization(url) { + url = url.replace(/\/$/, ''); // remove possibe `/` at the end of url + const names = url.toLowerCase().split(/\/|:/); + return names[names.length - 2]; + } }; diff --git a/utils/SpawnUtils.js b/utils/SpawnUtils.js index 43f561ce..4255fa84 100644 --- a/utils/SpawnUtils.js +++ b/utils/SpawnUtils.js @@ -1,6 +1,7 @@ 'use strict'; const spawnSync = require('child_process').spawnSync; +const spawnPr = require('child-process-promise').spawn; module.exports = class SpawnUtils { @@ -16,7 +17,7 @@ module.exports = class SpawnUtils { if (SpawnUtils.failed(result)) { return SpawnUtils.abort(`Failed: "${cmd} ${Array.isArray(argline) ? argline.join(' ') : argline}" - status code: ${result.status}`); - } else if (stdout && stdout.toString()) { + } else if (stdout && stdout.toString() && verbose) { console.log(stdout.toString().trim()); } @@ -31,10 +32,16 @@ module.exports = class SpawnUtils { */ static spawnSync(cmd, argline, cwd, verbose) { const options = { - ...cwd ? {cwd} : {}, - ...verbose ? {stdio: 'inherit'} : {} + ...cwd ? { cwd } : {}, + ...verbose ? { + stdio: 'inherit', + } : {} }; + if (verbose) { + console.log(Array.isArray(argline) ? argline.join(' ') : argline); + } + return spawnSync(cmd, Array.isArray(argline) ? argline : argline.split(' '), options); } @@ -53,4 +60,29 @@ module.exports = class SpawnUtils { static abort(msg) { return Promise.reject(msg ? msg : 'Step Failed: Aborting'); } + + /** + * Execute a shell command and return the decoded output + * @param command Command to execute + * @param argline Arguments to execute the command with + */ + static spawnWithOutput(command, argline, cwd) { + const options = { + ...cwd ? { cwd } : {}, + encoding: 'UTF-8' + }; + return spawnSync(command, Array.isArray(argline) ? argline : argline.split(' '), options).stdout.trim(); + } + + static async spawnPromise(command, argline, cwd,) { + const options = { + ...cwd ? { cwd } : {}, + encoding: 'UTF-8', + capture: ['stdout', 'stderr'] + }; + return spawnPr(command, Array.isArray(argline) ? argline : argline.split(' '), options) + .catch(e => { + throw new Error(`${e.message}${('\n' + e.stderr) || ''}${('\n' + e.stdout) || ''}`); + }); + } }; diff --git a/utils/WorkspaceUtils.js b/utils/WorkspaceUtils.js index 01bd05ac..810ac0c4 100644 --- a/utils/WorkspaceUtils.js +++ b/utils/WorkspaceUtils.js @@ -76,7 +76,7 @@ module.exports = class WorkspaceUtils { * @param {string} cwd Where to run the generator * @param {boolean} cloneSSH SSH or HTTP url */ - static cloneRepo(repo, branch, extras, dir = '', cwd, cloneSSH) { + static cloneRepo(repo, branch, extras, dir = '', cwd, cloneSSH = true) { const repoUrl = cloneSSH ? RepoUtils.toSSHRepoUrl(repo) : RepoUtils.toHTTPRepoUrl(repo); return GeneratorUtils.yo(`clone-repo`, { branch,