Chromium Code Reviews| Index: pkg/code_transformers/lib/messages/build_logger.dart |
| diff --git a/pkg/code_transformers/lib/messages/build_logger.dart b/pkg/code_transformers/lib/messages/build_logger.dart |
| index da54f430496d26b2a34bc21673eda1bdc6c807d1..e42e4d4a4c9eb601d06d539456103ad868cdcf38 100644 |
| --- a/pkg/code_transformers/lib/messages/build_logger.dart |
| +++ b/pkg/code_transformers/lib/messages/build_logger.dart |
| @@ -2,89 +2,126 @@ |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| -library polymer.src.build.wrapped_logger; |
| +library code_transformers.messages.messages_logger; |
| import 'dart:async'; |
| -import 'dart:convert'; |
| +import 'dart:convert' show JSON; |
| import 'package:barback/barback.dart'; |
| import 'package:source_span/source_span.dart'; |
| -import 'common.dart' as common; |
| - |
| -/// A simple class to wrap one TransformLogger with another one that writes all |
| -/// logs to a file and then forwards the calls to the child. |
| -class WrappedLogger implements TransformLogger { |
| - Transform _transform; |
| - List<Map> _logs = new List<Map>(); |
| - |
| - bool convertErrorsToWarnings; |
| - |
| - WrappedLogger(this._transform, {this.convertErrorsToWarnings: false}); |
| - |
| - void info(String message, {AssetId asset, SourceSpan span}) { |
| - _transform.logger.info(message, asset: asset, span: span); |
| - _addLog(asset, LogLevel.INFO, message, span); |
| +import 'messages.dart' show Message, MessageId, BuildLogEntry, LogEntryTable; |
| + |
| +/// A [TransformLogger] used to track error and warning messages produced during |
| +/// a build. |
| +/// |
| +/// This logger records all messages that were log and then forwards |
|
jakemac
2014/09/03 17:20:41
s/log/logged
Siggi Cherem (dart-lang)
2014/09/04 02:32:13
Done.
|
| +/// the calls to an underlying [TransformLogger]. The internal records support |
| +/// serializing the errors and emiting them to an asset (so they can be |
| +/// presented to the user in a web-based client), clustering similar messages |
| +/// together, sorting messages in order of importance, etc. |
| +/// |
| +/// The logger also supports reporting error messages as warnings. Barback makes |
| +/// error messages stop the transformation process, which sometimes can surprise |
| +/// users. Turning errors into warnings is especially useful when used within |
| +/// `pub serve`, where we would like the transformation to continue as far as it |
| +/// can. When this flag is turned on, the level is still recorded as an error, |
| +/// so a web client UI can still highlight their importance. |
| +// TODO(sigmund): also cluster messages when they are reported on the |
| +// command-line. |
| +class BuildLogger implements TransformLogger { |
| + /// Underling transform that is currently active. |
| + final Transform _transform; |
| + |
| + /// Logs created during the current transform. |
| + final LogEntryTable _logs = new LogEntryTable(); |
| + |
| + /// Whether to use `warning` or `error` when forwarding error messages to the |
| + /// underlying logger in `_transform.logger`. |
| + final bool convertErrorsToWarnings; |
| + |
| + BuildLogger(this._transform, {this.convertErrorsToWarnings: false}); |
| + |
| + /// Records a message at the fine level, [msg] can be a [String] or [Message]. |
|
jakemac
2014/09/03 17:20:41
Technically it doesn't have to be a String, it can
Siggi Cherem (dart-lang)
2014/09/04 02:32:13
Good point :), rephrased
|
| + void fine(msg, {AssetId asset, SourceSpan span}) { |
| + var snippet = msg is Message ? msg.snippet : '$msg'; |
|
jakemac
2014/09/03 17:20:41
I don't think either of these variables are really
Siggi Cherem (dart-lang)
2014/09/04 02:32:13
nice, done.
|
| + var message = msg is Message ? msg : new Message( |
| + MessageId.NOT_SPECIFIED, snippet); |
| + _transform.logger.fine(snippet, asset: asset, span: span); |
| + _logs.add(new BuildLogEntry(message, span, LogLevel.FINE.name)); |
| } |
| - void fine(String message, {AssetId asset, SourceSpan span}) { |
| - _transform.logger.fine(message, asset: asset, span: span); |
| - _addLog(asset, LogLevel.FINE, message, span); |
| + /// Records a message at the info level, [msg] can be a [String] or [Message]. |
| + void info(msg, {AssetId asset, SourceSpan span}) { |
| + var snippet = msg is Message ? msg.snippet : '$msg'; |
| + var message = msg is Message ? msg : new Message( |
| + MessageId.NOT_SPECIFIED, snippet); |
| + _transform.logger.info(snippet, asset: asset, span: span); |
| + _logs.add(new BuildLogEntry(message, span, LogLevel.INFO.name)); |
| } |
| - void warning(String message, {AssetId asset, SourceSpan span}) { |
| - _transform.logger.warning(message, asset: asset, span: span); |
| - _addLog(asset, LogLevel.WARNING, message, span); |
| + /// Records a warning message, [msg] can be a [String] or [Message]. |
| + void warning(msg, {AssetId asset, SourceSpan span}) { |
| + var snippet = msg is Message ? msg.snippet : '$msg'; |
| + var message = msg is Message ? msg : new Message( |
| + MessageId.NOT_SPECIFIED, snippet); |
| + _transform.logger.warning(snippet, asset: asset, span: span); |
| + _logs.add(new BuildLogEntry(message, span, LogLevel.WARNING.name)); |
| } |
| - void error(String message, {AssetId asset, SourceSpan span}) { |
| + /// Records an error message, [msg] can be a [String] or [Message]. |
| + void error(msg, {AssetId asset, SourceSpan span}) { |
| + var snippet = msg is Message ? msg.snippet : '$msg'; |
| + var message = msg is Message ? msg : new Message( |
| + MessageId.NOT_SPECIFIED, snippet); |
| if (convertErrorsToWarnings) { |
| - _transform.logger.warning(message, asset: asset, span: span); |
| + _transform.logger.warning(snippet, asset: asset, span: span); |
| } else { |
| - _transform.logger.error(message, asset: asset, span: span); |
| + _transform.logger.error(snippet, asset: asset, span: span); |
| } |
| - _addLog(asset, LogLevel.ERROR, message, span); |
| + _logs.add(new BuildLogEntry(message, span, LogLevel.ERROR.name)); |
| } |
| /// Outputs the log data to a JSON serialized file. |
| Future writeOutput() { |
| - return getNextLogAssetPath().then((path) { |
| - _transform.addOutput(new Asset.fromString(path, JSON.encode(_logs))); |
| + return _getNextLogAssetPath().then((path) { |
| + _transform.addOutput(new Asset.fromString(path, |
| + JSON.encode(_logs.toJson()))); |
|
jakemac
2014/09/03 17:20:41
I thought JSON.encode will automatically call toJs
Siggi Cherem (dart-lang)
2014/09/04 02:32:13
done.
|
| }); |
| } |
| // Each phase outputs a new log file with an incrementing # appended, this |
| // figures out the next # to use. |
| - Future<String> getNextLogAssetPath([int nextNumber = 1]) { |
| + Future<String> _getNextLogAssetPath([int nextNumber = 1]) { |
| var nextAssetPath = _transform.primaryInput.id.addExtension( |
| - '${common.LOG_EXTENSION}.$nextNumber'); |
| + '${LOG_EXTENSION}.$nextNumber'); |
| return _transform.hasInput(nextAssetPath).then((exists) { |
| if (!exists) return nextAssetPath; |
| - return getNextLogAssetPath(++nextNumber); |
| + return _getNextLogAssetPath(++nextNumber); |
| }); |
| } |
| // Reads all log files for an Asset into [logs]. |
| - static Future _readLogFilesForAsset( |
| - AssetId id, Transform transform, List<Map> logs, [nextNumber = 1]) { |
| - var nextAssetPath = id.addExtension('${common.LOG_EXTENSION}.$nextNumber'); |
| + static Future _readLogFilesForAsset(AssetId id, Transform transform, |
| + LogEntryTable entries, [nextNumber = 1]) { |
| + var nextAssetPath = id.addExtension('${LOG_EXTENSION}.$nextNumber'); |
| return transform.hasInput(nextAssetPath).then((exists) { |
| if (!exists) return null; |
| return transform.readInputAsString(nextAssetPath).then((data) { |
| - logs.addAll(JSON.decode(data)); |
| - return _readLogFilesForAsset(id, transform, logs, ++nextNumber); |
| + entries.addAll(new LogEntryTable.fromJson(JSON.decode(data))); |
| + return _readLogFilesForAsset(id, transform, entries, ++nextNumber); |
| }); |
| }); |
| } |
| // Combines all existing ._buildLogs.* files into a single ._buildLogs file. |
| static Future combineLogFiles(Transform transform) { |
| - var logs = new List<Map>(); |
| + var entries = new LogEntryTable(); |
| var id = transform.primaryInput.id; |
| - return _readLogFilesForAsset(id, transform, logs).then((_) { |
| + return _readLogFilesForAsset(id, transform, entries).then((_) { |
| return transform.addOutput(new Asset.fromString( |
| - id.addExtension(common.LOG_EXTENSION), |
| - JSON.encode(logs))); |
| + id.addExtension(LOG_EXTENSION), |
| + JSON.encode(entries.toJson()))); |
| }); |
| } |
| @@ -92,25 +129,7 @@ class WrappedLogger implements TransformLogger { |
| Future addLogFilesFromAsset(AssetId id, [int nextNumber = 1]) { |
| return _readLogFilesForAsset(id, _transform, _logs); |
| } |
| - |
| - void _addLog(AssetId assetId, LogLevel level, String message, |
| - SourceSpan span) { |
| - var data = { |
| - 'level': level.name, |
| - 'message': const HtmlEscape().convert(message), |
| - }; |
| - if (assetId != null) { |
| - data['assetId'] = { |
| - 'package': assetId.package, |
| - 'path': assetId.path, |
| - }; |
| - } |
| - if (span != null) { |
| - data['span'] = { |
| - 'location': span.start.toolString, |
| - 'text': new HtmlEscape().convert(span.text), |
| - }; |
| - } |
| - _logs.add(data); |
| - } |
| } |
| + |
| +/// Extension used for assets that contained serialized logs. |
| +const String LOG_EXTENSION = '._buildLogs'; |