Add a Watcher interface. Unlike DirectoryWatcher, this interface isn't directory-specific. This also allows ResubscribableDirectoryWatcher to become ResubscribableWatcher, which will make it easier to implement single-file watching. See dart-lang/watcher#17 R=rnystrom@google.com Review URL: https://codereview.chromium.org//1180233003.
diff --git a/pkgs/watcher/CHANGELOG.md b/pkgs/watcher/CHANGELOG.md index 7772980..f8c54bf 100644 --- a/pkgs/watcher/CHANGELOG.md +++ b/pkgs/watcher/CHANGELOG.md
@@ -1,3 +1,10 @@ +# 0.9.6 + +* Add a `Watcher` interface that encompasses watching both files and + directories. + +* Deprecate `DirectoryWatcher.directory`. Use `DirectoryWatcher.path` instead. + # 0.9.5 * Fix bugs where events could be added after watchers were closed.
diff --git a/pkgs/watcher/lib/src/directory_watcher.dart b/pkgs/watcher/lib/src/directory_watcher.dart index 605eaea..6979536 100644 --- a/pkgs/watcher/lib/src/directory_watcher.dart +++ b/pkgs/watcher/lib/src/directory_watcher.dart
@@ -4,10 +4,10 @@ library watcher.directory_watcher; -import 'dart:async'; import 'dart:io'; import 'watch_event.dart'; +import '../watcher.dart'; import 'directory_watcher/linux.dart'; import 'directory_watcher/mac_os.dart'; import 'directory_watcher/windows.dart'; @@ -15,35 +15,11 @@ /// Watches the contents of a directory and emits [WatchEvent]s when something /// in the directory has changed. -abstract class DirectoryWatcher { +abstract class DirectoryWatcher implements Watcher { /// The directory whose contents are being monitored. + @Deprecated("Expires in 1.0.0. Use DirectoryWatcher.path instead.") String get directory; - /// The broadcast [Stream] of events that have occurred to files in - /// [directory]. - /// - /// Changes will only be monitored while this stream has subscribers. Any - /// file changes that occur during periods when there are no subscribers - /// will not be reported the next time a subscriber is added. - Stream<WatchEvent> get events; - - /// Whether the watcher is initialized and watching for file changes. - /// - /// This is true if and only if [ready] is complete. - bool get isReady; - - /// A [Future] that completes when the watcher is initialized and watching - /// for file changes. - /// - /// If the watcher is not currently monitoring the directory (because there - /// are no subscribers to [events]), this returns a future that isn't - /// complete yet. It will complete when a subscriber starts listening and - /// the watcher finishes any initialization work it needs to do. - /// - /// If the watcher is already monitoring, this returns an already complete - /// future. - Future get ready; - /// Creates a new [DirectoryWatcher] monitoring [directory]. /// /// If a native directory watcher is available for this platform, this will
diff --git a/pkgs/watcher/lib/src/directory_watcher/linux.dart b/pkgs/watcher/lib/src/directory_watcher/linux.dart index 04d88e6..a747839 100644 --- a/pkgs/watcher/lib/src/directory_watcher/linux.dart +++ b/pkgs/watcher/lib/src/directory_watcher/linux.dart
@@ -7,9 +7,10 @@ import 'dart:async'; import 'dart:io'; +import '../directory_watcher.dart'; +import '../resubscribable.dart'; import '../utils.dart'; import '../watch_event.dart'; -import 'resubscribable.dart'; /// Uses the inotify subsystem to watch for filesystem events. /// @@ -21,13 +22,18 @@ /// [Directory.watch] producing multiple events for a single logical action /// (issue 14372) and providing insufficient information about move events /// (issue 14424). -class LinuxDirectoryWatcher extends ResubscribableDirectoryWatcher { +class LinuxDirectoryWatcher extends ResubscribableWatcher + implements DirectoryWatcher { + String get directory => path; + LinuxDirectoryWatcher(String directory) : super(directory, () => new _LinuxDirectoryWatcher(directory)); } -class _LinuxDirectoryWatcher implements ManuallyClosedDirectoryWatcher { - final String directory; +class _LinuxDirectoryWatcher + implements DirectoryWatcher, ManuallyClosedWatcher { + String get directory => path; + final String path; Stream<WatchEvent> get events => _eventsController.stream; final _eventsController = new StreamController<WatchEvent>.broadcast(); @@ -53,16 +59,15 @@ /// watcher is closed. final _subscriptions = new Set<StreamSubscription>(); - _LinuxDirectoryWatcher(String directory) - : directory = directory { + _LinuxDirectoryWatcher(this.path) { // Batch the inotify changes together so that we can dedup events. - var innerStream = new Directory(directory).watch() + var innerStream = new Directory(path).watch() .transform(new BatchedStreamTransformer<FileSystemEvent>()); _listen(innerStream, _onBatch, onError: _eventsController.addError, onDone: _onDone); - _listen(new Directory(directory).list(), (entity) { + _listen(new Directory(path).list(), (entity) { _entries[entity.path] = new _EntryState(entity is Directory); if (entity is! Directory) return; _watchSubdir(entity.path); @@ -182,7 +187,7 @@ // If the watched directory is deleted or moved, we'll get a deletion // event for it. Ignore it; we handle closing [this] when the underlying // stream is closed. - if (event.path == directory) continue; + if (event.path == path) continue; changedEntries.add(event.path);
diff --git a/pkgs/watcher/lib/src/directory_watcher/mac_os.dart b/pkgs/watcher/lib/src/directory_watcher/mac_os.dart index f3de727..487225e 100644 --- a/pkgs/watcher/lib/src/directory_watcher/mac_os.dart +++ b/pkgs/watcher/lib/src/directory_watcher/mac_os.dart
@@ -7,11 +7,12 @@ import 'dart:async'; import 'dart:io'; +import '../directory_watcher.dart'; import '../constructable_file_system_event.dart'; import '../path_set.dart'; +import '../resubscribable.dart'; import '../utils.dart'; import '../watch_event.dart'; -import 'resubscribable.dart'; /// Uses the FSEvents subsystem to watch for filesystem events. /// @@ -23,13 +24,18 @@ /// /// This also works around issues 16003 and 14849 in the implementation of /// [Directory.watch]. -class MacOSDirectoryWatcher extends ResubscribableDirectoryWatcher { +class MacOSDirectoryWatcher extends ResubscribableWatcher + implements DirectoryWatcher { + String get directory => path; + MacOSDirectoryWatcher(String directory) : super(directory, () => new _MacOSDirectoryWatcher(directory)); } -class _MacOSDirectoryWatcher implements ManuallyClosedDirectoryWatcher { - final String directory; +class _MacOSDirectoryWatcher + implements DirectoryWatcher, ManuallyClosedWatcher { + String get directory => path; + final String path; Stream<WatchEvent> get events => _eventsController.stream; final _eventsController = new StreamController<WatchEvent>.broadcast(); @@ -66,9 +72,9 @@ /// events (see issue 14373). Timer _bogusEventTimer; - _MacOSDirectoryWatcher(String directory) - : directory = directory, - _files = new PathSet(directory) { + _MacOSDirectoryWatcher(String path) + : path = path, + _files = new PathSet(path) { _startWatch(); // Before we're ready to emit events, wait for [_listDir] to complete and @@ -167,14 +173,14 @@ /// CREATE event for the destination. /// /// The returned events won't contain any [FileSystemMoveEvent]s, nor will it - /// contain any events relating to [directory]. + /// contain any events relating to [path]. Map<String, Set<FileSystemEvent>> _sortEvents(List<FileSystemEvent> batch) { var eventsForPaths = {}; // FSEvents can report past events, including events on the root directory // such as it being created. We want to ignore these. If the directory is // really deleted, that's handled by [_onDone]. - batch = batch.where((event) => event.path != directory).toList(); + batch = batch.where((event) => event.path != path).toList(); // Events within directories that already have events are superfluous; the // directory's full contents will be examined anyway, so we ignore such @@ -323,7 +329,7 @@ // If the directory still exists and we're still expecting bogus events, // this is probably issue 14849 rather than a real close event. We should // just restart the watcher. - if (!isReady && new Directory(directory).existsSync()) { + if (!isReady && new Directory(path).existsSync()) { _startWatch(); return; } @@ -341,7 +347,7 @@ /// Start or restart the underlying [Directory.watch] stream. void _startWatch() { // Batch the FSEvent changes together so that we can dedup events. - var innerStream = new Directory(directory).watch(recursive: true) + var innerStream = new Directory(path).watch(recursive: true) .transform(new BatchedStreamTransformer<FileSystemEvent>()); _watchSubscription = innerStream.listen(_onBatch, onError: _eventsController.addError, @@ -356,7 +362,7 @@ _files.clear(); var completer = new Completer(); - var stream = new Directory(directory).list(recursive: true); + var stream = new Directory(path).list(recursive: true); _initialListSubscription = stream.listen((entity) { if (entity is! Directory) _files.add(entity.path); },
diff --git a/pkgs/watcher/lib/src/directory_watcher/polling.dart b/pkgs/watcher/lib/src/directory_watcher/polling.dart index 144391f..7f417d6 100644 --- a/pkgs/watcher/lib/src/directory_watcher/polling.dart +++ b/pkgs/watcher/lib/src/directory_watcher/polling.dart
@@ -8,13 +8,17 @@ import 'dart:io'; import '../async_queue.dart'; +import '../directory_watcher.dart'; +import '../resubscribable.dart'; import '../stat.dart'; import '../utils.dart'; import '../watch_event.dart'; -import 'resubscribable.dart'; /// Periodically polls a directory for changes. -class PollingDirectoryWatcher extends ResubscribableDirectoryWatcher { +class PollingDirectoryWatcher extends ResubscribableWatcher + implements DirectoryWatcher { + String get directory => path; + /// Creates a new polling watcher monitoring [directory]. /// /// If [_pollingDelay] is passed, it specifies the amount of time the watcher @@ -28,8 +32,10 @@ }); } -class _PollingDirectoryWatcher implements ManuallyClosedDirectoryWatcher { - final String directory; +class _PollingDirectoryWatcher + implements DirectoryWatcher, ManuallyClosedWatcher { + String get directory => path; + final String path; Stream<WatchEvent> get events => _events.stream; final _events = new StreamController<WatchEvent>.broadcast(); @@ -68,7 +74,7 @@ /// but not in here when a poll completes have been removed. final _polledFiles = new Set<String>(); - _PollingDirectoryWatcher(this.directory, this._pollingDelay) { + _PollingDirectoryWatcher(this.path, this._pollingDelay) { _filesToProcess = new AsyncQueue<String>(_processFile, onError: (e, stackTrace) { if (!_events.isClosed) _events.addError(e, stackTrace); @@ -103,7 +109,7 @@ _filesToProcess.add(null); } - var stream = new Directory(directory).list(recursive: true); + var stream = new Directory(path).list(recursive: true); _listSubscription = stream.listen((entity) { assert(!_events.isClosed);
diff --git a/pkgs/watcher/lib/src/directory_watcher/windows.dart b/pkgs/watcher/lib/src/directory_watcher/windows.dart index bd17cf4..0899519 100644 --- a/pkgs/watcher/lib/src/directory_watcher/windows.dart +++ b/pkgs/watcher/lib/src/directory_watcher/windows.dart
@@ -12,12 +12,16 @@ import 'package:path/path.dart' as p; import '../constructable_file_system_event.dart'; +import '../directory_watcher.dart'; import '../path_set.dart'; +import '../resubscribable.dart'; import '../utils.dart'; import '../watch_event.dart'; -import 'resubscribable.dart'; -class WindowsDirectoryWatcher extends ResubscribableDirectoryWatcher { +class WindowsDirectoryWatcher extends ResubscribableWatcher + implements DirectoryWatcher { + String get directory => path; + WindowsDirectoryWatcher(String directory) : super(directory, () => new _WindowsDirectoryWatcher(directory)); } @@ -40,8 +44,10 @@ } } -class _WindowsDirectoryWatcher implements ManuallyClosedDirectoryWatcher { - final String directory; +class _WindowsDirectoryWatcher + implements DirectoryWatcher, ManuallyClosedWatcher { + String get directory => path; + final String path; Stream<WatchEvent> get events => _eventsController.stream; final _eventsController = new StreamController<WatchEvent>.broadcast(); @@ -79,8 +85,9 @@ final Set<StreamSubscription<FileSystemEntity>> _listSubscriptions = new HashSet<StreamSubscription<FileSystemEntity>>(); - _WindowsDirectoryWatcher(String directory) - : directory = directory, _files = new PathSet(directory) { + _WindowsDirectoryWatcher(String path) + : path = path, + _files = new PathSet(path) { // Before we're ready to emit events, wait for [_listDir] to complete. _listDir().then((_) { _startWatch(); @@ -110,12 +117,12 @@ /// On Windows, if [directory] is deleted, we will not receive any event. /// /// Instead, we add a watcher on the parent folder (if any), that can notify - /// us about [directory]. This also includes events such as moves. + /// us about [path]. This also includes events such as moves. void _startParentWatcher() { - var absoluteDir = p.absolute(directory); + var absoluteDir = p.absolute(path); var parent = p.dirname(absoluteDir); - // Check if [directory] is already the root directory. - if (FileSystemEntity.identicalSync(parent, directory)) return; + // Check if [path] is already the root directory. + if (FileSystemEntity.identicalSync(parent, path)) return; var parentStream = new Directory(parent).watch(recursive: false); _parentWatchSubscription = parentStream.listen((event) { // Only look at events for 'directory'. @@ -127,7 +134,7 @@ // the directory is now gone. if (event is FileSystemMoveEvent || event is FileSystemDeleteEvent || - (FileSystemEntity.typeSync(directory) == + (FileSystemEntity.typeSync(path) == FileSystemEntityType.NOT_FOUND)) { for (var path in _files.toSet()) { _emitEvent(ChangeType.REMOVE, path); @@ -210,7 +217,7 @@ /// CREATE event for the destination. /// /// The returned events won't contain any [FileSystemMoveEvent]s, nor will it - /// contain any events relating to [directory]. + /// contain any events relating to [path]. Map<String, Set<FileSystemEvent>> _sortEvents(List<FileSystemEvent> batch) { var eventsForPaths = {}; @@ -360,7 +367,7 @@ /// Start or restart the underlying [Directory.watch] stream. void _startWatch() { // Batch the events together so that we can dedup events. - var innerStream = new Directory(directory).watch(recursive: true); + var innerStream = new Directory(path).watch(recursive: true); _watchSubscription = innerStream.listen(_onEvent, onError: _eventsController.addError, onDone: _onDone); @@ -374,7 +381,7 @@ _files.clear(); var completer = new Completer(); - var stream = new Directory(directory).list(recursive: true); + var stream = new Directory(path).list(recursive: true); void handleEntity(entity) { if (entity is! Directory) _files.add(entity.path); }
diff --git a/pkgs/watcher/lib/src/directory_watcher/resubscribable.dart b/pkgs/watcher/lib/src/resubscribable.dart similarity index 74% rename from pkgs/watcher/lib/src/directory_watcher/resubscribable.dart rename to pkgs/watcher/lib/src/resubscribable.dart index 7d99fc0..2844c1e 100644 --- a/pkgs/watcher/lib/src/directory_watcher/resubscribable.dart +++ b/pkgs/watcher/lib/src/resubscribable.dart
@@ -2,33 +2,33 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -library watcher.directory_watcher.resubscribable; +library watcher.resubscribable; import 'dart:async'; -import '../directory_watcher.dart'; -import '../watch_event.dart'; +import '../watcher.dart'; +import 'watch_event.dart'; -typedef ManuallyClosedDirectoryWatcher WatcherFactory(); +typedef ManuallyClosedWatcher WatcherFactory(); -/// A wrapper for [ManuallyClosedDirectoryWatcher] that encapsulates support for -/// closing the watcher when it has no subscribers and re-opening it when it's +/// A wrapper for [ManuallyClosedWatcher] that encapsulates support for closing +/// the watcher when it has no subscribers and re-opening it when it's /// re-subscribed. /// /// It's simpler to implement watchers without worrying about this behavior. /// This class wraps a watcher class which can be written with the simplifying /// assumption that it can continue emitting events until an explicit `close` /// method is called, at which point it will cease emitting events entirely. The -/// [ManuallyClosedDirectoryWatcher] interface is used for these watchers. +/// [ManuallyClosedWatcher] interface is used for these watchers. /// /// This would be more cleanly implemented as a function that takes a class and /// emits a new class, but Dart doesn't support that sort of thing. Instead it /// takes a factory function that produces instances of the inner class. -abstract class ResubscribableDirectoryWatcher implements DirectoryWatcher { +abstract class ResubscribableWatcher implements Watcher { /// The factory function that produces instances of the inner class. final WatcherFactory _factory; - final String directory; + final String path; Stream<WatchEvent> get events => _eventsController.stream; StreamController<WatchEvent> _eventsController; @@ -38,9 +38,9 @@ Future get ready => _readyCompleter.future; var _readyCompleter = new Completer(); - /// Creates a new [ResubscribableDirectoryWatcher] wrapping the watchers + /// Creates a new [ResubscribableWatcher] wrapping the watchers /// emitted by [_factory]. - ResubscribableDirectoryWatcher(this.directory, this._factory) { + ResubscribableWatcher(this.path, this._factory) { var watcher; var subscription; @@ -67,8 +67,8 @@ /// An interface for watchers with an explicit, manual [close] method. /// -/// See [ResubscribableDirectoryWatcher]. -abstract class ManuallyClosedDirectoryWatcher implements DirectoryWatcher { +/// See [ResubscribableWatcher]. +abstract class ManuallyClosedWatcher implements Watcher { /// Closes the watcher. /// /// Subclasses should close their [events] stream and release any internal
diff --git a/pkgs/watcher/lib/watcher.dart b/pkgs/watcher/lib/watcher.dart index 88531f2..a078058 100644 --- a/pkgs/watcher/lib/watcher.dart +++ b/pkgs/watcher/lib/watcher.dart
@@ -4,6 +4,40 @@ library watcher; +import 'dart:async'; + +import 'src/watch_event.dart'; + export 'src/watch_event.dart'; export 'src/directory_watcher.dart'; export 'src/directory_watcher/polling.dart'; + +abstract class Watcher { + /// The path to the file or directory whose contents are being monitored. + String get path; + + /// The broadcast [Stream] of events that have occurred to the watched file or + /// files in the watched directory. + /// + /// Changes will only be monitored while this stream has subscribers. Any + /// changes that occur during periods when there are no subscribers will not + /// be reported the next time a subscriber is added. + Stream<WatchEvent> get events; + + /// Whether the watcher is initialized and watching for changes. + /// + /// This is true if and only if [ready] is complete. + bool get isReady; + + /// A [Future] that completes when the watcher is initialized and watching for + /// changes. + /// + /// If the watcher is not currently monitoring the file or directory (because + /// there are no subscribers to [events]), this returns a future that isn't + /// complete yet. It will complete when a subscriber starts listening and the + /// watcher finishes any initialization work it needs to do. + /// + /// If the watcher is already monitoring, this returns an already complete + /// future. + Future get ready; +}
diff --git a/pkgs/watcher/pubspec.yaml b/pkgs/watcher/pubspec.yaml index 08695c9..8853995 100644 --- a/pkgs/watcher/pubspec.yaml +++ b/pkgs/watcher/pubspec.yaml
@@ -9,7 +9,6 @@ sdk: '>=1.8.0 <2.0.0' dependencies: path: '>=0.9.0 <2.0.0' - stack_trace: '>=0.9.1 <2.0.0' dev_dependencies: scheduled_test: '^0.12.0' test: '^0.12.0'
diff --git a/pkgs/watcher/test/directory_watcher/linux_test.dart b/pkgs/watcher/test/directory_watcher/linux_test.dart index 15eb0ce..897b130 100644 --- a/pkgs/watcher/test/directory_watcher/linux_test.dart +++ b/pkgs/watcher/test/directory_watcher/linux_test.dart
@@ -27,7 +27,7 @@ () { withPermutations((i, j, k) => writeFile("dir/sub/sub-$i/sub-$j/file-$k.txt")); - startWatcher(dir: "dir"); + startWatcher(path: "dir"); renameDir("dir/sub", "sub"); renameDir("sub", "dir/sub");
diff --git a/pkgs/watcher/test/directory_watcher/mac_os_test.dart b/pkgs/watcher/test/directory_watcher/mac_os_test.dart index e9a1696..2c82f34 100644 --- a/pkgs/watcher/test/directory_watcher/mac_os_test.dart +++ b/pkgs/watcher/test/directory_watcher/mac_os_test.dart
@@ -30,7 +30,7 @@ deleteDir("dir"); createDir("dir"); - startWatcher(dir: "dir"); + startWatcher(path: "dir"); writeFile("dir/newer.txt"); expectAddEvent("dir/newer.txt"); }); @@ -40,7 +40,7 @@ withPermutations((i, j, k) => writeFile("dir/sub/sub-$i/sub-$j/file-$k.txt")); - startWatcher(dir: "dir"); + startWatcher(path: "dir"); renameDir("dir/sub", "sub"); renameDir("sub", "dir/sub");
diff --git a/pkgs/watcher/test/directory_watcher/shared.dart b/pkgs/watcher/test/directory_watcher/shared.dart index a4cec5e..ff48cb2 100644 --- a/pkgs/watcher/test/directory_watcher/shared.dart +++ b/pkgs/watcher/test/directory_watcher/shared.dart
@@ -69,7 +69,7 @@ writeFile("dir/a.txt"); writeFile("dir/b.txt"); - startWatcher(dir: "dir"); + startWatcher(path: "dir"); deleteDir("dir"); inAnyOrder([ @@ -82,7 +82,7 @@ writeFile("dir/a.txt"); writeFile("dir/b.txt"); - startWatcher(dir: "dir"); + startWatcher(path: "dir"); renameDir("dir", "moved_dir"); createDir("dir"); @@ -108,7 +108,7 @@ () { writeFile("old.txt"); createDir("dir"); - startWatcher(dir: "dir"); + startWatcher(path: "dir"); renameFile("old.txt", "dir/new.txt"); expectAddEvent("dir/new.txt"); @@ -116,7 +116,7 @@ test('notifies when a file is moved outside the watched directory', () { writeFile("dir/old.txt"); - startWatcher(dir: "dir"); + startWatcher(path: "dir"); renameFile("dir/old.txt", "new.txt"); expectRemoveEvent("dir/old.txt"); @@ -251,7 +251,7 @@ writeFile("sub/sub-$i/sub-$j/file-$k.txt")); createDir("dir"); - startWatcher(dir: "dir"); + startWatcher(path: "dir"); renameDir("sub", "dir/sub"); inAnyOrder(withPermutations((i, j, k) => @@ -263,7 +263,7 @@ writeFile("dir/sub/sub-$i/sub-$j/file-$k.txt")); createDir("dir"); - startWatcher(dir: "dir"); + startWatcher(path: "dir"); // Rename the directory rather than deleting it because native watchers // report a rename as a single DELETE event for the directory, whereas @@ -280,7 +280,7 @@ writeFile("dir/old/sub-$i/sub-$j/file-$k.txt")); createDir("dir"); - startWatcher(dir: "dir"); + startWatcher(path: "dir"); renameDir("dir/old", "dir/new"); inAnyOrder(unionAll(withPermutations((i, j, k) { @@ -296,7 +296,7 @@ writeFile("dir/sub"); withPermutations((i, j, k) => writeFile("old/sub-$i/sub-$j/file-$k.txt")); - startWatcher(dir: "dir"); + startWatcher(path: "dir"); deleteFile("dir/sub"); renameDir("old", "dir/sub");
diff --git a/pkgs/watcher/test/utils.dart b/pkgs/watcher/test/utils.dart index 85fe6d3..7dd8332 100644 --- a/pkgs/watcher/test/utils.dart +++ b/pkgs/watcher/test/utils.dart
@@ -20,8 +20,8 @@ /// operations are implicitly relative to this directory. String _sandboxDir; -/// The [DirectoryWatcher] being used for the current scheduled test. -DirectoryWatcher _watcher; +/// The [Watcher] being used for the current scheduled test. +Watcher _watcher; /// The mock modification times (in milliseconds since epoch) for each file. /// @@ -34,9 +34,9 @@ /// increment the mod time for that file instantly. Map<String, int> _mockFileModificationTimes; -typedef DirectoryWatcher WatcherFactory(String directory); +typedef Watcher WatcherFactory(String directory); -/// Sets the function used to create the directory watcher. +/// Sets the function used to create the watcher. set watcherFactory(WatcherFactory factory) { _watcherFactory = factory; } @@ -78,21 +78,21 @@ }, "delete sandbox"); } -/// Creates a new [DirectoryWatcher] that watches a temporary directory. +/// Creates a new [Watcher] that watches a temporary file or directory. /// /// Normally, this will pause the schedule until the watcher is done scanning /// and is polling for changes. If you pass `false` for [waitForReady], it will /// not schedule this delay. /// -/// If [dir] is provided, watches a subdirectory in the sandbox with that name. -DirectoryWatcher createWatcher({String dir, bool waitForReady}) { - if (dir == null) { - dir = _sandboxDir; +/// If [path] is provided, watches a subdirectory in the sandbox with that name. +Watcher createWatcher({String path, bool waitForReady}) { + if (path == null) { + path = _sandboxDir; } else { - dir = p.join(_sandboxDir, dir); + path = p.join(_sandboxDir, path); } - var watcher = _watcherFactory(dir); + var watcher = _watcherFactory(path); // Wait until the scan is finished so that we don't miss changes to files // that could occur before the scan completes. @@ -106,17 +106,17 @@ /// The stream of events from the watcher started with [startWatcher]. ScheduledStream<WatchEvent> _watcherEvents; -/// Creates a new [DirectoryWatcher] that watches a temporary directory and +/// Creates a new [Watcher] that watches a temporary file or directory and /// starts monitoring it for events. /// -/// If [dir] is provided, watches a subdirectory in the sandbox with that name. -void startWatcher({String dir}) { +/// If [path] is provided, watches a path in the sandbox with that name. +void startWatcher({String path}) { // We want to wait until we're ready *after* we subscribe to the watcher's // events. - _watcher = createWatcher(dir: dir, waitForReady: false); + _watcher = createWatcher(path: path, waitForReady: false); // Schedule [_watcher.events.listen] so that the watcher doesn't start - // watching [dir] before it exists. Expose [_watcherEvents] immediately so + // watching [path] before it exists. Expose [_watcherEvents] immediately so // that it can be accessed synchronously after this. _watcherEvents = new ScheduledStream(futureStream(schedule(() { currentSchedule.onComplete.schedule(() { @@ -139,8 +139,7 @@ /// Whether an event to close [_watcherEvents] has been scheduled. bool _closePending = false; -/// Schedule closing the directory watcher stream after the event queue has been -/// pumped. +/// Schedule closing the watcher stream after the event queue has been pumped. /// /// This is necessary when events are allowed to occur, but don't have to occur, /// at the end of a test. Otherwise, if they don't occur, the test will wait