2005-09-22 Chris Toshok <toshok@ximian.com>
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / Engine.cs
1 //
2 // Engine.cs: Main engine of XBuild.
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 // 
7 // (C) 2005 Marek Sieradzki
8 //
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:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
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.
27
28 #if NET_2_0
29
30 using System;
31 using System.Collections;
32 using Microsoft.Build.Framework;
33
34 namespace Microsoft.Build.BuildEngine {
35         public class Engine : IEngine {
36                 
37                 string                  binPath;
38                 bool                    buildEnabled;
39                 const string            engineVersion = "0.1";
40                 BuildPropertyGroup      environmentProperties;
41                 EventSource             eventSource;
42                 bool                    buildStarted;
43                 BuildPropertyGroup      globalProperties;
44                 IDictionary             importedProjects;
45                 IList                   loggers;
46                 bool                    onlyLogCriticalEvents;
47                 IDictionary             projects;
48                 BuildPropertyGroup      reservedProperties;
49
50                 // FIXME: GlobalEngine static property uses this but what about GlobalEngineAccessor?
51                 static Engine           globalEngine;
52
53                 
54                 public Engine ()
55                         : this (null)
56                 {
57                 }
58
59                 // engine should be invoked with path where binary files are
60                 // to find microsoft.build.tasks
61                 public Engine (string binPath)
62                 {
63                         this.binPath = binPath;
64                         this.projects = new Hashtable ();
65                         this.eventSource = new EventSource ();
66                         this.loggers = new ArrayList ();
67                         this.buildStarted = false;
68                         this.LoadEnvironmentProperties ();
69                         this.reservedProperties = new BuildPropertyGroup ();
70                         this.reservedProperties.AddNewProperty ("MSBuildBinPath", binPath, PropertyType.Reserved);
71                 }
72
73                 public bool BuildProject (Project project,
74                                           string[] targetNames,
75                                           IDictionary targetOutputs)
76                 {
77                         bool result;
78                         
79                         LogProjectStarted (project, targetNames);
80                                 
81                         result =  project.Build (targetNames, targetOutputs);
82                         
83                         LogProjectFinished (project, result);
84                         
85                         return result;
86                 }
87
88                 public bool BuildProjectFile (string projectFileName,
89                                           string[] targetNames,
90                                           BuildPropertyGroup globalPropertiesToUse,
91                                           IDictionary targetOutputs)
92                 {
93                         bool result;
94                         Project project;
95                         
96                         if (projects.Contains (projectFileName)) {
97                                 project = (Project) projects [projectFileName];
98                                 LogProjectStarted (project, targetNames);
99                                 result = project.Build (targetNames, targetOutputs);
100                         }
101                         else
102                                 return false;
103                         
104                         LogProjectFinished (project, result);
105                         
106                         return result;
107                 }
108
109                 public void ClearAllProjects ()
110                 {
111                         projects.Clear ();
112                 }
113
114                 public Project CreateNewProject ()
115                 {
116                         if (buildStarted == false) {
117                                 LogBuildStarted ();
118                                 buildStarted = true;
119                         }
120                         Project p = new Project (this);
121                         p.EnvironmentProperties = this.environmentProperties;
122                         p.ReservedProperties = this.reservedProperties;
123                         if (globalProperties != null) {
124                                 BuildPropertyGroup bpg = new BuildPropertyGroup ();
125                                 foreach (BuildProperty bp in globalProperties)
126                                         bpg.AddNewProperty (bp.Name, bp.Value, PropertyType.CommandLine);
127                                 p.GlobalProperties = bpg;
128                         }
129                         return p;
130                 }
131
132                 public string Escape (string input)
133                 {
134                         // FIXME: test it, probably returns XML escaped string
135                         return null;
136                 }
137
138                 public Project GetLoadedProject (string projectFullFileName)
139                 {
140                         return (Project) projects [projectFullFileName];
141                 }
142
143                 public void RegisterLogger (ILogger logger)
144                 {
145                         if (logger == null)
146                                 throw new ArgumentNullException ("logger");
147                         logger.Initialize (eventSource);
148                         loggers.Add (logger);
149                 }
150
151                 public void UnregisterAllLoggers ()
152                 {
153                         // FIXME: check if build succeeded
154                         LogBuildFinished (true);
155                         foreach (ILogger i in loggers) {
156                                 i.Shutdown ();
157                         }
158                         loggers.Clear ();
159                 }
160                 
161                 private void LoadEnvironmentProperties ()
162                 {
163                         environmentProperties = new BuildPropertyGroup ();
164                         IDictionary environment = Environment.GetEnvironmentVariables ();
165                         foreach (DictionaryEntry de in environment) {
166                                 environmentProperties.AddNewProperty ((string) de.Key, (string) de.Value, PropertyType.Environment);
167                         }
168                 }
169                 
170                 private void LogProjectStarted (Project project, string[] targetNames)
171                 {
172                         ProjectStartedEventArgs psea;
173                         if (targetNames.Length == 0) {
174                                 if (project.DefaultTargets != String.Empty)
175                                         psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName,
176                                                 project.DefaultTargets);
177                                 else
178                                         psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName, "default");
179                         } else
180                         psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName, String.Join (";",
181                                 targetNames));
182                         eventSource.FireProjectStarted (this, psea);
183                 }
184                 
185                 private void LogProjectFinished (Project project, bool succeeded)
186                 {
187                         ProjectFinishedEventArgs pfea;
188                         pfea = new ProjectFinishedEventArgs ("Project started.", null, project.FullFileName, succeeded);
189                         eventSource.FireProjectFinished (this, pfea);
190                 }
191                 
192                 private void LogBuildStarted ()
193                 {
194                         BuildStartedEventArgs bsea;
195                         bsea = new BuildStartedEventArgs ("Build started.", null);
196                         eventSource.FireBuildStarted (this, bsea);
197                 }
198                 
199                 private void LogBuildFinished (bool succeeded)
200                 {
201                         BuildFinishedEventArgs bfea;
202                         bfea = new BuildFinishedEventArgs ("Build finished.", null, succeeded);
203                         eventSource.FireBuildFinished (this, bfea);
204                 }
205
206                 public string BinPath {
207                         get { return binPath; }
208                         set { binPath = value; }
209                 }
210
211                 public bool BuildEnabled {
212                         get { return buildEnabled; }
213                         set { buildEnabled = value; }
214                 }
215
216                 public static string EngineVersion {
217                         get { return engineVersion; }
218                 }
219
220                 public static Engine GlobalEngine {
221                         get { return globalEngine; }
222                 }
223
224                 public BuildPropertyGroup GlobalProperties {
225                         get { return globalProperties; }
226                         set { globalProperties = value; }
227                 }
228
229                 public bool OnlyLogCriticalEvents {
230                         get { return eventSource.OnlyLogCriticalEvents; }
231                         set { eventSource.OnlyLogCriticalEvents = value; }
232                 }
233                 
234                 internal EventSource EventSource {
235                         get { return eventSource; }
236                 }
237         }
238 }
239
240 #endif