Skip to content

Commit 6d4b5c3

Browse files
committed
Hacking.
1 parent b2090bc commit 6d4b5c3

File tree

4 files changed

+174
-133
lines changed

4 files changed

+174
-133
lines changed

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

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -163,30 +163,35 @@ class _LinuxDirectoryWatcher
163163

164164
changed.add(event.path);
165165

166-
if (event.isMove) {
167-
files.remove(event.path);
168-
dirs.remove(event.path);
169-
170-
var destination = event.destination;
171-
if (destination == null) continue;
166+
switch (event.type) {
167+
case EventType.delete:
168+
files.remove(event.path);
169+
dirs.remove(event.path);
170+
171+
case EventType.moveFile:
172+
files.remove(event.path);
173+
var destination = event.destination;
174+
if (destination == null) continue;
175+
changed.add(destination);
176+
files.add(destination);
177+
dirs.remove(destination);
172178

173-
changed.add(destination);
174-
if (event.isDirectory!) {
179+
case EventType.moveDirectory:
180+
dirs.remove(event.path);
181+
var destination = event.destination;
182+
if (destination == null) continue;
175183
files.remove(destination);
176184
dirs.add(destination);
177-
} else {
178-
files.add(destination);
179-
dirs.remove(destination);
180-
}
181-
} else if (event is FileSystemDeleteEvent) {
182-
files.remove(event.path);
183-
dirs.remove(event.path);
184-
} else if (event.isDirectory!) {
185-
files.remove(event.path);
186-
dirs.add(event.path);
187-
} else {
188-
files.add(event.path);
189-
dirs.remove(event.path);
185+
186+
case EventType.createFile:
187+
case EventType.modifyFile:
188+
files.add(event.path);
189+
dirs.remove(event.path);
190+
191+
case EventType.createDirectory:
192+
case EventType.modifyDirectory:
193+
files.remove(event.path);
194+
dirs.add(event.path);
190195
}
191196
}
192197

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

Lines changed: 74 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ class _MacOSDirectoryWatcher
133133
: [canonicalEvent];
134134

135135
for (var event in events) {
136-
if (event.isCreate) {
137-
if (!event.isDirectory!) {
136+
switch (event.type) {
137+
case EventType.createFile:
138138
// If we already know about the file, treat it like a modification.
139139
// This can happen if a file is copied on top of an existing one.
140140
// We'll see an ADD event for the latter file when from the user's
@@ -144,47 +144,57 @@ class _MacOSDirectoryWatcher
144144

145145
_emitEvent(type, path);
146146
_files.add(path);
147-
continue;
148-
}
149-
150-
if (_files.containsDir(path)) continue;
151-
152-
var stream = Directory(path)
153-
.list(recursive: true)
154-
.ignoring<PathNotFoundException>();
155-
var subscription = stream.listen((entity) {
156-
if (entity is Directory) return;
157-
if (_files.contains(path)) return;
158-
159-
_emitEvent(ChangeType.ADD, entity.path);
160-
_files.add(entity.path);
161-
}, cancelOnError: true);
162-
subscription.onDone(() {
163-
_listSubscriptions.remove(subscription);
164-
});
165-
subscription.onError(_emitError);
166-
_listSubscriptions.add(subscription);
167-
} else if (event.isModify) {
168-
assert(!event.isDirectory!);
169-
_emitEvent(ChangeType.MODIFY, path);
170-
} else {
171-
assert(event.isDelete);
172-
for (var removedPath in _files.remove(path)) {
173-
_emitEvent(ChangeType.REMOVE, removedPath);
174-
}
147+
148+
case EventType.createDirectory:
149+
if (_files.containsDir(path)) continue;
150+
151+
var stream = Directory(path)
152+
.list(recursive: true)
153+
.ignoring<PathNotFoundException>();
154+
var subscription = stream.listen((entity) {
155+
if (entity is Directory) return;
156+
if (_files.contains(path)) return;
157+
158+
_emitEvent(ChangeType.ADD, entity.path);
159+
_files.add(entity.path);
160+
}, cancelOnError: true);
161+
subscription.onDone(() {
162+
_listSubscriptions.remove(subscription);
163+
});
164+
subscription.onError(_emitError);
165+
_listSubscriptions.add(subscription);
166+
167+
case EventType.modifyFile:
168+
_emitEvent(ChangeType.MODIFY, path);
169+
170+
case EventType.delete:
171+
for (var removedPath in _files.remove(path)) {
172+
_emitEvent(ChangeType.REMOVE, removedPath);
173+
}
174+
175+
// TODO(davidmorgan): explain.
176+
case EventType.modifyDirectory:
177+
throw ArgumentError();
178+
179+
// No move events on MacOS.
180+
case EventType.moveFile:
181+
case EventType.moveDirectory:
182+
throw ArgumentError();
175183
}
176184
}
177185
});
178186
}
179187

180188
/// Sort all the events in a batch into sets based on their path.
181189
///
182-
/// A single input event may result in multiple events in the returned map;
183-
/// for example, a MOVE event becomes a DELETE event for the source and a
184-
/// CREATE event for the destination.
190+
/// Events for `path` are discarded.
191+
///
192+
/// Events under directories that are created or modified are discarded.
185193
///
186-
/// The returned events won't contain any [FileSystemMoveEvent]s, nor will it
187-
/// contain any events relating to [path].
194+
/// There should already be no [EventType.moveFile] or
195+
/// [EventType.moveDirectory] events because the SDK does not send any on
196+
/// MacOS. See https://github.com/dart-lang/sdk/issues/14806. If there are
197+
/// any, they are dropped.
188198
Map<String, Set<Event>> _sortEvents(List<Event> batch) {
189199
var eventsForPaths = <String, Set<Event>>{};
190200

@@ -193,9 +203,10 @@ class _MacOSDirectoryWatcher
193203
// really deleted, that's handled by [_onDone].
194204
batch = batch.where((event) => event.path != path).toList();
195205

196-
// Events within directories that already have events are superfluous; the
197-
// directory's full contents will be examined anyway, so we ignore such
198-
// events. Emitting them could cause useless or out-of-order events.
206+
// Events within directories that already have create or modify events are
207+
// superfluous; the directory's full contents will be examined anyway, so we
208+
// ignore such events. Emitting them could cause useless or out-of-order
209+
// events.
199210
var directories = unionAll(batch.map((event) {
200211
if (event.isDelete || !event.isDirectory!) return <String>{};
201212
return event.paths;
@@ -210,8 +221,7 @@ class _MacOSDirectoryWatcher
210221
}
211222

212223
for (var event in batch) {
213-
// The Mac OS watcher doesn't emit move events. See issue 14806.
214-
assert(!event.isMove);
224+
if (event.isMove) continue;
215225
addEvent(event.path, event);
216226
}
217227

@@ -233,6 +243,7 @@ class _MacOSDirectoryWatcher
233243
// contradictory (e.g. because of a move).
234244
if (batch.isEmpty) return null;
235245

246+
var path = batch.first.path;
236247
var type = batch.first.type;
237248
var isDirectory = batch.first.isDirectory;
238249
var hadModifyEvent = false;
@@ -254,42 +265,50 @@ class _MacOSDirectoryWatcher
254265

255266
// If we previously thought this was a MODIFY, we now consider it to be a
256267
// CREATE or REMOVE event. This is safe for the same reason as above.
257-
if (type == EventType.modify) {
268+
if (type == EventType.modifyFile || type == EventType.modifyDirectory) {
258269
type = event.type;
259270
continue;
260271
}
261272

262273
// A CREATE event contradicts a REMOVE event and vice versa.
263-
assert(type == EventType.create || type == EventType.delete);
274+
assert(type == EventType.createFile ||
275+
type == EventType.createDirectory ||
276+
type == EventType.delete);
264277
if (type != event.type) return null;
265278
}
266279

267280
// If we got a CREATE event for a file we already knew about, that comes
268281
// from FSEvents reporting an add that happened prior to the watch
269282
// beginning. If we also received a MODIFY event, we want to report that,
270283
// but not the CREATE.
271-
if (type == EventType.create &&
284+
if (type == EventType.createFile &&
272285
hadModifyEvent &&
273-
_files.contains(batch.first.path)) {
274-
type = EventType.modify;
286+
_files.contains(path)) {
287+
type = EventType.modifyFile;
275288
}
276289

277290
switch (type) {
278-
case EventType.create:
291+
case EventType.createDirectory:
279292
// Issue 16003 means that a CREATE event for a directory can indicate
280293
// that the directory was moved and then re-created.
281294
// [_eventsBasedOnFileSystem] will handle this correctly by producing a
282295
// DELETE event followed by a CREATE event if the directory exists.
283-
if (isDirectory!) return null;
284-
return Event.createFile(batch.first.path);
296+
return null;
297+
case EventType.createFile:
298+
return Event.createFile(path);
299+
285300
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);
291-
default:
292-
throw StateError('unreachable');
301+
return Event.delete(path);
302+
303+
case EventType.modifyFile:
304+
return Event.modifyFile(path);
305+
case EventType.modifyDirectory:
306+
return Event.modifyDirectory(path);
307+
308+
// No move events on MacOS.
309+
case EventType.moveFile:
310+
case EventType.moveDirectory:
311+
throw ArgumentError();
293312
}
294313
}
295314

0 commit comments

Comments
 (0)