function bufferContents(file, enc, cb) { /* jshint validthis: true */ // ignore empty files if (file.isNull()) { cb(null, file); return; } if (file.isStream()) { this.emit('error', new PluginError(PLUGIN_NAME, 'Streaming not supported')); cb(); return; } if (options.text_domain === false) { this.emit('error', new PluginError(PLUGIN_NAME, 'Text domain not provided.')); cb(); return; } //Cast text_domain as an array to support multiple text domains options.text_domain = (options.text_domain instanceof Array) ? options.text_domain : [options.text_domain]; //correct_domain can only be used if one domain is specified: options.correct_domain = options.correct_domain && (options.text_domain.length === 1); if (options.keywords === false) { this.emit('error', new PluginError(PLUGIN_NAME, 'No keywords specified.')); cb(); return; } options.keywords.forEach(function(keyword) { //parts[0] is keyword name, e.g. __ or _x var parts = keyword.split(':'); var name = parts[0]; var argument = 0; //keyword argument identifiers if (parts.length > 1) { var args = parts[1]; var arg_parts = args.split(','); for (var j = 0; j < arg_parts.length; j++) { //check for domain identifier if (patt.test(arg_parts[j])) { argument = parseInt(patt.exec(arg_parts[j]), 10); break; } } //No domain identifier found, assume it is #ags + 1 argument = argument ? argument : arg_parts.length + 1; //keyword has no argument identifiers -- assume text domain is 2nd argument } else { argument = 2; } func_domain[name] = argument; functions.push(name); }); var all_errors = {}; var error_num = 0; // read file, if it exists var filename = path.basename(file.path); var dirname = path.dirname(file.path); if (!fileExists(file.path)) { this.emit('error', new PluginError(PLUGIN_NAME, 'Source file "' + file.path + '" not found.')); cb(); return; } var reader = new Parser({ parser: { // does not extract docs extractDoc: false, // do not fail if PHP syntax is broken suppressErrors: true }, ast: { // got line and col on every node withPositions: true }, lexer: { // accept <? ... short_tags: true, // accept <%= (old php4 syntax) asp_tags: true } }); // get every gettext call var corrections = []; var ast = reader.parseCode(file.contents.toString(), file.path); var calls = visitor(ast, functions); calls.forEach(function(call) { var domainOffset = func_domain[call.what.name] - 1; if (call.arguments.length > domainOffset) { var arg = call.arguments[domainOffset]; // bad domain type var domName = -1; // check argument type if (arg.kind === 'string') { // check the domain domName = arg.value; } else if (arg.kind === 'constref') { // check a constant name domName = arg.name.name; } // bad domain contents if (options.text_domain.indexOf(domName) === -1) { errors.push({ name: call.what.name, line: call.loc.start.line, domain: domName, argument: domainOffset }); if (options.correct_domain) { // try to correct it corrections.push([ arg, '\'' + options.text_domain[0] + '\'' ]); } } } else if (options.report_missing) { // argument not found errors.push({ name: call.what.name, line: call.loc.start.line, domain: false, argument: 0 }); } }); //Output errors if (errors.length > 0) { console.log('\n' + chalk.bold.underline(dirname + path.sep + filename)); var rows = [], error_line, func, message; for (var i = 0, len = errors.length; i < len; i++) { error_line = chalk.yellow('[L' + errors[i].line + ']'); func = chalk.cyan(errors[i].name); if (!errors[i].domain) { message = chalk.red('Missing text domain'); } else if (errors[i].domain === -1) { message = chalk.red('Variable used in domain argument'); } else { message = chalk.red('Incorrect text domain used ("' + errors[i].domain + '")'); } rows.push([error_line, func, message]); error_num++; } console.log(table(rows)); if (corrections.length > 0) { writer(file.path, file.contents.toString(), corrections); console.log(chalk.bold(dirname + path.sep + filename + ' corrected.')); } } all_errors[file.path] = errors; //Reset errors errors = []; if (options.create_report_file) { fs.writeFileSync('.' + path.basename(file.path, path.extname(file.path)) + '.json', JSON.stringify(all_errors)); } if (error_num > 0 && !options.force) { console.log(error_num + ' problem' + (error_num === 1 ? '' : 's'), 6); } else if (error_num > 0) { console.log("\n" + chalk.red.bold('✖ ' + error_num + ' problem' + (error_num === 1 ? '' : 's'))); } else if (options.report_success) { console.log("\n" + chalk.green.bold('✔ No problems') + "\n"); } this.push(file); cb(); }
'bundle-minify': { description: 'Generate a minified production build', type: 'boolean', dest: 'minify' }, }, }, params: { 'file_or_url': { description: 'Path or URL of the webtask\'s code. When not specified, code will be read from STDIN.', type: 'string', }, }, epilog: Chalk.underline('Sample usage:') + '\n' + '1. Create a basic webtask:' + '\n' + Chalk.bold(' $ wt create ./sample-webtasks/hello-world.js') + '\n' + '\n' + '2. Create a webtask with one secret:' + '\n' + Chalk.bold(' $ wt create --secret name=webtask ./sample-webtasks/html-response.js') + '\n' + '\n' + '3. Create a webtask that is bundled before deploying. Note that --no-parse is needed since we are using webtask-tools with Express and body-parser:' + '\n' + Chalk.bold(' $ wt create --secret name=webtask --bundle --no-parse ./sample-webtasks/bundled-webtask.js') + '\n' , handler: handleCreate, }); // Command handler function handleCreate(args) { args = ValidateCreateArgs(args);
BPromise.all(buildPromises).then(function () { sh.run("rm -rf builds/ios/"); sh.run("cordova create builds/ios org.bookstreams.app bookstreams"); sh.run("cd builds/ios && cordova plugin add org.apache.cordova.device"); sh.run("cd builds/ios && cordova plugin add org.apache.cordova.inappbrowser"); sh.run("cd builds/ios && cordova plugin add org.apache.cordova.geolocation"); sh.run("cd builds/ios && cordova plugin add com.phonegap.plugins.barcodescanner"); sh.run("cd builds/ios && cordova platform add ios"); sh.run("rm -rf builds/ios/www/"); sh.run("mv builds/ios.prod builds/ios/www"); var version = process.argv[2]; if (semver.valid(version) === null) { console.log(chalk.red("ERROR: invalid version")); console.log("Usage: " + chalk.bold("npm run ios 1.0.0")); return; } var config = fs.readFileSync("builds/ios/config.xml", "utf8"); var parser = new xml2js.Parser(); parser.parseString(config, function (err, res) { if (err) { console.log(chalk.red("Error parsing builds/ios/config.xml")); console.log(err); return; } res.widget.$.version = version; res.widget.platform = {$: { name: "ios" }}; res.widget.platform.icon = [ 76, 120, 152, 180 ].map(function (size) { return { $: { src: "www/assets/app-icon/ios-" + size + "x" + size + ".png", width: "" + size, height: "" + size } }; }); res.widget.platform.splash = [ ["640", "960"], ["768", "1024"], ["1536", "2048"], ["640", "1136"], ["750", "1334"], ["1242", "2208"] ].map(function (size) { return {$: { src: "www/assets/app-splash/" + size[0] + "x" + size[1] + ".png", width: size[0], height: size[1] }}; }); var builder = new xml2js.Builder(); var xml = builder.buildObject(res); fs.writeFileSync("builds/ios/config.xml", xml, "utf8"); // Build sh.run("cd builds/ios && cordova build ios"); console.log(chalk.green.bold("SUCCESS")); }); });
exec('node -v', (err, stdout, stderr) => { if (err) { this.warning('NodeJS is not found on your system.'); } else { const nodeVersion = semver.clean(stdout); const nodeFromPackageJson = packagejs.engines.node; if (!semver.satisfies(nodeVersion, nodeFromPackageJson)) { this.warning(`Your NodeJS version is too old (${nodeVersion}). You should use at least NodeJS ${chalk.bold(nodeFromPackageJson)}`); } } done(); });
function showMenu (opts, i18n) { var emitter = new EventEmitter() , menu = tmenu(xtend({ width : opts.width , x : 3 , y : 2 }, opts.menu)) , __ = i18n.__ , __n = i18n.__n function writeLine() { menu.write(repeat('\u2500', opts.width) + '\n') } function emit(event, value) { return process.nextTick.bind(process, emitter.emit.bind(emitter, event, value)) } function addEntry(entry) { menu.add(applyTextMarker(entry.name, entry.marker || '', opts.width), emit(entry.event, entry.payload)) } function addVariableEntry(variableEntry) { if (!variableEntry) return if (util.isArray(variableEntry)) return variableEntry.forEach(addVariableEntry) if (variableEntry.separator) return writeLine() addEntry(variableEntry) } menu.reset() menu.write(chalk.bold(__('title')) + '\n') if (i18n.has('subtitle')) menu.write(chalk.italic(__('subtitle')) + '\n') writeLine() opts.entries.forEach(addVariableEntry) function regexpEncode(str) { return str.replace(/([\.\*\+\?\{\}\[\]\- \(\)\|\^\$\\])/g, "\\$1") } menu.on('select', function (label) { menu.y = 0 menu.reset() menu.close() }) menu.createStream().pipe(process.stdout) return emitter }
function () { console.log('>', chalk.red('Always two there are, no more, no less. A master and a'), chalk.bold.red('stable') + chalk.red('.')); console.log('Use the', chalk.bold('stable'), 'branch for live blogs.', chalk.bold('Never'), 'master!'); });
.then(() => logger.info('Target application environment: ' + chalk.bold(project.env)))
sayHello: function() { this.log(chalk.white(chalk.bold('🐳') + ' Welcome to the JHipster Docker Compose Sub-Generator ' + chalk.bold('🐳'))); this.log(chalk.white('Files will be generated in folder: ' + chalk.yellow(this.destinationRoot()))); },
LoadedStaticGenerator.prototype.donezo = function donezo() { this.log(chalk.bold.green('\n\n------------------------\n\n\nAll Done!!\n'), {logPrefix: ''}); this.log(chalk.bold("Local:")+" "+chalk.underline("http://localhost/" + slugify(this.projectName) + "/source/")); this.log(chalk.bold("Projects:")+" "+chalk.underline("http://projects.loadedcommunications.com.au/" + slugify(this.projectName) + "/source/")); };
case 'fatal': color = (x) => chalk.bold(chalk.red(x)); output = process.stderr; break;
}).then(function() { utils.logSuccess('Database Rules for ' + chalk.bold(instance) + ' have been downloaded to ' + chalk.bold(filename) + '.'); logger.info('Future modifications to ' + chalk.bold(filename) + ' will update Database Rules when you run'); logger.info(chalk.bold('firebase deploy') + '.'); });
fs.writeFileSync(path.join(outputPath, 'index.html'), minify( mustache.render(templates.page, docs.readme, templates), minifyOptions)) mkdirp.sync(path.join(outputPath, 'api')) fs.writeFileSync(path.join(outputPath, 'api/index.html'), minify( mustache.render(templates.page, { root: '../', title: 'API Reference', year, api, content: mustache.render(templates.api, api) }, templates), minifyOptions)) for (let doc in docs) { mkdirp.sync(path.join(outputPath, doc)) fs.writeFileSync(path.join(outputPath, doc, 'index.html'), minify( mustache.render(templates.page, docs[doc], templates), minifyOptions)) } // Write CNAME file // ================ fs.writeFileSync(path.join(outputPath, 'CNAME'), CNAME) // End // === process.stderr.write(chalk.green(`Done! Build finished in ` + `${chalk.bold(((Date.now() - start) / 1000) + ' s')}.\n`))
/** * CLI engine. This is used by `bin/mdast`. * * @example * engine('--use toc . --output --quiet', console.log); * * @param {Array.<*>|Object} argv - CLI arguments. * @param {function(Error?, boolean)} done - Callback * invoked when done. */ function engine(argv, done) { var cli = new CLI(argv); var enabled = chalk.enabled; var watcher; chalk.enabled = cli.color; if (cli.watch) { cli.stdout.write( chalk.bold('Watching...') + ' (press CTRL+C to exit)\n' ); } run(cli, function (err, success) { chalk.enabled = enabled; done(err, success); /* * Exit when not-watching, or when an error * has occurred. */ if (err || !cli.watch) { return; } /* * Trigger warning when files need to be cached. */ if (cli.cache.length) { cli.stderr.write( chalk.yellow('Warning') + ': mdast does not overwrite ' + 'watched files until exit.\nMessages and other files are ' + 'not affected.\n' ); } /* * Watch files source-locations of files in * the file-set. */ watcher = chokidar.watch(cli.fileSet.sourcePaths, { 'ignoreInitial': true }).on('all', function (type, filePath) { if (type === 'add' || type === 'change') { cli.globs = [filePath]; run(cli, done); } }).on('error', done); process.on('SIGINT', function () { cli.cache.writeAll(); if (watcher) { watcher.close(); } }); }); }
fixtures.forEach(function (fixture) { console.log(chalk.bold(name) + ':', inspect(fn(require(fixture)))); });
function bold(str) { return chalk_1.default.bold(str); }
end: function() { this.log(yosay('My work here is ' + chalk.bold(chalk.green('done')) + '!')); this.log('Run ' + chalk.red('npm start') + ' to see the app in action or ' + chalk.red('npm start | bunyan') + ' for a better info display.'); this.log('Visit our source code at ' + chalk.blue('https://github.com/pcostesi/generator-express-micro')); }
/* eslint import/no-extraneous-dependencies: 0 */ const chalk = require('chalk'); const { getConsoleOutput } = require('jest-util'); const DefaultReporter = require('jest-cli/build/reporters/default_reporter') .default; const getResultHeader = require('jest-cli/build/reporters/get_result_header') .default; const TITLE_BULLET = chalk.bold('\u25cf '); // This Jest reporter does not output any console.log except when the tests are // failing, see: https://github.com/mozilla/addons-frontend/issues/2980. class FingersCrossedReporter extends DefaultReporter { printTestFileHeader(testPath, config, result) { this.log(getResultHeader(result, this._globalConfig, config)); const consoleBuffer = result.console; const testFailed = result.numFailingTests > 0; if (testFailed && consoleBuffer && consoleBuffer.length) { // prettier-ignore this.log( ` ${TITLE_BULLET}Console\n\n${getConsoleOutput( config.cwd, !!this._globalConfig.verbose, consoleBuffer )}` ); } } }
module.exports = function(projectPath, options) { let Botpress = null if (!projectPath || typeof projectPath !== 'string') { projectPath = '.' } projectPath = path.resolve(projectPath) try { // eslint-disable-next-line no-eval Botpress = eval('require')(path.join(projectPath, 'node_modules', 'botpress')).Botpress() } catch (err) { util.print('error', err.message) util.print('error', err.stack) util.print('error', '(fatal) Could not load the local version of botpress') util.print('Hint: 1) have you used `botpress init` to create a new bot the proper way?') util.print('Hint: 2) Do you have read and write permissions on the current directory?') util.print('-------------') util.print( 'If none of the above works, this might be a bug in botpress. ' + 'Please contact the Botpress Team on gitter and provide the printed error above.' ) process.exit(1) } const botfile = path.join(projectPath, 'botfile.js') if (!fs.existsSync(botfile)) { util.print('error', `(fatal) No ${chalk.bold('botfile.js')} file found at: ` + botfile) process.exit(1) } const getDefaultWatchIgnore = () => { // eslint-disable-next-line no-eval const bf = eval('require')(botfile) const dataDir = util.getDataLocation(bf.dataDir, projectPath) const modulesConfigDir = util.getDataLocation(bf.modulesConfigDir, projectPath) return [dataDir, modulesConfigDir, 'node_modules'] } const opts = options.opts() if (opts.watch || opts.w) { util.print('info', '*** watching files for changes ***') const argvWithoutWatch = process.argv.filter(arg => !/^(--watch|-w)$/.test(arg)) argvWithoutWatch[0] = getPath(argvWithoutWatch[0]) const nodemonOptions = { cwd: process.cwd(), exec: argvWithoutWatch.join(' '), ext: opts.watchExt, watch: opts.watchDir && opts.watchDir.length ? opts.watchDir : undefined, ignore: opts.watchIgnore && opts.watchIgnore.length ? opts.watchIgnore : getDefaultWatchIgnore(), stdin: false, restartable: false } const mon = nodemon(nodemonOptions) mon.on('restart', (changedFile, two) => util.print('info', '*** restarting botpress because of file change: ', changedFile) ) monitorCtrlC(() => { mon.emit('quit') setTimeout(() => process.exit(), 100) }) } else { const bot = new Botpress({ botfile }) bot.start() } }
grunt.registerTask('buildAboutPage', 'Compile assets for the About Ghost page', function () { var done = this.async(), templatePath = 'core/client/app/templates/-contributors.hbs', imagePath = 'core/client/public/assets/img/contributors/', timeSpan = moment().subtract(90, 'days').format('YYYY-MM-DD'), oauthKey = process.env.GITHUB_OAUTH_KEY; if (fs.existsSync(templatePath) && !grunt.option('force')) { grunt.log.writeln('Contributors template already exists.'); grunt.log.writeln(chalk.bold('Skipped')); return done(); } grunt.verbose.writeln('Downloading release and contributor information from GitHub'); return Promise.join( Promise.promisify(fs.mkdirs)(imagePath), getTopContribs({ user: '******', repo: 'ghost', oauthKey: oauthKey, sinceDate: timeSpan, count: 18, retry: true }) ).then(function (results) { var contributors = results[1], contributorTemplate = '<article>\n <a href="<%githubUrl%>" title="<%name%>">\n' + ' <img src="{{gh-path "admin" "/img/contributors"}}/<%name%>" alt="<%name%>" />\n' + ' </a>\n</article>', downloadImagePromise = function (url, name) { return new Promise(function (resolve, reject) { var file = fs.createWriteStream(path.join(__dirname, imagePath, name)); https.get(url, function (response) { response.pipe(file); file.on('finish', function () { file.close(); resolve(); }); }) .on('error', reject); }); }; grunt.verbose.writeln('Creating contributors template.'); grunt.file.write(templatePath, // Map contributors to the template. _.map(contributors, function (contributor) { return contributorTemplate .replace(/<%githubUrl%>/g, contributor.githubUrl) .replace(/<%name%>/g, contributor.name); }).join('\n') ); grunt.verbose.writeln('Downloading images for top contributors'); return Promise.all(_.map(contributors, function (contributor) { return downloadImagePromise(contributor.avatarUrl + '&s=60', contributor.name); })); }).then(done).catch(function (error) { grunt.log.error(error); if (error.http_status) { grunt.log.writeln('GitHub API request returned status: ' + error.http_status); } if (error.ratelimit_limit) { grunt.log.writeln('Rate limit data: limit: %d, remaining: %d, reset: %s', error.ratelimit_limit, error.ratelimit_remaining, moment.unix(error.ratelimit_reset).fromNow()); } done(false); }); });
started: (suite) => { if (!suite.title) return; print(`${colors.bold(suite.title)} --`); if (suite.comment) print(suite.comment); },
sayHello: function() { this.log(chalk.white(chalk.bold('[BETA]') + ' Welcome to the JHipster Kubernetes Generator ')); this.log(chalk.white('Files will be generated in folder: ' + chalk.yellow(this.destinationRoot()))); },
remove.handler(function (key, done) { if (!key) return done(cli.errors.MISSING_CONFIG_KEY); cli.cwd.removeConfigValue(key); cli.log('\n' + format.bold(key) + ' removed'); done(null, cli.cwd.getConfig()); });
Common.sink.resolveInterpreter = function(app) { var noInterpreter = (!app.exec_interpreter || 'none' == app.exec_interpreter), extName = path.extname(app.pm_exec_path), betterInterpreter = extItps[extName]; var thereIsNVMInstalled = false; // No interpreter defined and correspondance in schema hashmap if (noInterpreter && betterInterpreter) app.exec_interpreter = betterInterpreter; // Else if no Interpreter detect if process is binary else if (noInterpreter) app.exec_interpreter = isBinary(app.pm_exec_path) ? 'none' : 'node'; else if (app.exec_interpreter.indexOf('node@') > -1 || app.node_version && thereIsNVMInstalled) { if (!process.env.NVM_DIR) { Common.printError(cst.PREFIX_MSG_ERR + chalk.red('NVM is not available in PATH')); Common.printError(cst.PREFIX_MSG_ERR + chalk.red('Fallback to node in PATH')); Common.printOut(cst.PREFIX_MSG_ERR + chalk.bold('Install NVM:\n$ curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash')); } else { var node_version = app.exec_interpreter.split('@')[1]; var nvm_node_path; if (semver.satisfies(node_version, '>= 0.12.0')) nvm_node_path = path.join(process.env.NVM_DIR, '/versions/node/v' + node_version + '/bin/node'); else nvm_node_path = path.join(process.env.NVM_DIR, '/v' + node_version + '/bin/node'); try { fs.accessSync(nvm_node_path); } catch(e) { Common.printOut(cst.PREFIX_MSG + 'Installing Node v%s', node_version); var nvm_bin = path.join(process.env.NVM_DIR, 'nvm.sh'); var nvm_cmd = '. ' + nvm_bin + ' ; nvm install ' + node_version; Common.printOut(cst.PREFIX_MSG + 'Executing: %s', nvm_cmd); shelljs.exec(nvm_cmd); } Common.printOut(cst.PREFIX_MSG + chalk.green.bold('Setting Node to v%s (path=%s)'), node_version, nvm_node_path); app.exec_interpreter = nvm_node_path; } } /** * Specific installed JS transpilers */ if (app.exec_interpreter == 'ts-node') { app.exec_interpreter = path.join(__dirname, '../node_modules/.bin/ts-node'); } if (app.exec_interpreter == 'lsc') { app.exec_interpreter = path.join(__dirname, '../node_modules/.bin/lsc'); } if (app.exec_interpreter == 'coffee') { app.exec_interpreter = path.join(__dirname, '../node_modules/.bin/coffee'); } if (app.exec_interpreter != 'none' && shelljs.which(app.exec_interpreter) == null) { Common.printError(cst.PREFIX_MSG_ERR + 'Interpreter ' + app.exec_interpreter + ' does not seems to be available'); } return app; };
AppGenerator.prototype.hint = function hint() { console.info(chalk.yellow(separator)); console.info(chalk.bold('\nReady.')); console.info('\nAfter selecting preferred style for your app just run ' + chalk.bold.yellow('npm install') +' and ' + chalk.bold.yellow('bower install --dev') + ' to install the required dependencies.'); console.info(chalk.yellow(separator)); };
const isInteractive = process.stdout.isTTY; // Warn and crash if required files are missing if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) { process.exit(1); } // Tools like Cloud9 rely on this. const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000; const HOST = process.env.HOST || '0.0.0.0'; if (process.env.HOST) { console.log( chalk.cyan( `Attempting to bind to HOST environment variable: ${chalk.yellow( chalk.bold(process.env.HOST) )}` ) ); console.log( `If this was unintentional, check that you haven't mistakenly set it in your shell.` ); console.log( `Learn more here: ${chalk.yellow('http://bit.ly/CRA-advanced-config')}` ); console.log(); } // We require that you explictly set browsers and do not fall back to // browserslist defaults. const { checkBrowsers } = require('react-dev-utils/browsersHelper');
var chalk = require("chalk"); var message = chalk.bold(chalk.bgCyan("Hello ")) + chalk.strikethrough(chalk.yellow("World")); console.log(message);
.then( () => { warnings.flush(); if ( !silent ) stderr( chalk.green( `created ${chalk.bold( files.join( ', ' ) )} in ${chalk.bold(ms( Date.now() - start))}` ) ); })
execute: function(socket, command, command_access) { var chalk = require('chalk'); descMaxLength = 18; // this limit is being currently imposed due to .who's presentation layer if ((typeof command === 'undefined') || command.length < 1) { socket.write(chalk.yellow("[::] ") + "You have to use it this way: .desc <description here>\r\n"); } else if (command.length > descMaxLength) { socket.write(chalk.yellow(":: ") + "Your description can't have more than " + chalk.bold(descMaxLength) + " characters.\r\n"); } else { socket.db.desc = command; command_access.updateUser(socket.username, socket.db); socket.write(chalk.green("[::]") + " Your description is now: " + command + "\r\n"); } }
Promise.all(pullPromises).then((richPulls) => { richPulls.forEach((pr) => { // Convert merged_at to real Date for sorting pr.merged_at_date = new Date(pr.merged_at); }); richPulls = richPulls.sort((a, b) => a.merged_at_date - b.merged_at_date); this.log(`Found ${chalk.bold(richPulls.length)} pull requests:`); richPulls.forEach((pr) => { this.log(`${pr.html_url}: ${chalk.bold(pr.title)}`); }); this.prompt({ name: 'merge', type: 'confirm', message: `Merge these ${richPulls.length} pull requests?`, }, (res) => { if (res.merge) { richPulls.forEach((pr) => { git.cherryPickMerge(app, pr.merge_commit_sha); }); this.prompt({ name: 'push', type: 'confirm', message: 'Push these commits upstream?', }, (res) => { if (res.push) { git.push(app); this.log(`Pushed upstream! Removing "${DOCS_LABEL}" label from pull requests.`); } // TODO: actually test this var removeLabelsPromises = richPulls.map((pr) => { return new Promise((resolve, reject) => { const updatedLabels = pr.__originalIssue.labels .filter((label) => label.name !== DOCS_LABEL) .map(label => label.name); app.ghissues.editIssue(pr.number, {labels: updatedLabels}, (err, body) => { if (err) { reject(err); } else { resolve(pr); } }); }); }); Promise.all(removeLabelsPromises).then(() => { this.log('Done!'); actionCB(); }); }); } else { actionCB(); } }); });
function provision(profile, modules, options) { options = _.defaultsDeep({}, options, { logger: { info: _.noop, warn: _.noop, error: _.noop, }, }); const logger = options.logger; if (modules.length) { logger.info(`Resolving ${ Chalk.bold(modules.length) } module${ modules.length === 1 ? '' : 's' }...`); } return Bluebird.map(modules, resolveSpec).then(modules => { const total = Object.keys(modules).length; const pluralization = total === 1 ? 'module' : 'modules'; const stateToColor = { queued: Chalk.blue, available: Chalk.green, failed: Chalk.red, }; const moduleState = {}; let polls = 0; if (!total) { return modules; } logger.info(`Provisioning ${ Chalk.bold(total) } ${ pluralization }...`); const available$ = awaitAvailable(profile, modules, { onPoll }); return available$.then(() => modules); function onPoll(modules) { const countByState = _.countBy(modules, mod => mod.state); if (polls === 0 && countByState.queued && !countByState.failed) { const pluralization = countByState.queued === 1 ? 'module' : 'modules'; const verb = countByState.queued === 1 ? 'is' : 'are'; logger.info( wrapHint( Chalk.italic( `* Hint: ${countByState.queued} ${pluralization} ${verb} queued. Please be patient while we build missing modules. This could take a couple minutes and will only ever need to be done once per module version.` ) ) ); } _.forEach(modules, mod => { const modId = `${mod.name}@${mod.version}`; if ( mod.state !== 'queued' && mod.state !== moduleState[modId] ) { const color = stateToColor[mod.state]; const update = `${ Chalk.bold(modId) } is ${color(mod.state)}`; logger.info(update); } moduleState[modId] = mod.state; }); polls++; } }); }