Skip to content

Commit a654530

Browse files
authored
Rewrite MacOS directory watcher. (#2268)
1 parent ca52a3e commit a654530

20 files changed

+781
-416
lines changed

pkgs/watcher/CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@
3737
issues: tracking failure following subdirectory move, incorrect events when
3838
there are changes in a recently-moved subdirectory, incorrect events due to
3939
various situations involving subdirectory moves.
40-
- Bug fix: with `DirectoryWatcher` on MacOS, fix events for changes in new
41-
directories: don't emit duplicate ADD, don't emit MODIFY without ADD.
40+
- Bug fix: new `DirectoryWatcher` implementation on MacOS that fixes various
41+
issues including duplicate events for changes in new directories, incorrect
42+
events when close together directory renames have overlapping names.
4243
- Bug fix: with `FileWatcher` on MacOS, a modify event was sometimes reported if
4344
the file was created immediately before the watcher was created. Now, if the
4445
file exists when the watcher is created then this modify event is not sent.

pkgs/watcher/lib/src/directory_watcher.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import 'dart:io';
77
import '../watcher.dart';
88
import 'custom_watcher_factory.dart';
99
import 'directory_watcher/linux.dart';
10-
import 'directory_watcher/mac_os.dart';
10+
import 'directory_watcher/macos.dart';
1111
import 'directory_watcher/windows_resubscribable_watcher.dart';
1212

1313
/// Watches the contents of a directory and emits [WatchEvent]s when something
@@ -54,7 +54,7 @@ abstract class DirectoryWatcher implements Watcher {
5454
);
5555
if (customWatcher != null) return customWatcher;
5656
if (Platform.isLinux) return LinuxDirectoryWatcher(directory);
57-
if (Platform.isMacOS) return MacOSDirectoryWatcher(directory);
57+
if (Platform.isMacOS) return MacosDirectoryWatcher(directory);
5858
if (Platform.isWindows) {
5959
return WindowsDirectoryWatcher(directory,
6060
runInIsolate: runInIsolateOnWindows);

pkgs/watcher/lib/src/directory_watcher/linux/native_watch.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import 'dart:async';
66
import 'dart:io';
77

88
import '../../event.dart';
9+
import '../../unix_paths.dart';
910
import '../../utils.dart';
10-
import 'paths.dart';
1111

1212
/// Watches a directory with the native Linux watcher.
1313
///
@@ -104,8 +104,7 @@ class NativeWatch {
104104
// watched directory was deleted. But, it might be an incorrect event
105105
// that is the deletion event for the old location in a move. So, check
106106
// if the directory is actually now missing.
107-
if (watchedDirectory.statSync().type ==
108-
FileSystemEntityType.directory) {
107+
if (watchedDirectory.typeSync() == FileSystemEntityType.directory) {
109108
// The directory is still present, indicating either a watch failure
110109
// or that the directoy has been replaced with a new one. Either way,
111110
// restart watching.

pkgs/watcher/lib/src/directory_watcher/linux/watch_tree.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
import 'dart:io';
66

77
import '../../event.dart';
8+
import '../../unix_paths.dart';
89
import '../../utils.dart';
910
import '../../watch_event.dart';
1011
import 'native_watch.dart';
11-
import 'paths.dart';
1212

1313
/// Linux directory watcher.
1414
///
@@ -148,9 +148,9 @@ class WatchTree {
148148
/// needs to be watched again.
149149
void _poll(RelativePath path) {
150150
logForTesting?.call('Watch,$watchedDirectory,_poll,$path');
151-
final stat = watchedDirectory.append(path).statSync();
152-
if (stat.type == FileSystemEntityType.file ||
153-
stat.type == FileSystemEntityType.link) {
151+
final type = watchedDirectory.append(path).typeSync();
152+
if (type == FileSystemEntityType.file ||
153+
type == FileSystemEntityType.link) {
154154
logForTesting?.call('Watch,$watchedDirectory,poll,$path,file');
155155
if (_directories.containsKey(path)) {
156156
_emitDeleteDirectory(path);
@@ -160,7 +160,7 @@ class WatchTree {
160160
} else {
161161
_addFile(path);
162162
}
163-
} else if (stat.type == FileSystemEntityType.directory) {
163+
} else if (type == FileSystemEntityType.directory) {
164164
logForTesting?.call('Watch,$watchedDirectory,poll,$path,directory');
165165
if (_files.contains(path)) {
166166
_emitDeleteFile(path);

pkgs/watcher/lib/src/directory_watcher/linux/watch_tree_root.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
import 'dart:async';
66

7+
import '../../unix_paths.dart';
78
import '../../utils.dart';
89
import '../../watch_event.dart';
9-
import 'paths.dart';
1010
import 'watch_tree.dart';
1111

1212
/// Linux directory watcher using a [WatchTree].

0 commit comments

Comments
 (0)