2007-02-03 Marek Sieradzki <marek.sieradzki@gmail.com>
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / Engine.cs
index 3593134bd90235dc58998ccc0d2439386f7da13c..9f6befa5da82440cf5f0c08f740b53fe3a1ef62f 100644 (file)
 
 using System;
 using System.Collections;
+using System.Collections.Generic;
+using System.IO;
 using Microsoft.Build.Framework;
+using Mono.XBuild.Utilities;
 
 namespace Microsoft.Build.BuildEngine {
-       public class Engine : IEngine {
+       public class Engine {
                
                string                  binPath;
                bool                    buildEnabled;
-               const string            engineVersion = "0.1";
-               BuildPropertyGroup      environmentProperties;
+               TaskDatabase            defaultTasks;
+               bool                    defaultTasksRegistered;
+               const string            defaultTasksProjectName = "Microsoft.Common.tasks";
                EventSource             eventSource;
                bool                    buildStarted;
                BuildPropertyGroup      globalProperties;
-               IDictionary             importedProjects;
-               IList                   loggers;
-               bool                    onlyLogCriticalEvents;
-               IDictionary             projects;
-               BuildPropertyGroup      reservedProperties;
+               //IDictionary           importedProjects;
+               List <ILogger>          loggers;
+               //bool                  onlyLogCriticalEvents;
+               Dictionary <string, Project>    projects;
 
-               // FIXME: GlobalEngine static property uses this but what about GlobalEngineAccessor?
                static Engine           globalEngine;
+               static Version          version;
 
+               static Engine ()
+               {
+                       version = new Version ("0.1");
+               }
                
                public Engine ()
                        : this (null)
@@ -61,20 +68,51 @@ namespace Microsoft.Build.BuildEngine {
                public Engine (string binPath)
                {
                        this.binPath = binPath;
-                       this.projects = new Hashtable ();
+                       this.buildEnabled = true;
+                       this.projects = new Dictionary <string, Project> ();
                        this.eventSource = new EventSource ();
-                       this.loggers = new ArrayList ();
+                       this.loggers = new List <ILogger> ();
                        this.buildStarted = false;
-                       this.LoadEnvironmentProperties ();
-                       this.reservedProperties = new BuildPropertyGroup ();
-                       this.reservedProperties.AddNewProperty ("MSBuildBinPath", binPath, PropertyType.Reserved);
+                       this.globalProperties = new BuildPropertyGroup ();
+                       
+                       RegisterDefaultTasks ();
+               }
+               
+               [MonoTODO]
+               public bool BuildProject (Project project)
+               {
+                       return project.Build ();
+               }
+               
+               [MonoTODO]
+               public bool BuildProject (Project project, string targetName)
+               {
+                       return BuildProject (project, new string[] { targetName}, null, BuildSettings.None);
+               }
+               
+               [MonoTODO]
+               public bool BuildProject (Project project, string[] targetNames)
+               {
+                       return BuildProject (project, targetNames, null, BuildSettings.None);
                }
 
+               [MonoTODO]
                public bool BuildProject (Project project,
                                          string[] targetNames,
                                          IDictionary targetOutputs)
+               {
+                       return BuildProject (project, targetNames, targetOutputs, BuildSettings.None);
+               }
+               
+               [MonoTODO ("use buildFlags")]
+               public bool BuildProject (Project project,
+                                         string[] targetNames,
+                                         IDictionary targetOutputs,
+                                         BuildSettings buildFlags)
                {
                        bool result;
+
+                       StartBuild ();
                        
                        LogProjectStarted (project, targetNames);
                                
@@ -85,123 +123,213 @@ namespace Microsoft.Build.BuildEngine {
                        return result;
                }
 
-               public bool BuildProjectFile (string projectFileName,
-                                         string[] targetNames,
-                                         BuildPropertyGroup globalPropertiesToUse,
-                                         IDictionary targetOutputs)
+               [MonoTODO]
+               public bool BuildProjectFile (string projectFile)
+               {
+                       throw new NotImplementedException ();
+               }
+               
+               [MonoTODO]
+               public bool BuildProjectFile (string projectFile,
+                                             string targetName)
+               {
+                       throw new NotImplementedException ();
+               }
+               
+               [MonoTODO]
+               public bool BuildProjectFile (string projectFile,
+                                             string[] targetNames)
+               {
+                       throw new NotImplementedException ();
+               }
+               
+               [MonoTODO]
+               public bool BuildProjectFile (string projectFile,
+                                             string[] targetNames,
+                                             BuildPropertyGroup globalProperties)
+               {
+                       return BuildProjectFile (projectFile, targetNames, globalProperties, null, BuildSettings.None);
+               }
+               
+               [MonoTODO]
+               public bool BuildProjectFile (string projectFile,
+                                             string[] targetNames,
+                                             BuildPropertyGroup globalProperties,
+                                             IDictionary targetOutputs)
+               {
+                       return BuildProjectFile (projectFile, targetNames, globalProperties, targetOutputs, BuildSettings.None);
+               }
+               
+               [MonoTODO ("use buildFlags")]
+               public bool BuildProjectFile (string projectFile,
+                                             string[] targetNames,
+                                             BuildPropertyGroup globalProperties,
+                                             IDictionary targetOutputs,
+                                             BuildSettings buildFlags)
                {
                        bool result;
                        Project project;
+
+                       StartBuild ();
                        
-                       if (projects.Contains (projectFileName)) {
-                               project = (Project) projects [projectFileName];
+                       if (projects.ContainsKey (projectFile)) {
+                               project = (Project) projects [projectFile];
+                               LogProjectStarted (project, targetNames);
+                               result = project.Build (targetNames, targetOutputs);
+                       } else {
+                               project = CreateNewProject ();
+                               project.Load (projectFile);
                                LogProjectStarted (project, targetNames);
                                result = project.Build (targetNames, targetOutputs);
                        }
-                       else
-                               return false;
                        
                        LogProjectFinished (project, result);
                        
                        return result;
                }
 
-               public void ClearAllProjects ()
+               void CheckBinPath ()
                {
-                       projects.Clear ();
+                       if (BinPath == null) {
+                               throw new InvalidOperationException ("Before a project can be instantiated, " +
+                                       "Engine.BinPath must be set to the location on disk where MSBuild " + 
+                                       "is installed. This is used to evaluate $(MSBuildBinPath).");
+                       }
                }
 
                public Project CreateNewProject ()
                {
-                       if (buildStarted == false) {
-                               LogBuildStarted ();
-                               buildStarted = true;
-                       }
-                       Project p = new Project (this);
-                       p.EnvironmentProperties = this.environmentProperties;
-                       p.ReservedProperties = this.reservedProperties;
-                       if (globalProperties != null) {
-                               BuildPropertyGroup bpg = new BuildPropertyGroup ();
-                               foreach (BuildProperty bp in globalProperties)
-                                       bpg.AddNewProperty (bp.Name, bp.Value, PropertyType.CommandLine);
-                               p.GlobalProperties = bpg;
-                       }
-                       return p;
+                       if (defaultTasksRegistered)
+                               CheckBinPath ();
+                       return new Project (this);
+               }
+
+               public Project GetLoadedProject (string projectFullFileName)
+               {
+                       if (projectFullFileName == null)
+                               throw new ArgumentNullException ("projectFullFileName");
+                       
+                       // FIXME: test it
+                       return projects [projectFullFileName];
                }
 
-               public string Escape (string input)
+               internal void RemoveLoadedProject (Project p)
                {
-                       // FIXME: test it, probably returns XML escaped string
-                       return null;
+                       if (p.FullFileName != String.Empty)
+                               projects.Remove (p.FullFileName);
                }
 
-               public Project GetLoadedProject (string projectFullFileName)
+               internal void AddLoadedProject (Project p)
+               {
+                       if (p.FullFileName != String.Empty)
+                               projects.Add (p.FullFileName, p);
+               }
+       
+               public void UnloadProject (Project project)
+               {
+                       if (project == null)
+                               throw new ArgumentNullException ("project");
+
+                       if (project.ParentEngine != this)
+                               throw new InvalidOperationException ("The \"Project\" object specified does not belong to the correct \"Engine\" object.");
+                       
+                       project.CheckUnloaded ();
+                       
+                       if (project.FullFileName != String.Empty)
+                               projects.Remove (project.FullFileName);
+                       
+                       project.Unload ();
+               }
+
+               public void UnloadAllProjects ()
                {
-                       return (Project) projects [projectFullFileName];
+                       foreach (KeyValuePair <string, Project> e in projects)
+                               UnloadProject (e.Value);
                }
 
+               [MonoTODO]
                public void RegisterLogger (ILogger logger)
                {
                        if (logger == null)
                                throw new ArgumentNullException ("logger");
+                       
                        logger.Initialize (eventSource);
                        loggers.Add (logger);
                }
-
+               
+               [MonoTODO]
                public void UnregisterAllLoggers ()
                {
                        // FIXME: check if build succeeded
+                       // FIXME: it shouldn't be here
                        LogBuildFinished (true);
                        foreach (ILogger i in loggers) {
                                i.Shutdown ();
                        }
                        loggers.Clear ();
                }
-               
-               private void LoadEnvironmentProperties ()
+
+               internal void StartBuild ()
                {
-                       environmentProperties = new BuildPropertyGroup ();
-                       IDictionary environment = Environment.GetEnvironmentVariables ();
-                       foreach (DictionaryEntry de in environment) {
-                               environmentProperties.AddNewProperty ((string) de.Key, (string) de.Value, PropertyType.Environment);
+                       if (!buildStarted) {
+                               LogBuildStarted ();
+                               buildStarted = true;
                        }
                }
                
-               private void LogProjectStarted (Project project, string[] targetNames)
+               void LogProjectStarted (Project project, string [] targetNames)
                {
                        ProjectStartedEventArgs psea;
                        if (targetNames.Length == 0) {
                                if (project.DefaultTargets != String.Empty)
                                        psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName,
-                                               project.DefaultTargets);
+                                               project.DefaultTargets, null, null);
                                else
-                                       psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName, "default");
+                                       psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName, "default", null, null);
                        } else
                        psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName, String.Join (";",
-                               targetNames));
+                               targetNames), null, null);
                        eventSource.FireProjectStarted (this, psea);
                }
                
-               private void LogProjectFinished (Project project, bool succeeded)
+               void LogProjectFinished (Project project, bool succeeded)
                {
                        ProjectFinishedEventArgs pfea;
                        pfea = new ProjectFinishedEventArgs ("Project started.", null, project.FullFileName, succeeded);
                        eventSource.FireProjectFinished (this, pfea);
                }
                
-               private void LogBuildStarted ()
+               void LogBuildStarted ()
                {
                        BuildStartedEventArgs bsea;
                        bsea = new BuildStartedEventArgs ("Build started.", null);
                        eventSource.FireBuildStarted (this, bsea);
                }
                
-               private void LogBuildFinished (bool succeeded)
+               void LogBuildFinished (bool succeeded)
                {
                        BuildFinishedEventArgs bfea;
                        bfea = new BuildFinishedEventArgs ("Build finished.", null, succeeded);
                        eventSource.FireBuildFinished (this, bfea);
                }
+               
+               void RegisterDefaultTasks ()
+               {
+                       this.defaultTasksRegistered = false;
+                       
+                       Project defaultTasksProject = CreateNewProject ();
+                       
+                       if (binPath != null) {
+                               if (File.Exists (Path.Combine (binPath, defaultTasksProjectName))) {
+                                       defaultTasksProject.Load (Path.Combine (binPath, defaultTasksProjectName));
+                                       defaultTasks = defaultTasksProject.TaskDatabase;
+                               } else
+                                       defaultTasks = new TaskDatabase ();
+                       } else
+                               defaultTasks = new TaskDatabase ();
+                       
+                       this.defaultTasksRegistered = true;
+               }
 
                public string BinPath {
                        get { return binPath; }
@@ -213,12 +341,16 @@ namespace Microsoft.Build.BuildEngine {
                        set { buildEnabled = value; }
                }
 
-               public static string EngineVersion {
-                       get { return engineVersion; }
+               public static Version Version {
+                       get { return version; }
                }
 
                public static Engine GlobalEngine {
-                       get { return globalEngine; }
+                       get {
+                               if (globalEngine == null)
+                                       globalEngine = new Engine ();
+                               return globalEngine;
+                       }
                }
 
                public BuildPropertyGroup GlobalProperties {
@@ -234,7 +366,15 @@ namespace Microsoft.Build.BuildEngine {
                internal EventSource EventSource {
                        get { return eventSource; }
                }
+               
+               internal bool DefaultTasksRegistered {
+                       get { return defaultTasksRegistered; }
+               }
+               
+               internal TaskDatabase DefaultTasks {
+                       get { return defaultTasks; }
+               }
        }
 }
 
-#endif
\ No newline at end of file
+#endif