Add color support for errors/warnings etc.
[mcs.git] / tools / xbuild / Main.cs
blob346e9a210b0365b27a1ecb738a178999e0d6fb0b
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)
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:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
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.
31 #if NET_2_0
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;
42 namespace Mono.XBuild.CommandLine {
43 public class MainClass {
45 Parameters parameters;
46 string[] args;
47 string binPath;
48 string defaultSchema;
50 Engine engine;
51 Project project;
52 ConsoleReportPrinter printer;
55 public static void Main (string[] args)
57 MainClass mc = new MainClass ();
58 mc.args = args;
59 mc.Execute ();
62 public MainClass ()
64 binPath = ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20);
65 defaultSchema = Path.Combine (binPath, "Microsoft.Build.xsd");
66 parameters = new Parameters (binPath);
69 public void Execute ()
71 bool result = false;
72 bool show_stacktrace = false;
74 try {
75 parameters.ParseArguments (args);
76 show_stacktrace = (parameters.LoggerVerbosity == LoggerVerbosity.Detailed ||
77 parameters.LoggerVerbosity == LoggerVerbosity.Diagnostic);
79 if (parameters.DisplayVersion)
80 ErrorUtilities.ShowVersion (false);
82 engine = new Engine (binPath);
84 engine.GlobalProperties = this.parameters.Properties;
86 if (!parameters.NoConsoleLogger) {
87 printer = new ConsoleReportPrinter ();
88 ConsoleLogger cl = new ConsoleLogger (parameters.LoggerVerbosity,
89 printer.Print, printer.SetForeground, printer.ResetColor);
91 cl.Parameters = parameters.ConsoleLoggerParameters;
92 cl.Verbosity = parameters.LoggerVerbosity;
93 engine.RegisterLogger (cl);
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);
107 project = engine.CreateNewProject ();
109 if (parameters.Validate) {
110 if (parameters.ValidationSchema == null)
111 project.SchemaFile = defaultSchema;
112 else
113 project.SchemaFile = parameters.ValidationSchema;
116 string projectFile = parameters.ProjectFile;
117 if (!File.Exists (projectFile)) {
118 ErrorUtilities.ReportError (0, String.Format ("Project file '{0}' not found.", projectFile));
119 return;
122 project.Load (projectFile);
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);
132 catch (InvalidProjectFileException ipfe) {
133 ErrorUtilities.ReportError (0, show_stacktrace ? ipfe.ToString () : ipfe.Message);
136 catch (InternalLoggerException ile) {
137 ErrorUtilities.ReportError (0, show_stacktrace ? ile.ToString () : ile.Message);
140 catch (Exception) {
141 throw;
144 finally {
145 if (engine != null)
146 engine.UnregisterAllLoggers ();
148 Environment.Exit (result ? 0 : 1);
155 // code from mcs/report.cs
156 class ConsoleReportPrinter
158 string prefix, postfix;
159 bool color_supported;
160 TextWriter writer;
161 string [] colorPrefixes;
163 public ConsoleReportPrinter ()
164 : this (Console.Out)
168 public ConsoleReportPrinter (TextWriter writer)
170 this.writer = writer;
172 string term = Environment.GetEnvironmentVariable ("TERM");
173 bool xterm_colors = false;
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;
183 break;
185 case "xterm-color":
186 xterm_colors = true;
187 break;
189 if (!xterm_colors)
190 return;
192 if (!(UnixUtils.isatty (1) && UnixUtils.isatty (2)))
193 return;
195 color_supported = true;
196 PopulateColorPrefixes ();
197 postfix = "\x001b[0m";
200 void PopulateColorPrefixes ()
202 colorPrefixes = new string [16];
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");
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");
221 colorPrefixes [(int)ConsoleColor.White] = GetForeground ("brightwhite");
224 public void SetForeground (ConsoleColor color)
226 if (color_supported)
227 prefix = colorPrefixes [(int)color];
230 public void ResetColor ()
232 prefix = "\x001b[0m";
235 static int NameToCode (string s)
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;
256 return 7;
260 // maps a color name to its xterm color code
262 static string GetForeground (string s)
264 string highcode;
266 if (s.StartsWith ("bright")) {
267 highcode = "1;";
268 s = s.Substring (6);
269 } else
270 highcode = "";
272 return "\x001b[" + highcode + (30 + NameToCode (s)).ToString () + "m";
275 static string GetBackground (string s)
277 return "\x001b[" + (40 + NameToCode (s)).ToString () + "m";
280 string FormatText (string txt)
282 if (prefix != null && color_supported)
283 return prefix + txt + postfix;
285 return txt;
288 public void Print (string message)
290 writer.WriteLine (FormatText (message));
295 class UnixUtils {
296 [System.Runtime.InteropServices.DllImport ("libc", EntryPoint="isatty")]
297 extern static int _isatty (int fd);
299 public static bool isatty (int fd)
301 try {
302 return _isatty (fd) == 1;
303 } catch {
304 return false;
311 #endif