[xbuild] Implement FileLogger . Fix #676650 .
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / FileLogger.cs
1 //
2 // FileLogger.cs: Logs to file
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 //   Ankit Jain (jankit@novell.com)
7 // 
8 // (C) 2005 Marek Sieradzki
9 // Copyright 2011 Novell, Inc (http://www.novell.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 #if NET_2_0
31
32 using System;
33 using System.IO;
34 using System.Text;
35 using Microsoft.Build.Framework;
36
37 namespace Microsoft.Build.BuildEngine {
38         public class FileLogger : ConsoleLogger {
39                 StreamWriter sw;
40                 string logfile;
41                 string encoding = null;
42                 IEventSource eventSource;
43
44                 public FileLogger ()
45                 {
46                         base.Verbosity = LoggerVerbosity.Detailed;
47                 }
48
49                 public override void Initialize (IEventSource eventSource)
50                 {
51                         this.eventSource = eventSource;
52                         logfile = "msbuild.log";
53
54                         bool append = false;
55                         string key, value;
56                         string[] splittedParameters = Parameters.Split (new char [] {';'}, StringSplitOptions.RemoveEmptyEntries);
57                         foreach (string s in splittedParameters) {
58                                 if (String.Compare (s, "Append") == 0) {
59                                         append = true;
60                                         continue;
61                                 }
62
63                                 if (s.StartsWith ("Encoding")) {
64                                         if (!TrySplitKeyValuePair (s, out key, out value))
65                                                 throw new LoggerException ("Encoding should be specified as: Encoding=<encoding>, eg. Encoding=UTF-8");
66
67                                         if (String.IsNullOrEmpty (value))
68                                                 throw new LoggerException ("Encoding must be non-empty");
69
70                                         encoding = value;
71                                         continue;
72                                 }
73
74                                 if (s.StartsWith ("LogFile")) {
75                                         if (!TrySplitKeyValuePair (s, out key, out value))
76                                                 throw new LoggerException ("LogFile should be specified as: LogFile=<encoding>, eg. LogFile=foo.log");
77
78                                         if (String.IsNullOrEmpty (value))
79                                                 throw new LoggerException ("LogFile value must be non-empty");
80
81                                         logfile = value;
82                                         continue;
83                                 }
84                         }
85
86                         // Attach *our* HandleBuildStarted as the first one,
87                         // as it needs to create the writer!
88                         eventSource.BuildStarted += HandleBuildStarted;
89                         base.Initialize (eventSource);
90                         // Attach *our* HandleBuildFinished as the last one,
91                         // as it needs to close the writer!
92                         eventSource.BuildFinished += HandleBuildFinished;
93
94                         CreateWriter (append);
95                 }
96
97                 void CreateWriter (bool append_to)
98                 {
99                         if (sw != null)
100                                 return;
101
102                         if (!String.IsNullOrEmpty (encoding))
103                                 sw = new StreamWriter (logfile, append_to, Encoding.GetEncoding (encoding));
104                         else
105                                 sw = new StreamWriter (logfile, append_to, Encoding.Default);
106                         WriteHandler = sw.WriteLine;
107                 }
108
109                 void HandleBuildStarted (object sender, BuildStartedEventArgs args)
110                 {
111                         CreateWriter (true);
112                 }
113
114                 void HandleBuildFinished (object sender, BuildFinishedEventArgs args)
115                 {
116                         base.WriteHandler = null;
117                         if (sw != null) {
118                                 sw.Close ();
119                                 sw = null;
120                         }
121                 }
122
123                 bool TrySplitKeyValuePair (string pair, out string key, out string value)
124                 {
125                         key = value = null;
126                         string[] parts = pair.Split ('=');
127                         if (parts.Length != 2)
128                                 return false;
129
130                         key = parts [0];
131                         value = parts [1];
132                         return true;
133                 }
134
135                 public override void Shutdown ()
136                 {
137                         base.WriteHandler = null;
138                         if (sw != null) {
139                                 sw.Close ();
140                                 sw = null;
141                         }
142
143                         if (eventSource != null) {
144                                 eventSource.BuildStarted -= HandleBuildStarted;
145                                 eventSource.BuildFinished -= HandleBuildFinished;
146                         }
147
148                         base.Shutdown ();
149                 }
150         }
151 }
152
153 #endif