| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 /// Message logging. | 5 /// Message logging. |
| 6 import 'dart:async'; | 6 import 'dart:async'; |
| 7 import 'dart:convert'; | 7 import 'dart:convert'; |
| 8 import 'dart:io'; | 8 import 'dart:io'; |
| 9 | 9 |
| 10 import 'package:args/command_runner.dart'; | 10 import 'package:args/command_runner.dart'; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 /// | 22 /// |
| 23 /// log.json.error(...); | 23 /// log.json.error(...); |
| 24 final json = new _JsonLogger(); | 24 final json = new _JsonLogger(); |
| 25 | 25 |
| 26 /// The current logging verbosity. | 26 /// The current logging verbosity. |
| 27 Verbosity verbosity = Verbosity.NORMAL; | 27 Verbosity verbosity = Verbosity.NORMAL; |
| 28 | 28 |
| 29 /// Whether or not to log entries with prejudice. | 29 /// Whether or not to log entries with prejudice. |
| 30 bool withPrejudice = false; | 30 bool withPrejudice = false; |
| 31 | 31 |
| 32 /// Whether or not to log entries sparklily. |
| 33 bool sparkle = false; |
| 34 |
| 32 /// In cases where there's a ton of log spew, make sure we don't eat infinite | 35 /// In cases where there's a ton of log spew, make sure we don't eat infinite |
| 33 /// memory. | 36 /// memory. |
| 34 /// | 37 /// |
| 35 /// This can occur when the backtracking solver stumbles into a pathological | 38 /// This can occur when the backtracking solver stumbles into a pathological |
| 36 /// dependency graph. It generally will find a solution, but it may log | 39 /// dependency graph. It generally will find a solution, but it may log |
| 37 /// thousands and thousands of entries to get there. | 40 /// thousands and thousands of entries to get there. |
| 38 const _MAX_TRANSCRIPT = 10000; | 41 const _MAX_TRANSCRIPT = 10000; |
| 39 | 42 |
| 40 /// The list of recorded log messages. Will only be recorded if | 43 /// The list of recorded log messages. Will only be recorded if |
| 41 /// [recordTranscript()] is called. | 44 /// [recordTranscript()] is called. |
| 42 Transcript<Entry> _transcript; | 45 Transcript<Entry> _transcript; |
| 43 | 46 |
| 44 /// The currently-animated progress indicator, if any. | 47 /// The currently-animated progress indicator, if any. |
| 45 /// | 48 /// |
| 46 /// This will also be in [_progresses]. | 49 /// This will also be in [_progresses]. |
| 47 Progress _animatedProgress; | 50 Progress _animatedProgress; |
| 48 | 51 |
| 49 _Collapser _collapser; | 52 _Collapser _collapser; |
| 50 | 53 |
| 51 final _cyan = getSpecial('\u001b[36m'); | 54 final _cyan = getSpecial('\u001b[36m'); |
| 52 final _green = getSpecial('\u001b[32m'); | 55 final _green = getSpecial('\u001b[32m'); |
| 53 final _magenta = getSpecial('\u001b[35m'); | 56 final _magenta = getSpecial('\u001b[35m'); |
| 54 final _red = getSpecial('\u001b[31m'); | 57 final _red = getSpecial('\u001b[31m'); |
| 55 final _yellow = getSpecial('\u001b[33m'); | 58 final _yellow = getSpecial('\u001b[33m'); |
| 59 final _blue = getSpecial('\u001b[34m'); |
| 56 final _gray = getSpecial('\u001b[1;30m'); | 60 final _gray = getSpecial('\u001b[1;30m'); |
| 57 final _none = getSpecial('\u001b[0m'); | 61 final _none = getSpecial('\u001b[0m'); |
| 58 final _noColor = getSpecial('\u001b[39m'); | 62 final _noColor = getSpecial('\u001b[39m'); |
| 59 final _bold = getSpecial('\u001b[1m'); | 63 final _bold = getSpecial('\u001b[1m'); |
| 60 | 64 |
| 65 /// All color codees. |
| 66 var _allColors = [_cyan, _green, _magenta, _red, _yellow, _blue, '']; |
| 67 |
| 61 /// An enum type for defining the different logging levels a given message can | 68 /// An enum type for defining the different logging levels a given message can |
| 62 /// be associated with. | 69 /// be associated with. |
| 63 /// | 70 /// |
| 64 /// By default, [ERROR] and [WARNING] messages are printed to sterr. [MESSAGE] | 71 /// By default, [ERROR] and [WARNING] messages are printed to sterr. [MESSAGE] |
| 65 /// messages are printed to stdout, and others are ignored. | 72 /// messages are printed to stdout, and others are ignored. |
| 66 class Level { | 73 class Level { |
| 67 /// An error occurred and an operation could not be completed. | 74 /// An error occurred and an operation could not be completed. |
| 68 /// | 75 /// |
| 69 /// Usually shown to the user on stderr. | 76 /// Usually shown to the user on stderr. |
| 70 static const ERROR = const Level._("ERR "); | 77 static const ERROR = const Level._("ERR "); |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 var logFn = verbosity._loggers[level]; | 243 var logFn = verbosity._loggers[level]; |
| 237 if (logFn != null) logFn(entry); | 244 if (logFn != null) logFn(entry); |
| 238 | 245 |
| 239 if (_transcript != null) _transcript.add(entry); | 246 if (_transcript != null) _transcript.add(entry); |
| 240 } | 247 } |
| 241 | 248 |
| 242 final _capitalizedAnsiEscape = new RegExp(r'\u001b\[\d+(;\d+)?M'); | 249 final _capitalizedAnsiEscape = new RegExp(r'\u001b\[\d+(;\d+)?M'); |
| 243 | 250 |
| 244 /// Returns [string] formatted as it would be if it were logged. | 251 /// Returns [string] formatted as it would be if it were logged. |
| 245 String format(String string) { | 252 String format(String string) { |
| 246 if (!withPrejudice) return string; | 253 if (sparkle) { |
| 254 string = string.replaceAllMapped(new RegExp(r'.'), (match) { |
| 255 var char = "${choose(_allColors)}${match[0]}$_noColor"; |
| 256 return (withPrejudice || random.nextBool()) ? char : "$_bold$char$_none"; |
| 257 }); |
| 258 } |
| 247 | 259 |
| 248 // [toUpperCase] can corrupt terminal colorings, so fix them up using | 260 if (withPrejudice) { |
| 249 // [replaceAllMapped]. | 261 // [toUpperCase] can corrupt terminal colorings, so fix them up using |
| 250 string = string.toUpperCase().replaceAllMapped(_capitalizedAnsiEscape, | 262 // [replaceAllMapped]. |
| 251 (match) => match[0].toLowerCase()); | 263 string = string.toUpperCase().replaceAllMapped(_capitalizedAnsiEscape, |
| 264 (match) => match[0].toLowerCase()); |
| 252 | 265 |
| 253 // Don't use [bold] because it's disabled under [withPrejudice]. | 266 // Don't use [bold] because it's disabled under [withPrejudice]. |
| 254 return "$_bold$string$_none"; | 267 string = "$_bold$string$_none"; |
| 268 } |
| 269 |
| 270 return string; |
| 255 } | 271 } |
| 256 | 272 |
| 257 /// Logs an asynchronous IO operation. | 273 /// Logs an asynchronous IO operation. |
| 258 /// | 274 /// |
| 259 /// Logs [startMessage] before the operation starts, then when [operation] | 275 /// Logs [startMessage] before the operation starts, then when [operation] |
| 260 /// completes, invokes [endMessage] with the completion value and logs the | 276 /// completes, invokes [endMessage] with the completion value and logs the |
| 261 /// result of that. Returns a future that completes after the logging is done. | 277 /// result of that. Returns a future that completes after the logging is done. |
| 262 /// | 278 /// |
| 263 /// If [endMessage] is omitted, then logs "Begin [startMessage]" before the | 279 /// If [endMessage] is omitted, then logs "Begin [startMessage]" before the |
| 264 /// operation and "End [startMessage]" after it. | 280 /// operation and "End [startMessage]" after it. |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 } | 463 } |
| 448 } | 464 } |
| 449 | 465 |
| 450 /// Wraps [text] in the ANSI escape codes to make it bold when on a platform | 466 /// Wraps [text] in the ANSI escape codes to make it bold when on a platform |
| 451 /// that supports that. | 467 /// that supports that. |
| 452 /// | 468 /// |
| 453 /// Use this to highlight the most important piece of a long chunk of text. | 469 /// Use this to highlight the most important piece of a long chunk of text. |
| 454 /// | 470 /// |
| 455 /// This is disabled under [withPrejudice] since all text is bold with | 471 /// This is disabled under [withPrejudice] since all text is bold with |
| 456 /// prejudice. | 472 /// prejudice. |
| 457 String bold(text) => withPrejudice ? text : "$_bold$text$_none"; | 473 String bold(text) => (withPrejudice || sparkle) ? "$text" : "$_bold$text$_none"; |
| 458 | 474 |
| 459 /// Wraps [text] in the ANSI escape codes to make it gray when on a platform | 475 /// Wraps [text] in the ANSI escape codes to make it gray when on a platform |
| 460 /// that supports that. | 476 /// that supports that. |
| 461 /// | 477 /// |
| 462 /// Use this for text that's less important than the text around it. | 478 /// Use this for text that's less important than the text around it. |
| 463 /// | 479 /// |
| 464 /// The gray marker also enables bold, so it needs to be handled specially with | 480 /// The gray marker also enables bold, so it needs to be handled specially with |
| 465 /// [withPrejudice] to avoid disabling bolding entirely. | 481 /// [withPrejudice] to avoid disabling bolding entirely. |
| 466 String gray(text) => | 482 String gray(text) { |
| 467 withPrejudice ? "$_gray$text$_noColor" : "$_gray$text$_none"; | 483 if (sparkle) return "$text"; |
| 484 if (withPrejudice) return "$_gray$text$_noColor"; |
| 485 return "$_gray$text$_none"; |
| 486 } |
| 468 | 487 |
| 469 /// Wraps [text] in the ANSI escape codes to color it cyan when on a platform | 488 /// Wraps [text] in the ANSI escape codes to color it cyan when on a platform |
| 470 /// that supports that. | 489 /// that supports that. |
| 471 /// | 490 /// |
| 472 /// Use this to highlight something interesting but neither good nor bad. | 491 /// Use this to highlight something interesting but neither good nor bad. |
| 473 String cyan(text) => "$_cyan$text$_noColor"; | 492 String cyan(text) => sparkle ? "$text" : "$_cyan$text$_noColor"; |
| 474 | 493 |
| 475 /// Wraps [text] in the ANSI escape codes to color it green when on a platform | 494 /// Wraps [text] in the ANSI escape codes to color it green when on a platform |
| 476 /// that supports that. | 495 /// that supports that. |
| 477 /// | 496 /// |
| 478 /// Use this to highlight something successful or otherwise positive. | 497 /// Use this to highlight something successful or otherwise positive. |
| 479 String green(text) => "$_green$text$_noColor"; | 498 String green(text) => sparkle ? "$text" : "$_green$text$_noColor"; |
| 480 | 499 |
| 481 /// Wraps [text] in the ANSI escape codes to color it magenta when on a | 500 /// Wraps [text] in the ANSI escape codes to color it magenta when on a |
| 482 /// platform that supports that. | 501 /// platform that supports that. |
| 483 /// | 502 /// |
| 484 /// Use this to highlight something risky that the user should be aware of but | 503 /// Use this to highlight something risky that the user should be aware of but |
| 485 /// may intend to do. | 504 /// may intend to do. |
| 486 String magenta(text) => "$_magenta$text$_noColor"; | 505 String magenta(text) => sparkle ? "$text" : "$_magenta$text$_noColor"; |
| 487 | 506 |
| 488 /// Wraps [text] in the ANSI escape codes to color it red when on a platform | 507 /// Wraps [text] in the ANSI escape codes to color it red when on a platform |
| 489 /// that supports that. | 508 /// that supports that. |
| 490 /// | 509 /// |
| 491 /// Use this to highlight unequivocal errors, problems, or failures. | 510 /// Use this to highlight unequivocal errors, problems, or failures. |
| 492 String red(text) => "$_red$text$_noColor"; | 511 String red(text) => sparkle ? "$text" : "$_red$text$_noColor"; |
| 493 | 512 |
| 494 /// Wraps [text] in the ANSI escape codes to color it yellow when on a platform | 513 /// Wraps [text] in the ANSI escape codes to color it yellow when on a platform |
| 495 /// that supports that. | 514 /// that supports that. |
| 496 /// | 515 /// |
| 497 /// Use this to highlight warnings, cautions or other things that are bad but | 516 /// Use this to highlight warnings, cautions or other things that are bad but |
| 498 /// do not prevent the user's goal from being reached. | 517 /// do not prevent the user's goal from being reached. |
| 499 String yellow(text) => "$_yellow$text$_noColor"; | 518 String yellow(text) => sparkle ? "$text" : "$_yellow$text$_noColor"; |
| 500 | 519 |
| 501 /// Log function that prints the message to stdout. | 520 /// Log function that prints the message to stdout. |
| 502 void _logToStdout(Entry entry) { | 521 void _logToStdout(Entry entry) { |
| 503 _logToStream(stdout, entry, showLabel: false); | 522 _logToStream(stdout, entry, showLabel: false); |
| 504 } | 523 } |
| 505 | 524 |
| 506 /// Log function that prints the message to stdout with the level name. | 525 /// Log function that prints the message to stdout with the level name. |
| 507 void _logToStdoutWithLabel(Entry entry) { | 526 void _logToStdoutWithLabel(Entry entry) { |
| 508 _logToStream(stdout, entry, showLabel: true); | 527 _logToStream(stdout, entry, showLabel: true); |
| 509 } | 528 } |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 message(_firstMessage); | 652 message(_firstMessage); |
| 634 } else { | 653 } else { |
| 635 message(_template.replaceAll("##", _count.toString())); | 654 message(_template.replaceAll("##", _count.toString())); |
| 636 } | 655 } |
| 637 } | 656 } |
| 638 | 657 |
| 639 void _initTimer() { | 658 void _initTimer() { |
| 640 _timer = new Timer(_window, end); | 659 _timer = new Timer(_window, end); |
| 641 } | 660 } |
| 642 } | 661 } |
| OLD | NEW |