Skip to content

Commit cdc049a

Browse files
watch: fix --watch args not being properly filtered
currently when --watch is used, the argv arguments that the target script receive are filtered so that they don't contains watch related values, however the current filtering logic is incorrect and it causes some watch values to incorrectly pass the filtering, the changes here address such issue
1 parent 62426a7 commit cdc049a

File tree

2 files changed

+71
-5
lines changed

2 files changed

+71
-5
lines changed

lib/internal/main/watch_mode.js

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,27 @@ const argsWithoutWatchOptions = [];
4343

4444
for (let i = 0; i < process.execArgv.length; i++) {
4545
const arg = process.execArgv[i];
46-
if (StringPrototypeStartsWith(arg, '--watch')) {
47-
i++;
48-
const nextArg = process.execArgv[i];
49-
if (nextArg && nextArg[0] === '-') {
50-
ArrayPrototypePush(argsWithoutWatchOptions, nextArg);
46+
if (StringPrototypeStartsWith(arg, '--watch=')) {
47+
continue;
48+
}
49+
if (arg === '--watch') {
50+
const nextArg = process.execArgv[i + 1];
51+
if (nextArg && nextArg[0] !== '-') {
52+
// If `--watch` doesn't include `=` and the next
53+
// argument is not a flag then it is interpreted
54+
// as the watch argument (which can be `true` or
55+
// `false`), so we need to skip that too
56+
i++;
57+
}
58+
continue;
59+
}
60+
if (StringPrototypeStartsWith(arg, '--watch-path')) {
61+
const lengthOfWatchPathStr = 12;
62+
if (arg[lengthOfWatchPathStr] !== '=') {
63+
// if --watch-path doesn't include `=` it means
64+
// that the next arg is the target path, so we
65+
// need to skip that as well
66+
i++;
5167
}
5268
continue;
5369
}

test/sequential/test-watch-mode.mjs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,4 +791,54 @@ process.on('message', (message) => {
791791
`Completed running ${inspect(file)}`,
792792
]);
793793
});
794+
795+
it('when multiple `--watch` flags are provided should run as if only one was', async () => {
796+
const projectDir = tmpdir.resolve('project-multi-flag');
797+
mkdirSync(projectDir);
798+
799+
const file = createTmpFile(`
800+
console.log(
801+
process.argv.some(arg => arg === '--watch')
802+
? 'Error: unexpected --watch args present'
803+
: 'no --watch args present'
804+
);`, '.js', projectDir);
805+
const args = ['--watch', '--watch', file];
806+
const { stdout, stderr } = await runWriteSucceed({
807+
file, watchedFile: file, watchFlag: null, args, options: { cwd: projectDir }
808+
});
809+
810+
assert.strictEqual(stderr, '');
811+
assert.deepStrictEqual(stdout, [
812+
'no --watch args present',
813+
`Completed running ${inspect(file)}`,
814+
`Restarting ${inspect(file)}`,
815+
'no --watch args present',
816+
`Completed running ${inspect(file)}`,
817+
]);
818+
});
819+
820+
it('`--watch-path` ars without `=` used alongside `--watch` should not make it into the script', async () => {
821+
const projectDir = tmpdir.resolve('project-watch-watch-path-args');
822+
mkdirSync(projectDir);
823+
824+
const file = createTmpFile(`
825+
console.log(
826+
process.argv.slice(2).some(arg => arg.endsWith('.js'))
827+
? 'some cli args end with .js'
828+
: 'no cli arg ends with .js'
829+
);`, '.js', projectDir);
830+
const args = ['--watch', `--watch-path`, file, file];
831+
const { stdout, stderr } = await runWriteSucceed({
832+
file, watchedFile: file, watchFlag: null, args, options: { cwd: projectDir }
833+
});
834+
835+
assert.strictEqual(stderr, '');
836+
assert.deepStrictEqual(stdout, [
837+
'no cli arg ends with .js',
838+
`Completed running ${inspect(file)}`,
839+
`Restarting ${inspect(file)}`,
840+
'no cli arg ends with .js',
841+
`Completed running ${inspect(file)}`,
842+
]);
843+
});
794844
});

0 commit comments

Comments
 (0)