watch: fix interaction with multiple env files

PR-URL: https://github.com/nodejs/node/pull/60605
Fixes: https://github.com/nodejs/node/issues/60599
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Stefan Stojanovic <stefan.stojanovic@janeasystems.com>
Reviewed-By: Pietro Marchini <pietro.marchini94@gmail.com>
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
Marco Ippolito 2025-11-08 15:35:07 +01:00 committed by GitHub
parent 1727a8f1b2
commit 4e7f9c997d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 43 additions and 5 deletions

View File

@ -34,7 +34,10 @@ markBootstrapComplete();
const kKillSignal = convertToValidSignal(getOptionValue('--watch-kill-signal'));
const kShouldFilterModules = getOptionValue('--watch-path').length === 0;
const kEnvFile = getOptionValue('--env-file') || getOptionValue('--env-file-if-exists');
const kEnvFiles = [
...getOptionValue('--env-file'),
...getOptionValue('--env-file-if-exists'),
];
const kWatchedPaths = ArrayPrototypeMap(getOptionValue('--watch-path'), (path) => resolve(path));
const kPreserveOutput = getOptionValue('--watch-preserve-output');
const kCommand = ArrayPrototypeSlice(process.argv, 1);
@ -100,8 +103,8 @@ function start() {
},
});
watcher.watchChildProcessModules(child);
if (kEnvFile) {
watcher.filterFile(resolve(kEnvFile));
if (kEnvFiles.length > 0) {
ArrayPrototypeForEach(kEnvFiles, (file) => watcher.filterFile(resolve(file)));
}
child.once('exit', (code) => {
exited = true;

View File

@ -185,8 +185,8 @@ class EnvironmentOptions : public Options {
#endif // HAVE_INSPECTOR
std::string redirect_warnings;
std::string diagnostic_dir;
std::string env_file;
std::string optional_env_file;
std::vector<std::string> env_file;
std::vector<std::string> optional_env_file;
bool has_env_file_string = false;
bool test_runner = false;
uint64_t test_runner_concurrency = 0;

View File

@ -39,6 +39,17 @@ describe('.env supports edge cases', () => {
})));
});
it('should not support comma-separated env files', async () => {
const code = 'assert.strictEqual(1, 1)';
const child = await common.spawnPromisified(
process.execPath,
[`--env-file=${validEnvFilePath},${nodeOptionsEnvFilePath}`, '--eval', code],
{ cwd: __dirname },
);
assert.notStrictEqual(child.stderr, '');
assert.strictEqual(child.code, 9);
});
it('supports absolute paths', async () => {
const code = `
assert.strictEqual(process.env.BASIC, 'basic');

View File

@ -860,4 +860,28 @@ process.on('message', (message) => {
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
]);
});
it('should support multiple --env-file flags', async () => {
const envKey = `TEST_ENV_A_${Date.now()}`;
const envKey2 = `TEST_ENV_B_${Date.now()}`;
const jsFile = createTmpFile(`console.log('ENV_A: ' + process.env.${envKey} + '\\n' + 'ENV_B: ' + process.env.${envKey2});`);
const envFileA = createTmpFile(`${envKey}=123`, '.env');
const envFileB = createTmpFile(`${envKey2}=456`, '.env');
const { done, restart } = runInBackground({
args: ['--watch', `--env-file=${envFileA}`, `--env-file=${envFileB}`, jsFile]
});
try {
const { stderr, stdout } = await restart();
assert.strictEqual(stderr, '');
assert.deepStrictEqual(stdout, [
'ENV_A: 123',
'ENV_B: 456',
`Completed running ${inspect(jsFile)}. Waiting for file changes before restarting...`,
]);
} finally {
await done();
}
});
});