diff --git a/meta.js b/meta.js index 451e32d..c28a740 100644 --- a/meta.js +++ b/meta.js @@ -31,8 +31,7 @@ module.exports = { css: { type: 'list', - message: 'Pick your favorite CSS preprocessor: (can be changed later)', - default: 'scss', + message: 'Pick your CSS preprocessor:', choices: [ { name: 'Sass with SCSS syntax (recommended)', @@ -175,6 +174,12 @@ module.exports = { short: 'no', } ] + }, + + autoInitializeGit: { + type: 'confirm', + message: 'Automatically initialize git repository and commit all files?', + default: true, } }, diff --git a/utils/index.js b/utils/index.js index 8ce48e6..9625f45 100644 --- a/utils/index.js +++ b/utils/index.js @@ -1,8 +1,17 @@ const path = require('path') const fs = require('fs') -const spawn = require('child_process').spawn +const { spawn, execSync } = require('child_process') -const lintStyles = ['standard', 'airbnb', 'prettier'] +const lintStyles = ['prettier', 'standard', 'airbnb'] + +/** + * Shows a colored string prefixed with a star char + * @param {Function} color Helper color function + * @param {string} messagge Message to display + */ +function starredLog(color, message) { + console.log(`\n\n ${color(`[*] ${message}`)}\n\n`) +} /** * Sorts dependencies in package.json alphabetically. @@ -36,9 +45,18 @@ function sortDependencies(data) { * @param {string} cwd Path of the created project directory * @param {object} data Data from questionnaire */ -function installDependencies(cwd, executable = 'npm', color) { - console.log(`\n\n ${color('[*] Installing project dependencies ...')}\n`) - return runCommand(executable, ['install'], { cwd }) +async function installDependencies(cwd, executable = 'npm', color) { + starredLog(color, 'Installing project dependencies...') + + try { + await runCommand(executable, ['install'], { cwd }) + } catch(e) { + console.log() + console.log(` ${executable} install FAILED... Possible temporary npm registry issues?`) + console.log(` Please try again later...`) + console.log() + process.exit(1) + } } /** @@ -46,22 +64,23 @@ function installDependencies(cwd, executable = 'npm', color) { * @param {string} cwd Path of the created project directory * @param {object} data Data from questionnaire */ -function runLintFix(cwd, data, color) { +async function runLintFix(cwd, data, color) { if (data.preset.lint && lintStyles.indexOf(data.lintConfig) !== -1) { - console.log( - `\n\n ${color( - '[*] Running eslint --fix to comply with chosen preset rules...' - )}\n\n` - ) + starredLog(color, 'Running eslint --fix to comply with chosen preset rules...') const args = data.autoInstall === 'npm' ? ['run', 'lint', '--', '--fix'] : ['run', 'lint', '--fix'] - return runCommand(data.autoInstall, args, { - cwd, - }) + + try { + await runCommand(data.autoInstall, args, { cwd }) + } catch(e) { + console.log() + console.log(` ${data.autoInstall} lint FAILED...`) + console.log(` Please try again later...`) + console.log() + } } - return Promise.resolve() } /** @@ -77,6 +96,61 @@ function lintMsg(data) { : '' } +/** + * Checks if Git is present in the system + */ +function hasGit() { + try { + execSync('git --version', { stdio: 'ignore' }) + return true + } catch (e) { + return false + } +} + +/** + * Checks if the project already have an initialized Git repo + * @param {string} cwd Path of the created project directory + */ +function hasProjectGit(cwd) { + try { + execSync('git status', { stdio: 'ignore', cwd }) + return true + } catch (e) { + return false + } +} + +/** + * Initialize a git repository into the project directory, if possible + * @param {string} cwd Path of the created project directory + * @param {object} chalk Console log color helpers + */ +async function initializeGit(cwd, { green, yellow }) { + starredLog(green, 'Initializing Git repository...') + + if(!hasGit()) { + console.log(yellow(' Git is not present on the system, skipping...')) + return + } + + if(hasProjectGit(cwd)) { + console.log(yellow(' The project already have an initialized Git repository, skipping...')) + return + } + + await runCommand('git', ['init'], { cwd }) + await runCommand('git', ['add', '-A'], { cwd }) + + try { + await runCommand('git', ['commit', '-m', 'init', '--no-verify'], { cwd, stdio: 'ignore' }) + } catch (e) { + console.log() + console.log(yellow(' Skipped git commit because an error occurred, you will need to perform the initial commit yourself.')) + console.log() + } +} + /** * Prints the final message with instructions of necessary next steps. * @param {Object} data Data from questionnaire. @@ -143,14 +217,11 @@ function runCommand(cmd, args, options) { spwan.on('exit', code => { if (code) { - console.log() - console.log(` ${cmd} install FAILED... Possible temporary npm registry issues?`) - console.log(` Please try again later...`) - console.log() - process.exit(1) + reject(code) + } + else { + resolve() } - - resolve() }) }) } @@ -166,26 +237,25 @@ function sortObject(object) { return sortedObject } -module.exports.complete = function (data, { chalk }) { - const green = chalk.green +module.exports.complete = async function (data, { chalk }) { + const { green } = chalk sortDependencies(data, green) const cwd = path.join(process.cwd(), data.inPlace ? '' : data.destDirName) - if (data.autoInstall) { - installDependencies(cwd, data.autoInstall, green) - .then(() => { - return runLintFix(cwd, data, green) - }) - .then(() => { - printMessage(data, green) - }) - .catch(e => { - console.log(chalk.red('Error:'), e) - }) - } - else { - printMessage(data, chalk) + try { + if (data.autoInstall) { + await installDependencies(cwd, data.autoInstall, green) + await runLintFix(cwd, data, green) + } + + if (data.autoInitializeGit) { + await initializeGit(cwd, chalk) + } + } catch(e) { + console.log(chalk.red('Error:'), e) } + + printMessage(data, chalk) }