diff --git a/lib/bootstrap.js b/lib/bootstrap.js index 41ad24e7..7a49d140 100644 --- a/lib/bootstrap.js +++ b/lib/bootstrap.js @@ -24,7 +24,9 @@ var rename = require('gulp-rename'); var promptly = require('promisified-promptly'); var gitconfiglocal = require('gitconfiglocal'); var through2 = require('through2'); -var gutil = require('gulp-util'); +var chalk = require('chalk'); +var changeCase = require('change-case'); +var cli = require('cli'); function gitUrl(dir) { return new Promise(function (resolve, reject) { @@ -42,10 +44,10 @@ function gitUrl(dir) { } function templateConfigPrompt(defaultConfig) { - gutil.log('The current template configuration is:'); - gutil.log(templateConfigToString(defaultConfig)); + console.log('Your app\'s configuration is:\n'); + console.log(templateConfigToString(defaultConfig)); - return promptly.confirm('Would you like to change any of the above configuration values?').then(function(fillInConfig) { + return promptly.confirm('Would you like to change its configuration (y/N)?', { default: false }).then(function(fillInConfig) { if (!fillInConfig) { return defaultConfig; } @@ -58,10 +60,12 @@ function templateConfigPrompt(defaultConfig) { }); } - return prompt('Project name: ', 'name') - .then(prompt.bind(null, 'Repository URL: ', 'repository')) - .then(prompt.bind(null, 'Description: ', 'description')) - .then(prompt.bind(null, 'License: ', 'license')) + console.log('\n'); + + return prompt(chalk.bold('Name:'), 'name') + .then(prompt.bind(null, chalk.bold('Repository:'), 'repository')) + .then(prompt.bind(null, chalk.bold('Description:'), 'description')) + .then(prompt.bind(null, chalk.bold('License:'), 'license')) .then(function() { return config; }); @@ -81,9 +85,9 @@ function templateConfigOption(defaultConfig, config) { function templateConfigToString(config) { var out = []; for (var key in config) { - out.push(key + ': ' + config[key]); + out.push(chalk.bold(changeCase.upperCaseFirst(key)) + ': ' + config[key]); } - return out.join('\n'); + return out.join('\n') + '\n'; } function getDefaultTemplateConfig(dir) { @@ -115,6 +119,8 @@ function sink() { module.exports = function(config) { config = config || {}; + console.log('Bootstrapping current directory as Oghliner app…\n'); + var rootDir = config.rootDir ? config.rootDir : '.'; return getDefaultTemplateConfig(rootDir) .then(function(defaultConfig) { @@ -124,6 +130,8 @@ module.exports = function(config) { return templateConfigPrompt(defaultConfig); }) .then(function(templateConfig) { + console.log('\nCreating files…'); + return new Promise(function(resolve, reject) { var stream = gulp.src([__dirname + '/../templates/**']) .pipe(rename(function (path) { @@ -133,11 +141,42 @@ module.exports = function(config) { } })) .pipe(template(templateConfig)) - .pipe(conflict(rootDir)) + .pipe(conflict(rootDir, { + logger: function(message, fileName, extraText) { + console.log(chalk.green('✓ ') + message + ' ' + chalk.stripColor(fileName)); + }, + })) .pipe(gulp.dest(rootDir)) - .pipe(install()) + .on('end', function() { + console.log('\n' + chalk.green('✓ ') + 'Creating files… done!'); + cli.spinner(' Installing npm dependencies…'); + }) + .pipe(install({ + log: function() { + cli.spinner(chalk.red('× ') + 'Installing npm dependencies… error!\n', true); + console.log(Array.prototype.slice.call(arguments).join('')); + }, + npmStdio: ['ignore', 'ignore', 'ignore'], + })) + .on('end', function() { + cli.spinner(chalk.green('✓ ') + 'Installing npm dependencies… done!\n', true); + }) .pipe(sink()); // Sink is required to trigger the finish event with install. - stream.on('finish', resolve); + + stream.on('finish', function() { + console.log( + 'Your app has been bootstrapped! Just commit the changes and push the commit\n' + + 'to the origin/master branch:\n\n' + + chalk.bold('git commit -m"initial version of Oghliner app" --all') + '\n' + + chalk.bold('git push origin master') + '\n\n' + + 'Then you can build, offline, and deploy the app using ' + chalk.bold.italic('gulp') + ' commands.\n\n' + + chalk.bold.blue('ℹ For more information about building, offlining and deployment, see:\n' + + ' https://mozilla.github.io/oghliner/') + ); + + resolve(); + }); + stream.on('error', reject); }); }); diff --git a/package.json b/package.json index e1c60f1c..6e72206f 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ ], "dependencies": { "chalk": "^1.1.1", + "change-case": "^2.3.0", "cli": "^0.11.1", "commander": "^2.8.1", "fs-extra": "^0.26.0", @@ -44,7 +45,7 @@ "gulp-conflict": "^0.4.0", "gulp-connect": "^2.2.0", "gulp-gh-pages": "^0.5.2", - "gulp-install": "^0.6.0", + "gulp-install": "https://github.com/marco-c/gulp-install/tarball/56f8ebf87f14651f586d6377dea75c2f3d1b1691", "gulp-rename": "^1.2.2", "gulp-template": "^3.0.0", "gulp-util": "^3.0.6", diff --git a/test/testLiveAsTemplate.js b/test/testLiveAsTemplate.js index 8d51cd6b..cec237af 100644 --- a/test/testLiveAsTemplate.js +++ b/test/testLiveAsTemplate.js @@ -51,7 +51,7 @@ describe('CLI interface, oghliner as a template', function() { .then(liveUtils.spawn.bind(null, 'npm', ['install', path.dirname(__dirname)])) .then(liveUtils.spawn.bind(null, path.join('node_modules', '.bin', 'oghliner'), ['bootstrap', '.'], [ { - q: 'Would you like to change any of the above configuration values?', + q: 'Would you like to change its configuration (y/N)?', r: 'n', } ]))