2010-01-20 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mcs / tools / xbuild / Main.cs
1 //
2 // Main.cs: Main program file of command line utility.
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 //   Miguel de Icaza (miguel@ximian.com)
7 //   Marek Safar (marek.safar@seznam.cz)
8 //
9 // (C) 2005 Marek Sieradzki
10 // Copyright 2009 Novell, Inc (http://www.novell.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
31 #if NET_2_0
32
33 using System;
34 using System.Collections;
35 using System.IO;
36 using System.Reflection;
37 using Microsoft.Build.BuildEngine;
38 using Microsoft.Build.Framework;
39 using Microsoft.Build.Utilities;
40 using Mono.XBuild.Framework;
41
42 namespace Mono.XBuild.CommandLine {
43         public class MainClass {
44                 
45                 Parameters      parameters;
46                 string[]        args;
47                 string          binPath;
48                 string          defaultSchema;
49                 
50                 Engine          engine;
51                 Project         project;
52                 ConsoleReportPrinter printer;
53
54                 
55                 public static void Main (string[] args)
56                 {
57                         MainClass mc = new MainClass ();
58                         mc.args = args;
59                         mc.Execute ();
60                 }
61                 
62                 public MainClass ()
63                 {
64                         binPath = ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20);
65                         defaultSchema = Path.Combine (binPath, "Microsoft.Build.xsd");
66                         parameters = new Parameters (binPath);
67                 }
68                 
69                 public void Execute ()
70                 {
71                         bool result = false;
72                         bool show_stacktrace = false;
73                         
74                         try {
75                                 parameters.ParseArguments (args);
76                                 show_stacktrace = (parameters.LoggerVerbosity == LoggerVerbosity.Detailed ||
77                                         parameters.LoggerVerbosity == LoggerVerbosity.Diagnostic);
78                                 
79                                 if (parameters.DisplayVersion)
80                                         ErrorUtilities.ShowVersion (false);
81                                 
82                                 engine  = new Engine (binPath);
83                                 
84                                 engine.GlobalProperties = this.parameters.Properties;
85                                 
86                                 if (!parameters.NoConsoleLogger) {
87                                         printer = new ConsoleReportPrinter ();
88                                         ConsoleLogger cl = new ConsoleLogger (parameters.LoggerVerbosity,
89                                                         printer.Print, printer.SetForeground, printer.ResetColor);
90
91                                         cl.Parameters = parameters.ConsoleLoggerParameters;
92                                         cl.Verbosity = parameters.LoggerVerbosity; 
93                                         engine.RegisterLogger (cl);
94                                 }
95                                 
96                                 foreach (LoggerInfo li in parameters.Loggers) {
97                                         Assembly assembly;
98                                         if (li.InfoType == LoadInfoType.AssemblyFilename)
99                                                 assembly = Assembly.LoadFrom (li.Filename);
100                                         else
101                                                 assembly = Assembly.Load (li.AssemblyName);
102                                         ILogger logger = (ILogger)Activator.CreateInstance (assembly.GetType (li.ClassName));
103                                         logger.Parameters = li.Parameters;
104                                         engine.RegisterLogger (logger); 
105                                 }
106                                 
107                                 project = engine.CreateNewProject ();
108                                 
109                                 if (parameters.Validate) {
110                                         if (parameters.ValidationSchema == null)
111                                                 project.SchemaFile = defaultSchema;
112                                         else
113                                                 project.SchemaFile = parameters.ValidationSchema;
114                                 }
115
116                                 string projectFile = parameters.ProjectFile;
117                                 if (!File.Exists (projectFile)) {
118                                         ErrorUtilities.ReportError (0, String.Format ("Project file '{0}' not found.", projectFile));
119                                         return;
120                                 }
121
122                                 project.Load (projectFile);
123                                 
124                                 string oldCurrentDirectory = Environment.CurrentDirectory;
125                                 string dir = Path.GetDirectoryName (projectFile);
126                                 if (!String.IsNullOrEmpty (dir))
127                                         Directory.SetCurrentDirectory (dir);
128                                 result = engine.BuildProject (project, parameters.Targets, null);
129                                 Directory.SetCurrentDirectory (oldCurrentDirectory);
130                         }
131                         
132                         catch (InvalidProjectFileException ipfe) {
133                                 ErrorUtilities.ReportError (0, show_stacktrace ? ipfe.ToString () : ipfe.Message);
134                         }
135
136                         catch (InternalLoggerException ile) {
137                                 ErrorUtilities.ReportError (0, show_stacktrace ? ile.ToString () : ile.Message);
138                         }
139
140                         catch (Exception) {
141                                 throw;
142                         }
143                         
144                         finally {
145                                 if (engine != null)
146                                         engine.UnregisterAllLoggers ();
147
148                                 Environment.Exit (result ? 0 : 1);
149                         }
150
151                 }
152
153         }
154
155         // code from mcs/report.cs
156         class ConsoleReportPrinter
157         {
158                 string prefix, postfix;
159                 bool color_supported;
160                 TextWriter writer;
161                 string [] colorPrefixes;
162
163                 public ConsoleReportPrinter ()
164                         : this (Console.Out)
165                 {
166                 }
167
168                 public ConsoleReportPrinter (TextWriter writer)
169                 {
170                         this.writer = writer;
171
172                         string term = Environment.GetEnvironmentVariable ("TERM");
173                         bool xterm_colors = false;
174
175                         color_supported = false;
176                         switch (term){
177                         case "xterm":
178                         case "rxvt":
179                         case "rxvt-unicode":
180                                 if (Environment.GetEnvironmentVariable ("COLORTERM") != null){
181                                         xterm_colors = true;
182                                 }
183                                 break;
184
185                         case "xterm-color":
186                                 xterm_colors = true;
187                                 break;
188                         }
189                         if (!xterm_colors)
190                                 return;
191
192                         if (!(UnixUtils.isatty (1) && UnixUtils.isatty (2)))
193                                 return;
194
195                         color_supported = true;
196                         PopulateColorPrefixes ();
197                         postfix = "\x001b[0m";
198                 }
199
200                 void PopulateColorPrefixes ()
201                 {
202                         colorPrefixes = new string [16];
203
204                         colorPrefixes [(int)ConsoleColor.Black] = GetForeground ("black");
205                         colorPrefixes [(int)ConsoleColor.DarkBlue] = GetForeground ("blue");
206                         colorPrefixes [(int)ConsoleColor.DarkGreen] = GetForeground ("green");
207                         colorPrefixes [(int)ConsoleColor.DarkCyan] = GetForeground ("cyan");
208                         colorPrefixes [(int)ConsoleColor.DarkRed] = GetForeground ("red");
209                         colorPrefixes [(int)ConsoleColor.DarkMagenta] = GetForeground ("magenta");
210                         colorPrefixes [(int)ConsoleColor.DarkYellow] = GetForeground ("yellow");
211                         colorPrefixes [(int)ConsoleColor.DarkGray] = GetForeground ("grey");
212
213                         colorPrefixes [(int)ConsoleColor.Gray] = GetForeground ("brightgrey");
214                         colorPrefixes [(int)ConsoleColor.Blue] = GetForeground ("brightblue");
215                         colorPrefixes [(int)ConsoleColor.Green] = GetForeground ("brightgreen");
216                         colorPrefixes [(int)ConsoleColor.Cyan] = GetForeground ("brightcyan");
217                         colorPrefixes [(int)ConsoleColor.Red] = GetForeground ("brightred");
218                         colorPrefixes [(int)ConsoleColor.Magenta] = GetForeground ("brightmagenta");
219                         colorPrefixes [(int)ConsoleColor.Yellow] = GetForeground ("brightyellow");
220
221                         colorPrefixes [(int)ConsoleColor.White] = GetForeground ("brightwhite");
222                 }
223
224                 public void SetForeground (ConsoleColor color)
225                 {
226                         if (color_supported)
227                                 prefix = colorPrefixes [(int)color];
228                 }
229
230                 public void ResetColor ()
231                 {
232                         prefix = "\x001b[0m";
233                 }
234
235                 static int NameToCode (string s)
236                 {
237                         switch (s) {
238                         case "black":
239                                 return 0;
240                         case "red":
241                                 return 1;
242                         case "green":
243                                 return 2;
244                         case "yellow":
245                                 return 3;
246                         case "blue":
247                                 return 4;
248                         case "magenta":
249                                 return 5;
250                         case "cyan":
251                                 return 6;
252                         case "grey":
253                         case "white":
254                                 return 7;
255                         }
256                         return 7;
257                 }
258
259                 //
260                 // maps a color name to its xterm color code
261                 //
262                 static string GetForeground (string s)
263                 {
264                         string highcode;
265
266                         if (s.StartsWith ("bright")) {
267                                 highcode = "1;";
268                                 s = s.Substring (6);
269                         } else
270                                 highcode = "";
271
272                         return "\x001b[" + highcode + (30 + NameToCode (s)).ToString () + "m";
273                 }
274
275                 static string GetBackground (string s)
276                 {
277                         return "\x001b[" + (40 + NameToCode (s)).ToString () + "m";
278                 }
279
280                 string FormatText (string txt)
281                 {
282                         if (prefix != null && color_supported)
283                                 return prefix + txt + postfix;
284
285                         return txt;
286                 }
287
288                 public void Print (string message)
289                 {
290                         writer.WriteLine (FormatText (message));
291                 }
292
293         }
294
295         class UnixUtils {
296                 [System.Runtime.InteropServices.DllImport ("libc", EntryPoint="isatty")]
297                 extern static int _isatty (int fd);
298
299                 public static bool isatty (int fd)
300                 {
301                         try {
302                                 return _isatty (fd) == 1;
303                         } catch {
304                                 return false;
305                         }
306                 }
307         }
308
309 }
310
311 #endif