UNPKG

@edenjs/cli

Version:

Web Application Framework built on Express.js, Redis and RiotJS

303 lines (257 loc) 7.49 kB
// require dependencies const fs = require('fs-extra'); const path = require('path'); const chalk = require('chalk'); const Events = require('events'); const yargonaut = require('yargonaut'); // Must precede yargs const prettyTime = require('pretty-hrtime'); const extractComments = require('extract-comments'); // initialization logic const initEden = require('lib/utilities/init'); const packageJSON = require('../../package.json'); // Set yargs colors yargonaut .style('underline.green') .errorsStyle('red'); /** * create eden generator class * * @extends Events */ class EdenCore extends Events { /** * construct eden generator */ constructor() { // run super // eslint-disable-next-line prefer-rest-params super(...arguments); // bind base this.base = { command : this.baseCommand.bind(this), }; this.start = { command : this.startCommand.bind(this), handler : this.startHandler.bind(this), }; this.run = { command : this.runCommand.bind(this), handler : this.runHandler.bind(this), }; this.init = { command : this.initCommand.bind(this), handler : this.initHandler.bind(this), }; } // //////////////////////////////////////////////////////////////////////////// // // INIT METHODS // // //////////////////////////////////////////////////////////////////////////// /** * Init logger * * @param {Yargs} yy * @param {Function} logger */ build(yy, logger) { // assign logger this._logger = logger; // add namespaced commands return Promise.all(['base', 'start', 'run', 'init'].map((namespace) => { // return command return this[namespace].command(yy); })); } // //////////////////////////////////////////////////////////////////////////// // // BASE METHODS // // //////////////////////////////////////////////////////////////////////////// /** * Base Command function * * @param {yargs} yy */ baseCommand(yy) { // Hashbang must be removed for comment parser to work // I know this is stupid but it looks cool at the top of the script too :) const extractedComments = extractComments(fs.readFileSync(path.join(global.edenRoot, 'index.js'), 'utf8').split('\n').slice(1).join('\n')); const subText = extractedComments[0].raw; const logo = extractedComments[1].raw; // set process arguments const rtn = yy .usage(`${chalk.green(logo)}\n${chalk.bold(subText)}\n\nVersion: ${packageJSON.version}\n\nUsage: $0 <command> [options]`) .strict() .wrap(Math.min(100, yy.terminalWidth())) .demandCommand(1) .help('help', 'Show usage instructions') .alias('help', 'h'); // return handler return { usage : rtn, command : '', run : () => {}, }; } // //////////////////////////////////////////////////////////////////////////// // // START METHODS // // //////////////////////////////////////////////////////////////////////////// /** * Start Command function * * @param {yargs} yy */ startCommand(yy) { // command description const command = 'start'; const description = 'Starts EdenJS in production.'; // create command yy.command(command, description, () => { // return yy return yy .strict(false); // Additional options will be done in lib/aliases/config.js }); // return return { command, description, run : this.start.handler, }; } /** * Start run function */ startHandler() { // setup globals global.isCLI = false; // require base app const App = require(path.join(global.edenRoot, 'app.js')); // eslint-disable-line global-require, import/no-dynamic-require // run base app new App(); // eslint-disable-line no-new // The ride never ends return new Promise(() => {}); } // //////////////////////////////////////////////////////////////////////////// // // RUN METHODS // // //////////////////////////////////////////////////////////////////////////// /** * Start Command function * * @param {yargs} args */ runCommand(yy) { // command description const command = 'run [fn]'; const description = 'Runs EdenJS gulp function.'; // create command yy.command(command, description, () => { return yy .strict(false) // Additional options will be done in lib/aliases/config.js .positional('fn', { desc : 'Gulp function to run', default : 'dev', type : 'string', }); }); // return return { command, description, run : this.run.handler, }; } /** * Run Handler function * * @param {Object} args */ runHandler(args) { // run gulp logic (imports are local here for CLI optimization) const gulp = require('gulp'); // eslint-disable-line global-require require(path.join(global.edenRoot, 'gulpfile.js')); // eslint-disable-line global-require, import/no-dynamic-require // logged errors const loggedErrors = []; // add start logging gulp.on('start', (evt) => { this._logger.log(evt.branch ? 'debug' : 'info', `[${chalk.cyan(evt.name)}] Starting`); }); // add stop logging gulp.on('stop', (evt) => { this._logger.log(evt.branch ? 'debug' : 'info', `[${chalk.cyan(evt.name)}] Finished in ${chalk.magenta(prettyTime(evt.duration))}`); }); // on error gulp.on('error', (evt) => { this._logger.log(evt.branch ? 'debug' : 'error', `[${chalk.cyan(evt.name)}] Errored after ${chalk.magenta(prettyTime(evt.duration))}`); if (!loggedErrors.includes(evt.error)) { loggedErrors.push(evt.error); global.printError(evt.error); } }); // run task return new Promise((resolve, reject) => { // gulp series gulp.series([args.fn === 'dev' ? 'default' : args.fn])((err) => { if (err) { reject(err); } else { resolve(); } }); }); } // //////////////////////////////////////////////////////////////////////////// // // INIT METHODS // // //////////////////////////////////////////////////////////////////////////// /** * Init Command function * * @param {yargs} yy */ initCommand(yy) { // command description const command = 'init [dirType]'; const description = 'Initialize new or fix existing EdenJS directory.'; // create command yy.command(command, description, () => { // return build command return yy .positional('dirType', { desc : 'EdenJS directory type', type : 'string', }) .choices('dirType', ['app', 'module', 'none']) .option('migrateGit', { alias : 'g', describe : 'Migrate .git directory if misplaced in current directory', }); }); // return return { command, description, run : this.init.handler, }; } /** * Init handler function * * @param {Object} args */ async initHandler(args) { // init eden const res = await initEden(args.dirType, args.migrateGit); // log initialized this._logger.log('info', `[${chalk.green('init')}] Finished initializing type: ${res}`); } } // create new eden generator const edenCore = new EdenCore(); // export module module.exports = edenCore;