Skip to content

Commit 8943312

Browse files
author
Benjamin E. Coe
authored
refactor: most recent code review changes (#118)
1 parent 6ca85cd commit 8943312

File tree

3 files changed

+39
-34
lines changed

3 files changed

+39
-34
lines changed

README.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ added: REPLACEME
2121
Keys of `options` are the long names of options and values are an
2222
{Object} accepting the following properties:
2323
* `type` {string} Type of argument, which must be either `boolean` or `string`.
24-
**Default:** `boolean`.
2524
* `multiple` {boolean} Whether this option can be provided multiple
2625
times. If `true`, all values will be collected in an array. If
2726
`false`, values for the option are last-wins. **Default:** `false`.
@@ -30,20 +29,21 @@ added: REPLACEME
3029
are encountered, or when arguments are passed that do not match the
3130
`type` configured in `options`.
3231
**Default:** `true`.
33-
* `allowPositionals`: {boolean} Whether this command accepts positional arguments.
32+
* `allowPositionals`: {boolean} Whether this command accepts positional
33+
arguments.
3434
**Default:** `false` if `strict` is `true`, otherwise `true`.
3535

36-
* Returns: {Object} An {Object} representing the parsed command line
37-
arguments:
38-
* `values` {Object} With properties and {string} or {boolean} values
39-
corresponding to parsed options passed.
40-
* `positionals` {string\[]}, containing positional arguments.
36+
* Returns: {Object} The parsed command line arguments:
37+
* `values` {Object} A mapping of parsed option names with their {string}
38+
or {boolean} values.
39+
* `positionals` {string\[]} Positional arguments.
4140

4241
Provides a higher level API for command-line argument parsing than interacting
43-
with `process.argv` directly. Takes a specification for the expected arguments and returns a structured object with the parsed options and positionals.
42+
with `process.argv` directly. Takes a specification for the expected arguments
43+
and returns a structured object with the parsed options and positionals.
4444

4545
```mjs
46-
import { parseArgs } from 'util';
46+
import { parseArgs } from 'node:util';
4747
const args = ['-f', '--bar', 'b'];
4848
const options = {
4949
foo: {
@@ -58,10 +58,12 @@ const {
5858
values,
5959
positionals
6060
} = parseArgs({ args, options });
61+
console.log(values, positionals);
62+
// Prints: [Object: null prototype] { foo: true, bar: 'b' } []
6163
```
6264

6365
```cjs
64-
const { parseArgs } = require('util');
66+
const { parseArgs } = require('node:util');
6567
const args = ['-f', '--bar', 'b'];
6668
const options = {
6769
foo: {
@@ -76,6 +78,8 @@ const {
7678
values,
7779
positionals
7880
} = parseArgs({ args, options });
81+
console.log(values, positionals);
82+
// Prints: [Object: null prototype] { foo: true, bar: 'b' } []ss
7983
```
8084

8185
`util.parseArgs` is experimental and behavior may change. Join the

index.js

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
'use strict';
22

33
const {
4-
ArrayPrototypeConcat,
54
ArrayPrototypeForEach,
5+
ArrayPrototypeIncludes,
66
ArrayPrototypeShift,
77
ArrayPrototypeSlice,
88
ArrayPrototypePush,
9+
ArrayPrototypePushApply,
10+
ArrayPrototypeUnshiftApply,
911
ObjectEntries,
1012
ObjectPrototypeHasOwnProperty: ObjectHasOwn,
1113
StringPrototypeCharAt,
12-
StringPrototypeIncludes,
1314
StringPrototypeIndexOf,
1415
StringPrototypeSlice,
1516
} = require('./primordials');
@@ -32,7 +33,7 @@ const {
3233
isShortOptionAndValue,
3334
isShortOptionGroup,
3435
objectGetOwn,
35-
optionsGetOwn
36+
optionsGetOwn,
3637
} = require('./utils');
3738

3839
const {
@@ -48,29 +49,29 @@ function getMainArgs() {
4849
// This function is a placeholder for proposed process.mainArgs.
4950
// Work out where to slice process.argv for user supplied arguments.
5051

51-
// Electron is an interested example, with work-arounds implemented in
52+
// Electron is an interesting example, with workarounds implemented in
5253
// Commander and Yargs. Hopefully Electron would support process.mainArgs
53-
// itself and render this work-around moot.
54+
// itself and render this workaround moot.
5455
//
5556
// In a bundled Electron app, the user CLI args directly
5657
// follow executable. (No special processing required for unbundled.)
5758
// 1) process.versions.electron is either set by electron, or undefined
58-
// see https://github.com/electron/electron/blob/master/docs/api/process.md#processversionselectron-readonly
59+
// see: https://www.electronjs.org/docs/latest/api/process#processversionselectron-readonly
5960
// 2) process.defaultApp is undefined in a bundled Electron app, and set
6061
// in an unbundled Electron app
61-
// see https://github.com/electron/electron/blob/master/docs/api/process.md#processversionselectron-readonly
62+
// see: https://www.electronjs.org/docs/latest/api/process#processdefaultapp-readonly
6263
// (Not included in tests as hopefully temporary example.)
6364
/* c8 ignore next 3 */
64-
if (process.versions && process.versions.electron && !process.defaultApp) {
65+
if (process.versions?.electron && !process.defaultApp) {
6566
return ArrayPrototypeSlice(process.argv, 1);
6667
}
6768

6869
// Check node options for scenarios where user CLI args follow executable.
6970
const execArgv = process.execArgv;
70-
if (StringPrototypeIncludes(execArgv, '-e') ||
71-
StringPrototypeIncludes(execArgv, '--eval') ||
72-
StringPrototypeIncludes(execArgv, '-p') ||
73-
StringPrototypeIncludes(execArgv, '--print')) {
71+
if (ArrayPrototypeIncludes(execArgv, '-e') ||
72+
ArrayPrototypeIncludes(execArgv, '--eval') ||
73+
ArrayPrototypeIncludes(execArgv, '-p') ||
74+
ArrayPrototypeIncludes(execArgv, '--print')) {
7475
return ArrayPrototypeSlice(process.argv, 1);
7576
}
7677

@@ -107,6 +108,7 @@ To specify an option argument starting with a dash use ${example}.`;
107108
* @param {object} options - option configs, from parseArgs({ options })
108109
* @param {string} shortOrLong - option used, with dashes e.g. `-l` or `--long`
109110
* @param {boolean} strict - show errors, from parseArgs({ strict })
111+
* @param {boolean} allowPositionals - from parseArgs({ allowPositionals })
110112
*/
111113
function checkOptionUsage(longOption, optionValue, options,
112114
shortOrLong, strict, allowPositionals) {
@@ -203,7 +205,7 @@ const parseArgs = (config = { __proto__: null }) => {
203205
positionals: []
204206
};
205207

206-
let remainingArgs = ArrayPrototypeSlice(args);
208+
const remainingArgs = ArrayPrototypeSlice(args);
207209
while (remainingArgs.length > 0) {
208210
const arg = ArrayPrototypeShift(remainingArgs);
209211
const nextArg = remainingArgs[0];
@@ -216,7 +218,7 @@ const parseArgs = (config = { __proto__: null }) => {
216218
}
217219

218220
// Everything after a bare '--' is considered a positional argument.
219-
result.positionals = ArrayPrototypeConcat(
221+
ArrayPrototypePushApply(
220222
result.positionals,
221223
remainingArgs
222224
);
@@ -257,7 +259,7 @@ const parseArgs = (config = { __proto__: null }) => {
257259
break; // finished short group
258260
}
259261
}
260-
remainingArgs = ArrayPrototypeConcat(expanded, remainingArgs);
262+
ArrayPrototypeUnshiftApply(remainingArgs, expanded);
261263
continue;
262264
}
263265

@@ -309,5 +311,5 @@ const parseArgs = (config = { __proto__: null }) => {
309311
};
310312

311313
module.exports = {
312-
parseArgs
314+
parseArgs,
313315
};

utils.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@ const {
66
ObjectPrototypeHasOwnProperty: ObjectHasOwn,
77
StringPrototypeCharAt,
88
StringPrototypeIncludes,
9-
StringPrototypeSlice,
109
StringPrototypeStartsWith,
1110
} = require('./primordials');
1211

1312
const {
14-
validateObject
13+
validateObject,
1514
} = require('./validators');
1615

1716
// These are internal utilities to make the parsing logic easier to read, and
@@ -85,7 +84,7 @@ function isLoneShortOption(arg) {
8584
function isLoneLongOption(arg) {
8685
return arg.length > 2 &&
8786
StringPrototypeStartsWith(arg, '--') &&
88-
!StringPrototypeIncludes(StringPrototypeSlice(arg, 3), '=');
87+
!StringPrototypeIncludes(arg, '=', 3);
8988
}
9089

9190
/**
@@ -97,7 +96,7 @@ function isLoneLongOption(arg) {
9796
function isLongOptionAndValue(arg) {
9897
return arg.length > 2 &&
9998
StringPrototypeStartsWith(arg, '--') &&
100-
StringPrototypeIncludes(StringPrototypeSlice(arg, 3), '=');
99+
StringPrototypeIncludes(arg, '=', 3);
101100
}
102101

103102
/**
@@ -164,11 +163,11 @@ function isShortOptionAndValue(arg, options) {
164163
*/
165164
function findLongOptionForShort(shortOption, options) {
166165
validateObject(options, 'options');
167-
const { 0: longOption } = ArrayPrototypeFind(
166+
const longOptionEntry = ArrayPrototypeFind(
168167
ObjectEntries(options),
169168
({ 1: optionConfig }) => objectGetOwn(optionConfig, 'short') === shortOption
170-
) || [];
171-
return longOption || shortOption;
169+
);
170+
return longOptionEntry?.[0] ?? shortOption;
172171
}
173172

174173
module.exports = {
@@ -181,5 +180,5 @@ module.exports = {
181180
isShortOptionAndValue,
182181
isShortOptionGroup,
183182
objectGetOwn,
184-
optionsGetOwn
183+
optionsGetOwn,
185184
};

0 commit comments

Comments
 (0)