2 // ConsoleLogger.cs: Outputs to the console
5 // Marek Sieradzki (marek.sieradzki@gmail.com)
7 // (C) 2005 Marek Sieradzki
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Runtime.InteropServices;
32 using System.Collections;
33 using System.Collections.Generic;
36 using System.Security;
38 using Microsoft.Build.Framework;
40 namespace Microsoft.Build.BuildEngine {
41 public class ConsoleLogger : ILogger {
45 LoggerVerbosity verbosity;
46 WriteHandler writeHandler;
50 bool performanceSummary;
52 bool skipProjectStartedText;
53 List<string> errors, warnings;
55 ConsoleColor errorColor, warningColor, eventColor, messageColor, highMessageColor;
57 ColorResetter colorReset;
58 IEventSource eventSource;
59 bool no_message_color, use_colors;
60 bool noItemAndPropertyList;
62 List<BuildEvent> events;
63 Dictionary<string, List<string>> errorsTable;
64 Dictionary<string, List<string>> warningsTable;
65 SortedDictionary<string, PerfInfo> targetPerfTable, tasksPerfTable;
66 string current_events_string;
68 public ConsoleLogger ()
69 : this (LoggerVerbosity.Normal, null, null, null)
73 public ConsoleLogger (LoggerVerbosity verbosity)
74 : this (LoggerVerbosity.Normal, null, null, null)
78 public ConsoleLogger (LoggerVerbosity verbosity,
81 ColorResetter colorReset)
83 this.verbosity = verbosity;
86 this.warningCount = 0;
88 this.writeHandler += new WriteHandler (WriteHandlerFunction);
90 this.writeHandler += write;
91 this.performanceSummary = false;
92 this.showSummary = true;
93 this.skipProjectStartedText = false;
94 errors = new List<string> ();
95 warnings = new List<string> ();
96 this.colorSet = colorSet;
97 this.colorReset = colorReset;
99 events = new List<BuildEvent> ();
100 errorsTable = new Dictionary<string, List<string>> ();
101 warningsTable = new Dictionary<string, List<string>> ();
102 targetPerfTable = new SortedDictionary<string, PerfInfo> ();
103 tasksPerfTable = new SortedDictionary<string, PerfInfo> ();
106 errorColor = ConsoleColor.DarkRed;
107 warningColor = ConsoleColor.DarkYellow;
108 eventColor = ConsoleColor.DarkCyan;
109 messageColor = ConsoleColor.DarkGray;
110 highMessageColor = ConsoleColor.White;
112 // if message color is not set via the env var,
113 // then don't use any color for it.
114 no_message_color = true;
117 if (colorSet == null || colorReset == null)
121 string config = Environment.GetEnvironmentVariable ("XBUILD_COLORS");
122 if (config == null) {
127 if (config == "disable")
131 string [] pairs = config.Split (new char[] {','}, StringSplitOptions.RemoveEmptyEntries);
132 foreach (string pair in pairs) {
133 string [] parts = pair.Split (new char[] {'='}, StringSplitOptions.RemoveEmptyEntries);
134 if (parts.Length != 2)
137 if (parts [0] == "errors")
138 TryParseConsoleColor (parts [1], ref errorColor);
139 else if (parts [0] == "warnings")
140 TryParseConsoleColor (parts [1], ref warningColor);
141 else if (parts [0] == "events")
142 TryParseConsoleColor (parts [1], ref eventColor);
143 else if (parts [0] == "messages") {
144 if (TryParseConsoleColor (parts [1], ref messageColor)) {
145 highMessageColor = GetBrightColorFor (messageColor);
146 no_message_color = false;
152 bool TryParseConsoleColor (string color_str, ref ConsoleColor color)
154 switch (color_str.ToLower ()) {
155 case "black": color = ConsoleColor.Black; break;
157 case "blue": color = ConsoleColor.DarkBlue; break;
158 case "green": color = ConsoleColor.DarkGreen; break;
159 case "cyan": color = ConsoleColor.DarkCyan; break;
160 case "red": color = ConsoleColor.DarkRed; break;
161 case "magenta": color = ConsoleColor.DarkMagenta; break;
162 case "yellow": color = ConsoleColor.DarkYellow; break;
163 case "grey": color = ConsoleColor.DarkGray; break;
165 case "brightgrey": color = ConsoleColor.Gray; break;
166 case "brightblue": color = ConsoleColor.Blue; break;
167 case "brightgreen": color = ConsoleColor.Green; break;
168 case "brightcyan": color = ConsoleColor.Cyan; break;
169 case "brightred": color = ConsoleColor.Red; break;
170 case "brightmagenta": color = ConsoleColor.Magenta; break;
171 case "brightyellow": color = ConsoleColor.Yellow; break;
174 case "brightwhite": color = ConsoleColor.White; break;
175 default: return false;
181 ConsoleColor GetBrightColorFor (ConsoleColor color)
184 case ConsoleColor.DarkBlue: return ConsoleColor.Blue;
185 case ConsoleColor.DarkGreen: return ConsoleColor.Green;
186 case ConsoleColor.DarkCyan: return ConsoleColor.Cyan;
187 case ConsoleColor.DarkRed: return ConsoleColor.Red;
188 case ConsoleColor.DarkMagenta: return ConsoleColor.Magenta;
189 case ConsoleColor.DarkYellow: return ConsoleColor.Yellow;
190 case ConsoleColor.DarkGray: return ConsoleColor.Gray;
191 case ConsoleColor.Gray: return ConsoleColor.White;
193 default: return color;
197 public void ApplyParameter (string parameterName,
198 string parameterValue)
200 switch (parameterName) {
201 case "PerformanceSummary":
202 this.performanceSummary = true;
205 this.showSummary = true;
208 this.showSummary = false;
210 case "NoItemAndPropertyList":
211 this.noItemAndPropertyList = true;
214 if (parameterName.StartsWith ("Verbosity="))
215 ParseVerbosity (parameterName);
220 void ParseVerbosity (string s)
223 if (!TrySplitKeyValuePair (s, out key, out value))
224 throw new LoggerException ("Unknown Verbosity, should be set as 'Verbosity=<verbosity>'");
229 Verbosity = LoggerVerbosity.Quiet;
233 Verbosity = LoggerVerbosity.Minimal;
237 Verbosity = LoggerVerbosity.Normal;
241 Verbosity = LoggerVerbosity.Detailed;
245 Verbosity = LoggerVerbosity.Diagnostic;
248 throw new LoggerException (String.Format ("Unknown verbosity - '{0}'", s));
252 bool TrySplitKeyValuePair (string pair, out string key, out string value)
255 string[] parts = pair.Split ('=');
256 if (parts.Length != 2)
264 public virtual void Initialize (IEventSource eventSource)
266 this.eventSource = eventSource;
268 eventSource.BuildStarted += BuildStartedHandler;
269 eventSource.BuildFinished += BuildFinishedHandler;
271 eventSource.ProjectStarted += PushEvent;
272 eventSource.ProjectFinished += PopEvent;
274 eventSource.TargetStarted += PushEvent;
275 eventSource.TargetFinished += PopEvent;
277 eventSource.TaskStarted += PushEvent;
278 eventSource.TaskFinished += PopEvent;
280 eventSource.MessageRaised += MessageHandler;
281 eventSource.WarningRaised += WarningHandler;
282 eventSource.ErrorRaised += ErrorHandler;
284 if (!String.IsNullOrEmpty (parameters))
288 public void BuildStartedHandler (object sender, BuildStartedEventArgs args)
290 if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
291 WriteLine (String.Empty);
292 WriteLine (String.Format ("Build started {0}.", args.Timestamp));
293 WriteLine ("__________________________________________________");
295 buildStart = args.Timestamp;
300 public void BuildFinishedHandler (object sender, BuildFinishedEventArgs args)
302 BuildFinishedHandlerActual (args);
306 errorsTable.Clear ();
307 warningsTable.Clear ();
308 targetPerfTable.Clear ();
309 tasksPerfTable.Clear ();
316 projectFailed = false;
319 void BuildFinishedHandlerActual (BuildFinishedEventArgs args)
321 if (!IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
326 TimeSpan timeElapsed = args.Timestamp - buildStart;
327 if (performanceSummary || verbosity == LoggerVerbosity.Diagnostic)
328 DumpPerformanceSummary ();
330 if (args.Succeeded == true && !projectFailed) {
331 WriteLine ("Build succeeded.");
333 WriteLine ("Build FAILED.");
335 if (warnings.Count > 0) {
336 WriteLine (Environment.NewLine + "Warnings:");
337 SetColor (warningColor);
339 WriteLine (String.Empty);
340 foreach (KeyValuePair<string, List<string>> pair in warningsTable) {
341 if (!String.IsNullOrEmpty (pair.Key))
342 WriteLine (pair.Key);
344 string indent_str = String.IsNullOrEmpty (pair.Key) ? String.Empty : "\t";
345 foreach (string msg in pair.Value)
346 WriteLine (String.Format ("{0}{1}", indent_str, msg));
348 WriteLine (String.Empty);
354 if (errors.Count > 0) {
355 WriteLine ("Errors:");
356 SetColor (errorColor);
358 WriteLine (String.Empty);
359 foreach (KeyValuePair<string, List<string>> pair in errorsTable) {
360 if (!String.IsNullOrEmpty (pair.Key))
361 WriteLine (pair.Key);
363 string indent_str = String.IsNullOrEmpty (pair.Key) ? String.Empty : "\t";
364 foreach (string msg in pair.Value)
365 WriteLine (String.Format ("{0}{1}", indent_str, msg));
367 WriteLine (String.Empty);
372 if (showSummary == true){
373 WriteLine (String.Format ("\t {0} Warning(s)", warningCount));
374 WriteLine (String.Format ("\t {0} Error(s)", errorCount));
375 WriteLine (String.Empty);
376 WriteLine (String.Format ("Time Elapsed {0}", timeElapsed));
382 public void ProjectStartedHandler (object sender, ProjectStartedEventArgs args)
384 if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
385 SetColor (eventColor);
386 WriteLine (String.Format ("Project \"{0}\" ({1} target(s)):", args.ProjectFile,
387 String.IsNullOrEmpty (args.TargetNames) ? "default" : args.TargetNames));
389 DumpProperties (args.Properties);
390 DumpItems (args.Items);
394 public void ProjectFinishedHandler (object sender, ProjectFinishedEventArgs args)
396 if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
399 SetColor (eventColor);
400 WriteLine (String.Format ("Done building project \"{0}\".{1}", args.ProjectFile,
401 args.Succeeded ? String.Empty : "-- FAILED"));
403 WriteLine (String.Empty);
406 // no project has failed yet, so update the flag
407 projectFailed = !args.Succeeded;
410 public void TargetStartedHandler (object sender, TargetStartedEventArgs args)
412 if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
414 SetColor (eventColor);
415 WriteLine (String.Empty);
416 WriteLine (String.Format ("Target {0}:",args.TargetName));
421 public void TargetFinishedHandler (object sender, TargetFinishedEventArgs args)
423 if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Detailed) ||
424 (!args.Succeeded && IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal))) {
425 SetColor (eventColor);
426 WriteLine (String.Format ("Done building target \"{0}\" in project \"{1}\".{2}",
427 args.TargetName, args.ProjectFile,
428 args.Succeeded ? String.Empty : "-- FAILED"));
430 WriteLine (String.Empty);
435 public void TaskStartedHandler (object sender, TaskStartedEventArgs args)
437 if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Detailed)) {
438 SetColor (eventColor);
439 WriteLine (String.Format ("Task \"{0}\"",args.TaskName));
445 public void TaskFinishedHandler (object sender, TaskFinishedEventArgs args)
448 if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Detailed) ||
449 (!args.Succeeded && IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal))) {
450 SetColor (eventColor);
452 WriteLine (String.Format ("Done executing task \"{0}\"", args.TaskName));
454 WriteLine (String.Format ("Task \"{0}\" execution -- FAILED", args.TaskName));
459 public void MessageHandler (object sender, BuildMessageEventArgs args)
461 if (IsMessageOk (args)) {
462 if (no_message_color) {
463 ExecutePendingEventHandlers ();
464 WriteLine (args.Message);
466 ExecutePendingEventHandlers ();
467 SetColor (args.Importance == MessageImportance.High ? highMessageColor : messageColor);
468 WriteLine (args.Message);
474 public void WarningHandler (object sender, BuildWarningEventArgs args)
476 string msg = FormatWarningEvent (args);
477 if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Quiet)) {
478 ExecutePendingEventHandlers ();
479 SetColor (warningColor);
480 WriteLineWithoutIndent (msg);
485 List<string> list = null;
486 if (!warningsTable.TryGetValue (EventsAsString, out list))
487 warningsTable [EventsAsString] = list = new List<string> ();
493 public void ErrorHandler (object sender, BuildErrorEventArgs args)
495 string msg = FormatErrorEvent (args);
496 if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Quiet)) {
497 ExecutePendingEventHandlers ();
498 SetColor (errorColor);
499 WriteLineWithoutIndent (msg);
504 List<string> list = null;
505 if (!errorsTable.TryGetValue (EventsAsString, out list))
506 errorsTable [EventsAsString] = list = new List<string> ();
512 public void CustomEventHandler (object sender, CustomBuildEventArgs args)
516 private void WriteLine (string message)
519 StringBuilder sb = new StringBuilder ();
520 for (int i = 0; i < indent; i++)
523 string indent_str = sb.ToString ();
525 foreach (string line in message.Split (new string[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries))
526 writeHandler (indent_str + line);
528 writeHandler (message);
532 void PushEvent<T> (object sender, T args) where T: BuildStatusEventArgs
537 void PushEvent<T> (T args) where T: BuildStatusEventArgs
539 BuildEvent be = new BuildEvent {
541 StartHandlerHasExecuted = false,
546 current_events_string = null;
549 void PopEvent<T> (object sender, T finished_args) where T: BuildStatusEventArgs
551 PopEvent (finished_args);
554 void PopEvent<T> (T finished_args) where T: BuildStatusEventArgs
556 if (events.Count == 0)
557 throw new InvalidOperationException ("INTERNAL ERROR: Trying to pop from an empty events stack");
559 BuildEvent be = events [events.Count - 1];
560 if (performanceSummary || verbosity == LoggerVerbosity.Diagnostic) {
561 var args = be.EventArgs;
562 TargetStartedEventArgs tgt_args = args as TargetStartedEventArgs;
563 if (tgt_args != null) {
564 AddPerfInfo (tgt_args.TargetName, args.Timestamp, targetPerfTable);
566 TaskStartedEventArgs tsk_args = args as TaskStartedEventArgs;
567 if (tsk_args != null)
568 AddPerfInfo (tsk_args.TaskName, args.Timestamp, tasksPerfTable);
572 be.ExecuteFinishedHandler (finished_args);
573 events.RemoveAt (events.Count - 1);
574 current_events_string = null;
577 void ExecutePendingEventHandlers ()
579 foreach (var be in events)
580 be.ExecuteStartedHandler ();
583 string EventsToString ()
585 StringBuilder sb = new StringBuilder ();
587 string last_imported_target_file = String.Empty;
588 for (int i = 0; i < events.Count; i ++) {
589 var args = events [i].EventArgs;
590 ProjectStartedEventArgs pargs = args as ProjectStartedEventArgs;
592 sb.AppendFormat ("{0} ({1}) ->\n", pargs.ProjectFile,
593 String.IsNullOrEmpty (pargs.TargetNames) ?
596 last_imported_target_file = String.Empty;
600 TargetStartedEventArgs targs = args as TargetStartedEventArgs;
602 if (targs.TargetFile != targs.ProjectFile && targs.TargetFile != last_imported_target_file)
603 // target from an imported file,
604 // and it hasn't been mentioned as yet
605 sb.AppendFormat ("{0} ", targs.TargetFile);
607 last_imported_target_file = targs.TargetFile;
608 sb.AppendFormat ("({0} target) ->\n", targs.TargetName);
612 return sb.ToString ();
615 void AddPerfInfo (string name, DateTime start, IDictionary<string, PerfInfo> perf_table)
618 if (!perf_table.TryGetValue (name, out pi)) {
619 pi = new PerfInfo ();
620 perf_table [name] = pi;
623 pi.Time += DateTime.Now - start;
627 void DumpPerformanceSummary ()
629 SetColor (eventColor);
630 WriteLine ("Target perfomance summary:");
633 foreach (var pi in targetPerfTable.OrderBy (pair => pair.Value.Time))
634 WriteLine (String.Format ("{0,10:0.000} ms {1,-50} {2,5} calls", pi.Value.Time.TotalMilliseconds, pi.Key, pi.Value.NumberOfCalls));
636 WriteLine (String.Empty);
638 SetColor (eventColor);
639 WriteLine ("Tasks perfomance summary:");
642 foreach (var pi in tasksPerfTable.OrderBy (pair => pair.Value.Time))
643 WriteLine (String.Format ("{0,10:0.000} ms {1,-50} {2,5} calls", pi.Value.Time.TotalMilliseconds, pi.Key, pi.Value.NumberOfCalls));
645 WriteLine (String.Empty);
648 private void WriteLineWithoutIndent (string message)
650 writeHandler (message);
653 private void WriteHandlerFunction (string message)
655 Console.WriteLine (message);
658 void SetColor (ConsoleColor color)
670 private void ParseParameters ()
672 string[] splittedParameters = parameters.Split (';');
673 foreach (string s in splittedParameters )
674 ApplyParameter (s, null);
677 public virtual void Shutdown ()
679 if (eventSource == null)
682 eventSource.BuildStarted -= BuildStartedHandler;
683 eventSource.BuildFinished -= BuildFinishedHandler;
685 eventSource.ProjectStarted -= PushEvent;
686 eventSource.ProjectFinished -= PopEvent;
688 eventSource.TargetStarted -= PushEvent;
689 eventSource.TargetFinished -= PopEvent;
691 eventSource.TaskStarted -= PushEvent;
692 eventSource.TaskFinished -= PopEvent;
694 eventSource.MessageRaised -= MessageHandler;
695 eventSource.WarningRaised -= WarningHandler;
696 eventSource.ErrorRaised -= ErrorHandler;
699 static bool InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t";
701 private string FormatErrorEvent (BuildErrorEventArgs args)
703 // For some reason we get an 1-char empty string as Subcategory somtimes.
704 string subprefix = args.Subcategory == null || args.Subcategory == "" || args.Subcategory == " " ? "" : " ";
705 string subcat = subprefix == "" ? "" : args.Subcategory;
707 if (args.LineNumber != 0){
708 if (args.ColumnNumber != 0 && !InEmacs)
709 return String.Format ("{0}({1},{2}): {3}{4}error {5}: {6}",
710 args.File, args.LineNumber, args.ColumnNumber,
711 subprefix, subcat, args.Code, args.Message);
713 return String.Format ("{0}({1}): {2}{3}error {4}: {5}",
714 args.File, args.LineNumber,
715 subprefix, subcat, args.Code, args.Message);
717 return String.Format ("{0}: {1}{2}error {3}: {4}", args.File, subprefix, subcat, args.Code,
722 private string FormatWarningEvent (BuildWarningEventArgs args)
724 // For some reason we get an 1-char empty string as Subcategory somtimes.
725 string subprefix = args.Subcategory == null || args.Subcategory == "" || args.Subcategory == " " ? "" : " ";
726 string subcat = subprefix == "" ? "" : args.Subcategory;
728 // FIXME: show more complicated args
729 if (args.LineNumber != 0){
731 if (args.ColumnNumber != 0 && !InEmacs) {
732 return String.Format ("{0}({1},{2}): {3}{4}warning {5}: {6}",
733 args.File, args.LineNumber, args.ColumnNumber,
734 subprefix, subcat, args.Code, args.Message);
736 return String.Format ("{0}({1}): {2}{3}warning {4}: {5}",
737 args.File, args.LineNumber,
738 subprefix, subcat, args.Code, args.Message);
740 return String.Format ("{0}: {1} warning {2}: {3}", args.File, args.Subcategory, args.Code,
745 private bool IsMessageOk (BuildMessageEventArgs bsea)
747 if (bsea.Importance == MessageImportance.High && IsVerbosityGreaterOrEqual (LoggerVerbosity.Minimal)) {
749 } else if (bsea.Importance == MessageImportance.Normal && IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
751 } else if (bsea.Importance == MessageImportance.Low && IsVerbosityGreaterOrEqual (LoggerVerbosity.Detailed)) {
757 private bool IsVerbosityGreaterOrEqual (LoggerVerbosity v)
759 if (v == LoggerVerbosity.Diagnostic) {
760 return LoggerVerbosity.Diagnostic <= verbosity;
761 } else if (v == LoggerVerbosity.Detailed) {
762 return LoggerVerbosity.Detailed <= verbosity;
763 } else if (v == LoggerVerbosity.Normal) {
764 return LoggerVerbosity.Normal <= verbosity;
765 } else if (v == LoggerVerbosity.Minimal) {
766 return LoggerVerbosity.Minimal <= verbosity;
767 } else if (v == LoggerVerbosity.Quiet) {
773 void DumpProperties (IEnumerable properties)
775 if (noItemAndPropertyList || !IsVerbosityGreaterOrEqual (LoggerVerbosity.Diagnostic))
778 SetColor (eventColor);
779 WriteLine (String.Empty);
780 WriteLine ("Initial Properties:");
783 if (properties == null)
786 var dict = new SortedDictionary<string, string> ();
787 foreach (DictionaryEntry de in properties)
788 dict [(string)de.Key] = (string)de.Value;
790 foreach (KeyValuePair<string, string> pair in dict)
791 WriteLine (String.Format ("{0} = {1}", pair.Key, pair.Value));
794 void DumpItems (IEnumerable items)
796 if (noItemAndPropertyList || !IsVerbosityGreaterOrEqual (LoggerVerbosity.Diagnostic) || items == null)
799 SetColor (eventColor);
800 WriteLine (String.Empty);
801 WriteLine ("Initial Items:");
806 var items_table = new SortedDictionary<string, List<ITaskItem>> ();
807 foreach (DictionaryEntry de in items) {
808 string key = (string)de.Key;
809 if (!items_table.ContainsKey (key))
810 items_table [key] = new List<ITaskItem> ();
812 items_table [key].Add ((ITaskItem) de.Value);
815 foreach (string name in items_table.Keys) {
818 foreach (ITaskItem item in items_table [name])
819 WriteLine (item.ItemSpec);
824 public string Parameters {
830 throw new ArgumentNullException ();
835 string EventsAsString {
837 if (current_events_string == null)
838 current_events_string = EventsToString ();
839 return current_events_string;
843 public bool ShowSummary {
844 get { return showSummary; }
845 set { showSummary = value; }
848 public bool SkipProjectStartedText {
849 get { return skipProjectStartedText; }
850 set { skipProjectStartedText = value; }
853 public LoggerVerbosity Verbosity {
854 get { return verbosity; }
855 set { verbosity = value; }
858 protected WriteHandler WriteHandler {
859 get { return writeHandler; }
860 set { writeHandler = value; }
865 public BuildStatusEventArgs EventArgs;
866 public bool StartHandlerHasExecuted;
867 public ConsoleLogger ConsoleLogger;
869 public void ExecuteStartedHandler ()
871 if (StartHandlerHasExecuted)
874 if (EventArgs is ProjectStartedEventArgs)
875 ConsoleLogger.ProjectStartedHandler (null, (ProjectStartedEventArgs)EventArgs);
876 else if (EventArgs is TargetStartedEventArgs)
877 ConsoleLogger.TargetStartedHandler (null, (TargetStartedEventArgs)EventArgs);
878 else if (EventArgs is TaskStartedEventArgs)
879 ConsoleLogger.TaskStartedHandler (null, (TaskStartedEventArgs)EventArgs);
880 else if (!(EventArgs is BuildStartedEventArgs))
881 throw new InvalidOperationException ("Unexpected event on the stack, type: " + EventArgs.GetType ());
883 StartHandlerHasExecuted = true;
886 public void ExecuteFinishedHandler (BuildStatusEventArgs finished_args)
888 if (!StartHandlerHasExecuted)
891 if (EventArgs is ProjectStartedEventArgs)
892 ConsoleLogger.ProjectFinishedHandler (null, finished_args as ProjectFinishedEventArgs);
893 else if (EventArgs is TargetStartedEventArgs)
894 ConsoleLogger.TargetFinishedHandler (null, finished_args as TargetFinishedEventArgs);
895 else if (EventArgs is TaskStartedEventArgs)
896 ConsoleLogger.TaskFinishedHandler (null, finished_args as TaskFinishedEventArgs);
897 else if (!(EventArgs is BuildStartedEventArgs))
898 throw new InvalidOperationException ("Unexpected event on the stack, type: " + EventArgs.GetType ());
903 public TimeSpan Time;
904 public int NumberOfCalls;