Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow function in watchOptions.ignored #197

Merged
merged 3 commits into from Nov 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -49,6 +49,8 @@ var wp = new Watchpack({
// ignored: "string" - a glob pattern for files or folders that should not be watched
// ignored: ["string", "string"] - multiple glob patterns that should be ignored
// ignored: /regexp/ - a regular expression for files or folders that should not be watched
// ignored: (entry) => boolean - an arbitrary function which must return truthy to ignore an entry
// For all cases expect the arbitrary function the path will have path separator normalized to '/'.
// All subdirectories are ignored too
});

Expand Down
14 changes: 4 additions & 10 deletions lib/DirectoryWatcher.js
Expand Up @@ -71,7 +71,7 @@ class DirectoryWatcher extends EventEmitter {
this.directories = new Map();
this.lastWatchEvent = 0;
this.initialScan = true;
this.ignored = options.ignored;
this.ignored = options.ignored || (() => false);
this.nestedWatching = false;
this.polledWatching =
typeof options.poll === "number"
Expand All @@ -96,12 +96,6 @@ class DirectoryWatcher extends EventEmitter {
this.doScan(true);
}

checkIgnore(path) {
if (!this.ignored) return false;
path = path.replace(/\\/g, "/");
return this.ignored.test(path);
}

createWatcher() {
try {
if (this.polledWatching) {
Expand Down Expand Up @@ -178,7 +172,7 @@ class DirectoryWatcher extends EventEmitter {
setFileTime(filePath, mtime, initial, ignoreWhenEqual, type) {
const now = Date.now();

if (this.checkIgnore(filePath)) return;
if (this.ignored(filePath)) return;

const old = this.files.get(filePath);

Expand Down Expand Up @@ -237,7 +231,7 @@ class DirectoryWatcher extends EventEmitter {
}

setDirectory(directoryPath, birthtime, initial, type) {
if (this.checkIgnore(directoryPath)) return;
if (this.ignored(directoryPath)) return;
if (directoryPath === this.path) {
if (!initial) {
this.forEachWatcher(this.path, w =>
Expand Down Expand Up @@ -398,7 +392,7 @@ class DirectoryWatcher extends EventEmitter {
}

const filePath = path.join(this.path, filename);
if (this.checkIgnore(filePath)) return;
if (this.ignored(filePath)) return;

if (this._activeEvents.get(filename) === undefined) {
this._activeEvents.set(filename, false);
Expand Down
18 changes: 10 additions & 8 deletions lib/watchpack.js
Expand Up @@ -31,24 +31,28 @@ const stringToRegexp = ignored => {
return matchingStart;
};

const ignoredToRegexp = ignored => {
const ignoredToFunction = ignored => {
if (Array.isArray(ignored)) {
return new RegExp(ignored.map(i => stringToRegexp(i)).join("|"));
const regexp = new RegExp(ignored.map(i => stringToRegexp(i)).join("|"));
return x => regexp.test(x.replace(/\\/g, "/"));
} else if (typeof ignored === "string") {
return new RegExp(stringToRegexp(ignored));
const regexp = new RegExp(stringToRegexp(ignored));
return x => regexp.test(x.replace(/\\/g, "/"));
} else if (ignored instanceof RegExp) {
return x => ignored.test(x.replace(/\\/g, "/"));
} else if (ignored instanceof Function) {
return ignored;
} else if (ignored) {
throw new Error(`Invalid option for 'ignored': ${ignored}`);
} else {
return undefined;
return () => false;
}
};

const normalizeOptions = options => {
return {
followSymlinks: !!options.followSymlinks,
ignored: ignoredToRegexp(options.ignored),
ignored: ignoredToFunction(options.ignored),
poll: options.poll
};
};
Expand Down Expand Up @@ -102,9 +106,7 @@ class Watchpack extends EventEmitter {
const oldFileWatchers = this.fileWatchers;
const oldDirectoryWatchers = this.directoryWatchers;
const ignored = this.watcherOptions.ignored;
const filter = ignored
? path => !ignored.test(path.replace(/\\/g, "/"))
: () => true;
const filter = path => !ignored(path);
const addToMap = (map, key, item) => {
const list = map.get(key);
if (list === undefined) {
Expand Down
26 changes: 26 additions & 0 deletions test/Watchpack.js
Expand Up @@ -118,6 +118,32 @@ describe("Watchpack", function() {
});
});

it("should not watch a single ignored file (function)", function(done) {
var w = new Watchpack({
aggregateTimeout: 300,
ignored: (entry) => entry.includes("a")
});
var changeEvents = 0;
var aggregatedEvents = 0;
w.on("change", () => {
changeEvents++;
});
w.on("aggregated", () => {
aggregatedEvents++;
});
w.watch([path.join(fixtures, "a")], []);
testHelper.tick(() => {
testHelper.file("a");
testHelper.tick(1000, () => {
changeEvents.should.be.eql(0);
aggregatedEvents.should.be.eql(0);
testHelper.getNumberOfWatchers().should.be.eql(0);
w.close();
done();
});
});
});

it("should watch multiple files", function(done) {
var w = new Watchpack({
aggregateTimeout: 1000
Expand Down