Skip to content

Commit fe11954

Browse files
committed
ignore changes in nested package dirs
1 parent 1ecd76d commit fe11954

File tree

4 files changed

+89
-33
lines changed

4 files changed

+89
-33
lines changed

lib/src/generate/watch_impl.dart

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,34 @@ class WatchImpl {
164164

165165
final watchers = <DirectoryWatcher>[];
166166
_logger.info('Setting up file watchers');
167+
168+
// Collect absolute file paths for all the packages. This needs to happen
169+
// before setting up the watchers.
170+
final absolutePackagePaths = <PackageNode, String>{};
171+
for (var package in _packageGraph.allPackages.values) {
172+
absolutePackagePaths[package] =
173+
path.normalize(path.absolute(package.location.toFilePath()));
174+
}
175+
176+
// Set up watchers for all the packages
167177
for (var package in _packageGraph.allPackages.values) {
168-
_logger.fine('Setting up watcher at ${package.location.toFilePath()}');
169-
var watcher = _directoryWatcherFactory(package.location.toFilePath());
178+
var absolutePackagePath = absolutePackagePaths[package];
179+
_logger.fine('Setting up watcher at $absolutePackagePath');
180+
181+
// Ignore all subfolders which are other packages.
182+
var pathsToIgnore = absolutePackagePaths.values.where((path) =>
183+
path != absolutePackagePath && path.startsWith(absolutePackagePath));
184+
185+
var watcher = _directoryWatcherFactory(absolutePackagePath);
170186
watchers.add(watcher);
171187
_allListeners.add(watcher.events.listen((WatchEvent e) {
172-
_logger.finest('Got WatchEvent for path ${e.path}');
173-
var id = new AssetId(package.name, path.normalize(e.path));
188+
// Check for ignored paths and immediately bail.
189+
if (pathsToIgnore.any((path) => e.path.startsWith(path))) return;
190+
191+
var relativePath = path.relative(e.path, from: absolutePackagePath);
192+
_logger.finest(
193+
'Got ${e.type} event for path $relativePath from ${watcher.path}');
194+
var id = new AssetId(package.name, relativePath);
174195
var node = _assetGraph.get(id);
175196
// Short circuit for deletes of nodes that aren't in the graph.
176197
if (e.type == ChangeType.REMOVE && node == null) return;

test/common/fake_watcher.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ class FakeWatcher implements DirectoryWatcher {
3131
static notifyWatchers(WatchEvent event) {
3232
for (var watcher in watchers) {
3333
if (event.path.startsWith(watcher.path)) {
34-
watcher._eventsController.add(new WatchEvent(
35-
event.type, event.path.replaceFirst(watcher.path, '')));
34+
watcher._eventsController.add(new WatchEvent(event.type, event.path));
3635
}
3736
}
3837
}

test/generate/serve_test.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ main() {
4545
checkOutputs({'a|web/a.txt.copy': 'a'}, result, writer.assets);
4646

4747
await writer.writeAsString(makeAsset('a|web/a.txt', 'b'));
48-
FakeWatcher.notifyWatchers(
49-
new WatchEvent(ChangeType.MODIFY, path.join('a', 'web', 'a.txt')));
48+
FakeWatcher.notifyWatchers(new WatchEvent(
49+
ChangeType.MODIFY, path.absolute('a', 'web', 'a.txt')));
5050

5151
result = await nextResult(results);
5252
checkOutputs({'a|web/a.txt.copy': 'b',}, result, writer.assets);
@@ -83,8 +83,8 @@ main() {
8383
/// Make an edit to force another build, and we should block again.
8484
copyBuilder.blockUntil = buildBlocker2.future;
8585
await writer.writeAsString(makeAsset('a|web/a.txt', 'b'));
86-
FakeWatcher.notifyWatchers(
87-
new WatchEvent(ChangeType.MODIFY, path.join('a', 'web', 'a.txt')));
86+
FakeWatcher.notifyWatchers(new WatchEvent(
87+
ChangeType.MODIFY, path.absolute('a', 'web', 'a.txt')));
8888
// Give the build enough time to get started.
8989
await wait(500);
9090
var done = new Completer();

test/generate/watch_test.dart

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ main() {
4141
checkOutputs({'a|web/a.txt.copy': 'a',}, result, writer.assets);
4242

4343
await writer.writeAsString(makeAsset('a|web/a.txt', 'b'));
44-
FakeWatcher.notifyWatchers(
45-
new WatchEvent(ChangeType.MODIFY, path.join('a', 'web', 'a.txt')));
44+
FakeWatcher.notifyWatchers(new WatchEvent(
45+
ChangeType.MODIFY, path.absolute('a', 'web', 'a.txt')));
4646

4747
result = await nextResult(results);
4848
checkOutputs({'a|web/a.txt.copy': 'b',}, result, writer.assets);
@@ -59,7 +59,7 @@ main() {
5959

6060
await writer.writeAsString(makeAsset('a|web/b.txt', 'b'));
6161
FakeWatcher.notifyWatchers(
62-
new WatchEvent(ChangeType.ADD, path.join('a', 'web', 'b.txt')));
62+
new WatchEvent(ChangeType.ADD, path.absolute('a', 'web', 'b.txt')));
6363

6464
result = await nextResult(results);
6565
checkOutputs({'a|web/b.txt.copy': 'b',}, result, writer.assets);
@@ -79,8 +79,8 @@ main() {
7979
result, writer.assets);
8080

8181
await writer.delete(makeAssetId('a|web/a.txt'));
82-
FakeWatcher.notifyWatchers(
83-
new WatchEvent(ChangeType.REMOVE, path.join('a', 'web', 'a.txt')));
82+
FakeWatcher.notifyWatchers(new WatchEvent(
83+
ChangeType.REMOVE, path.absolute('a', 'web', 'a.txt')));
8484

8585
result = await nextResult(results);
8686

@@ -106,10 +106,10 @@ main() {
106106

107107
await writer.writeAsString(makeAsset('a|web/c.txt', 'c'));
108108
FakeWatcher.notifyWatchers(
109-
new WatchEvent(ChangeType.ADD, path.join('a', 'web', 'c.txt')));
109+
new WatchEvent(ChangeType.ADD, path.absolute('a', 'web', 'c.txt')));
110110
await writer.delete(makeAssetId('a|web/a.txt'));
111-
FakeWatcher.notifyWatchers(
112-
new WatchEvent(ChangeType.REMOVE, path.join('a', 'web', 'a.txt')));
111+
FakeWatcher.notifyWatchers(new WatchEvent(
112+
ChangeType.REMOVE, path.absolute('a', 'web', 'a.txt')));
113113

114114
result = await nextResult(results);
115115
checkOutputs({'a|web/c.txt.copy': 'c'}, result, writer.assets);
@@ -142,12 +142,45 @@ main() {
142142
await writer.writeAsString(makeAsset('test|lib/test.dart', ''),
143143
lastModified: new DateTime.now().add(new Duration(days: 1)));
144144
await writer.writeAsString(makeAsset('a|web/a.txt', 'b'));
145-
FakeWatcher.notifyWatchers(
146-
new WatchEvent(ChangeType.MODIFY, path.join('a', 'web', 'a.txt')));
145+
FakeWatcher.notifyWatchers(new WatchEvent(
146+
ChangeType.MODIFY, path.absolute('a', 'web', 'a.txt')));
147147

148148
result = await nextResult(results);
149149
expect(result.status, BuildStatus.Failure);
150150
});
151+
152+
test('ignores events from nested packages', () async {
153+
var writer = new InMemoryAssetWriter();
154+
var results = <BuildResult>[];
155+
var packageA = new PackageNode(
156+
'a', '0.1.0', PackageDependencyType.Path, new Uri.file('a/'));
157+
var packageB = new PackageNode(
158+
'b', '0.1.0', PackageDependencyType.Path, new Uri.file('a/b/'));
159+
packageA.dependencies.add(packageB);
160+
var packageGraph = new PackageGraph.fromRoot(packageA);
161+
162+
startWatch(copyAPhaseGroup, {'a|web/a.txt': 'a', 'b|web/b.txt': 'b'},
163+
writer,
164+
packageGraph: packageGraph)
165+
.listen(results.add);
166+
167+
var result = await nextResult(results);
168+
// Should ignore the files under the `b` package, even though they
169+
// match the input set.
170+
checkOutputs({'a|web/a.txt.copy': 'a',}, result, writer.assets);
171+
172+
await writer.writeAsString(makeAsset('a|web/a.txt', 'b'));
173+
await writer.writeAsString(makeAsset('b|web/b.txt', 'c'));
174+
FakeWatcher.notifyWatchers(new WatchEvent(
175+
ChangeType.MODIFY, path.absolute('a', 'b', 'web', 'a.txt')));
176+
FakeWatcher.notifyWatchers(new WatchEvent(
177+
ChangeType.MODIFY, path.absolute('a', 'web', 'a.txt')));
178+
179+
result = await nextResult(results);
180+
// Ignores the modifcation under the `b` package, even though it
181+
// matches the input set.
182+
checkOutputs({'a|web/a.txt.copy': 'b',}, result, writer.assets);
183+
});
151184
});
152185

153186
group('multiple phases', () {
@@ -166,8 +199,8 @@ main() {
166199
result, writer.assets);
167200

168201
await writer.writeAsString(makeAsset('a|web/a.txt', 'b'));
169-
FakeWatcher.notifyWatchers(
170-
new WatchEvent(ChangeType.MODIFY, path.join('a', 'web', 'a.txt')));
202+
FakeWatcher.notifyWatchers(new WatchEvent(
203+
ChangeType.MODIFY, path.absolute('a', 'web', 'a.txt')));
171204

172205
result = await nextResult(results);
173206
checkOutputs({'a|web/a.txt.copy': 'b', 'a|web/a.txt.copy.copy': 'b'},
@@ -190,7 +223,7 @@ main() {
190223

191224
await writer.writeAsString(makeAsset('a|web/b.txt', 'b'));
192225
FakeWatcher.notifyWatchers(
193-
new WatchEvent(ChangeType.ADD, path.join('a', 'web', 'b.txt')));
226+
new WatchEvent(ChangeType.ADD, path.absolute('a', 'web', 'b.txt')));
194227

195228
result = await nextResult(results);
196229
checkOutputs({'a|web/b.txt.copy': 'b', 'a|web/b.txt.copy.copy': 'b'},
@@ -220,8 +253,8 @@ main() {
220253
}, result, writer.assets);
221254

222255
await writer.delete(makeAssetId('a|web/a.txt'));
223-
FakeWatcher.notifyWatchers(
224-
new WatchEvent(ChangeType.REMOVE, path.join('a', 'web', 'a.txt')));
256+
FakeWatcher.notifyWatchers(new WatchEvent(
257+
ChangeType.REMOVE, path.absolute('a', 'web', 'a.txt')));
225258

226259
result = await nextResult(results);
227260
// Shouldn't rebuild anything, no outputs.
@@ -251,7 +284,7 @@ main() {
251284

252285
await writer.delete(makeAssetId('a|web/a.txt.copy'));
253286
FakeWatcher.notifyWatchers(new WatchEvent(
254-
ChangeType.REMOVE, path.join('a', 'web', 'a.txt.copy')));
287+
ChangeType.REMOVE, path.absolute('a', 'web', 'a.txt.copy')));
255288

256289
result = await nextResult(results);
257290
// Should rebuild the generated asset and its outputs.
@@ -276,8 +309,8 @@ main() {
276309
checkOutputs({'a|web/a.txt.copy': 'b'}, result, writer.assets);
277310

278311
await writer.writeAsString(makeAsset('a|web/b.txt', 'c'));
279-
FakeWatcher.notifyWatchers(
280-
new WatchEvent(ChangeType.MODIFY, path.join('a', 'web', 'b.txt')));
312+
FakeWatcher.notifyWatchers(new WatchEvent(
313+
ChangeType.MODIFY, path.absolute('a', 'web', 'b.txt')));
281314

282315
result = await nextResult(results);
283316
checkOutputs({'a|web/a.txt.copy': 'c'}, result, writer.assets);
@@ -304,8 +337,8 @@ main() {
304337
result, writer.assets);
305338

306339
await writer.writeAsString(makeAsset('a|web/b.txt', 'c'));
307-
FakeWatcher.notifyWatchers(
308-
new WatchEvent(ChangeType.MODIFY, path.join('a', 'web', 'b.txt')));
340+
FakeWatcher.notifyWatchers(new WatchEvent(
341+
ChangeType.MODIFY, path.absolute('a', 'web', 'b.txt')));
309342

310343
result = await nextResult(results);
311344
checkOutputs({'a|web/a.txt.copy.copy': 'c'}, result, writer.assets);
@@ -319,14 +352,17 @@ StreamController _terminateWatchController;
319352

320353
/// Start watching files and running builds.
321354
Stream<BuildResult> startWatch(
322-
PhaseGroup phases, Map<String, String> inputs, InMemoryAssetWriter writer) {
355+
PhaseGroup phases, Map<String, String> inputs, InMemoryAssetWriter writer,
356+
{PackageGraph packageGraph}) {
323357
inputs.forEach((serializedId, contents) {
324358
writer.writeAsString(makeAsset(serializedId, contents));
325359
});
326360
final actualAssets = writer.assets;
327361
final reader = new InMemoryAssetReader(actualAssets);
328-
final rootPackage = new PackageNode('a', null, null, new Uri.file('a/'));
329-
final packageGraph = new PackageGraph.fromRoot(rootPackage);
362+
if (packageGraph == null) {
363+
packageGraph ??= new PackageGraph.fromRoot(
364+
new PackageNode('a', null, null, new Uri.file('a/')));
365+
}
330366
final watcherFactory = (String path) => new FakeWatcher(path);
331367

332368
return watch(phases,

0 commit comments

Comments
 (0)