| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -963,7 +963,7 @@ changes: | |||
| 963 | 963 | ||
| 964 | 964 | Enable experimental import support for `.node` addons. | |
| 965 | 965 | ||
| 966 | - ### `--experimental-config-file=config` | ||
| 966 | + ### `--experimental-config-file=path`, `--experimental-config-file` | ||
| 967 | 967 | ||
| 968 | 968 | <!-- YAML | |
| 969 | 969 | added: v23.10.0 | |
@@ -972,6 +972,12 @@ added: v23.10.0 | |||
| 972 | 972 | > Stability: 1.0 - Early development | |
| 973 | 973 | ||
| 974 | 974 | If present, Node.js will look for a configuration file at the specified path. | |
| 975 | + If the path is not specified, Node.js will look for a `node.config.json` file | ||
| 976 | + in the current working directory. | ||
| 977 | + To specify a custom path, use the `--experimental-config-file=path` form. | ||
| 978 | + The space-separated `--experimental-config-file path` form is not supported. | ||
| 979 | + The alias `--experimental-default-config-file` is equivalent to | ||
| 980 | + `--experimental-config-file` without an argument. | ||
| 975 | 981 | Node.js will read the configuration file and apply the settings. The | |
| 976 | 982 | configuration file should be a JSON file with the following structure. `vX.Y.Z` | |
| 977 | 983 | in the `$schema` must be replaced with the version of Node.js you are using or | |
@@ -1044,9 +1050,10 @@ added: v23.10.0 | |||
| 1044 | 1050 | ||
| 1045 | 1051 | > Stability: 1.0 - Early development | |
| 1046 | 1052 | ||
| 1047 | - If the `--experimental-default-config-file` flag is present, Node.js will look for a | ||
| 1053 | + This flag is an alias for `--experimental-config-file` without an argument. | ||
| 1054 | + If present, Node.js will look for a | ||
| 1048 | 1055 | `node.config.json` file in the current working directory and load it as a | |
| 1049 | - as configuration file. | ||
| 1056 | + configuration file. | ||
| 1050 | 1057 | ||
| 1051 | 1058 | ### `--experimental-eventsource` | |
| 1052 | 1059 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4698,7 +4698,7 @@ test.describe('my suite', (suite) => { | |||
| 4698 | 4698 | [`suite()`]: #suitename-options-fn | |
| 4699 | 4699 | [`test()`]: #testname-options-fn | |
| 4700 | 4700 | [code coverage]: #collecting-code-coverage | |
| 4701 | - [configuration files]: cli.md#--experimental-config-fileconfig | ||
| 4701 | + [configuration files]: cli.md#--experimental-config-filepath---experimental-config-file | ||
| 4702 | 4702 | [describe options]: #describename-options-fn | |
| 4703 | 4703 | [it options]: #testname-options-fn | |
| 4704 | 4704 | [module customization hooks]: module.md#customization-hooks | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -169,11 +169,75 @@ Interpret the entry point as a URL. | |||
| 169 | 169 | .It Fl -experimental-addon-modules | |
| 170 | 170 | Enable experimental addon module support. | |
| 171 | 171 | . | |
| 172 | - .It Fl -experimental-config-file | ||
| 173 | - Specifies the configuration file to load. | ||
| 172 | + .It Fl -experimental-config-file , Fl -experimental-config-file Ns = Ns Ar config , Fl -experimental-default-config-file | ||
| 173 | + If present, Node.js will look for a configuration file at the specified path. | ||
| 174 | + If the path is not specified, Node.js will look for a \fBnode.config.json\fR file | ||
| 175 | + in the current working directory. | ||
| 176 | + To specify a custom path, use the \fB--experimental-config-file=\fR\fBpath\fR form. | ||
| 177 | + The space-separated \fB--experimental-config-file path\fR form is not supported. | ||
| 178 | + Node.js will read the configuration file and apply the settings. The | ||
| 179 | + configuration file should be a JSON file with the following structure. \fBvX.Y.Z\fR | ||
| 180 | + in the \fB$schema\fR must be replaced with the version of Node.js you are using. | ||
| 181 | + .Bd -literal | ||
| 182 | + { | ||
| 183 | + "$schema": "https://nodejs.org/dist/vX.Y.Z/docs/node-config-schema.json", | ||
| 184 | + "nodeOptions": { | ||
| 185 | + "import": [ | ||
| 186 | + "amaro/strip" | ||
| 187 | + ], | ||
| 188 | + "watch-path": "src", | ||
| 189 | + "watch-preserve-output": true | ||
| 190 | + }, | ||
| 191 | + "testRunner": { | ||
| 192 | + "test-isolation": "process" | ||
| 193 | + }, | ||
| 194 | + "watch": { | ||
| 195 | + "watch-preserve-output": true | ||
| 196 | + } | ||
| 197 | + } | ||
| 198 | + .Ed | ||
| 199 | + The configuration file supports namespace-specific options: | ||
| 200 | + .Bl -bullet | ||
| 201 | + .It | ||
| 202 | + The \fBnodeOptions\fR field contains CLI flags that are allowed in \fBNODE_OPTIONS\fR. | ||
| 203 | + .It | ||
| 204 | + Namespace fields like \fBtestRunner\fR contain configuration specific to that subsystem. | ||
| 205 | + .El | ||
| 206 | + No-op flags are not supported. | ||
| 207 | + Not all V8 flags are currently supported. | ||
| 208 | + It is possible to use the official JSON schema | ||
| 209 | + to validate the configuration file, which may vary depending on the Node.js version. | ||
| 210 | + Each key in the configuration file corresponds to a flag that can be passed | ||
| 211 | + as a command-line argument. The value of the key is the value that would be | ||
| 212 | + passed to the flag. | ||
| 213 | + For example, the configuration file above is equivalent to | ||
| 214 | + the following command-line arguments: | ||
| 215 | + .Bd -literal | ||
| 216 | + node --import amaro/strip --watch-path=src --watch-preserve-output --test-isolation=process | ||
| 217 | + .Ed | ||
| 218 | + The priority in configuration is as follows: | ||
| 219 | + .Bl -bullet | ||
| 220 | + .It | ||
| 221 | + NODE_OPTIONS and command-line options | ||
| 222 | + .It | ||
| 223 | + Dotenv NODE_OPTIONS | ||
| 224 | + .It | ||
| 225 | + Configuration file | ||
| 226 | + .El | ||
| 227 | + Values in the configuration file will not override the values in the environment | ||
| 228 | + variables, command-line options, or the \fBNODE_OPTIONS\fR env file parsed by the | ||
| 229 | + \fB--env-file\fR flag. | ||
| 230 | + Keys cannot be duplicated within the same or different namespaces. | ||
| 231 | + The configuration parser will throw an error if the configuration file contains | ||
| 232 | + unknown keys or keys that cannot be used in a namespace. | ||
| 233 | + Node.js will not sanitize or perform validation on the user-provided configuration, | ||
| 234 | + so \fBNEVER\fR use untrusted configuration files. | ||
| 174 | 235 | . | |
| 175 | 236 | .It Fl -experimental-default-config-file | |
| 176 | - Enable support for automatically loading node.config.json. | ||
| 237 | + This flag is an alias for \fB--experimental-config-file\fR without an argument. | ||
| 238 | + If present, Node.js will look for a | ||
| 239 | + \fBnode.config.json\fR file in the current working directory and load it as a | ||
| 240 | + configuration file. | ||
| 177 | 241 | . | |
| 178 | 242 | .It Fl -experimental-import-meta-resolve | |
| 179 | 243 | Enable experimental ES modules support for import.meta.resolve(). | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,7 +1,6 @@ | |||
| 1 | 1 | 'use strict'; | |
| 2 | 2 | const { | |
| 3 | 3 | ArrayPrototypeForEach, | |
| 4 | - ArrayPrototypeIncludes, | ||
| 5 | 4 | ArrayPrototypeJoin, | |
| 6 | 5 | ArrayPrototypeMap, | |
| 7 | 6 | ArrayPrototypePush, | |
@@ -67,11 +66,8 @@ for (let i = 0; i < process.execArgv.length; i++) { | |||
| 67 | 66 | } | |
| 68 | 67 | continue; | |
| 69 | 68 | } | |
| 70 | - if (StringPrototypeStartsWith(arg, '--experimental-config-file')) { | ||
| 71 | - if (!ArrayPrototypeIncludes(arg, '=')) { | ||
| 72 | - // Skip the flag and the next argument (the config file path) | ||
| 73 | - i++; | ||
| 74 | - } | ||
| 69 | + if (arg === '--experimental-config-file' || | ||
| 70 | + StringPrototypeStartsWith(arg, '--experimental-config-file=')) { | ||
| 75 | 71 | continue; | |
| 76 | 72 | } | |
| 77 | 73 | if (arg === '--experimental-default-config-file') { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -386,8 +386,7 @@ function setupSQLite() { | |||
| 386 | 386 | } | |
| 387 | 387 | ||
| 388 | 388 | function initializeConfigFileSupport() { | |
| 389 | - if (getOptionValue('--experimental-default-config-file') || | ||
| 390 | - getOptionValue('--experimental-config-file')) { | ||
| 389 | + if (getOptionValue('--experimental-config-file')) { | ||
| 391 | 390 | emitExperimentalWarning('--experimental-config-file'); | |
| 392 | 391 | } | |
| 393 | 392 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -171,7 +171,11 @@ function createTestFileList(patterns, cwd) { | |||
| 171 | 171 | ||
| 172 | 172 | function filterExecArgv(arg, i, arr) { | |
| 173 | 173 | return !ArrayPrototypeIncludes(kFilterArgs, arg) && | |
| 174 | - !ArrayPrototypeSome(kFilterArgValues, (p) => arg === p || (i > 0 && arr[i - 1] === p) || StringPrototypeStartsWith(arg, `${p}=`)); | ||
| 174 | + !ArrayPrototypeSome(kFilterArgValues, (p) => { | ||
| 175 | + return arg === p || | ||
| 176 | + StringPrototypeStartsWith(arg, `${p}=`) || | ||
| 177 | + (p !== '--experimental-config-file' && i > 0 && arr[i - 1] === p); | ||
| 178 | + }); | ||
| 175 | 179 | } | |
| 176 | 180 | ||
| 177 | 181 | function getRunArgs(path, { forceExit, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -911,15 +911,21 @@ static ExitCode InitializeNodeWithArgsInternal( | |||
| 911 | 911 | } | |
| 912 | 912 | ||
| 913 | 913 | std::string node_options_from_config; | |
| 914 | - if (auto path = per_process::config_reader.GetDataFromArgs(*argv)) { | ||
| 915 | - switch (per_process::config_reader.ParseConfig(*path)) { | ||
| 914 | + auto config_path = per_process::config_reader.GetDataFromArgs(argv); | ||
| 915 | + if (per_process::config_reader.HasInvalidDefaultConfigFileArgument()) { | ||
| 916 | + errors->push_back("--experimental-default-config-file does not take an " | ||
| 917 | + "argument"); | ||
| 918 | + return ExitCode::kInvalidCommandLineArgument; | ||
| 919 | + } | ||
| 920 | + if (config_path) { | ||
| 921 | + switch (per_process::config_reader.ParseConfig(*config_path)) { | ||
| 916 | 922 | case ParseResult::Valid: | |
| 917 | 923 | break; | |
| 918 | 924 | case ParseResult::InvalidContent: | |
| 919 | - errors->push_back(std::string(*path) + ": invalid content"); | ||
| 925 | + errors->push_back(std::string(*config_path) + ": invalid content"); | ||
| 920 | 926 | break; | |
| 921 | 927 | case ParseResult::FileError: | |
| 922 | - errors->push_back(std::string(*path) + ": not found"); | ||
| 928 | + errors->push_back(std::string(*config_path) + ": not found"); | ||
| 923 | 929 | break; | |
| 924 | 930 | default: | |
| 925 | 931 | UNREACHABLE(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,39 +2,53 @@ | |||
| 2 | 2 | #include "debug_utils-inl.h" | |
| 3 | 3 | #include "simdjson.h" | |
| 4 | 4 | ||
| 5 | - #include <string> | ||
| 6 | - | ||
| 7 | 5 | namespace node { | |
| 8 | 6 | ||
| 7 | + constexpr std::string_view kConfigFileFlag = "--experimental-config-file"; | ||
| 8 | + constexpr std::string_view kDefaultConfigFileFlag = | ||
| 9 | + "--experimental-default-config-file"; | ||
| 10 | + constexpr std::string_view kDefaultConfigFileName = "node.config.json"; | ||
| 11 | + | ||
| 12 | + inline bool HasEqualsPrefix(std::string_view arg, std::string_view flag) { | ||
| 13 | + return arg.size() > flag.size() && arg.starts_with(flag) && | ||
| 14 | + arg[flag.size()] == '='; | ||
| 15 | + } | ||
| 16 | + | ||
| 9 | 17 | std::optional<std::string_view> ConfigReader::GetDataFromArgs( | |
| 10 | - const std::vector<std::string>& args) { | ||
| 11 | - constexpr std::string_view flag_path = "--experimental-config-file"; | ||
| 12 | - constexpr std::string_view default_file = | ||
| 13 | - "--experimental-default-config-file"; | ||
| 14 | - | ||
| 15 | - bool has_default_config_file = false; | ||
| 16 | - | ||
| 17 | - for (auto it = args.begin(); it != args.end(); ++it) { | ||
| 18 | - if (*it == flag_path) { | ||
| 19 | - // Case: "--experimental-config-file foo" | ||
| 20 | - if (auto next = std::next(it); next != args.end()) { | ||
| 21 | - return *next; | ||
| 18 | + std::vector<std::string>* args) { | ||
| 19 | + std::optional<std::string_view> result; | ||
| 20 | + invalid_default_config_file_argument_ = false; | ||
| 21 | + | ||
| 22 | + for (size_t i = 0; i < args->size(); ++i) { | ||
| 23 | + std::string& arg = (*args)[i]; | ||
| 24 | + | ||
| 25 | + if (arg == kConfigFileFlag) { | ||
| 26 | + // --experimental-config-file | ||
| 27 | + arg = std::string(kConfigFileFlag) + "=" + | ||
| 28 | + std::string(kDefaultConfigFileName); | ||
| 29 | + result = kDefaultConfigFileName; | ||
| 30 | + } else if (HasEqualsPrefix(arg, kConfigFileFlag)) { | ||
| 31 | + // --experimental-config-file=path | ||
| 32 | + std::string_view path = | ||
| 33 | + std::string_view(arg).substr(kConfigFileFlag.size() + 1); | ||
| 34 | + if (!path.empty()) { | ||
| 35 | + result = path; | ||
| 22 | 36 | } | |
| 23 | - } else if (it->starts_with(flag_path)) { | ||
| 24 | - // Case: "--experimental-config-file=foo" | ||
| 25 | - if (it->size() > flag_path.size() && (*it)[flag_path.size()] == '=') { | ||
| 26 | - return std::string_view(*it).substr(flag_path.size() + 1); | ||
| 27 | - } | ||
| 28 | - } else if (*it == default_file || it->starts_with(default_file)) { | ||
| 29 | - has_default_config_file = true; | ||
| 37 | + } else if (arg == kDefaultConfigFileFlag) { | ||
| 38 | + // --experimental-default-config-file | ||
| 39 | + arg = std::string(kConfigFileFlag) + "=" + | ||
| 40 | + std::string(kDefaultConfigFileName); | ||
| 41 | + result = kDefaultConfigFileName; | ||
| 42 | + } else if (HasEqualsPrefix(arg, kDefaultConfigFileFlag)) { | ||
| 43 | + invalid_default_config_file_argument_ = true; | ||
| 30 | 44 | } | |
| 31 | 45 | } | |
| 32 | 46 | ||
| 33 | - if (has_default_config_file) { | ||
| 34 | - return "node.config.json"; | ||
| 35 | - } | ||
| 47 | + return result; | ||
| 48 | + } | ||
| 36 | 49 | ||
| 37 | - return std::nullopt; | ||
| 50 | + bool ConfigReader::HasInvalidDefaultConfigFileArgument() const { | ||
| 51 | + return invalid_default_config_file_argument_; | ||
| 38 | 52 | } | |
| 39 | 53 | ||
| 40 | 54 | ParseResult ConfigReader::ProcessOptionValue( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -30,7 +30,8 @@ class ConfigReader { | |||
| 30 | 30 | ParseResult ParseConfig(const std::string_view& config_path); | |
| 31 | 31 | ||
| 32 | 32 | std::optional<std::string_view> GetDataFromArgs( | |
| 33 | - const std::vector<std::string>& args); | ||
| 33 | + std::vector<std::string>* args); | ||
| 34 | + bool HasInvalidDefaultConfigFileArgument() const; | ||
| 34 | 35 | ||
| 35 | 36 | std::string GetNodeOptions(); | |
| 36 | 37 | const std::vector<std::string>& GetNamespaceFlags() const; | |
@@ -53,6 +54,7 @@ class ConfigReader { | |||
| 53 | 54 | ||
| 54 | 55 | std::vector<std::string> node_options_; | |
| 55 | 56 | std::vector<std::string> namespace_options_; | |
| 57 | + bool invalid_default_config_file_argument_ = false; | ||
| 56 | 58 | ||
| 57 | 59 | // Cache for fast lookup of environment options | |
| 58 | 60 | std::unordered_map<std::string, options_parser::OptionMappingDetails> | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -856,11 +856,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { | |||
| 856 | 856 | &EnvironmentOptions::optional_env_file); | |
| 857 | 857 | Implies("--env-file-if-exists", "[has_env_file_string]"); | |
| 858 | 858 | AddOption("--experimental-config-file", | |
| 859 | - "set config file from supplied file", | ||
| 860 | - &EnvironmentOptions::experimental_config_file_path); | ||
| 861 | - AddOption("--experimental-default-config-file", | ||
| 862 | - "set config file from default config file", | ||
| 863 | - &EnvironmentOptions::experimental_default_config_file); | ||
| 859 | + "set config file path", | ||
| 860 | + &EnvironmentOptions::experimental_config_file_path, | ||
| 861 | + kDisallowedInEnvvar); | ||
| 862 | + AddAlias("--experimental-default-config-file", "--experimental-config-file"); | ||
| 864 | 863 | AddOption("--test", | |
| 865 | 864 | "launch test runner on startup", | |
| 866 | 865 | &EnvironmentOptions::test_runner, | |
| Back | FazBrowse Home | New Git URL |
0 commit comments