Skip to content

Commit 0227635

Browse files
addaleaxdanbev
authored andcommitted
cli: normalize _- when parsing options
This allows for option syntax similar to V8’s one, e.g. `--no_warnings` has the same effect as `--no-warnings`. PR-URL: #23020 Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Richard Lau <[email protected]> Reviewed-By: Daniel Bevenius <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]>
1 parent 5605cec commit 0227635

File tree

8 files changed

+45
-58
lines changed

8 files changed

+45
-58
lines changed

doc/api/cli.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@ Execute without arguments to start the [REPL][].
2121
_For more info about `node inspect`, please see the [debugger][] documentation._
2222

2323
## Options
24+
<!-- YAML
25+
changes:
26+
- version: REPLACEME
27+
pr-url: https://github.com/nodejs/node/pull/23020
28+
description: Underscores instead of dashes are now allowed for
29+
Node.js options as well, in addition to V8 options.
30+
-->
31+
32+
All options, including V8 options, allow words to be separated by both
33+
dashes (`-`) or underscores (`_`).
34+
35+
For example, `--pending-deprecation` is equivalent to `--pending_deprecation`.
2436

2537
### `-`
2638
<!-- YAML
@@ -390,11 +402,6 @@ added: v0.1.3
390402

391403
Print V8 command line options.
392404

393-
V8 options allow words to be separated by both dashes (`-`) or
394-
underscores (`_`).
395-
396-
For example, `--stack-trace-limit` is equivalent to `--stack_trace_limit`.
397-
398405
### `--v8-pool-size=num`
399406
<!-- YAML
400407
added: v5.10.0

lib/internal/bootstrap/node.js

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@
742742
// This builds process.allowedNodeEnvironmentFlags
743743
// from data in the config binding
744744

745-
const replaceDashesRegex = /-/g;
745+
const replaceUnderscoresRegex = /_/g;
746746
const leadingDashesRegex = /^--?/;
747747
const trailingValuesRegex = /=.*$/;
748748

@@ -754,20 +754,14 @@
754754
const get = () => {
755755
const {
756756
getOptions,
757-
types: { kV8Option },
758757
envSettings: { kAllowedInEnvironment }
759758
} = internalBinding('options');
760759
const { options, aliases } = getOptions();
761760

762-
const allowedV8EnvironmentFlags = [];
763761
const allowedNodeEnvironmentFlags = [];
764762
for (const [name, info] of options) {
765763
if (info.envVarSettings === kAllowedInEnvironment) {
766-
if (info.type === kV8Option) {
767-
allowedV8EnvironmentFlags.push(name);
768-
} else {
769-
allowedNodeEnvironmentFlags.push(name);
770-
}
764+
allowedNodeEnvironmentFlags.push(name);
771765
}
772766
}
773767

@@ -801,11 +795,9 @@
801795
// process.allowedNodeEnvironmentFlags.has() which lack leading dashes.
802796
// Avoid interference w/ user code by flattening `Set.prototype` into
803797
// each object.
804-
const [nodeFlags, v8Flags] = [
805-
allowedNodeEnvironmentFlags, allowedV8EnvironmentFlags
806-
].map((flags) => Object.defineProperties(
807-
new Set(flags.map(trimLeadingDashes)),
808-
Object.getOwnPropertyDescriptors(Set.prototype))
798+
const nodeFlags = Object.defineProperties(
799+
new Set(allowedNodeEnvironmentFlags.map(trimLeadingDashes)),
800+
Object.getOwnPropertyDescriptors(Set.prototype)
809801
);
810802

811803
class NodeEnvironmentFlagsSet extends Set {
@@ -829,29 +821,18 @@
829821
has(key) {
830822
// This will return `true` based on various possible
831823
// permutations of a flag, including present/missing leading
832-
// dash(es) and/or underscores-for-dashes in the case of V8-specific
833-
// flags. Strips any values after `=`, inclusive.
824+
// dash(es) and/or underscores-for-dashes.
825+
// Strips any values after `=`, inclusive.
834826
// TODO(addaleax): It might be more flexible to run the option parser
835827
// on a dummy option set and see whether it rejects the argument or
836828
// not.
837829
if (typeof key === 'string') {
838-
key = replace(key, trailingValuesRegex, '');
830+
key = replace(key, replaceUnderscoresRegex, '-');
839831
if (test(leadingDashesRegex, key)) {
840-
return has(this, key) ||
841-
has(v8Flags,
842-
replace(
843-
replace(
844-
key,
845-
leadingDashesRegex,
846-
''
847-
),
848-
replaceDashesRegex,
849-
'_'
850-
)
851-
);
832+
key = replace(key, trailingValuesRegex, '');
833+
return has(this, key);
852834
}
853-
return has(nodeFlags, key) ||
854-
has(v8Flags, replace(key, replaceDashesRegex, '_'));
835+
return has(nodeFlags, key);
855836
}
856837
return false;
857838
}
@@ -862,7 +843,7 @@
862843

863844
return process.allowedNodeEnvironmentFlags = Object.freeze(
864845
new NodeEnvironmentFlagsSet(
865-
allowedNodeEnvironmentFlags.concat(allowedV8EnvironmentFlags)
846+
allowedNodeEnvironmentFlags
866847
));
867848
};
868849

src/node_options-inl.h

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,12 @@ void OptionsParser<Options>::Parse(
307307
if (equals_index != std::string::npos)
308308
original_name += '=';
309309

310+
// Normalize by replacing `_` with `-` in options.
311+
for (std::string::size_type i = 2; i < name.size(); ++i) {
312+
if (name[i] == '_')
313+
name[i] = '-';
314+
}
315+
310316
{
311317
auto it = aliases_.end();
312318
// Expand aliases:
@@ -341,19 +347,6 @@ void OptionsParser<Options>::Parse(
341347

342348
auto it = options_.find(name);
343349

344-
if (it == options_.end()) {
345-
// We would assume that this is a V8 option if neither we nor any child
346-
// parser knows about it, so we convert - to _ for
347-
// canonicalization (since V8 accepts both) and look up again in order
348-
// to find a match.
349-
// TODO(addaleax): Make the canonicalization unconditional, i.e. allow
350-
// both - and _ in Node's own options as well.
351-
std::string::size_type index = 2; // Start after initial '--'.
352-
while ((index = name.find('-', index + 1)) != std::string::npos)
353-
name[index] = '_';
354-
it = options_.find(name);
355-
}
356-
357350
if ((it == options_.end() ||
358351
it->second.env_setting == kDisallowedInEnvironment) &&
359352
required_env_settings == kAllowedInEnvironment) {

src/node_options.cc

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,6 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
102102
&EnvironmentOptions::experimental_worker,
103103
kAllowedInEnvironment);
104104
AddOption("--expose-internals", "", &EnvironmentOptions::expose_internals);
105-
// TODO(addaleax): Remove this when adding -/_ canonicalization to the parser.
106-
AddAlias("--expose_internals", "--expose-internals");
107105
AddOption("--loader",
108106
"(with --experimental-modules) use the specified file as a "
109107
"custom loader",
@@ -204,15 +202,15 @@ PerIsolateOptionsParser::PerIsolateOptionsParser() {
204202
kAllowedInEnvironment);
205203

206204
// Explicitly add some V8 flags to mark them as allowed in NODE_OPTIONS.
207-
AddOption("--abort_on_uncaught_exception",
205+
AddOption("--abort-on-uncaught-exception",
208206
"aborting instead of exiting causes a core file to be generated "
209207
"for analysis",
210208
V8Option{},
211209
kAllowedInEnvironment);
212-
AddOption("--max_old_space_size", "", V8Option{}, kAllowedInEnvironment);
213-
AddOption("--perf_basic_prof", "", V8Option{}, kAllowedInEnvironment);
214-
AddOption("--perf_prof", "", V8Option{}, kAllowedInEnvironment);
215-
AddOption("--stack_trace_limit", "", V8Option{}, kAllowedInEnvironment);
210+
AddOption("--max-old-space-size", "", V8Option{}, kAllowedInEnvironment);
211+
AddOption("--perf-basic-prof", "", V8Option{}, kAllowedInEnvironment);
212+
AddOption("--perf-prof", "", V8Option{}, kAllowedInEnvironment);
213+
AddOption("--stack-trace-limit", "", V8Option{}, kAllowedInEnvironment);
216214

217215
Insert(&EnvironmentOptionsParser::instance,
218216
&PerIsolateOptions::get_per_env_options);

test/parallel/test-cli-node-options-disallowed.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ disallow('--interactive');
2929
disallow('-i');
3030
disallow('--v8-options');
3131
disallow('--');
32-
disallow('--no_warnings'); // Node options don't allow '_' instead of '-'.
3332

3433
function disallow(opt) {
3534
const env = Object.assign({}, process.env, { NODE_OPTIONS: opt });

test/parallel/test-cli-node-options.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ expect(`-r ${printA}`, 'A\nB\n');
1919
expect(`-r ${printA} -r ${printA}`, 'A\nB\n');
2020
expect('--no-deprecation', 'B\n');
2121
expect('--no-warnings', 'B\n');
22+
expect('--no_warnings', 'B\n');
2223
expect('--trace-warnings', 'B\n');
2324
expect('--redirect-warnings=_', 'B\n');
2425
expect('--trace-deprecation', 'B\n');

test/parallel/test-pending-deprecation.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ switch (process.argv[2]) {
3636
assert.strictEqual(code, 0, message('--pending-deprecation'));
3737
}));
3838

39+
// Test the --pending_deprecation command line switch.
40+
fork(__filename, ['switch'], {
41+
execArgv: ['--pending_deprecation'],
42+
silent: true
43+
}).on('exit', common.mustCall((code) => {
44+
assert.strictEqual(code, 0, message('--pending_deprecation'));
45+
}));
46+
3947
// Test the NODE_PENDING_DEPRECATION environment var.
4048
fork(__filename, ['env'], {
4149
env: Object.assign({}, process.env, { NODE_PENDING_DEPRECATION: 1 }),

test/parallel/test-process-env-allowed-flags.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ require('../common');
1919
].concat(process.config.variables.v8_enable_inspector ? [
2020
'--inspect-brk',
2121
'inspect-brk',
22+
'--inspect_brk',
2223
] : []);
2324

2425
const badFlags = [
25-
'--inspect_brk',
2626
'INSPECT-BRK',
2727
'--INSPECT-BRK',
2828
'--r',

0 commit comments

Comments
 (0)