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 {
string binPath;
bool buildEnabled;
- 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");
+ version = new Version ("0.1");
}
public Engine ()
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.AddProperty (new BuildProperty ("MSBuildBinPath", binPath, PropertyType.Reserved));
+ this.globalProperties = new BuildPropertyGroup ();
+
+ RegisterDefaultTasks ();
}
[MonoTODO]
bool result;
Project project;
- if (projects.Contains (projectFile)) {
+ 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 Project CreateNewProject ()
+ private void CheckBinPath ()
{
- if (buildStarted == false) {
- LogBuildStarted ();
- buildStarted = true;
+ 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).");
}
- 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.AddProperty (bp.Clone (false));
- p.GlobalProperties = bpg;
- }
- return p;
+ }
+
+ public Project CreateNewProject ()
+ {
+ if (defaultTasksRegistered)
+ CheckBinPath ();
+ // FIXME: I don't really know if it should be here
+ LogBuildStarted ();
+ return new Project (this);
}
public Project GetLoadedProject (string projectFullFileName)
{
- return (Project) projects [projectFullFileName];
+ if (projectFullFileName == null)
+ throw new ArgumentNullException ("projectFullFileName");
+
+ return projects [projectFullFileName];
}
+ internal void RemoveLoadedProject (Project p)
+ {
+ if (p.FullFileName != String.Empty)
+ projects.Remove (p.FullFileName);
+ }
+
+ internal void AddLoadedProject (Project p)
+ {
+ if (p.FullFileName != String.Empty)
+ projects.Add (p.FullFileName, p);
+ }
+
+ public void UnloadProject (Project project)
+ {
+ if (project.ParentEngine != this)
+ throw new InvalidOperationException ("This project is not loaded in this engine");
+
+ project.CheckUnloaded ();
+
+ if (project.FullFileName != String.Empty)
+ projects.Remove (project.FullFileName);
+
+ project.Unload ();
+ }
+
+ public void UnloadAllProjects ()
+ {
+ 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 UnloadAllProjects ()
- {
- }
-
- [MonoTODO]
- public void UnloadProject (Project project)
- {
- }
-
public void UnregisterAllLoggers ()
{
// FIXME: check if build succeeded
loggers.Clear ();
}
- private void LoadEnvironmentProperties ()
- {
- environmentProperties = new BuildPropertyGroup ();
- IDictionary environment = Environment.GetEnvironmentVariables ();
- foreach (DictionaryEntry de in environment) {
- BuildProperty bp;
- bp = new BuildProperty ((string) de.Key, (string) de.Value, PropertyType.Environment);
- environmentProperties.AddProperty (bp);
- }
- }
-
private void LogProjectStarted (Project project, string[] targetNames)
{
ProjectStartedEventArgs psea;
bfea = new BuildFinishedEventArgs ("Build finished.", null, succeeded);
eventSource.FireBuildFinished (this, bfea);
}
+
+ private 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; }
}
public static Engine GlobalEngine {
- get { return globalEngine; }
+ get {
+ if (globalEngine == null)
+ globalEngine = new Engine ();
+ return globalEngine;
+ }
}
public BuildPropertyGroup GlobalProperties {
internal EventSource EventSource {
get { return eventSource; }
}
+
+ internal bool DefaultTasksRegistered {
+ get { return defaultTasksRegistered; }
+ }
+
+ internal TaskDatabase DefaultTasks {
+ get { return defaultTasks; }
+ }
}
}