msbuild: test fixes. Implemented GlobalEngine and project unloading
[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 {
36                 
37                 string                  binPath;
38                 bool                    buildEnabled;
39                 EventSource             eventSource;
40                 bool                    buildStarted;
41                 BuildPropertyGroup      globalProperties;
42                 IDictionary             importedProjects;
43                 IList                   loggers;
44                 bool                    onlyLogCriticalEvents;
45                 IDictionary             projects;
46
47                 static Engine           globalEngine;
48                 static Version          version;
49
50                 static Engine ()
51                 {
52                         version = new Version ("0.1");
53                 }
54                 
55                 public Engine ()
56                         : this (null)
57                 {
58                 }
59
60                 // engine should be invoked with path where binary files are
61                 // to find microsoft.build.tasks
62                 public Engine (string binPath)
63                 {
64                         this.binPath = binPath;
65                         this.projects = new Hashtable ();
66                         this.eventSource = new EventSource ();
67                         this.loggers = new ArrayList ();
68                         this.buildStarted = false;
69                         this.globalProperties = new BuildPropertyGroup ();
70                 }
71                 
72                 [MonoTODO]
73                 public bool BuildProject (Project project)
74                 {
75                         return project.Build ();
76                 }
77                 
78                 [MonoTODO]
79                 public bool BuildProject (Project project, string targetName)
80                 {
81                         return BuildProject (project, new string[] { targetName}, new Hashtable (), BuildSettings.None);
82                 }
83                 
84                 [MonoTODO]
85                 public bool BuildProject (Project project, string[] targetNames)
86                 {
87                         return BuildProject (project, targetNames, new Hashtable (), BuildSettings.None);
88                 }
89
90                 [MonoTODO]
91                 public bool BuildProject (Project project,
92                                           string[] targetNames,
93                                           IDictionary targetOutputs)
94                 {
95                         return BuildProject (project, targetNames, targetOutputs, BuildSettings.None);
96                 }
97                 
98                 [MonoTODO ("use buildFlags")]
99                 public bool BuildProject (Project project,
100                                           string[] targetNames,
101                                           IDictionary targetOutputs,
102                                           BuildSettings buildFlags)
103                 {
104                         bool result;
105                         
106                         LogProjectStarted (project, targetNames);
107                                 
108                         result =  project.Build (targetNames, targetOutputs);
109                         
110                         LogProjectFinished (project, result);
111                         
112                         return result;
113                 }
114
115                 [MonoTODO]
116                 public bool BuildProjectFile (string projectFile)
117                 {
118                         throw new NotImplementedException ();
119                 }
120                 
121                 [MonoTODO]
122                 public bool BuildProjectFile (string projectFile,
123                                               string targetName)
124                 {
125                         throw new NotImplementedException ();
126                 }
127                 
128                 [MonoTODO]
129                 public bool BuildProjectFile (string projectFile,
130                                               string[] targetNames)
131                 {
132                         throw new NotImplementedException ();
133                 }
134                 
135                 [MonoTODO]
136                 public bool BuildProjectFile (string projectFile,
137                                               string[] targetNames,
138                                               BuildPropertyGroup globalProperties)
139                 {
140                         return BuildProjectFile (projectFile, targetNames, globalProperties, new Hashtable (), BuildSettings.None);
141                 }
142                 
143                 [MonoTODO]
144                 public bool BuildProjectFile (string projectFile,
145                                               string[] targetNames,
146                                               BuildPropertyGroup globalProperties,
147                                               IDictionary targetOutputs)
148                 {
149                         return BuildProjectFile (projectFile, targetNames, globalProperties, targetOutputs, BuildSettings.None);
150                 }
151                 
152                 [MonoTODO ("use buildFlags")]
153                 public bool BuildProjectFile (string projectFile,
154                                               string[] targetNames,
155                                               BuildPropertyGroup globalProperties,
156                                               IDictionary targetOutputs,
157                                               BuildSettings buildFlags)
158                 {
159                         bool result;
160                         Project project;
161                         
162                         if (projects.Contains (projectFile)) {
163                                 project = (Project) projects [projectFile];
164                                 LogProjectStarted (project, targetNames);
165                                 result = project.Build (targetNames, targetOutputs);
166                         }
167                         else
168                                 return false;
169                         
170                         LogProjectFinished (project, result);
171                         
172                         return result;
173                 }
174
175                 internal void CheckBinPath ()
176                 {
177                         if (BinPath == null) {
178                                 throw new InvalidOperationException("Before a project can be instantiated, " +
179                                         "Engine.BinPath must be set to the location on disk where MSBuild " + 
180                                         "is installed. This is used to evaluate $(MSBuildBinPath).");
181                         }
182                 }
183
184                 public Project CreateNewProject ()
185                 {
186                         CheckBinPath ();
187                         return new Project (this);
188                 }
189
190                 public Project GetLoadedProject (string projectFullFileName)
191                 {
192                         if (projectFullFileName == null) {
193                                 throw new ArgumentNullException ("projectFullFileName");
194                         }
195                         return (Project) projects [projectFullFileName];
196                 }
197
198                 internal void RemoveLoadedProject (Project p)
199                 {
200                         if (p.FullFileName != "") {
201                                 projects.Remove (p.FullFileName);
202                         }
203                 }
204
205                 internal void AddLoadedProject (Project p)
206                 {
207                         if (p.FullFileName != "") {
208                                 projects.Add (p.FullFileName, p);
209                         }
210                 }
211         
212                 public void UnloadProject (Project project)
213                 {
214                         if (project.ParentEngine != this) {
215                                 throw new InvalidOperationException("This project is not loaded in this engine");
216                         }
217                         project.CheckUnloaded ();
218                         if (project.FullFileName != "") {
219                                 projects.Remove (project.FullFileName);
220                         }
221                         project.Unload ();
222                 }
223
224                 public void UnloadAllProjects ()
225                 {
226                         foreach (DictionaryEntry e in projects) {
227                                 UnloadProject ((Project) e.Value);
228                         }
229                 }
230
231                 public void RegisterLogger (ILogger logger)
232                 {
233                         if (logger == null)
234                                 throw new ArgumentNullException ("logger");
235                         logger.Initialize (eventSource);
236                         loggers.Add (logger);
237                 }
238                 
239                 public void UnregisterAllLoggers ()
240                 {
241                         // FIXME: check if build succeeded
242                         LogBuildFinished (true);
243                         foreach (ILogger i in loggers) {
244                                 i.Shutdown ();
245                         }
246                         loggers.Clear ();
247                 }
248                 
249                 private void LogProjectStarted (Project project, string[] targetNames)
250                 {
251                         ProjectStartedEventArgs psea;
252                         if (targetNames.Length == 0) {
253                                 if (project.DefaultTargets != String.Empty)
254                                         psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName,
255                                                 project.DefaultTargets, null, null);
256                                 else
257                                         psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName, "default", null, null);
258                         } else
259                         psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName, String.Join (";",
260                                 targetNames), null, null);
261                         eventSource.FireProjectStarted (this, psea);
262                 }
263                 
264                 private void LogProjectFinished (Project project, bool succeeded)
265                 {
266                         ProjectFinishedEventArgs pfea;
267                         pfea = new ProjectFinishedEventArgs ("Project started.", null, project.FullFileName, succeeded);
268                         eventSource.FireProjectFinished (this, pfea);
269                 }
270                 
271                 private void LogBuildStarted ()
272                 {
273                         BuildStartedEventArgs bsea;
274                         bsea = new BuildStartedEventArgs ("Build started.", null);
275                         eventSource.FireBuildStarted (this, bsea);
276                 }
277                 
278                 private void LogBuildFinished (bool succeeded)
279                 {
280                         BuildFinishedEventArgs bfea;
281                         bfea = new BuildFinishedEventArgs ("Build finished.", null, succeeded);
282                         eventSource.FireBuildFinished (this, bfea);
283                 }
284
285                 public string BinPath {
286                         get { return binPath; }
287                         set { binPath = value; }
288                 }
289
290                 public bool BuildEnabled {
291                         get { return buildEnabled; }
292                         set { buildEnabled = value; }
293                 }
294
295                 public static Version Version {
296                         get { return version; }
297                 }
298
299                 public static Engine GlobalEngine {
300                         get {
301                                 if (globalEngine == null) {
302                                         globalEngine = new Engine ();
303                                 }
304                                 return globalEngine;
305                         }
306                 }
307
308                 public BuildPropertyGroup GlobalProperties {
309                         get { return globalProperties; }
310                         set { globalProperties = value; }
311                 }
312
313                 public bool OnlyLogCriticalEvents {
314                         get { return eventSource.OnlyLogCriticalEvents; }
315                         set { eventSource.OnlyLogCriticalEvents = value; }
316                 }
317                 
318                 internal EventSource EventSource {
319                         get { return eventSource; }
320                 }
321         }
322 }
323
324 #endif