Skip to content

Commit

Permalink
refactor: use primordials (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
bcoe authored Jan 17, 2022
1 parent 421c6e2 commit a35c9b7
Show file tree
Hide file tree
Showing 7 changed files with 566 additions and 96 deletions.
6 changes: 4 additions & 2 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
{
"extends": ["plugin:eslint-plugin-node-core/recommended"],
"env": {
"node": true
"node": true,
"es6": true
},
"rules": {
"linebreak-style": 0
}
},
"ignorePatterns": ["README.md"]
}
6 changes: 6 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
coverage
test
.nycrc
.eslintrc
.github
CONTRIBUTING.md
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ const { parseArgs } = require('@pkgjs/parseargs');

```js
// unconfigured
const { parseArgs } = require('@pkgjs/parseargs');
const argv = ['-f', '--foo=a', '--bar', 'b'];
const options = {};
const { flags, values, positionals } = parseArgs(argv, options);
Expand All @@ -107,6 +108,7 @@ const { flags, values, positionals } = parseArgs(argv, options);
```

```js
const { parseArgs } = require('@pkgjs/parseargs');
// withValue
const argv = ['-f', '--foo=a', '--bar', 'b'];
const options = {
Expand All @@ -119,6 +121,7 @@ const { flags, values, positionals } = parseArgs(argv, options);
```

```js
const { parseArgs } = require('@pkgjs/parseargs');
// withValue & multiples
const argv = ['-f', '--foo=a', '--foo', 'b'];
const options = {
Expand All @@ -132,6 +135,7 @@ const { flags, values, positionals } = parseArgs(argv, options);
```

```js
const { parseArgs } = require('@pkgjs/parseargs');
// shorts
const argv = ['-f', 'b'];
const options = {
Expand Down
89 changes: 57 additions & 32 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
'use strict';

const {
ArrayIsArray,
ArrayPrototypeConcat,
ArrayPrototypeIncludes,
ArrayPrototypeSlice,
ArrayPrototypePush,
StringPrototypeCharAt,
StringPrototypeIncludes,
StringPrototypeSlice,
StringPrototypeSplit,
StringPrototypeStartsWith,
} = require('./primordials');

function getMainArgs() {
// This function is a placeholder for proposed process.mainArgs.
// Work out where to slice process.argv for user supplied arguments.
Expand All @@ -18,18 +31,20 @@ function getMainArgs() {
// (Not included in tests as hopefully temporary example.)
/* c8 ignore next 3 */
if (process.versions && process.versions.electron && !process.defaultApp) {
return process.argv.slice(1);
return ArrayPrototypeSlice(process.argv, 1);
}

// Check node options for scenarios where user CLI args follow executable.
const execArgv = process.execArgv;
if (execArgv.includes('-e') || execArgv.includes('--eval') ||
execArgv.includes('-p') || execArgv.includes('--print')) {
return process.argv.slice(1);
if (StringPrototypeIncludes(execArgv, '-e') ||
StringPrototypeIncludes(execArgv, '--eval') ||
StringPrototypeIncludes(execArgv, '-p') ||
StringPrototypeIncludes(execArgv, '--print')) {
return ArrayPrototypeSlice(process.argv, 1);
}

// Normally first two arguments are executable and script, then CLI arguments
return process.argv.slice(2);
return ArrayPrototypeSlice(process.argv, 2);
}

const parseArgs = (
Expand All @@ -39,7 +54,7 @@ const parseArgs = (
if (typeof options !== 'object' || options === null) {
throw new Error('Whoops!');
}
if (options.withValue !== undefined && !Array.isArray(options.withValue)) {
if (options.withValue !== undefined && !ArrayIsArray(options.withValue)) {
throw new Error('Whoops! options.withValue should be an array.');
}

Expand All @@ -53,37 +68,44 @@ const parseArgs = (
while (pos < argv.length) {
let arg = argv[pos];

if (arg.startsWith('-')) {
if (StringPrototypeStartsWith(arg, '-')) {
// Everything after a bare '--' is considered a positional argument
// and is returned verbatim
if (arg === '--') {
result.positionals.push(...argv.slice(++pos));
result.positionals = ArrayPrototypeConcat(
result.positionals,
ArrayPrototypeSlice(argv, ++pos)
);
return result;
} else if (arg.charAt(1) !== '-') { // Look for shortcodes: -fXzy
} else if (
StringPrototypeCharAt(arg, 1) !== '-'
) { // Look for shortcodes: -fXzy
throw new Error('What are we doing with shortcodes!?!');
}

arg = arg.slice(2); // remove leading --
arg = StringPrototypeSlice(arg, 2); // remove leading --

if (arg.includes('=')) {
if (StringPrototypeIncludes(arg, '=')) {
// withValue equals(=) case
const argParts = arg.split('=');
const argParts = StringPrototypeSplit(arg, '=');

result.flags[argParts[0]] = true;
// If withValue option is specified, take 2nd part after '=' as value,
// else set value as undefined
const val = options.withValue &&
options.withValue.includes(argParts[0]) ?
ArrayPrototypeIncludes(options.withValue, argParts[0]) ?
argParts[1] : undefined;
// Append value to previous values array for case of multiples
// option, else add to empty array
result.values[argParts[0]] = [].concat(
options.multiples &&
options.multiples.includes(argParts[0]) &&
result.values[argParts[0]] = ArrayPrototypeConcat([],
options.multiples &&
ArrayPrototypeIncludes(options.multiples, argParts[0]) &&
result.values[argParts[0]] || [],
val,
val,
);
} else if (pos + 1 < argv.length && !argv[pos + 1].startsWith('-')) {
} else if (pos + 1 < argv.length &&
!StringPrototypeStartsWith(argv[pos + 1], '-')
) {
// withValue option should also support setting values when '=
// isn't used ie. both --foo=b and --foo b should work

Expand All @@ -92,36 +114,39 @@ const parseArgs = (
// value and then increment pos so that we don't re-evaluate that
// arg, else set value as undefined ie. --foo b --bar c, after setting
// b as the value for foo, evaluate --bar next and skip 'b'
const val = options.withValue && options.withValue.includes(arg) ?
argv[++pos] :
const val = options.withValue &&
ArrayPrototypeIncludes(options.withValue, arg) ? argv[++pos] :
undefined;
// Append value to previous values array for case of multiples
// option, else add to empty array
result.values[arg] = [].concat(
options.multiples && options.multiples.includes(arg) &&
result.values[arg] ?
result.values[arg] :
[],
val);
result.values[arg] = ArrayPrototypeConcat(
[],
options.multiples &&
ArrayPrototypeIncludes(options.multiples, arg) &&
result.values[arg] ||
[],
val
);
} else {
// Cases when an arg is specified without a value, example
// '--foo --bar' <- 'foo' and 'bar' flags should be set to true and
// shave value as undefined
result.flags[arg] = true;
// Append undefined to previous values array for case of
// multiples option, else add to empty array
result.values[arg] = [].concat(
options.multiples && options.multiples.includes(arg) &&
result.values[arg] ?
result.values[arg] :
[],
result.values[arg] = ArrayPrototypeConcat(
[],
options.multiples &&
ArrayPrototypeIncludes(options.multiples, arg) &&
result.values[arg] ||
[],
undefined
);
}

} else {
// Arguements without a dash prefix are considered "positional"
result.positionals.push(arg);
ArrayPrototypePush(result.positionals, arg);
}

pos++;
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"scripts": {
"coverage": "c8 --check-coverage node test/index.js",
"test": "c8 node test/index.js",
"posttest": "eslint index.js",
"fix": "eslint index.js --fix"
"posttest": "eslint .",
"fix": "npm run posttest -- --fix"
},
"repository": {
"type": "git",
Expand Down
Loading

0 comments on commit a35c9b7

Please sign in to comment.