Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Side by Side Diff: pkg/barback/lib/src/asset_graph.dart

Issue 5695057915019264: Make barback more package-aware. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/barback/lib/src/asset_graph_manager.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library barback.asset_graph; 5 library barback.asset_graph;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import 'asset.dart'; 10 import 'asset.dart';
11 import 'asset_id.dart'; 11 import 'asset_id.dart';
12 import 'asset_graph_manager.dart';
12 import 'asset_provider.dart'; 13 import 'asset_provider.dart';
13 import 'asset_set.dart'; 14 import 'asset_set.dart';
14 import 'errors.dart'; 15 import 'errors.dart';
15 import 'change_batch.dart'; 16 import 'change_batch.dart';
16 import 'phase.dart'; 17 import 'phase.dart';
17 import 'transformer.dart'; 18 import 'transformer.dart';
19 import 'utils.dart';
18 20
19 /// The main build dependency manager. 21 /// The asset manager for an individual package.
20 /// 22 ///
21 /// For any given input file, it can tell which output files are affected by 23 /// This keeps track of which transformers are applied to which assets, and
22 /// it, and vice versa. 24 /// re-runs those transformers when their dependencies change. The transformed
25 /// assets are accessible via [getAssetById].
23 class AssetGraph { 26 class AssetGraph {
24 final AssetProvider _provider; 27 /// The name of the package whose assets are managed.
28 final String package;
29
30 /// The [AssetGraphManager] that manages the [AssetGraph]s for all
31 /// dependencies of the current app.
32 final AssetGraphManager _manager;
25 33
26 final _phases = <Phase>[]; 34 final _phases = <Phase>[];
27 35
28 /// A stream that emits a [BuildResult] each time the build is completed, 36 /// A stream that emits a [BuildResult] each time the build is completed,
29 /// whether or not it succeeded. 37 /// whether or not it succeeded.
30 /// 38 ///
31 /// If an unexpected error in barback itself occurs, it will be emitted 39 /// If an unexpected error in barback itself occurs, it will be emitted
32 /// through this stream's error channel. 40 /// through this stream's error channel.
33 Stream<BuildResult> get results => _resultsController.stream; 41 Stream<BuildResult> get results => _resultsController.stream;
34 final _resultsController = new StreamController<BuildResult>.broadcast(); 42 final _resultsController = new StreamController<BuildResult>.broadcast();
(...skipping 15 matching lines...) Expand all
50 58
51 /// A future that completes when the currently running build process finishes. 59 /// A future that completes when the currently running build process finishes.
52 /// 60 ///
53 /// If no build it in progress, is `null`. 61 /// If no build it in progress, is `null`.
54 Future _processDone; 62 Future _processDone;
55 63
56 ChangeBatch _sourceChanges; 64 ChangeBatch _sourceChanges;
57 65
58 /// Creates a new [AssetGraph]. 66 /// Creates a new [AssetGraph].
59 /// 67 ///
60 /// It loads source assets using [provider] and then uses [transformerPhases] 68 /// It loads source assets within [package] using [provider] and then uses
61 /// to generate output files from them. 69 /// [transformerPhases] to generate output files from them.
62 //TODO(rnystrom): Better way of specifying transformers and their ordering. 70 //TODO(rnystrom): Better way of specifying transformers and their ordering.
63 AssetGraph(this._provider, 71 AssetGraph(this._manager, this.package,
64 Iterable<Iterable<Transformer>> transformerPhases) { 72 Iterable<Iterable<Transformer>> transformerPhases) {
65 // Flatten the phases to a list so we can traverse backwards to wire up 73 // Flatten the phases to a list so we can traverse backwards to wire up
66 // each phase to its next. 74 // each phase to its next.
67 var phases = transformerPhases.toList(); 75 var phases = transformerPhases.toList();
68 76
69 // Each phase writes its outputs as inputs to the next phase after it. 77 // Each phase writes its outputs as inputs to the next phase after it.
70 // Add a phase at the end for the final outputs of the last phase. 78 // Add a phase at the end for the final outputs of the last phase.
71 phases.add([]); 79 phases.add([]);
72 80
73 Phase nextPhase = null; 81 Phase nextPhase = null;
74 for (var transformers in phases.reversed) { 82 for (var transformers in phases.reversed) {
75 nextPhase = new Phase(this, _phases.length, transformers.toList(), 83 nextPhase = new Phase(this, _phases.length, transformers.toList(),
76 nextPhase); 84 nextPhase);
77 _phases.insert(0, nextPhase); 85 _phases.insert(0, nextPhase);
78 } 86 }
79 } 87 }
80 88
81 /// Gets the asset identified by [id]. 89 /// Gets the asset identified by [id].
82 /// 90 ///
83 /// If [id] is for a generated or transformed asset, this will wait until 91 /// If [id] is for a generated or transformed asset, this will wait until
84 /// it has been created and return it. If the asset cannot be found, throws 92 /// it has been created and return it. If the asset cannot be found, throws
85 /// [AssetNotFoundException]. 93 /// [AssetNotFoundException].
86 Future<Asset> getAssetById(AssetId id) { 94 Future<Asset> getAssetById(AssetId id) {
95 assert(id.package == package);
96
87 // TODO(rnystrom): Waiting for the entire build to complete is unnecessary 97 // TODO(rnystrom): Waiting for the entire build to complete is unnecessary
88 // in some cases. Should optimize: 98 // in some cases. Should optimize:
89 // * [id] may be generated before the compilation is finished. We should 99 // * [id] may be generated before the compilation is finished. We should
90 // be able to quickly check whether there are any more in-place 100 // be able to quickly check whether there are any more in-place
91 // transformations that can be run on it. If not, we can return it early. 101 // transformations that can be run on it. If not, we can return it early.
92 // * If everything is compiled, something that didn't output [id] is 102 // * If everything is compiled, something that didn't output [id] is
93 // dirtied, and then [id] is requested, we can return it immediately, 103 // dirtied, and then [id] is requested, we can return it immediately,
94 // since anything overwriting it at that point is an error. 104 // since anything overwriting it at that point is an error.
95 // * If [id] has never been generated and all active transformers provide 105 // * If [id] has never been generated and all active transformers provide
96 // metadata about the file names of assets it can emit, we can prove that 106 // metadata about the file names of assets it can emit, we can prove that
97 // none of them can emit [id] and fail early. 107 // none of them can emit [id] and fail early.
98 return _waitForProcess().then((_) { 108 return (_processDone == null ? new Future.value() : _processDone).then((_) {
99 // Each phase's inputs are the outputs of the previous phase. Find the 109 // Each phase's inputs are the outputs of the previous phase. Find the
100 // last phase that contains the asset. Since the last phase has no 110 // last phase that contains the asset. Since the last phase has no
101 // transformers, this will find the latest output for that id. 111 // transformers, this will find the latest output for that id.
102 112
103 // TODO(rnystrom): Currently does not omit assets that are actually used 113 // TODO(rnystrom): Currently does not omit assets that are actually used
104 // as inputs for transformers. This means you can request and get an 114 // as inputs for transformers. This means you can request and get an
105 // asset that should be "consumed" because it's used to generate the 115 // asset that should be "consumed" because it's used to generate the
106 // real asset you care about. Need to figure out how we want to handle 116 // real asset you care about. Need to figure out how we want to handle
107 // that and what use cases there are related to it. 117 // that and what use cases there are related to it.
108 for (var i = _phases.length - 1; i >= 0; i--) { 118 for (var i = _phases.length - 1; i >= 0; i--) {
(...skipping 10 matching lines...) Expand all
119 }); 129 });
120 } 130 }
121 131
122 /// Adds [sources] to the graph's known set of source assets. 132 /// Adds [sources] to the graph's known set of source assets.
123 /// 133 ///
124 /// Begins applying any transforms that can consume any of the sources. If a 134 /// Begins applying any transforms that can consume any of the sources. If a
125 /// given source is already known, it is considered modified and all 135 /// given source is already known, it is considered modified and all
126 /// transforms that use it will be re-applied. 136 /// transforms that use it will be re-applied.
127 void updateSources(Iterable<AssetId> sources) { 137 void updateSources(Iterable<AssetId> sources) {
128 if (_sourceChanges == null) _sourceChanges = new ChangeBatch(); 138 if (_sourceChanges == null) _sourceChanges = new ChangeBatch();
139 assert(sources.every((id) => id.package == package));
Bob Nystrom 2013/07/11 23:03:40 Alternatively, it could just ignore sources outsid
nweiz 2013/07/15 22:11:44 Since this should only be called by [AssetGraphMan
129 _sourceChanges.update(sources); 140 _sourceChanges.update(sources);
130 141
131 _waitForProcess(); 142 _waitForProcess();
132 } 143 }
133 144
134 /// Removes [removed] from the graph's known set of source assets. 145 /// Removes [removed] from the graph's known set of source assets.
135 void removeSources(Iterable<AssetId> removed) { 146 void removeSources(Iterable<AssetId> removed) {
136 if (_sourceChanges == null) _sourceChanges = new ChangeBatch(); 147 if (_sourceChanges == null) _sourceChanges = new ChangeBatch();
148 assert(removed.every((id) => id.package == package));
137 _sourceChanges.remove(removed); 149 _sourceChanges.remove(removed);
138 150
139 _waitForProcess(); 151 _waitForProcess();
140 } 152 }
141 153
142 void reportError(error) { 154 void reportError(error) {
143 _accumulatedErrors.add(error); 155 _accumulatedErrors.add(error);
144 _errorsController.add(error); 156 _errorsController.add(error);
145 } 157 }
146 158
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 223
212 // Take the current batch to ensure it doesn't get added to while we're 224 // Take the current batch to ensure it doesn't get added to while we're
213 // processing it. 225 // processing it.
214 var changes = _sourceChanges; 226 var changes = _sourceChanges;
215 _sourceChanges = null; 227 _sourceChanges = null;
216 228
217 var updated = new AssetSet(); 229 var updated = new AssetSet();
218 var futures = []; 230 var futures = [];
219 for (var id in changes.updated) { 231 for (var id in changes.updated) {
220 // TODO(rnystrom): Catch all errors from provider and route to results. 232 // TODO(rnystrom): Catch all errors from provider and route to results.
221 futures.add(_provider.getAsset(id).then((asset) { 233 futures.add(_manager.provider.getAsset(id).then((asset) {
222 updated.add(asset); 234 updated.add(asset);
223 }).catchError((error) { 235 }).catchError((error) {
224 if (error is AssetNotFoundException) { 236 if (error is AssetNotFoundException) {
225 // Handle missing asset errors like regular missing assets. 237 // Handle missing asset errors like regular missing assets.
226 reportError(error); 238 reportError(error);
227 } else { 239 } else {
228 // It's an unexpected error, so rethrow it. 240 // It's an unexpected error, so rethrow it.
229 throw error; 241 throw error;
230 } 242 }
231 })); 243 }));
(...skipping 13 matching lines...) Expand all
245 /// although individual assets may still have built successfully. 257 /// although individual assets may still have built successfully.
246 class BuildResult { 258 class BuildResult {
247 /// All errors that occurred during the build. 259 /// All errors that occurred during the build.
248 final List errors; 260 final List errors;
249 261
250 /// `true` if the build succeeded. 262 /// `true` if the build succeeded.
251 bool get succeeded => errors.isEmpty; 263 bool get succeeded => errors.isEmpty;
252 264
253 BuildResult(Iterable errors) 265 BuildResult(Iterable errors)
254 : errors = errors.toList(); 266 : errors = errors.toList();
267
268 /// Creates a build result indicating a successful build.
269 ///
270 /// This equivalent to a build result with no errors.
271 BuildResult.success()
272 : this([]);
273
274 String toString() {
275 if (succeeded) return "success";
276
277 return "errors:\n" + errors.map((error) {
278 var stackTrace = getAttachedStackTrace(error);
279 if (stackTrace != null) stackTrace = new Trace.from(stackTrace);
280
281 var msg = new StringBuffer();
282 msg.write(prefixLines(error.toString()));
283 if (stackTrace != null) {
284 msg.write("\n\n");
285 msg.write("Stack trace:\n");
286 msg.write(prefixLines(stackTrace.toString()));
287 }
288 return msg.toString();
289 }).join("\n\n");
290 }
255 } 291 }
OLDNEW
« no previous file with comments | « no previous file | pkg/barback/lib/src/asset_graph_manager.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698