Skip to content

Commit 475e4d8

Browse files
src: add watch config namespace
1 parent 6797c6e commit 475e4d8

File tree

6 files changed

+129
-11
lines changed

6 files changed

+129
-11
lines changed

doc/api/cli.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,9 @@ in the `$schema` must be replaced with the version of Node.js you are using.
10221022
},
10231023
"testRunner": {
10241024
"test-isolation": "process"
1025+
},
1026+
"watch": {
1027+
"watch-preserve-output": true
10251028
}
10261029
}
10271030
```

doc/node-config-schema.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,35 @@
734734
"type": "boolean"
735735
}
736736
}
737+
},
738+
"watch": {
739+
"type": "object",
740+
"additionalProperties": false,
741+
"properties": {
742+
"watch": {
743+
"type": "boolean"
744+
},
745+
"watch-kill-signal": {
746+
"type": "string"
747+
},
748+
"watch-path": {
749+
"oneOf": [
750+
{
751+
"type": "string"
752+
},
753+
{
754+
"items": {
755+
"type": "string",
756+
"minItems": 1
757+
},
758+
"type": "array"
759+
}
760+
]
761+
},
762+
"watch-preserve-output": {
763+
"type": "boolean"
764+
}
765+
}
737766
}
738767
},
739768
"type": "object"

lib/internal/main/watch_mode.js

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const {
1717
triggerUncaughtException,
1818
exitCodes: { kNoFailure },
1919
} = internalBinding('errors');
20-
const { getOptionValue } = require('internal/options');
20+
const { getOptionValue, getOptionsAsFlagsFromBinding } = require('internal/options');
2121
const { FilesWatcher } = require('internal/watch_mode/files_watcher');
2222
const { green, blue, red, white, clear } = require('internal/util/colors');
2323
const { convertToValidSignal } = require('internal/util');
@@ -40,14 +40,14 @@ const kCommand = ArrayPrototypeSlice(process.argv, 1);
4040
const kCommandStr = inspect(ArrayPrototypeJoin(kCommand, ' '));
4141

4242
const argsWithoutWatchOptions = [];
43-
44-
for (let i = 0; i < process.execArgv.length; i++) {
45-
const arg = process.execArgv[i];
43+
const argsFromBinding = getOptionsAsFlagsFromBinding();
44+
for (let i = 0; i < argsFromBinding.length; i++) {
45+
const arg = argsFromBinding[i];
4646
if (StringPrototypeStartsWith(arg, '--watch=')) {
4747
continue;
4848
}
4949
if (arg === '--watch') {
50-
const nextArg = process.execArgv[i + 1];
50+
const nextArg = argsFromBinding[i + 1];
5151
if (nextArg && nextArg[0] !== '-') {
5252
// If `--watch` doesn't include `=` and the next
5353
// argument is not a flag then it is interpreted as
@@ -66,6 +66,16 @@ for (let i = 0; i < process.execArgv.length; i++) {
6666
}
6767
continue;
6868
}
69+
if (StringPrototypeStartsWith(arg, '--experimental-config-file')) {
70+
if (!arg.includes('=')) {
71+
// Skip the flag and the next argument (the config file path)
72+
i++;
73+
}
74+
continue;
75+
}
76+
if (arg === '--experimental-default-config-file') {
77+
continue;
78+
}
6979
ArrayPrototypePush(argsWithoutWatchOptions, arg);
7080
}
7181

src/node_options.cc

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ void EnvironmentOptions::CheckOptions(std::vector<std::string>* errors,
242242
} else if (test_runner_force_exit) {
243243
errors->push_back("either --watch or --test-force-exit "
244244
"can be used, not both");
245-
} else if (!test_runner && (argv->size() < 1 || (*argv)[1].empty())) {
245+
} else if (!test_runner && watch_mode_paths.empty() && argv->size() < 1) {
246246
errors->push_back("--watch requires specifying a file");
247247
}
248248

@@ -1013,20 +1013,26 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
10131013
AddOption("--watch",
10141014
"run in watch mode",
10151015
&EnvironmentOptions::watch_mode,
1016-
kAllowedInEnvvar);
1016+
kAllowedInEnvvar,
1017+
false,
1018+
OptionNamespaces::kWatchNamespace);
10171019
AddOption("--watch-path",
10181020
"path to watch",
10191021
&EnvironmentOptions::watch_mode_paths,
1020-
kAllowedInEnvvar);
1022+
kAllowedInEnvvar,
1023+
OptionNamespaces::kWatchNamespace);
10211024
AddOption("--watch-kill-signal",
10221025
"kill signal to send to the process on watch mode restarts"
10231026
"(default: SIGTERM)",
10241027
&EnvironmentOptions::watch_mode_kill_signal,
1025-
kAllowedInEnvvar);
1028+
kAllowedInEnvvar,
1029+
OptionNamespaces::kWatchNamespace);
10261030
AddOption("--watch-preserve-output",
10271031
"preserve outputs on watch mode restart",
10281032
&EnvironmentOptions::watch_mode_preserve_output,
1029-
kAllowedInEnvvar);
1033+
kAllowedInEnvvar,
1034+
false,
1035+
OptionNamespaces::kWatchNamespace);
10301036
Implies("--watch-path", "--watch");
10311037
AddOption("--check",
10321038
"syntax check script without executing",

src/node_options.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,8 @@ std::vector<std::string> MapAvailableNamespaces();
415415
// Define all namespace entries
416416
#define OPTION_NAMESPACE_LIST(V) \
417417
V(kNoNamespace, "") \
418-
V(kTestRunnerNamespace, "testRunner")
418+
V(kTestRunnerNamespace, "testRunner") \
419+
V(kWatchNamespace, "watch")
419420

420421
enum class OptionNamespaces {
421422
#define V(name, _) name,

test/sequential/test-watch-mode.mjs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,4 +791,73 @@ process.on('message', (message) => {
791791
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
792792
]);
793793
});
794+
795+
it('should watch changes to a file from config file', async () => {
796+
const file = createTmpFile();
797+
const configFile = createTmpFile(JSON.stringify({ watch: { 'watch': true } }), '.json');
798+
const { stderr, stdout } = await runWriteSucceed({
799+
file, watchedFile: file, args: ['--experimental-config-file', configFile, file], options: {
800+
timeout: 10000
801+
}
802+
});
803+
804+
assert.strictEqual(stderr, '');
805+
assert.deepStrictEqual(stdout, [
806+
'running',
807+
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
808+
`Restarting ${inspect(file)}`,
809+
'running',
810+
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
811+
]);
812+
});
813+
814+
it('should watch changes to a file with watch-path from config file', {
815+
skip: !supportsRecursive,
816+
}, async () => {
817+
const dir = tmpdir.resolve('subdir4');
818+
mkdirSync(dir);
819+
const file = createTmpFile();
820+
const watchedFile = createTmpFile('', '.js', dir);
821+
const configFile = createTmpFile(JSON.stringify({ watch: { 'watch-path': [dir] } }), '.json', dir);
822+
823+
const args = ['--experimental-config-file', configFile, file];
824+
const { stderr, stdout } = await runWriteSucceed({ file, watchedFile, args });
825+
826+
assert.strictEqual(stderr, '');
827+
assert.deepStrictEqual(stdout, [
828+
'running',
829+
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
830+
`Restarting ${inspect(file)}`,
831+
'running',
832+
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
833+
]);
834+
assert.strictEqual(stderr, '');
835+
});
836+
837+
it('should watch changes to a file from default config file', async () => {
838+
const dir = tmpdir.resolve('subdir5');
839+
mkdirSync(dir);
840+
841+
const file = createTmpFile('console.log("running");', '.js', dir);
842+
writeFileSync(path.join(dir, 'node.config.json'), JSON.stringify({ watch: { 'watch': true } }));
843+
844+
const { stderr, stdout } = await runWriteSucceed({
845+
file,
846+
watchedFile: file,
847+
args: ['--experimental-default-config-file', file],
848+
options: {
849+
timeout: 10000,
850+
cwd: dir
851+
}
852+
});
853+
854+
assert.strictEqual(stderr, '');
855+
assert.deepStrictEqual(stdout, [
856+
'running',
857+
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
858+
`Restarting ${inspect(file)}`,
859+
'running',
860+
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
861+
]);
862+
});
794863
});

0 commit comments

Comments
 (0)