From acec47d410d67062b32480517452fd699d883a73 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Fri, 29 Apr 2016 10:35:29 -0700 Subject: [PATCH] Fix GeneratedAssetNode bug (#102) --- CHANGELOG.md | 4 ++++ lib/src/generate/build_impl.dart | 9 +++++++-- pubspec.yaml | 2 +- test/common/copy_builder.dart | 6 ++++++ test/generate/build_test.dart | 13 +++++++++++++ 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69d58f825..aef2f7923 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.3.0+1 +- Fix an AssetGraph bug where generated nodes might be created as non-generated + nodes if they are attempted to be read from previous build steps. + ## 0.3.0 - **BREAKING** Renamed values of three enums to be lower-case: `BuildType`, `BuildStatus`, and `PackageDependencyType`. diff --git a/lib/src/generate/build_impl.dart b/lib/src/generate/build_impl.dart index c3a7ec6c1..19ab46ff6 100644 --- a/lib/src/generate/build_impl.dart +++ b/lib/src/generate/build_impl.dart @@ -529,8 +529,13 @@ class BuildImpl { _assetGraph.addIfAbsent(input, () => new AssetNode(input)); for (var output in expectedOutputs) { inputNode.outputs.add(output); - _assetGraph.addIfAbsent( - output, () => new GeneratedAssetNode(input, true, false, output)); + var existing = _assetGraph.get(output); + /// If its null or of type [AssetNode], then insert a + /// [GeneratedAssetNode]. + if (existing is! GeneratedAssetNode) { + _assetGraph.remove(output); + _assetGraph.add(new GeneratedAssetNode(input, true, false, output)); + } } /// Skip the build step if none of the outputs need updating. diff --git a/pubspec.yaml b/pubspec.yaml index d12c8ece9..bc5ca1130 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: build -version: 0.3.0 +version: 0.3.0+1 description: A build system for Dart. author: Dart Team homepage: https://github.com/dart-lang/build diff --git a/test/common/copy_builder.dart b/test/common/copy_builder.dart index 0af9194bd..b7c8f0e43 100644 --- a/test/common/copy_builder.dart +++ b/test/common/copy_builder.dart @@ -20,6 +20,9 @@ class CopyBuilder implements Builder { /// asset. final AssetId copyFromAsset; + /// Will touch this asset, so that it becomes a dependency. + final AssetId touchAsset; + /// No `build` step will complete until this future completes. It may be /// re-assigned in between builds. Future blockUntil; @@ -29,6 +32,7 @@ class CopyBuilder implements Builder { this.extension: 'copy', this.outputPackage, this.copyFromAsset, + this.touchAsset, this.blockUntil}); @override @@ -42,6 +46,8 @@ class CopyBuilder implements Builder { : await buildStep.readAsString(copyFromAsset); buildStep.writeAsString(new Asset(id, content)); } + + if (touchAsset != null) await buildStep.hasInput(touchAsset); } @override diff --git a/test/generate/build_test.dart b/test/generate/build_test.dart index 50bbe2983..97c3cfdfd 100644 --- a/test/generate/build_test.dart +++ b/test/generate/build_test.dart @@ -82,6 +82,19 @@ void main() { 'a|web/a.txt.clone.copy.1': 'a', }); }); + + test('early step touches a not-yet-generated asset', () async { + var phases = new PhaseGroup(); + phases.newPhase() + ..addAction( + new CopyBuilder(touchAsset: new AssetId('a', 'lib/a.txt.copy')), + new InputSet('a', ['lib/b.txt'])); + phases.newPhase() + ..addAction(new CopyBuilder(), new InputSet('a', ['lib/a.txt'])); + + await testPhases(phases, {'a|lib/a.txt': 'a', 'a|lib/b.txt': 'b',}, + outputs: {'a|lib/a.txt.copy': 'a', 'a|lib/b.txt.copy': 'b',}); + }); }); group('inputs from other packages', () {