diff --git a/bin/cli.js b/bin/cli.js index 0feab0b4..e5706f1a 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -17,13 +17,8 @@ * */ - -let program = require('jake').program; -delete global.jake; // NO NOT WANT -program.setTaskNames = function (n) { this.taskNames = n; }; - let ejs = require('../lib/ejs'); -let { hyphenToCamel } = require('../lib/utils'); +let { hyphenToCamel, parseArgs } = require('../lib/utils'); let fs = require('fs'); let args = process.argv.slice(2); let usage = fs.readFileSync(`${__dirname}/../usage.txt`).toString(); @@ -99,13 +94,22 @@ const CLI_OPTS = [ }, ]; +function die(msg) { + console.log(msg); + process.stdout.write('', function () { + process.stderr.write('', function () { + process.exit(); + }); + }); +} + let preempts = { version: function () { - program.die(ejs.VERSION); + die(ejs.VERSION); }, help: function () { - program.die(usage); - } + die(usage); + }, }; let stdin = ''; @@ -118,10 +122,7 @@ process.stdin.on('readable', () => { }); function run() { - - program.availableOpts = CLI_OPTS; - program.parseArgs(args); - + let program = parseArgs(CLI_OPTS, args); let templatePath = program.taskNames[0]; let pVals = program.envVars; let pOpts = {}; diff --git a/lib/utils.js b/lib/utils.js index 5aef7c82..68257edf 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -208,4 +208,105 @@ exports.createNullProtoObjWherePossible = (function () { }; })(); +// Embedded argument parser from https://github.com/jakejs/jake/blob/master/lib/parseargs.js +// See original source for doc. +// Fixes #510 and allows removing `jake` as a prod dependency. +exports.parseArgs = function parseArgs(programOpts, programArgs) { + let isOpt = function (arg) { + return arg.indexOf('-') === 0; + }; + let removeOptPrefix = function (opt) { + return opt.replace(/^--/, '').replace(/^-/, ''); + }; + + const Parser = function (opts) { + this.opts = {}; + this.taskNames = null; + this.envVars = null; + this.reg = opts; + this.shortOpts = {}; + this.longOpts = {}; + + let self = this; + [].forEach.call(opts, function (item) { + self.shortOpts[item.abbr] = item; + self.longOpts[item.full] = item; + }); + }; + + Parser.prototype = new (function () { + let _trueOrNextVal = function (argParts, args) { + if (argParts[1]) { + return argParts[1]; + } else { + return !args[0] || isOpt(args[0]) ? true : args.shift(); + } + }; + + this.parse = function (args) { + let cmds = []; + let cmd; + let envVars = {}; + let opts = {}; + let arg; + let argItem; + let argParts; + let cmdItems; + let taskNames = []; + let preempt; + while (args.length) { + arg = args.shift(); + + if (isOpt(arg)) { + arg = removeOptPrefix(arg); + argParts = arg.split('='); + argItem = this.longOpts[argParts[0]] || this.shortOpts[argParts[0]]; + if (argItem) { + // First-encountered preemptive opt takes precedence -- no further opts + // or possibility of ambiguity, so just look for a value, or set to + // true and then bail + if (argItem.preempts) { + opts[argItem.full] = _trueOrNextVal(argParts, args); + preempt = true; + break; + } + // If the opt requires a value, see if we can get a value from the + // next arg, or infer true from no-arg -- if it's followed by another + // opt, throw an error + if (argItem.expectValue || argItem.allowValue) { + opts[argItem.full] = _trueOrNextVal(argParts, args); + if (argItem.expectValue && !opts[argItem.full]) { + throw new Error(argItem.full + ' option expects a value.'); + } + } else { + opts[argItem.full] = true; + } + } + } else { + cmds.unshift(arg); + } + } + + if (!preempt) { + // Parse out any env-vars and task-name + while ((cmd = cmds.pop())) { + cmdItems = cmd.split('='); + if (cmdItems.length > 1) { + envVars[cmdItems[0]] = cmdItems[1]; + } else { + taskNames.push(cmd); + } + } + } + + return { + opts: opts, + envVars: envVars, + taskNames: taskNames, + }; + }; + })(); + + return new Parser(programOpts).parse(programArgs); +}; diff --git a/package-lock.json b/package-lock.json index 77bd807b..be9d7fe6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -127,6 +127,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -197,12 +198,14 @@ "async": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "dev": true }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "base64-js": { "version": "1.3.1", @@ -232,6 +235,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -475,6 +479,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -568,6 +573,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "dev": true, "requires": { "color-name": "^1.1.1" } @@ -575,7 +581,8 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true }, "combine-source-map": { "version": "0.8.0", @@ -592,7 +599,8 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "concat-stream": { "version": "1.6.2", @@ -894,7 +902,8 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true }, "eslint": { "version": "6.8.0", @@ -1110,6 +1119,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.1.tgz", "integrity": "sha512-8zSK6Nu0DQIC08mUC46sWGXi+q3GGpKydAG36k+JDba6VRpkevvOWUW5a/PhShij4+vHT9M+ghgG7eM+a9JDUQ==", + "dev": true, "requires": { "minimatch": "^3.0.4" } @@ -1269,7 +1279,8 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true }, "has-symbols": { "version": "1.0.1", @@ -1593,6 +1604,7 @@ "version": "10.6.1", "resolved": "https://registry.npmjs.org/jake/-/jake-10.6.1.tgz", "integrity": "sha512-pHUK3+V0BjOb1XSi95rbBksrMdIqLVC9bJqDnshVyleYsET3H0XAq+3VB2E3notcYvv4wRdRHn13p7vobG+wfQ==", + "dev": true, "requires": { "async": "0.9.x", "chalk": "^2.4.2", @@ -1853,6 +1865,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -2760,6 +2773,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "requires": { "has-flag": "^3.0.0" } diff --git a/package.json b/package.json index 2e7bdb32..bb7621b4 100644 --- a/package.json +++ b/package.json @@ -21,13 +21,12 @@ }, "bugs": "https://github.com/mde/ejs/issues", "homepage": "https://github.com/mde/ejs", - "dependencies": { - "jake": "^10.6.1" - }, + "dependencies": {}, "devDependencies": { "browserify": "^16.5.1", "eslint": "^6.8.0", "git-directory-deploy": "^1.5.1", + "jake": "^10.6.1", "jsdoc": "^3.6.7", "lru-cache": "^4.0.1", "mocha": "^7.1.1",