UNPKG

js-pages

Version:

Custom Git script to compile JSDoc / ngdoc and deploy to gh-pages

418 lines (354 loc) 11.8 kB
/** * @overview * @author James Feigel {@link https://github.com/jfeigel|@jfeigel} * @description * Custom Git script to compile JSDoc / ngdoc and deploy to gh-pages * * @requires {@link https://github.com/petkaantonov/bluebird|bluebird} * @requires {@link https://github.com/chalk/chalk|chalk} * @requires {@link https://github.com/SBoudrias/Inquirer.js|Inquirer} */ "use strict"; const Promise = require("bluebird"); const chalk = require("chalk"); const inquirer = require("inquirer"); const execSync = require("child_process").execSync; const fs = require("fs"); const config = require("./config")(); const seperatorLine = "=============================="; const seperator = `\n${seperatorLine}\n` const squelch = "> /dev/null 2>&1"; let packageJSONExists = null; // Object to easily access the runner setup functions let runnerSetup = { "grunt": { "install": installGrunt, "configure": configureGrunt }, "gulp": { "install": installGulp, "configure": configureGulp } }; console.log(`\n${seperatorLine}`); console.log(chalk.gray.bgCyan(' JS-PAGES ')); console.log(`${seperatorLine}\n`); // Initial question set and kick-off point inquirer.prompt([ { "type": "list", "name": "runner", "message": "Which task runner will you use?", "choices": [ { "name": "Grunt", "value": "grunt", "short": "Grunt" }, { "name": "Gulp", "value": "gulp", "short": "Gulp" } ] }, { "type": "list", "name": "docs", "message": "Which documentation generator will you use?", "choices": ["ngdocs", "jsdoc"] }, { "type": "input", "name": "command_name", "message": "Name of custom Git command", "default": "pushdoc", "validate": function(value) { var pass = value.match(/^[A-Z]{1}([A-Z0-9-]+)?$/i); if (pass) { try { execSync(`git config -l --local | grep 'alias.${value}'`); if (overwriteAliasCommand === null || overwriteAliasCommand !== value) { overwriteAliasCommand = value; return "Alias already exists. Enter the same alias again to overwrite the current alias."; } else { execSync(`git config --local --unset-all alias.${answers.command_name}`); return true; } } catch (err) { return true; } } else { return "Please enter a valid command name"; } } }, { "type": "list", "name": "sudo", "message": "Are your npm packages installed with 'sudo'?", "choices": [ { "name": "No", "value": false, "short": "No" }, { "name": "Yes", "value": true, "short": "Yes" } ] } ], init); /** * @function * @name init * @description * Start setup after questions have been answered * * @param {Object} answers - Answer values from the setup questions */ function init(answers) { console.log(seperator); console.log(chalk.gray(`Setting up selected task runner: ${chalk.reset(answers.runner)}`)); // Check if package.json exists try { fs.statSync(`./package.json`); packageJSONExists = true; console.log(chalk.green('package.json exists')); console.log(chalk.gray('Running npm install...')); // If package.json exists make sure all listed packages are installed execSync(`npm install ${squelch}`); } catch (err) { packageJSONExists = false; console.log(chalk.yellow('package.json does not exist')); console.log(chalk.gray('Creating package.json with default options...')); // If package.json does not exist then create a new, default one execSync(`npm init --force ${squelch}`); } // Install documentation packages configureDocumentation(answers); // Initialize the selected task runner runnerSetup[answers.runner].install(answers); // Compile the runner's template files runnerSetup[answers.runner].configure(answers.docs, config['gh-pages'].name); // Configure the custom git script configureGitAlias(answers, config['gh-pages'].name); } //////////// /** * @function * @name checkInstall * @description * Check whether or not the given package is installed * * @param {String} packageToCheck - Name of the package to check * @param {boolean} isGlobal - Is the package supposed to be installed globally? * * @returns {boolean} Whether or not the package is installed */ function checkInstall(packageToCheck, isGlobal) { let command = 'npm list'; if (isGlobal === true) { command = `${command} -g`; } command = `${command} --depth 0 ${packageToCheck} ${squelch}` try { execSync(command); console.log(chalk.green(`${packageToCheck} is installed.`)); return true; } catch (err) { console.log(chalk.yellow(`${packageToCheck} is not installed.`)); return false; } } /** * @function * @name installPackage * @description * Install the given package * * @param {String} packageToInstall - Name of the package to install * @param {boolean} isGlobal - Should the package be installed globally? * @param {boolean} isSudo - Should the package be installed using `sudo`? * @param {String} doSave - Should the package be saved in `package.json`? ```['save', 'save-dev']``` */ function installPackage(packageToInstall, isGlobal, isSudo, doSave) { let command = 'npm install'; if (isSudo === true) { command = `sudo ${command}`; } if (isGlobal === true) { command = `${command} -g`; } if (packageToInstall !== null) { command = `${command} ${packageToInstall}`; } if (doSave) { command = `${command} --${doSave}`; } execSync(command); return true; } /** * @function * @name configureDocumentation * @description * Configure the documentation packages and gh-pages * * @param {Object} answers - Answer values from the setup questions */ function configureDocumentation(answers) { let docPackage = config.dependencies[answers.runner][answers.docs]; let ghpagesPackage = config.dependencies[answers.runner]['gh-pages']; console.log(chalk.gray(`Installing ${docPackage}...`)); installPackage(docPackage, false, answers.sudo, 'save-dev'); console.log(chalk.gray(`Installing ${ghpagesPackage}...`)); installPackage(ghpagesPackage, false, answers.sudo, 'save-dev'); if (answers.docs === 'jsdoc') { let jsdocConfFile = `${config.path.templates}/${[answers.runner]}/${config.jsdoc.conf}`; execSync(`cp ${jsdocConfFile} ./`); } // Create empty `docs` folder execSync('mkdir docs'); } /** * @function * @name installGrunt * @description * Install grunt as the task-runner * * @param {Object} answers - Answer values from the setup questions */ function installGrunt(answers) { console.log(chalk.gray("Installing 'grunt-cli' globally...")); installPackage('grunt-cli', true, answers.sudo); console.log(chalk.gray("Installing 'grunt' locally...")); installPackage('grunt', false, answers.sudo, 'save-dev'); } /** * @function * @name configureGrunt * @description * Configure grunt templates * * @param {String} runner - Selected task-runner * @param {String} docs - Selected documentation generator * @param {String} ghpages - Selected gh-pages script */ function configureGrunt(docs, ghpages) { console.log(chalk.gray("Compiling the grunt template file...")); let templateFilePath = `${config.path.templates}/grunt`; let gruntfileName = 'Gruntfile.js'; let gruntfileFiles = [ `"${templateFilePath}/Gruntfile_header.js"`, `"${templateFilePath}/Gruntfile_${ghpages}.js"`, `"${templateFilePath}/Gruntfile_${docs}.js"`, `"${templateFilePath}/Gruntfile_middle.js"`, `"${templateFilePath}/Gruntfile_${ghpages}_npm.js"`, `"${templateFilePath}/Gruntfile_${docs}_npm.js"`, `"${templateFilePath}/Gruntfile_footer.js"` ]; let gruntfileExists = fs.readdirSync('./').some((file, index, array) => { return file.toLowerCase() == gruntfileName.toLowerCase(); }); if (gruntfileExists === true) { console.log(chalk.yellow("Gruntfile.js already exists. Creating a temporary file instead...")); gruntfileName = `${gruntfileName}.tmp`; } execSync(`cat ${gruntfileFiles.join(' ')} > ${gruntfileName}`); } /** * @function * @name installGulp * @description * Install gulp as the task-runner * * @param {Object} answers - Answer values from the setup questions */ function installGulp(answers) { console.log(chalk.gray("Installing 'gulp'...")); installPackage('gulp', false, answers.sudo, 'save-dev'); } /** * @function * @name configureGulp * @description * Configure gulp templates * * @param {String} runner - Selected task-runner * @param {String} docs - Selected documentation generator * @param {String} ghpages - Selected gh-pages script */ function configureGulp(docs, ghpages) { console.log(chalk.gray("Compiling the gulp template files...")); let templateFilePath = `${config.path.templates}/gulp`; // gulp.config.js set up let gulpconfigName = 'gulp.config.js'; let gulpconfigFiles = [ `"${templateFilePath}/gulp.config_header.js"`, `"${templateFilePath}/gulp.config_${ghpages}.js"`, `"${templateFilePath}/gulp.config_${docs}.js"`, `"${templateFilePath}/gulp.config_footer.js"` ]; let gulpconfigExists = fs.readdirSync('./').some((file, index, array) => { return file.toLowerCase() == gulpconfigName.toLowerCase(); }); if (gulpconfigExists === true) { console.log(chalk.yellow("gulp.config.js already exists. Creating a temporary file instead...")); gulpconfigName = `${gulpconfigName}.tmp`; } execSync(`cat ${gulpconfigFiles.join(' ')} > ${gulpconfigName}`); // gulpfile.js set up let gulpfileName = 'gulpfile.js'; let gulpfileFiles = [ `"${templateFilePath}/gulpfile_header.js"`, `"${templateFilePath}/gulpfile_${ghpages}.js"`, `"${templateFilePath}/gulpfile_${docs}.js"`, `"${templateFilePath}/gulpfile_footer.js"` ]; let gulpfileExists = fs.readdirSync('./').some((file, index, array) => { return file.toLowerCase() == gulpfileName.toLowerCase(); }); if (gulpfileExists === true) { console.log(chalk.yellow("gulpfile.js already exists. Creating a temporary file instead...")); gulpfileName = `${gulpfileName}.tmp`; } execSync(`cat ${gulpfileFiles.join(' ')} > ${gulpfileName}`); } /** * @function * @name configureGitAlias * @description * Configure the custom git script * * @param {String} runner - Selected task-runner * @param {String} docs - Selected documentation generator * @param {String} ghpages - Selected gh-pages script * * @returns {Promise} Promise object that is resolved after Inquirer * and custom script creation completes */ function configureGitAlias(answers, ghpages) { try { console.log(chalk.gray('Verifying git has been initialized...')); execSync(`git status ${squelch}`); } catch (e) { console.log(chalk.yellow('Git has not been initialized')); console.log(chalk.gray('Initializing git...')); execSync(`git init ${squelch}`); } // Create the custom git script let gitFilePath = `./git-${answers.command_name}`; let stream = fs.createWriteStream(gitFilePath); stream.once('open', function(fd) { stream.write("#!/bin/sh\n\n"); stream.write("git push \"$@\"\n"); stream.write(`test $? -eq 0 && ${answers.runner} ${answers.docs} && ${answers.runner} ${ghpages}`) stream.end(); }); // Make the script executable fs.chmodSync(gitFilePath, "0755"); execSync(`git config --local --add alias.${answers.command_name} '!sh -c "./git-${answers.command_name}"'`); }