Chromium Code Reviews| OLD | NEW |
|---|---|
| 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_cascade; | 5 library barback.asset_cascade; |
| 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_node.dart'; | 12 import 'asset_node.dart'; |
| 13 import 'asset_set.dart'; | 13 import 'asset_set.dart'; |
| 14 import 'barback_logger.dart'; | |
| 14 import 'build_result.dart'; | 15 import 'build_result.dart'; |
| 15 import 'cancelable_future.dart'; | 16 import 'cancelable_future.dart'; |
| 16 import 'errors.dart'; | 17 import 'errors.dart'; |
| 17 import 'package_graph.dart'; | 18 import 'package_graph.dart'; |
| 18 import 'phase.dart'; | 19 import 'phase.dart'; |
| 19 import 'stream_pool.dart'; | 20 import 'stream_pool.dart'; |
| 20 import 'transformer.dart'; | 21 import 'transformer.dart'; |
| 21 import 'utils.dart'; | 22 import 'utils.dart'; |
| 22 | 23 |
| 23 /// The asset cascade for an individual package. | 24 /// The asset cascade for an individual package. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 77 /// | 78 /// |
| 78 /// This may emit events when the cascade was already dirty. Events are | 79 /// This may emit events when the cascade was already dirty. Events are |
| 79 /// emitted synchronously to ensure that the dirty state is thoroughly | 80 /// emitted synchronously to ensure that the dirty state is thoroughly |
| 80 /// propagated as soon as any assets are changed. | 81 /// propagated as soon as any assets are changed. |
| 81 Stream get onDirty => _onDirtyPool.stream; | 82 Stream get onDirty => _onDirtyPool.stream; |
| 82 final _onDirtyPool = new StreamPool.broadcast(); | 83 final _onDirtyPool = new StreamPool.broadcast(); |
| 83 | 84 |
| 84 /// A controller whose stream feeds into [_onDirtyPool]. | 85 /// A controller whose stream feeds into [_onDirtyPool]. |
| 85 final _onDirtyController = new StreamController.broadcast(sync: true); | 86 final _onDirtyController = new StreamController.broadcast(sync: true); |
| 86 | 87 |
| 88 /// A stream that emits an event whenever any transforms in this cascade log | |
|
nweiz
2013/10/16 19:41:27
"log" -> "logs"
Bob Nystrom
2013/10/28 23:45:56
Done.
| |
| 89 /// an entry. | |
| 90 Stream<LogEntry> get onLog => _onLogPool.stream; | |
| 91 final _onLogPool = new StreamPool<LogEntry>.broadcast(); | |
| 92 | |
| 87 /// The errors that have occurred since the current build started. | 93 /// The errors that have occurred since the current build started. |
| 88 /// | 94 /// |
| 89 /// This will be empty if no build is occurring. | 95 /// This will be empty if no build is occurring. |
| 90 Queue<BarbackException> _accumulatedErrors; | 96 Queue<BarbackException> _accumulatedErrors; |
| 91 | 97 |
| 98 /// The number of errors that have been logged since the current build | |
| 99 /// started. | |
| 100 int _numLogErrors; | |
| 101 | |
| 92 /// A future that completes when the currently running build process finishes. | 102 /// A future that completes when the currently running build process finishes. |
| 93 /// | 103 /// |
| 94 /// If no build it in progress, is `null`. | 104 /// If no build it in progress, is `null`. |
| 95 Future _processDone; | 105 Future _processDone; |
| 96 | 106 |
| 97 /// Whether any source assets have been updated or removed since processing | 107 /// Whether any source assets have been updated or removed since processing |
| 98 /// last began. | 108 /// last began. |
| 99 var _newChanges = false; | 109 var _newChanges = false; |
| 100 | 110 |
| 101 /// Returns all currently-available output assets from this cascade. | 111 /// Returns all currently-available output assets from this cascade. |
| 102 AssetSet get availableOutputs => | 112 AssetSet get availableOutputs => |
| 103 new AssetSet.from(_phases.last.availableOutputs.map((node) => node.asset)); | 113 new AssetSet.from(_phases.last.availableOutputs.map((node) => node.asset)); |
| 104 | 114 |
| 105 /// Creates a new [AssetCascade]. | 115 /// Creates a new [AssetCascade]. |
| 106 /// | 116 /// |
| 107 /// It loads source assets within [package] using [provider]. | 117 /// It loads source assets within [package] using [provider]. |
| 108 AssetCascade(this.graph, this.package) { | 118 AssetCascade(this.graph, this.package) { |
| 109 _onDirtyPool.add(_onDirtyController.stream); | 119 _onDirtyPool.add(_onDirtyController.stream); |
| 110 _addPhase(new Phase(this, [])); | 120 _addPhase(new Phase(this, [])); |
| 121 | |
| 122 // Keep track of logged errors so we can know that the build failed. | |
| 123 onLog.listen((entry) { | |
| 124 if (entry.level == LogLevel.ERROR) _numLogErrors++; | |
| 125 }); | |
| 111 } | 126 } |
| 112 | 127 |
| 113 /// Gets the asset identified by [id]. | 128 /// Gets the asset identified by [id]. |
| 114 /// | 129 /// |
| 115 /// If [id] is for a generated or transformed asset, this will wait until it | 130 /// If [id] is for a generated or transformed asset, this will wait until it |
| 116 /// has been created and return it. This means that the returned asset will | 131 /// has been created and return it. This means that the returned asset will |
| 117 /// always be [AssetState.AVAILABLE]. | 132 /// always be [AssetState.AVAILABLE]. |
| 118 /// | 133 /// |
| 119 /// If the asset cannot be found, returns null. | 134 /// If the asset cannot be found, returns null. |
| 120 Future<AssetNode> getAssetNode(AssetId id) { | 135 Future<AssetNode> getAssetNode(AssetId id) { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 } | 230 } |
| 216 | 231 |
| 217 void reportError(BarbackException error) { | 232 void reportError(BarbackException error) { |
| 218 _accumulatedErrors.add(error); | 233 _accumulatedErrors.add(error); |
| 219 _errorsController.add(error); | 234 _errorsController.add(error); |
| 220 } | 235 } |
| 221 | 236 |
| 222 /// Add [phase] to the end of [_phases] and watch its [onDirty] stream. | 237 /// Add [phase] to the end of [_phases] and watch its [onDirty] stream. |
| 223 void _addPhase(Phase phase) { | 238 void _addPhase(Phase phase) { |
| 224 _onDirtyPool.add(phase.onDirty); | 239 _onDirtyPool.add(phase.onDirty); |
| 240 _onLogPool.add(phase.onLog); | |
| 225 phase.onDirty.listen((_) { | 241 phase.onDirty.listen((_) { |
| 226 _newChanges = true; | 242 _newChanges = true; |
| 227 _waitForProcess(); | 243 _waitForProcess(); |
| 228 }); | 244 }); |
| 229 _phases.add(phase); | 245 _phases.add(phase); |
| 230 } | 246 } |
| 231 | 247 |
| 232 /// Starts the build process asynchronously if there is work to be done. | 248 /// Starts the build process asynchronously if there is work to be done. |
| 233 /// | 249 /// |
| 234 /// Returns a future that completes with the background processing is done. | 250 /// Returns a future that completes with the background processing is done. |
| 235 /// If there is no work to do, returns a future that completes immediately. | 251 /// If there is no work to do, returns a future that completes immediately. |
| 236 /// All errors that occur during processing will be caught (and routed to the | 252 /// All errors that occur during processing will be caught (and routed to the |
| 237 /// [results] stream) before they get to the returned future, so it is safe | 253 /// [results] stream) before they get to the returned future, so it is safe |
| 238 /// to discard it. | 254 /// to discard it. |
| 239 Future _waitForProcess() { | 255 Future _waitForProcess() { |
| 240 if (_processDone != null) return _processDone; | 256 if (_processDone != null) return _processDone; |
| 241 | 257 |
| 242 _accumulatedErrors = new Queue(); | 258 _accumulatedErrors = new Queue(); |
| 259 _numLogErrors = 0; | |
| 243 return _processDone = _process().then((_) { | 260 return _processDone = _process().then((_) { |
| 244 // Report the build completion. | 261 // Report the build completion. |
| 245 // TODO(rnystrom): Put some useful data in here. | 262 // TODO(rnystrom): Put some useful data in here. |
| 246 _resultsController.add(new BuildResult(_accumulatedErrors)); | 263 _resultsController.add( |
| 264 new BuildResult(_accumulatedErrors, _numLogErrors)); | |
| 247 }).catchError((error) { | 265 }).catchError((error) { |
| 248 // If we get here, it's an unexpected error. Runtime errors like missing | 266 // If we get here, it's an unexpected error. Runtime errors like missing |
| 249 // assets should be handled earlier. Errors from transformers or other | 267 // assets should be handled earlier. Errors from transformers or other |
| 250 // external code that barback calls into should be caught at that API | 268 // external code that barback calls into should be caught at that API |
| 251 // boundary. | 269 // boundary. |
| 252 // | 270 // |
| 253 // On the off chance we get here, pipe the error to the results stream | 271 // On the off chance we get here, pipe the error to the results stream |
| 254 // as an error. That will let applications handle it without it appearing | 272 // as an error. That will let applications handle it without it appearing |
| 255 // in the same path as "normal" errors that get reported. | 273 // in the same path as "normal" errors that get reported. |
| 256 _resultsController.addError(error); | 274 _resultsController.addError(error); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 280 | 298 |
| 281 // Otherwise, everything is done. | 299 // Otherwise, everything is done. |
| 282 return; | 300 return; |
| 283 } | 301 } |
| 284 | 302 |
| 285 // Process that phase and then loop onto the next. | 303 // Process that phase and then loop onto the next. |
| 286 return future.then((_) => _process()); | 304 return future.then((_) => _process()); |
| 287 }); | 305 }); |
| 288 } | 306 } |
| 289 } | 307 } |
| OLD | NEW |