Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/internal/fs/glob.js
Original file line number Diff line number Diff line change
Expand Up @@ -783,4 +783,5 @@ module.exports = {
__proto__: null,
Glob,
matchGlobPattern,
createMatcher,
};
18 changes: 17 additions & 1 deletion lib/internal/main/watch_mode.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';
const {
ArrayPrototypeFlatMap,
ArrayPrototypeForEach,
ArrayPrototypeJoin,
ArrayPrototypeMap,
Expand Down Expand Up @@ -27,14 +28,29 @@ const { inspect } = require('util');
const { setTimeout, clearTimeout } = require('timers');
const { resolve } = require('path');
const { once } = require('events');
const { createMatcher } = require('internal/fs/glob');
const { globSync } = require('fs');

prepareMainThreadExecution(false, false);
markBootstrapComplete();

function hasGlobPattern(path) {
return createMatcher(path).hasMagic();
}

function handleWatchedPath(path) {
if (hasGlobPattern(path)) {
const matchedFilesFromGlob = globSync(path);
const resolvedMatchedFiles = ArrayPrototypeMap(matchedFilesFromGlob, (path) => resolve(path));
return resolvedMatchedFiles;
}
return resolve(path);
}

const kKillSignal = convertToValidSignal(getOptionValue('--watch-kill-signal'));
const kShouldFilterModules = getOptionValue('--watch-path').length === 0;
Comment thread
louiellan marked this conversation as resolved.
Outdated
const kEnvFile = getOptionValue('--env-file') || getOptionValue('--env-file-if-exists');
const kWatchedPaths = ArrayPrototypeMap(getOptionValue('--watch-path'), (path) => resolve(path));
const kWatchedPaths = ArrayPrototypeFlatMap(getOptionValue('--watch-path'), (path) => handleWatchedPath(path));
const kPreserveOutput = getOptionValue('--watch-preserve-output');
const kCommand = ArrayPrototypeSlice(process.argv, 1);
const kCommandStr = inspect(ArrayPrototypeJoin(kCommand, ' '));
Expand Down
78 changes: 73 additions & 5 deletions test/sequential/test-watch-mode.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,21 @@ async function runWriteSucceed({
let stderr = '';
const stdout = [];

let watchedFiles = [];
let currentWatchedFileIndex = 0;
const isWatchingMultpileFiles = Array.isArray(watchedFile) && watchedFile.length > 1;
const isWatchingSingleFile = !isWatchingMultpileFiles;

if (isWatchingMultpileFiles) {
watchedFiles = watchedFile;
restarts = watchedFiles.length + 1;
}

child.stderr.on('data', (data) => {
stderr += data;
});


try {
// Break the chunks into lines
for await (const data of createInterface({ input: child.stdout })) {
Expand All @@ -120,11 +131,22 @@ async function runWriteSucceed({
}
if (data.startsWith(completed)) {
completes++;
if (completes === restarts) {
break;
}
if (completes === 1) {
cancelRestarts = restart(watchedFile);
if (isWatchingSingleFile) {
if (completes === restarts) {
break;
}
if (completes === 1) {
cancelRestarts = restart(watchedFile);
}
} else {
if (completes === restarts) {
break;
}
if (completes < restarts) {
cancelRestarts();
const currentlyWatchedFile = watchedFiles[currentWatchedFileIndex++];
cancelRestarts = restart(currentlyWatchedFile);
}
}
}

Expand Down Expand Up @@ -791,4 +813,50 @@ process.on('message', (message) => {
`Completed running ${inspect(file)}. Waiting for file changes before restarting...`,
]);
});

it('should watch files from a given glob pattern --watch-path=./**/*.js', async () => {

const tmpDirForGlobTest = tmpdir.resolve('glob-test-dir');
mkdirSync(tmpDirForGlobTest);

const globPattern = path.resolve(tmpDirForGlobTest, '**/*.js');

const directory1 = path.join(tmpDirForGlobTest, 'directory1');
const directory2 = path.join(tmpDirForGlobTest, 'directory2');

mkdirSync(directory1);
mkdirSync(directory2);

const tmpJsFile1 = createTmpFile('', '.js', directory1);
const tmpJsFile2 = createTmpFile('', '.js', directory1);
const tmpJsFile3 = createTmpFile('', '.js', directory2);
const tmpJsFile4 = createTmpFile('', '.js', directory2);
const tmpJsFile5 = createTmpFile('', '.js', directory2);

const mainJsFile = createTmpFile('console.log(\'running\')', '.js', tmpDirForGlobTest);

const args = ['--watch-path', globPattern, mainJsFile];
const watchedFiles = [tmpJsFile1, tmpJsFile2, tmpJsFile3, tmpJsFile4, tmpJsFile5];

const { stderr, stdout } = await runWriteSucceed({
args,
watchedFile: watchedFiles,
});

function expectRepeatedCompletes(n) {
const expectedStdout = [];
for (let i = 0; i < n; i++) {
if (i !== 0) {
expectedStdout.push(`Restarting ${inspect((mainJsFile))}`);
}
expectedStdout.push('running');
expectedStdout.push(`Completed running ${inspect(mainJsFile)}. Waiting for file changes before restarting...`);
}
return expectedStdout;
}

assert.strictEqual(stderr, '');
assert.deepStrictEqual(stdout, expectRepeatedCompletes(6));

});
});
Loading