Skip to content

Commit

Permalink
Merge f4d0e65 into 24ad42f
Browse files Browse the repository at this point in the history
  • Loading branch information
ijjk committed Feb 15, 2020
2 parents 24ad42f + f4d0e65 commit ac9697c
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 0 deletions.
47 changes: 47 additions & 0 deletions lib/DirectoryWatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ class DirectoryWatcher extends EventEmitter {
this.scanning = false;
this.scanAgain = false;
this.scanAgainInitial = false;
this.isCaseInsensitive = undefined;

// check if we're on a case insensitive system
try {
fs.statSync(__dirname.toUpperCase());
this.isCaseInsensitive = true;
} catch (_) {
this.isCaseInsensitive = false;
}

this.createWatcher();
this.doScan(true);
Expand Down Expand Up @@ -374,6 +383,44 @@ class DirectoryWatcher extends EventEmitter {
return;
}
this._activeEvents.delete(filename);

if (this.isCaseInsensitive) {
// we need to make sure the file's casing wasn't
// changed on a case insensitive filesystem
const noCaseFilePath = withoutCase(filePath);
const dirCache = {};

for (const file of Array.from(this.files.keys()).concat(filePath)) {
if (withoutCase(file) === noCaseFilePath) {
const curFileDir = path.dirname(file);

if (!dirCache[curFileDir]) {
try {
dirCache[curFileDir] = fs.readdirSync(curFileDir);
} catch (err) {
if (err.code === "ENOENT" || err.code === "EPERM") {
this.setMissing(file, false, eventType);
if (file === filePath) return;
break;
}
throw err;
}
}
const curFilename = path.basename(file);

if (
!dirCache[curFileDir].some(curFile => curFile === curFilename)
) {
this.setMissing(file, false, eventType);
// make sure to return so we don't re-add it below
if (file === filePath) {
return;
}
}
}
}
}

// ENOENT happens when the file/directory doesn't exist
// EPERM happens when the containing directory doesn't exist
if (err) {
Expand Down
66 changes: 66 additions & 0 deletions test/Casing.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,71 @@ if (fsIsCaseInsensitive) {
testHelper.file("A");
});
});

it("should mark as missing on changing filename casing (dir watch)", function(done) {
var w = new Watchpack({
aggregateTimeout: 1000
});
var dir = "case-rename";
var testFile = path.join(dir, "hello.txt");
var testFileRename = path.join(dir, "hEllO.txt");
testHelper.dir(dir);
testHelper.file(testFile);

let afterRename = false;

w.on("aggregated", function(changes, removals) {
if (!afterRename) return;
const files = w.getTimeInfoEntries();
w.close();

for (const file of files.keys()) {
if (file.endsWith("hello.txt")) {
return done(new Error(`Renamed file was still in timeInfoEntries`));
}
}
return done();
});

w.watch([], [path.join(fixtures, "case-rename")], 0);

testHelper.tick(function() {
afterRename = true;
testHelper.rename(testFile, testFileRename);
});
});

it("should mark as missing on changing filename casing (file watch)", function(done) {
var w = new Watchpack({
aggregateTimeout: 1000
});
var dir = "case-rename";
var testFile = path.join(dir, "hello.txt");
var testFileRename = path.join(dir, "hEllO.txt");
testHelper.dir(dir);
testHelper.file(testFile);

let afterRename = false;

w.on("aggregated", function(changes, removals) {
if (!afterRename) return;
const files = w.getTimeInfoEntries();
w.close();

for (const file of files.keys()) {
if (file.endsWith("hello.txt") && files.get(file)) {
return done(new Error(`Renamed file was still in timeInfoEntries`));
}
}
return done();
});

w.watch([path.join(fixtures, testFile)], [], 0);

testHelper.tick(function() {
afterRename = true;
testHelper.rename(testFile, testFileRename);
});
});
});
}
4 changes: 4 additions & 0 deletions test/helpers/TestHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ TestHelper.prototype.dir = function dir(name) {
fs.mkdirSync(path.join(this.testdir, name));
};

TestHelper.prototype.rename = function rename(orig, dest) {
fs.renameSync(path.join(this.testdir, orig), path.join(this.testdir, dest));
};

TestHelper.prototype.file = function file(name) {
fs.writeFileSync(path.join(this.testdir, name), Math.random() + "", "utf-8");
};
Expand Down

0 comments on commit ac9697c

Please sign in to comment.