New tests.
[mono.git] / mcs / class / Microsoft.Build.Tasks / Microsoft.Build.Tasks / MSBuild.cs
index af6817afb8a885a9df2625432443388a517969dd..90c54cd38c5cb987ae6302701db1ecee5835df44 100644 (file)
 
 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 ()
                {
@@ -49,85 +55,166 @@ namespace Microsoft.Build.Tasks {
 
                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