Skip to content

Commit 6425807

Browse files
committed
cli: fix negated boolean options not removing implied options
1 parent 7560778 commit 6425807

2 files changed

Lines changed: 124 additions & 8 deletions

File tree

src/node_options-inl.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -388,18 +388,17 @@ void OptionsParser<Options>::Parse(
388388
}
389389

390390
{
391-
std::string implied_name = name;
392-
if (is_negation) {
393-
// Implications for negated options are defined with "--no-".
394-
implied_name.insert(2, "no-");
395-
}
396-
auto implications = implications_.equal_range(implied_name);
391+
auto implications = implications_.equal_range(name);
397392
for (auto imp = implications.first; imp != implications.second; ++imp) {
398393
if (imp->second.type == kV8Option) {
399394
v8_args->push_back(imp->second.name);
400395
} else {
401-
*imp->second.target_field->template Lookup<bool>(options) =
402-
imp->second.target_value;
396+
auto p = imp->second.target_field->template Lookup<bool>(options);
397+
if (is_negation) {
398+
if (it->second.type == kBoolean) *p = !imp->second.target_value;
399+
} else {
400+
*p = imp->second.target_value;
401+
}
403402
}
404403
}
405404
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const { describe, it } = require('node:test');
6+
7+
describe('negative and implies options', () => {
8+
it('should remove --inspect option when --no-inspect-brk is specified', async () => {
9+
const { stdout, stderr } = await common.spawnPromisified(
10+
process.execPath,
11+
['--inspect-brk=0', '--no-inspect-brk', '-e', "console.log('inspect-brk')"]);
12+
assert.strictEqual(stdout, 'inspect-brk\n');
13+
assert.strictEqual(stderr, '');
14+
});
15+
16+
it('should remove --inspect option when --no-inspect-wait is specified', async () => {
17+
const { stdout, stderr } = await common.spawnPromisified(
18+
process.execPath,
19+
['--inspect-wait=0', '--no-inspect-wait', '-e', "console.log('inspect-wait')"]);
20+
assert.strictEqual(stdout, 'inspect-wait\n');
21+
assert.strictEqual(stderr, '');
22+
});
23+
24+
it('should remove --trace-env option when --no-trace-env-js-stack is specified', async () => {
25+
const { stdout, stderr } = await common.spawnPromisified(
26+
process.execPath,
27+
['--trace-env-js-stack', '--no-trace-env-js-stack', '-e', "console.log('trace-env-js-stack')"]);
28+
assert.strictEqual(stdout, 'trace-env-js-stack\n');
29+
assert.strictEqual(stderr, '');
30+
});
31+
32+
it('should remove --trace-env option when --no-trace-env-native-stack is specified', async () => {
33+
const { stdout, stderr } = await common.spawnPromisified(
34+
process.execPath,
35+
['--trace-env-native-stack', '--no-trace-env-native-stack', '-e', "console.log('trace-env-native-stack')"]);
36+
assert.strictEqual(stdout, 'trace-env-native-stack\n');
37+
assert.strictEqual(stderr, '');
38+
});
39+
40+
it('should remove implies options when --no-experimental-transform-types is specified',
41+
async () => {
42+
{
43+
const { stdout, stderr } = await common.spawnPromisified(
44+
process.execPath,
45+
['--experimental-transform-types',
46+
'--no-experimental-transform-types',
47+
'-e',
48+
"console.log('experimental-transform-types')"]);
49+
assert.strictEqual(stdout, 'experimental-transform-types\n');
50+
assert.strictEqual(stderr, '');
51+
}
52+
{
53+
const { stderr } = await common.spawnPromisified(
54+
process.execPath,
55+
['--experimental-transform-types',
56+
'--no-experimental-transform-types',
57+
'../fixtures/source-map/throw-async.mjs']);
58+
assert.doesNotMatch(
59+
stderr,
60+
/at Throw \([^)]+throw-async\.ts:4:9\)/
61+
);
62+
}
63+
});
64+
it('should remove shadow-realm option when negate shadow-realm options are specified', async () => {
65+
{
66+
const { stdout, stderr } = await common.spawnPromisified(
67+
process.execPath,
68+
['--experimental-shadow-realm',
69+
'--no-experimental-shadow-realm',
70+
'-e',
71+
"new ShadowRealm().eval('console.log(1)')",
72+
]);
73+
assert.strictEqual(stdout, '');
74+
assert.match(stderr, /Error: Not supported/);
75+
}
76+
{
77+
const { stdout, stderr } = await common.spawnPromisified(
78+
process.execPath,
79+
['--harmony-shadow-realm', '--no-harmony-shadow-realm', '-e', "new ShadowRealm().eval('console.log(1)')"]);
80+
assert.strictEqual(stdout, '');
81+
assert.match(stderr, /ReferenceError: ShadowRealm is not defined/);
82+
}
83+
{
84+
const { stdout, stderr } = await common.spawnPromisified(
85+
process.execPath,
86+
['--harmony-shadow-realm', '--no-experimental-shadow-realm', '-e', "new ShadowRealm().eval('console.log(1)')"]);
87+
assert.strictEqual(stdout, '');
88+
assert.match(stderr, /Error: Not supported/);
89+
}
90+
{
91+
const { stdout, stderr } = await common.spawnPromisified(
92+
process.execPath,
93+
['--experimental-shadow-realm', '--no-harmony-shadow-realm', '-e', "new ShadowRealm().eval('console.log(1)')"]);
94+
assert.strictEqual(stdout, '');
95+
assert.match(stderr, /ReferenceError: ShadowRealm is not defined/);
96+
}
97+
});
98+
99+
100+
it('should not affect with only negation option', async () => {
101+
const { stdout, stderr } = await common.spawnPromisified(
102+
process.execPath,
103+
['--no-inspect-brk', '-e', "console.log('inspect-brk')"]);
104+
assert.strictEqual(stdout, 'inspect-brk\n');
105+
assert.strictEqual(stderr, '');
106+
});
107+
108+
it('should throw no boolean option error', async () => {
109+
const { stdout, stderr } = await common.spawnPromisified(
110+
process.execPath,
111+
[`--env-file=../fixtures/dotenv/.env`, '--no-env-file', '-e', 'const foo = 1'],
112+
{ cwd: __dirname });
113+
114+
assert.strictEqual(stdout, '');
115+
assert.match(stderr, /--no-env-file is an invalid negation because it is not a boolean option/);
116+
});
117+
});

0 commit comments

Comments
 (0)