UNPKG

feds-cli

Version:

CLI for Front-end Dev Stack

188 lines (164 loc) 5.58 kB
/* create commander component * To use add require('../cmds/create.js')(program) to your commander.js based node executable before program.parse */ 'use strict'; require('shelljs/global'); var inquirer = require('inquirer'); var Case = require('case'); var r = require('../utils/reporter'); var path = require('path') var fse = require('fs-extra') var set = require('lodash.set') var each = require('lodash.foreach') var get = require('lodash.get') var assign = require('lodash.assign') var keys = require('lodash.keys') var template = require('lodash.template') var chalk = require('chalk') var readline = require('readline') var EMAIL_PATTERN = /^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*@([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i var REPO_PATTERN = /(?:git|ssh|https?|git@[\w\.]+):(?:\/\/)?[\w\.@:\/~_-]+\.git(?:\/?|\#[\d\w\.\-_]+?)$/ var GA_PATTERN = /\bUA-\d{4,10}(-\d{1,4})?\b/ var SEMVER_PATTERN = /\bv?(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)(?:-[\da-z\-]+(?:\.[\da-z\-]+)*)?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?\b/ig var QUESTIONS = [ { type: 'input', name: 'name', message: 'Project name', default: process.cwd().replace(/\/([^\/]+\/)+/gi, ''), filter: function(v) { return Case.kebab(v) } }, { type: 'input', name: 'version', message: 'Version', default: '0.0.0', validate: function(v) { return SEMVER_PATTERN.test(v) || 'Invalid version format. Should be MAJOR.MINOR.PATH. See semver.org for more info.' } }, { type: 'input', name: 'description', message: 'Project description' }, { type: 'input', name: 'author.name', message: 'Author name', default: '' }, { type: 'input', name: 'author.email', message: 'Author email', default: '', validate: function(v) { return v === '' || EMAIL_PATTERN.test(v) || 'Invalid email address' } }, { type: 'input', name: 'repository.url', message: 'Repo URL', default: '', validate: function(v) { return v === '' || REPO_PATTERN.test(v) || 'Invalid repo URL' } }, { type: 'list', name: 'createDir', message: 'Create folder for project?', choices: ['Yes', 'No'], default: 'Yes', filter: function(v) { return v === 'Yes' } } ]; function installDeps(location, callback) { exec('cd ' + location + ' && npm install', addCheckMark.bind(null, callback)); } function addCheckMark(callback) { process.stdout.write(chalk.green(' ✓')); callback(); } function animateProgress(message, amountOfDots) { if (typeof amountOfDots !== 'number') { amountOfDots = 3; } var i = 0; return setInterval(function() { readline.cursorTo(process.stdout, 0); i = (i + 1) % (amountOfDots + 1); var dots = new Array(i + 1) .join('.'); process.stdout.write(message + dots); }, 500); } module.exports = function(program) { var interval; program .command('create') .version('0.0.0') .description('Create a new Front-end Dev Stack project') .action(function() { if (!which('git')) { r.error('Sorry, this script requires git'); exit(1); } inquirer.prompt(QUESTIONS) .then(function(answers) { var PROJECT_ROOT = answers.createDir ? path.join(process.cwd(), answers.name) : process.cwd() // create project dir if (answers.createDir) { mkdir('-p', PROJECT_ROOT) r.success('Project folder created') } // check whether target folder is empty/exists if (ls('-A', PROJECT_ROOT) != '') { r.error('Project target folder is not empty.'); exit(1); } r.success('Target folder is available') // clone universal boilerplate if (exec('git clone https://git.siteone.cz/feds/universal-boilerplate.git ' + PROJECT_ROOT).code !== 0) { r.error('Creating new project failed.'); exit(1); } r.success('Successfully cloned project boilerplate') // update package meta var oldPackage = fse.readJsonSync(path.join(PROJECT_ROOT, 'package.json')) var newPackage = assign({}, oldPackage) each(keys(answers), function(key) { set(newPackage, key, get(answers, key)) }) // update package file fse.writeJsonSync(path.join(PROJECT_ROOT, 'package.json'), newPackage) r.success('Successfully composed project package.json') // remove boilerplate readme rm('-fr', path.join(PROJECT_ROOT, 'readme.md')) // compose new readme var templateReadme = template(fse.readFileSync(path.join(__dirname, '../templates/', 'readme._md'))) fse.writeFileSync(path.join(PROJECT_ROOT, 'README.md'), templateReadme(answers)) r.success('Successfully composed project README.md') // remove universal boilerplate repository rm('-fr', path.join(PROJECT_ROOT, '.git')) // initialize a new repository if (exec('cd ' + PROJECT_ROOT + ' && git init && git add . --all && git commit -qm "Initial commit"') .code !== 0) { r.error('Failed to initialize new repository'); exit(1) } r.success('Successfully initialized project repository') setTimeout(function() { readline.cursorTo(process.stdout, 0); interval = animateProgress('Installing dependencies'); }, 500); r.info('Installing project dependencies... (Will take a white)') installDeps(PROJECT_ROOT, function(error) { clearInterval(interval); if (error) { r.error(error); } }) }) }) }