Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2021-06-13 13:46:35 +0300
committerMichaël Zasso <targos@protonmail.com>2021-06-21 21:18:20 +0300
commit1bbe66f432591aea83555d27dd76c55fea040a0d (patch)
tree112ae06f8c3c305341967af71acbeb82c1b0d02f /src/node_options-inl.h
parent86d6d816fd41bb015488c8a0022cc9cf4d1a174b (diff)
src: allow to negate boolean CLI flags
This change allows all boolean flags to be negated using the `--no-` prefix. Flags that are `true` by default (for example `--deprecation`) are still documented as negations. With this change, it becomes possible to easily flip the default value of a boolean flag and to override the value of a flag passed in the NODE_OPTIONS environment variable. `process.allowedNodeEnvironmentFlags` contains both the negated and non-negated versions of boolean flags. Co-authored-by: Anna Henningsen <anna@addaleax.net> PR-URL: https://github.com/nodejs/node/pull/39023 Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: Michael Dawson <midawson@redhat.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Diffstat (limited to 'src/node_options-inl.h')
-rw-r--r--src/node_options-inl.h36
1 files changed, 31 insertions, 5 deletions
diff --git a/src/node_options-inl.h b/src/node_options-inl.h
index 4e1a12296bc..7facb22afc3 100644
--- a/src/node_options-inl.h
+++ b/src/node_options-inl.h
@@ -23,12 +23,14 @@ template <typename Options>
void OptionsParser<Options>::AddOption(const char* name,
const char* help_text,
bool Options::* field,
- OptionEnvvarSettings env_setting) {
+ OptionEnvvarSettings env_setting,
+ bool default_is_true) {
options_.emplace(name,
OptionInfo{kBoolean,
std::make_shared<SimpleOptionField<bool>>(field),
env_setting,
- help_text});
+ help_text,
+ default_is_true});
}
template <typename Options>
@@ -186,7 +188,8 @@ auto OptionsParser<Options>::Convert(
return OptionInfo{original.type,
Convert(original.field, get_child),
original.env_setting,
- original.help_text};
+ original.help_text,
+ original.default_is_true};
}
template <typename Options>
@@ -225,6 +228,10 @@ inline std::string RequiresArgumentErr(const std::string& arg) {
return arg + " requires an argument";
}
+inline std::string NegationImpliesBooleanError(const std::string& arg) {
+ return arg + " is an invalid negation because it is not a boolean option";
+}
+
// We store some of the basic information around a single Parse call inside
// this struct, to separate storage of command line arguments and their
// handling. In particular, this makes it easier to introduce 'synthetic'
@@ -325,6 +332,13 @@ void OptionsParser<Options>::Parse(
name[i] = '-';
}
+ // Convert --no-foo to --foo and keep in mind that we're negating.
+ bool is_negation = false;
+ if (name.find("--no-") == 0) {
+ name.erase(2, 3); // remove no-
+ is_negation = true;
+ }
+
{
auto it = aliases_.end();
// Expand aliases:
@@ -367,7 +381,12 @@ void OptionsParser<Options>::Parse(
}
{
- auto implications = implications_.equal_range(name);
+ std::string implied_name = name;
+ if (is_negation) {
+ // Implications for negated options are defined with "--no-".
+ implied_name.insert(2, "no-");
+ }
+ auto implications = implications_.equal_range(implied_name);
for (auto it = implications.first; it != implications.second; ++it) {
if (it->second.type == kV8Option) {
v8_args->push_back(it->second.name);
@@ -384,6 +403,13 @@ void OptionsParser<Options>::Parse(
}
const OptionInfo& info = it->second;
+
+ // Some V8 options can be negated and they are validated by V8 later.
+ if (is_negation && info.type != kBoolean && info.type != kV8Option) {
+ errors->push_back(NegationImpliesBooleanError(arg));
+ break;
+ }
+
std::string value;
if (info.type != kBoolean && info.type != kNoOp && info.type != kV8Option) {
if (equals_index != std::string::npos) {
@@ -412,7 +438,7 @@ void OptionsParser<Options>::Parse(
switch (info.type) {
case kBoolean:
- *Lookup<bool>(info.field, options) = true;
+ *Lookup<bool>(info.field, options) = !is_negation;
break;
case kInteger:
*Lookup<int64_t>(info.field, options) = std::atoll(value.c_str());