Fix race with directory list on Windows (#2235)
diff --git a/pkgs/watcher/CHANGELOG.md b/pkgs/watcher/CHANGELOG.md
index fef8a9e..6e21f5f 100644
--- a/pkgs/watcher/CHANGELOG.md
+++ b/pkgs/watcher/CHANGELOG.md
@@ -10,6 +10,9 @@
the file was created immediately before the watcher was created. Now, if the
file exists when the watcher is created then this modify event is not sent.
This matches the Linux native and polling (Windows) watchers.
+- Bug fix: with `DirectoryWatcher` on Windows, the last of a rapid sequence of
+ modifications in a newly-created directory was sometimes dropped. Make it
+ reliably report the last modification.
- Bug fix: with `DirectoryWatcher` on Windows, a move over an existing file was
reported incorrectly. For example, if `a` and `b` already exist, then `a` is
moved onto `b`, it would be reported as three events: delete `a`, delete `b`,
diff --git a/pkgs/watcher/lib/src/directory_watcher/windows.dart b/pkgs/watcher/lib/src/directory_watcher/windows.dart
index 009a312..d25680a 100644
--- a/pkgs/watcher/lib/src/directory_watcher/windows.dart
+++ b/pkgs/watcher/lib/src/directory_watcher/windows.dart
@@ -321,7 +321,16 @@
types.contains(EventType.createFile)) {
// Combine events of type [EventType.modifyFile] and
// [EventType.createFile] to one event.
- type = EventType.createFile;
+
+ // The file can be already in `_files` if it's in a recently-created
+ // directory, the directory list finds it and adds it. In that case a pair
+ // of "create"+"modify" should be reported as "modify".
+ //
+ // Otherwise, it's a new file, "create"+"modify" should be reported as
+ // "create".
+ type = _files.contains(batch.first.path)
+ ? EventType.modifyFile
+ : EventType.createFile;
} else {
// There are incompatible event types, check the filesystem.
return null;
diff --git a/pkgs/watcher/test/directory_watcher/end_to_end_tests.dart b/pkgs/watcher/test/directory_watcher/end_to_end_tests.dart
index 086a4f6..af2a200 100644
--- a/pkgs/watcher/test/directory_watcher/end_to_end_tests.dart
+++ b/pkgs/watcher/test/directory_watcher/end_to_end_tests.dart
@@ -57,10 +57,6 @@
print('Ignoring expected failure for Linux native watcher.');
return;
}
- if (Platform.isWindows && isNative) {
- print('Ignoring expected failure for Windows native watcher.');
- return;
- }
// Write the file operations before the failure to a log, fail the test.
final logTemp = Directory.systemTemp.createTempSync();