diff --git a/CHANGELOG.md b/CHANGELOG.md index a39b38a2d9..53664c0412 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.3.0+6 +- Convert `packages` paths in the file watcher to their absolute paths. This + fixes [#109](https://github.com/dart-lang/build/issues/109). + ## 0.3.0+5 - Fix duplicate logs issue when running as a BuilderTransformer. diff --git a/lib/src/generate/watch_impl.dart b/lib/src/generate/watch_impl.dart index df458d2873..2014d027b0 100644 --- a/lib/src/generate/watch_impl.dart +++ b/lib/src/generate/watch_impl.dart @@ -195,17 +195,23 @@ class WatchImpl { _logger.fine('Setting up watcher at $absolutePackagePath'); // Ignore all subfolders which are other packages. - var pathsToIgnore = absolutePackagePaths.values.where((path) => - path != absolutePackagePath && - path.startsWith(absolutePackagePath)); + var pathsToIgnore = absolutePackagePaths.values + .where((path) => + path != absolutePackagePath && + path.startsWith(absolutePackagePath)) + .toList(); var watcher = _directoryWatcherFactory(absolutePackagePath); watchers.add(watcher); _allListeners.add(watcher.events.listen((WatchEvent e) { + var changePath = _normalizeChangePath(e.path, absolutePackagePaths); + if (changePath == null) return; + // Check for ignored paths and immediately bail. - if (pathsToIgnore.any((path) => e.path.startsWith(path))) return; + if (pathsToIgnore.any((path) => changePath.startsWith(path))) return; - var relativePath = path.relative(e.path, from: absolutePackagePath); + var relativePath = + path.relative(changePath, from: absolutePackagePath); _logger.finest( 'Got ${e.type} event for path $relativePath from ${watcher.path}'); var id = new AssetId(package.name, relativePath); @@ -233,4 +239,30 @@ class WatchImpl { var node = _assetGraph.get(id); return node is GeneratedAssetNode && type != ChangeType.REMOVE; } + + // Convert `packages` paths to absolute paths. Returns null if it finds an + // invalid package path. + String _normalizeChangePath( + String changePath, Map absolutePackagePaths) { + var changePathParts = path.split(changePath); + var packagesIndex = changePathParts.indexOf('packages'); + if (packagesIndex == -1) return changePath; + + if (changePathParts.length < packagesIndex + 2) { + _logger.severe('Invalid change path: $changePath'); + return null; + } + + var packageName = changePathParts[packagesIndex + 1]; + var packageNode = _packageGraph[packageName]; + if (packageNode == null) { + _logger.severe('Got update for invalid package: $packageName'); + return null; + } + var packagePath = absolutePackagePaths[packageNode]; + var libPath = path.joinAll(['lib'] + ..addAll( + changePathParts.getRange(packagesIndex + 2, changePathParts.length))); + return path.join(packagePath, libPath); + } } diff --git a/pubspec.yaml b/pubspec.yaml index 06926248fe..274f77d6e9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: build -version: 0.3.0+5 +version: 0.3.0+6 description: A build system for Dart. author: Dart Team homepage: https://github.com/dart-lang/build diff --git a/test/generate/watch_test.dart b/test/generate/watch_test.dart index df6433f19e..5d2741a8d8 100644 --- a/test/generate/watch_test.dart +++ b/test/generate/watch_test.dart @@ -181,6 +181,23 @@ void main() { // matches the input set. checkOutputs({'a|web/a.txt.copy': 'b',}, result, writer.assets); }); + + test('converts packages paths to absolute ones', () async { + var writer = new InMemoryAssetWriter(); + var results = []; + startWatch(copyAPhaseGroup, {'a|lib/a.txt': 'a'}, writer) + .listen(results.add); + + var result = await nextResult(results); + checkOutputs({'a|lib/a.txt.copy': 'a',}, result, writer.assets); + + await writer.writeAsString(makeAsset('a|lib/a.txt', 'b')); + FakeWatcher.notifyWatchers(new WatchEvent( + ChangeType.MODIFY, path.absolute('a', 'packages', 'a', 'a.txt'))); + + result = await nextResult(results); + checkOutputs({'a|lib/a.txt.copy': 'b',}, result, writer.assets); + }); }); group('multiple phases', () {