Skip to content

Commit b829958

Browse files
addaleaxtargos
authored andcommitted
src: make CLI options programatically accesible
Provide `internalBinding('options')` with some utilities around making the options parser and current options values programatically accessible. Backport-PR-URL: #22644 PR-URL: #22490 Reviewed-By: Michaël Zasso <[email protected]>
1 parent 7627b04 commit b829958

9 files changed

+478
-103
lines changed

src/env.h

+4
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ struct PackageConfig {
118118
// for the sake of convenience. Strings should be ASCII-only.
119119
#define PER_ISOLATE_STRING_PROPERTIES(V) \
120120
V(address_string, "address") \
121+
V(aliases_string, "aliases") \
121122
V(args_string, "args") \
122123
V(async, "async") \
123124
V(async_ids_stack_string, "async_ids_stack") \
@@ -156,6 +157,7 @@ struct PackageConfig {
156157
V(entries_string, "entries") \
157158
V(entry_type_string, "entryType") \
158159
V(env_pairs_string, "envPairs") \
160+
V(env_var_settings_string, "envVarSettings") \
159161
V(errno_string, "errno") \
160162
V(error_string, "error") \
161163
V(exit_code_string, "exitCode") \
@@ -176,6 +178,7 @@ struct PackageConfig {
176178
V(get_shared_array_buffer_id_string, "_getSharedArrayBufferId") \
177179
V(gid_string, "gid") \
178180
V(handle_string, "handle") \
181+
V(help_text_string, "helpText") \
179182
V(homedir_string, "homedir") \
180183
V(host_string, "host") \
181184
V(hostmaster_string, "hostmaster") \
@@ -233,6 +236,7 @@ struct PackageConfig {
233236
V(onunpipe_string, "onunpipe") \
234237
V(onwrite_string, "onwrite") \
235238
V(openssl_error_stack, "opensslErrorStack") \
239+
V(options_string, "options") \
236240
V(output_string, "output") \
237241
V(order_string, "order") \
238242
V(parse_error_string, "Parse Error") \

src/node.cc

+17-9
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ typedef int mode_t;
126126

127127
namespace node {
128128

129+
using options_parser::kAllowedInEnvironment;
130+
using options_parser::kDisallowedInEnvironment;
129131
using v8::Array;
130132
using v8::ArrayBuffer;
131133
using v8::Boolean;
@@ -183,6 +185,7 @@ bool linux_at_secure = false;
183185
// process-relative uptime base, initialized at start-up
184186
double prog_start_time;
185187

188+
Mutex per_process_opts_mutex;
186189
std::shared_ptr<PerProcessOptions> per_process_opts {
187190
new PerProcessOptions() };
188191

@@ -2346,8 +2349,6 @@ void LoadEnvironment(Environment* env) {
23462349
}
23472350

23482351
static void PrintHelp() {
2349-
// XXX: If you add an option here, please also add it to doc/node.1 and
2350-
// doc/api/cli.md
23512352
printf("Usage: node [options] [ -e script | script.js | - ] [arguments]\n"
23522353
" node inspect script.js [arguments]\n"
23532354
"\n"
@@ -2747,13 +2748,20 @@ void ProcessArgv(std::vector<std::string>* args,
27472748
// Parse a few arguments which are specific to Node.
27482749
std::vector<std::string> v8_args;
27492750
std::string error;
2750-
PerProcessOptionsParser::instance.Parse(
2751-
args,
2752-
exec_args,
2753-
&v8_args,
2754-
per_process_opts.get(),
2755-
is_env ? kAllowedInEnvironment : kDisallowedInEnvironment,
2756-
&error);
2751+
2752+
{
2753+
// TODO(addaleax): The mutex here should ideally be held during the
2754+
// entire function, but that doesn't play well with the exit() calls below.
2755+
Mutex::ScopedLock lock(per_process_opts_mutex);
2756+
options_parser::PerProcessOptionsParser::instance.Parse(
2757+
args,
2758+
exec_args,
2759+
&v8_args,
2760+
per_process_opts.get(),
2761+
is_env ? kAllowedInEnvironment : kDisallowedInEnvironment,
2762+
&error);
2763+
}
2764+
27572765
if (!error.empty()) {
27582766
fprintf(stderr, "%s: %s\n", args->at(0).c_str(), error.c_str());
27592767
exit(9);

src/node_internals.h

+2
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ struct sockaddr;
119119
V(js_stream) \
120120
V(messaging) \
121121
V(module_wrap) \
122+
V(options) \
122123
V(os) \
123124
V(performance) \
124125
V(pipe_wrap) \
@@ -176,6 +177,7 @@ extern Mutex environ_mutex;
176177
// Tells whether it is safe to call v8::Isolate::GetCurrent().
177178
extern bool v8_initialized;
178179

180+
extern Mutex per_process_opts_mutex;
179181
extern std::shared_ptr<PerProcessOptions> per_process_opts;
180182

181183
extern const char* const environment_flags[];

src/node_options-inl.h

+51-39
Original file line numberDiff line numberDiff line change
@@ -21,73 +21,88 @@ EnvironmentOptions* PerIsolateOptions::get_per_env_options() {
2121
return per_env.get();
2222
}
2323

24+
namespace options_parser {
25+
2426
template <typename Options>
2527
void OptionsParser<Options>::AddOption(const std::string& name,
28+
const std::string& help_text,
2629
bool Options::* field,
2730
OptionEnvvarSettings env_setting) {
28-
options_.emplace(name, OptionInfo {
29-
kBoolean,
30-
std::make_shared<SimpleOptionField<bool>>(field),
31-
env_setting
32-
});
31+
options_.emplace(name,
32+
OptionInfo{kBoolean,
33+
std::make_shared<SimpleOptionField<bool>>(field),
34+
env_setting,
35+
help_text});
3336
}
3437

3538
template <typename Options>
3639
void OptionsParser<Options>::AddOption(const std::string& name,
40+
const std::string& help_text,
3741
int64_t Options::* field,
3842
OptionEnvvarSettings env_setting) {
39-
options_.emplace(name, OptionInfo {
40-
kInteger,
41-
std::make_shared<SimpleOptionField<int64_t>>(field),
42-
env_setting
43-
});
43+
options_.emplace(
44+
name,
45+
OptionInfo{kInteger,
46+
std::make_shared<SimpleOptionField<int64_t>>(field),
47+
env_setting,
48+
help_text});
4449
}
4550

4651
template <typename Options>
4752
void OptionsParser<Options>::AddOption(const std::string& name,
53+
const std::string& help_text,
4854
std::string Options::* field,
4955
OptionEnvvarSettings env_setting) {
50-
options_.emplace(name, OptionInfo {
51-
kString,
52-
std::make_shared<SimpleOptionField<std::string>>(field),
53-
env_setting
54-
});
56+
options_.emplace(
57+
name,
58+
OptionInfo{kString,
59+
std::make_shared<SimpleOptionField<std::string>>(field),
60+
env_setting,
61+
help_text});
5562
}
5663

5764
template <typename Options>
5865
void OptionsParser<Options>::AddOption(
5966
const std::string& name,
67+
const std::string& help_text,
6068
std::vector<std::string> Options::* field,
6169
OptionEnvvarSettings env_setting) {
6270
options_.emplace(name, OptionInfo {
6371
kStringList,
6472
std::make_shared<SimpleOptionField<std::vector<std::string>>>(field),
65-
env_setting
73+
env_setting,
74+
help_text
6675
});
6776
}
6877

6978
template <typename Options>
7079
void OptionsParser<Options>::AddOption(const std::string& name,
80+
const std::string& help_text,
7181
HostPort Options::* field,
7282
OptionEnvvarSettings env_setting) {
73-
options_.emplace(name, OptionInfo {
74-
kHostPort,
75-
std::make_shared<SimpleOptionField<HostPort>>(field),
76-
env_setting
77-
});
83+
options_.emplace(
84+
name,
85+
OptionInfo{kHostPort,
86+
std::make_shared<SimpleOptionField<HostPort>>(field),
87+
env_setting,
88+
help_text});
7889
}
7990

8091
template <typename Options>
81-
void OptionsParser<Options>::AddOption(const std::string& name, NoOp no_op_tag,
92+
void OptionsParser<Options>::AddOption(const std::string& name,
93+
const std::string& help_text,
94+
NoOp no_op_tag,
8295
OptionEnvvarSettings env_setting) {
83-
options_.emplace(name, OptionInfo { kNoOp, nullptr, env_setting });
96+
options_.emplace(name, OptionInfo{kNoOp, nullptr, env_setting, help_text});
8497
}
8598

8699
template <typename Options>
87100
void OptionsParser<Options>::AddOption(const std::string& name,
101+
const std::string& help_text,
88102
V8Option v8_option_tag,
89103
OptionEnvvarSettings env_setting) {
90-
options_.emplace(name, OptionInfo { kV8Option, nullptr, env_setting });
104+
options_.emplace(name,
105+
OptionInfo{kV8Option, nullptr, env_setting, help_text});
91106
}
92107

93108
template <typename Options>
@@ -161,11 +176,10 @@ template <typename ChildOptions>
161176
auto OptionsParser<Options>::Convert(
162177
typename OptionsParser<ChildOptions>::OptionInfo original,
163178
ChildOptions* (Options::* get_child)()) {
164-
return OptionInfo {
165-
original.type,
166-
Convert(original.field, get_child),
167-
original.env_setting
168-
};
179+
return OptionInfo{original.type,
180+
Convert(original.field, get_child),
181+
original.env_setting,
182+
original.help_text};
169183
}
170184

171185
template <typename Options>
@@ -385,24 +399,21 @@ void OptionsParser<Options>::Parse(
385399

386400
switch (info.type) {
387401
case kBoolean:
388-
*std::static_pointer_cast<OptionField<bool>>(info.field)
389-
->Lookup(options) = true;
402+
*Lookup<bool>(info.field, options) = true;
390403
break;
391404
case kInteger:
392-
*std::static_pointer_cast<OptionField<int64_t>>(info.field)
393-
->Lookup(options) = std::atoll(value.c_str());
405+
*Lookup<int64_t>(info.field, options) = std::atoll(value.c_str());
394406
break;
395407
case kString:
396-
*std::static_pointer_cast<OptionField<std::string>>(info.field)
397-
->Lookup(options) = value;
408+
*Lookup<std::string>(info.field, options) = value;
398409
break;
399410
case kStringList:
400-
std::static_pointer_cast<OptionField<std::vector<std::string>>>(
401-
info.field)->Lookup(options)->emplace_back(std::move(value));
411+
Lookup<std::vector<std::string>>(info.field, options)
412+
->emplace_back(std::move(value));
402413
break;
403414
case kHostPort:
404-
std::static_pointer_cast<OptionField<HostPort>>(info.field)
405-
->Lookup(options)->Update(SplitHostPort(value, error));
415+
Lookup<HostPort>(info.field, options)
416+
->Update(SplitHostPort(value, error));
406417
break;
407418
case kNoOp:
408419
break;
@@ -415,6 +426,7 @@ void OptionsParser<Options>::Parse(
415426
}
416427
}
417428

429+
} // namespace options_parser
418430
} // namespace node
419431

420432
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

0 commit comments

Comments
 (0)