watch: fix watch args not being properly filtered

currently when --watch is used, the argv arguments that
the target script receives are filtered so that they don't
include watch related arguments, however the current
filtering logic is incorrect and it causes some watch values
to incorrectly pass the filtering, the changes here address
such issue

PR-URL: https://github.com/nodejs/node/pull/57936
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
This commit is contained in:
Dario Piotrowicz 2025-05-05 16:08:04 +01:00 committed by GitHub
parent c46b2b9da3
commit 4acb854039
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 70 additions and 5 deletions

View file

@ -43,11 +43,26 @@ const argsWithoutWatchOptions = [];
for (let i = 0; i < process.execArgv.length; i++) {
const arg = process.execArgv[i];
if (StringPrototypeStartsWith(arg, '--watch')) {
i++;
const nextArg = process.execArgv[i];
if (nextArg && nextArg[0] === '-') {
ArrayPrototypePush(argsWithoutWatchOptions, nextArg);
if (StringPrototypeStartsWith(arg, '--watch=')) {
continue;
}
if (arg === '--watch') {
const nextArg = process.execArgv[i + 1];
if (nextArg && nextArg[0] !== '-') {
// If `--watch` doesn't include `=` and the next
// argument is not a flag then it is interpreted as
// the watch argument, so we need to skip that as well
i++;
}
continue;
}
if (StringPrototypeStartsWith(arg, '--watch-path')) {
const lengthOfWatchPathStr = 12;
if (arg[lengthOfWatchPathStr] !== '=') {
// if --watch-path doesn't include `=` it means
// that the next arg is the target path, so we
// need to skip that as well
i++;
}
continue;
}

View file

@ -791,4 +791,54 @@ process.on('message', (message) => {
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
]);
});
it('when multiple `--watch` flags are provided should run as if only one was', async () => {
const projectDir = tmpdir.resolve('project-multi-flag');
mkdirSync(projectDir);
const file = createTmpFile(`
console.log(
process.argv.some(arg => arg === '--watch')
? 'Error: unexpected --watch args present'
: 'no --watch args present'
);`, '.js', projectDir);
const args = ['--watch', '--watch', file];
const { stdout, stderr } = await runWriteSucceed({
file, watchedFile: file, watchFlag: null, args, options: { cwd: projectDir }
});
assert.strictEqual(stderr, '');
assert.deepStrictEqual(stdout, [
'no --watch args present',
`Completed running ${inspect(file)}`,
`Restarting ${inspect(file)}`,
'no --watch args present',
`Completed running ${inspect(file)}`,
]);
});
it('`--watch-path` ars without `=` used alongside `--watch` should not make it into the script', async () => {
const projectDir = tmpdir.resolve('project-watch-watch-path-args');
mkdirSync(projectDir);
const file = createTmpFile(`
console.log(
process.argv.slice(2).some(arg => arg.endsWith('.js'))
? 'some cli args end with .js'
: 'no cli arg ends with .js'
);`, '.js', projectDir);
const args = ['--watch', `--watch-path`, file, file];
const { stdout, stderr } = await runWriteSucceed({
file, watchedFile: file, watchFlag: null, args, options: { cwd: projectDir }
});
assert.strictEqual(stderr, '');
assert.deepStrictEqual(stdout, [
'no cli arg ends with .js',
`Completed running ${inspect(file)}`,
`Restarting ${inspect(file)}`,
'no cli arg ends with .js',
`Completed running ${inspect(file)}`,
]);
});
});