using System;
using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using Microsoft.Build.BuildEngine;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace Microsoft.Build.Tasks {
+
+ [MonoTODO]
public class MSBuild : TaskExtension {
- ITaskItem[] projects;
- string[] properties;
+ ITaskItem [] projects;
+ string [] properties;
bool rebaseOutputs;
bool runEachTargetSeparately;
bool stopOnFirstFailure;
- ITaskItem[] targetOutputs;
- string[] targets;
+ bool buildInParallel;
+ ITaskItem [] targetOutputs;
+ string [] targets;
public MSBuild ()
{
public override bool Execute ()
{
+ if (projects.Length == 0)
+ return true;
+
string filename;
bool result = true;
stopOnFirstFailure = false;
+ List <ITaskItem > outputItems = new List <ITaskItem> ();
+ string currentDirectory = Environment.CurrentDirectory;
+ Hashtable outputs;
+ var global_properties = SplitPropertiesToDictionary ();
+ Dictionary<string, ITaskItem> projectsByFileName = new Dictionary<string, ITaskItem> ();
+
+ Log.LogMessage (MessageImportance.Low, "Global Properties:");
+ if (global_properties != null)
+ foreach (KeyValuePair<string, string> pair in global_properties)
+ Log.LogMessage (MessageImportance.Low, "\t{0} = {1}", pair.Key, pair.Value);
+
foreach (ITaskItem project in projects) {
filename = project.GetMetadata ("FullPath");
-
- result = BuildEngine.BuildProjectFile (filename, targets, new Hashtable (), new Hashtable ());
- if (result == false) {
- Log.LogError ("Error while building {0}", filename);
+ if (!File.Exists (filename)) {
+ Log.LogError ("Could not find the project file '{0}'", filename);
+ if (stopOnFirstFailure)
+ break;
+
+ continue;
+ }
+
+ Directory.SetCurrentDirectory (Path.GetDirectoryName (filename));
+ outputs = new Hashtable ();
+
+ try {
+ // Order of precedence:
+ // %(Project.ToolsVersion) , ToolsVersion property
+ string tv = project.GetMetadata ("ToolsVersion");
+ if (String.IsNullOrEmpty (tv))
+ tv = ToolsVersion;
+ ThrowIfNotValidToolsVersion (tv);
+
+ result = BuildEngine2.BuildProjectFile (filename, targets, global_properties, outputs, tv);
+ } catch (InvalidProjectFileException e) {
+ Log.LogError ("Error building project {0}: {1}", filename, e.Message);
+ result = false;
+ }
+
+ if (result) {
+ // Metadata from the first item for the project file is copied
+ ITaskItem first_item;
+ if (!projectsByFileName.TryGetValue (filename, out first_item))
+ projectsByFileName [filename] = first_item = project;
+
+ foreach (DictionaryEntry de in outputs) {
+ ITaskItem [] array = (ITaskItem []) de.Value;
+ foreach (ITaskItem item in array) {
+ // DONT share items!
+ ITaskItem new_item = new TaskItem (item);
+
+ // copy the metadata from original @project to here
+ // CopyMetadataTo does _not_ overwrite
+ first_item.CopyMetadataTo (new_item);
+
+ outputItems.Add (new_item);
+
+ //FIXME: Correctly rebase output paths to be relative to the
+ // calling project
+ //if (rebaseOutputs)
+ // File.Copy (item.ItemSpec, Path.Combine (currentDirectory, item.ItemSpec), true);
+ }
+ }
+ } else {
if (stopOnFirstFailure)
break;
}
+
+ Directory.SetCurrentDirectory (currentDirectory);
}
+
+ if (result)
+ targetOutputs = outputItems.ToArray ();
+
+ Directory.SetCurrentDirectory (currentDirectory);
return result;
}
+ void ThrowIfNotValidToolsVersion (string toolsVersion)
+ {
+ if (!String.IsNullOrEmpty (toolsVersion) && Engine.GlobalEngine.Toolsets [toolsVersion] == null)
+ throw new Exception (String.Format ("Unknown ToolsVersion : {0}", toolsVersion));
+ }
+
[Required]
- public ITaskItem[] Projects {
- get {
- return projects;
- }
- set {
- projects = value;
- }
+ public ITaskItem [] Projects {
+ get { return projects; }
+ set { projects = value; }
}
- public string[] Properties {
- get {
- return properties;
- }
- set {
- properties = value;
- }
+ [MonoTODO]
+ public string [] Properties {
+ get { return properties; }
+ set { properties = value; }
}
public bool RebaseOutputs {
- get {
- return rebaseOutputs;
- }
- set {
- rebaseOutputs = value;
- }
+ get { return rebaseOutputs; }
+ set { rebaseOutputs = value; }
}
+ [MonoTODO]
public bool RunEachTargetSeparately {
- get {
- return runEachTargetSeparately;
- }
- set {
- runEachTargetSeparately = value;
- }
+ get { return runEachTargetSeparately; }
+ set { runEachTargetSeparately = value; }
}
public bool StopOnFirstFailure {
- get {
- return stopOnFirstFailure;
- }
- set {
- stopOnFirstFailure = value;
- }
+ get { return stopOnFirstFailure; }
+ set { stopOnFirstFailure = value; }
}
[Output]
- public ITaskItem[] TargetOutputs {
- get {
- return targetOutputs;
- }
+ public ITaskItem [] TargetOutputs {
+ get { return targetOutputs; }
}
- public string[] Targets {
- get {
- return targets;
- }
- set {
- targets = value;
+ public string [] Targets {
+ get { return targets; }
+ set { targets = value; }
+ }
+
+ public bool BuildInParallel {
+ get { return buildInParallel; }
+ set { buildInParallel = value; }
+ }
+
+ public string ToolsVersion {
+ get; set;
+ }
+
+ SortedDictionary<string, string> SplitPropertiesToDictionary ()
+ {
+ if (properties == null)
+ return null;
+
+ var global_properties = new SortedDictionary<string, string> ();
+ foreach (string kvpair in properties) {
+ if (String.IsNullOrEmpty (kvpair))
+ continue;
+
+ string [] parts = kvpair.Trim ().Split (new char [] {'='}, 2);
+ if (parts.Length != 2) {
+ Log.LogWarning ("Invalid key/value pairs ({0}) in Properties, ignoring.", kvpair);
+ continue;
+ }
+
+ global_properties.Add (parts [0], parts [1]);
}
+
+ return global_properties;
}
+
}
}
-#endif
\ No newline at end of file
+#endif