Skip to content

Commit e79280c

Browse files
committed
Add WatcherFilesystemEvent.
1 parent 6866f9b commit e79280c

File tree

8 files changed

+196
-102
lines changed

8 files changed

+196
-102
lines changed

.github/workflows/watcher.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ jobs:
5454
fail-fast: false
5555
matrix:
5656
os: [ubuntu-latest, macos-latest, windows-latest]
57-
sdk: [3.1, dev]
57+
sdk: [3.3, dev]
5858
steps:
5959
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
6060
- uses: dart-lang/setup-dart@e51d8e571e22473a2ddebf0ef8a2123f0ab2c02c

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'dart:io';
88
import 'package:async/async.dart';
99

1010
import '../directory_watcher.dart';
11+
import '../event.dart';
1112
import '../path_set.dart';
1213
import '../resubscribable.dart';
1314
import '../utils.dart';
@@ -145,7 +146,7 @@ class _LinuxDirectoryWatcher
145146
}
146147

147148
/// The callback that's run when a batch of changes comes in.
148-
void _onBatch(List<FileSystemEvent> batch) {
149+
void _onBatch(List<Event> batch) {
149150
var files = <String>{};
150151
var dirs = <String>{};
151152
var changed = <String>{};
@@ -162,15 +163,15 @@ class _LinuxDirectoryWatcher
162163

163164
changed.add(event.path);
164165

165-
if (event is FileSystemMoveEvent) {
166+
if (event.isMove) {
166167
files.remove(event.path);
167168
dirs.remove(event.path);
168169

169170
var destination = event.destination;
170171
if (destination == null) continue;
171172

172173
changed.add(destination);
173-
if (event.isDirectory) {
174+
if (event.isDirectory!) {
174175
files.remove(destination);
175176
dirs.add(destination);
176177
} else {
@@ -180,7 +181,7 @@ class _LinuxDirectoryWatcher
180181
} else if (event is FileSystemDeleteEvent) {
181182
files.remove(event.path);
182183
dirs.remove(event.path);
183-
} else if (event.isDirectory) {
184+
} else if (event.isDirectory!) {
184185
files.remove(event.path);
185186
dirs.add(event.path);
186187
} else {

pkgs/watcher/lib/src/directory_watcher/mac_os.dart

Lines changed: 42 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'dart:io';
88
import 'package:path/path.dart' as p;
99

1010
import '../directory_watcher.dart';
11+
import '../event.dart';
1112
import '../path_set.dart';
1213
import '../resubscribable.dart';
1314
import '../utils.dart';
@@ -63,7 +64,7 @@ class _MacOSDirectoryWatcher
6364
///
6465
/// This is separate from [_listSubscriptions] because this stream
6566
/// occasionally needs to be resubscribed in order to work around issue 14849.
66-
StreamSubscription<List<FileSystemEvent>>? _watchSubscription;
67+
StreamSubscription<List<Event>>? _watchSubscription;
6768

6869
/// The subscription to the [Directory.list] call for the initial listing of
6970
/// the directory to determine its initial state.
@@ -109,7 +110,7 @@ class _MacOSDirectoryWatcher
109110
}
110111

111112
/// The callback that's run when [Directory.watch] emits a batch of events.
112-
void _onBatch(List<FileSystemEvent> batch) {
113+
void _onBatch(List<Event> batch) {
113114
// If we get a batch of events before we're ready to begin emitting events,
114115
// it's probable that it's a batch of pre-watcher events (see issue 14373).
115116
// Ignore those events and re-list the directory.
@@ -132,8 +133,8 @@ class _MacOSDirectoryWatcher
132133
: [canonicalEvent];
133134

134135
for (var event in events) {
135-
if (event is FileSystemCreateEvent) {
136-
if (!event.isDirectory) {
136+
if (event.isCreate) {
137+
if (!event.isDirectory!) {
137138
// If we already know about the file, treat it like a modification.
138139
// This can happen if a file is copied on top of an existing one.
139140
// We'll see an ADD event for the latter file when from the user's
@@ -163,11 +164,11 @@ class _MacOSDirectoryWatcher
163164
});
164165
subscription.onError(_emitError);
165166
_listSubscriptions.add(subscription);
166-
} else if (event is FileSystemModifyEvent) {
167-
assert(!event.isDirectory);
167+
} else if (event.isModify) {
168+
assert(!event.isDirectory!);
168169
_emitEvent(ChangeType.MODIFY, path);
169170
} else {
170-
assert(event is FileSystemDeleteEvent);
171+
assert(event.isDelete);
171172
for (var removedPath in _files.remove(path)) {
172173
_emitEvent(ChangeType.REMOVE, removedPath);
173174
}
@@ -184,8 +185,8 @@ class _MacOSDirectoryWatcher
184185
///
185186
/// The returned events won't contain any [FileSystemMoveEvent]s, nor will it
186187
/// contain any events relating to [path].
187-
Map<String, Set<FileSystemEvent>> _sortEvents(List<FileSystemEvent> batch) {
188-
var eventsForPaths = <String, Set<FileSystemEvent>>{};
188+
Map<String, Set<Event>> _sortEvents(List<Event> batch) {
189+
var eventsForPaths = <String, Set<Event>>{};
189190

190191
// FSEvents can report past events, including events on the root directory
191192
// such as it being created. We want to ignore these. If the directory is
@@ -196,27 +197,21 @@ class _MacOSDirectoryWatcher
196197
// directory's full contents will be examined anyway, so we ignore such
197198
// events. Emitting them could cause useless or out-of-order events.
198199
var directories = unionAll(batch.map((event) {
199-
if (!event.isDirectory) return <String>{};
200-
if (event is FileSystemMoveEvent) {
201-
var destination = event.destination;
202-
if (destination != null) {
203-
return {event.path, destination};
204-
}
205-
}
206-
return {event.path};
200+
if (event.isDelete || !event.isDirectory!) return <String>{};
201+
return event.paths;
207202
}));
208203

209204
bool isInModifiedDirectory(String path) =>
210205
directories.any((dir) => path != dir && p.isWithin(dir, path));
211206

212-
void addEvent(String path, FileSystemEvent event) {
207+
void addEvent(String path, Event event) {
213208
if (isInModifiedDirectory(path)) return;
214-
eventsForPaths.putIfAbsent(path, () => <FileSystemEvent>{}).add(event);
209+
eventsForPaths.putIfAbsent(path, () => <Event>{}).add(event);
215210
}
216211

217212
for (var event in batch) {
218213
// The Mac OS watcher doesn't emit move events. See issue 14806.
219-
assert(event is! FileSystemMoveEvent);
214+
assert(!event.isMove);
220215
addEvent(event.path, event);
221216
}
222217

@@ -233,64 +228,66 @@ class _MacOSDirectoryWatcher
233228
/// If [batch] does contain contradictory events, this returns `null` to
234229
/// indicate that the state of the path on the filesystem should be checked to
235230
/// determine what occurred.
236-
FileSystemEvent? _canonicalEvent(Set<FileSystemEvent> batch) {
231+
Event? _canonicalEvent(Set<Event> batch) {
237232
// An empty batch indicates that we've learned earlier that the batch is
238233
// contradictory (e.g. because of a move).
239234
if (batch.isEmpty) return null;
240235

241236
var type = batch.first.type;
242-
var isDir = batch.first.isDirectory;
237+
var isDirectory = batch.first.isDirectory;
243238
var hadModifyEvent = false;
244239

245240
for (var event in batch.skip(1)) {
246241
// If one event reports that the file is a directory and another event
247242
// doesn't, that's a contradiction.
248-
if (isDir != event.isDirectory) return null;
243+
if (isDirectory != event.isDirectory) return null;
249244

250245
// Modify events don't contradict either CREATE or REMOVE events. We can
251246
// safely assume the file was modified after a CREATE or before the
252247
// REMOVE; otherwise there will also be a REMOVE or CREATE event
253248
// (respectively) that will be contradictory.
254-
if (event is FileSystemModifyEvent) {
249+
if (event.isModify) {
255250
hadModifyEvent = true;
256251
continue;
257252
}
258-
assert(event is FileSystemCreateEvent || event is FileSystemDeleteEvent);
253+
assert(event.isCreate || event.isDelete);
259254

260255
// If we previously thought this was a MODIFY, we now consider it to be a
261256
// CREATE or REMOVE event. This is safe for the same reason as above.
262-
if (type == FileSystemEvent.modify) {
257+
if (type == EventType.modify) {
263258
type = event.type;
264259
continue;
265260
}
266261

267262
// A CREATE event contradicts a REMOVE event and vice versa.
268-
assert(type == FileSystemEvent.create || type == FileSystemEvent.delete);
263+
assert(type == EventType.create || type == EventType.delete);
269264
if (type != event.type) return null;
270265
}
271266

272267
// If we got a CREATE event for a file we already knew about, that comes
273268
// from FSEvents reporting an add that happened prior to the watch
274269
// beginning. If we also received a MODIFY event, we want to report that,
275270
// but not the CREATE.
276-
if (type == FileSystemEvent.create &&
271+
if (type == EventType.create &&
277272
hadModifyEvent &&
278273
_files.contains(batch.first.path)) {
279-
type = FileSystemEvent.modify;
274+
type = EventType.modify;
280275
}
281276

282277
switch (type) {
283-
case FileSystemEvent.create:
278+
case EventType.create:
284279
// Issue 16003 means that a CREATE event for a directory can indicate
285280
// that the directory was moved and then re-created.
286281
// [_eventsBasedOnFileSystem] will handle this correctly by producing a
287282
// DELETE event followed by a CREATE event if the directory exists.
288-
if (isDir) return null;
289-
return FileSystemCreateEvent(batch.first.path, false);
290-
case FileSystemEvent.delete:
291-
return FileSystemDeleteEvent(batch.first.path, isDir);
292-
case FileSystemEvent.modify:
293-
return FileSystemModifyEvent(batch.first.path, isDir, false);
283+
if (isDirectory!) return null;
284+
return Event.createFile(batch.first.path);
285+
case EventType.delete:
286+
return Event.delete(batch.first.path);
287+
case EventType.modify:
288+
return isDirectory!
289+
? Event.modifyDirectory(batch.first.path)
290+
: Event.modifyFile(batch.first.path);
294291
default:
295292
throw StateError('unreachable');
296293
}
@@ -303,35 +300,35 @@ class _MacOSDirectoryWatcher
303300
/// to the user, unlike the batched events from [Directory.watch]. The
304301
/// returned list may be empty, indicating that no changes occurred to [path]
305302
/// (probably indicating that it was created and then immediately deleted).
306-
List<FileSystemEvent> _eventsBasedOnFileSystem(String path) {
303+
List<Event> _eventsBasedOnFileSystem(String path) {
307304
var fileExisted = _files.contains(path);
308305
var dirExisted = _files.containsDir(path);
309306
var fileExists = File(path).existsSync();
310307
var dirExists = Directory(path).existsSync();
311308

312-
var events = <FileSystemEvent>[];
309+
var events = <Event>[];
313310
if (fileExisted) {
314311
if (fileExists) {
315-
events.add(FileSystemModifyEvent(path, false, false));
312+
events.add(Event.modifyFile(path));
316313
} else {
317-
events.add(FileSystemDeleteEvent(path, false));
314+
events.add(Event.delete(path));
318315
}
319316
} else if (dirExisted) {
320317
if (dirExists) {
321318
// If we got contradictory events for a directory that used to exist and
322319
// still exists, we need to rescan the whole thing in case it was
323320
// replaced with a different directory.
324-
events.add(FileSystemDeleteEvent(path, true));
325-
events.add(FileSystemCreateEvent(path, true));
321+
events.add(Event.delete(path));
322+
events.add(Event.createDirectory(path));
326323
} else {
327-
events.add(FileSystemDeleteEvent(path, true));
324+
events.add(Event.delete(path));
328325
}
329326
}
330327

331328
if (!fileExisted && fileExists) {
332-
events.add(FileSystemCreateEvent(path, false));
329+
events.add(Event.createFile(path));
333330
} else if (!dirExisted && dirExists) {
334-
events.add(FileSystemCreateEvent(path, true));
331+
events.add(Event.createDirectory(path));
335332
}
336333

337334
return events;

0 commit comments

Comments
 (0)