Implement more precise DefaultTargets handling.
authorAtsushi Eno <atsushieno@veritas-vos-liberabit.com>
Thu, 14 Nov 2013 19:46:55 +0000 (04:46 +0900)
committerAtsushi Eno <atsushieno@veritas-vos-liberabit.com>
Fri, 29 Nov 2013 09:21:57 +0000 (18:21 +0900)
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectInstance.cs
mcs/class/Microsoft.Build/Microsoft.Build_test.dll.sources
mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/ProjectTargetInstanceTest.cs

index cb9135263f8fbc45fccd839a5a770e4d59dd7716..0c54d3175c9019e3c62ab7f37e617cc350685c0b 100644 (file)
@@ -107,6 +107,14 @@ namespace Microsoft.Build.Execution
                List<ProjectPropertyInstance> properties;
                Dictionary<string, ProjectTargetInstance> targets;
                string tools_version;
+               
+               List<string> GetDefaultTargets (ProjectRootElement xml)
+               {
+                       var ret = xml.DefaultTargets.Split (item_target_sep, StringSplitOptions.RemoveEmptyEntries).Select (s => s.Trim ()).ToList ();
+                       if (ret.Count == 0 && xml.Targets.Any ())
+                               ret.Add (xml.Targets.First ().Name);
+                       return ret;
+               }
 
                void InitializeProperties (ProjectRootElement xml, ProjectInstance parent)
                {
@@ -115,8 +123,8 @@ namespace Microsoft.Build.Execution
                        #endif
                        full_path = xml.FullPath;
                        directory = string.IsNullOrWhiteSpace (xml.DirectoryPath) ? System.IO.Directory.GetCurrentDirectory () : xml.DirectoryPath;
-                       DefaultTargets = xml.DefaultTargets.Split (';').Select (s => s.Trim ()).ToList ();
-                       InitialTargets = xml.InitialTargets.Split (';').Select (s => s.Trim ()).ToList ();
+                       DefaultTargets = GetDefaultTargets (xml);
+                       InitialTargets = xml.InitialTargets.Split (item_target_sep, StringSplitOptions.RemoveEmptyEntries).Select (s => s.Trim ()).ToList ();
 
                        raw_imports = new List<ResolvedImport> ();
                        item_definitions = new Dictionary<string, ProjectItemDefinitionInstance> ();
@@ -143,7 +151,7 @@ namespace Microsoft.Build.Execution
                        ProcessXml (parent, xml);
                }
                
-               static readonly char [] item_sep = {';'};
+               static readonly char [] item_target_sep = {';'};
                
                void ProcessXml (ProjectInstance parent, ProjectRootElement xml)
                {
@@ -199,8 +207,8 @@ namespace Microsoft.Build.Execution
                                        foreach (var p in ige.Items) {
                                                if (!EvaluateCondition (ige.Condition) || !EvaluateCondition (p.Condition))
                                                        continue;
-                                               var includes = ExpandString (p.Include).Split (item_sep, StringSplitOptions.RemoveEmptyEntries);
-                                               var excludes = ExpandString (p.Exclude).Split (item_sep, StringSplitOptions.RemoveEmptyEntries);
+                                               var includes = ExpandString (p.Include).Split (item_target_sep, StringSplitOptions.RemoveEmptyEntries);
+                                               var excludes = ExpandString (p.Exclude).Split (item_target_sep, StringSplitOptions.RemoveEmptyEntries);
                                                
                                                if (includes.Length == 0)
                                                        continue;                                               
@@ -264,6 +272,8 @@ namespace Microsoft.Build.Execution
                        try {
                                using (var reader = XmlReader.Create (path)) {
                                        var root = ProjectRootElement.Create (reader, projects);
+                                       if (DefaultTargets.Count == 0)
+                                               DefaultTargets.AddRange (GetDefaultTargets (root));
                                        raw_imports.Add (new ResolvedImport (import, root, true));
                                        return this.EvaluatePropertiesAndImports (root.Children).ToArray ();
                                }
@@ -349,7 +359,7 @@ namespace Microsoft.Build.Execution
                
                public bool Build (IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers)
                {
-                       return Build ((string []) null, loggers, remoteLoggers);
+                       return Build (DefaultTargets.ToArray (), loggers, remoteLoggers);
                }
 
                public bool Build (string target, IEnumerable<ILogger> loggers)
index e0cda20608d008cfc01850c4933f354436592038..0fa6cc97f7efe84d7940e4da195d702ffe4fd13f 100644 (file)
@@ -12,6 +12,7 @@ Microsoft.Build.Execution/BuildParametersTest.cs
 Microsoft.Build.Execution/BuildManagerTest.cs
 Microsoft.Build.Execution/ProjectInstanceTest.cs
 Microsoft.Build.Execution/ProjectMetadataInstanceTest.cs
+Microsoft.Build.Execution/ProjectTargetInstanceTest.cs
 Microsoft.Build.Internal/CollectionFromEnumerableTest.cs
 Microsoft.Build.Internal/ExpressionParserTest.cs
 Microsoft.Build.Logging/ConsoleLoggerTest.cs
index 80a3fdd6762a46a86f009adef82e4fa094760843..c67604abee10d111a298ae5c9e3ef2ff6124b1d4 100644 (file)
@@ -12,8 +12,92 @@ namespace MonoTests.Microsoft.Build.Execution
        public class ProjectTargetInstanceTest
        {
                [Test]
-               public void SimpleCall ()
+               public void DefaultTargetsEmpty ()
                {
+            string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+</Project>";
+            var xml = XmlReader.Create (new StringReader (project_xml));
+            var root = ProjectRootElement.Create (xml);
+            var proj = new ProjectInstance (root);
+                       Assert.AreEqual (new string [0], proj.DefaultTargets, "#1");
+               }
+               
+               [Test]
+               public void DefaultTargetsFromAttribute ()
+               {
+            string project_xml = @"<Project DefaultTargets='Foo Bar Baz;Foo' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+</Project>";
+            var xml = XmlReader.Create (new StringReader (project_xml));
+            var root = ProjectRootElement.Create (xml);
+            var proj = new ProjectInstance (root);
+                       string [] expected = {"Foo Bar Baz", "Foo"};
+                       Assert.AreEqual (expected, proj.DefaultTargets, "#1");
+               }
+               
+               [Test]
+               public void DefaultTargetsFromElements ()
+               {
+                       string [] defaultTargetAtts = {string.Empty, "DefaultTargets=''"};
+                       
+                       for (int i = 0; i < defaultTargetAtts.Length; i++) {
+                               string project_xml = string.Format (@"<Project {0} xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+       <Target Name='Foo' />
+       <Target Name='Bar' />
+</Project>", defaultTargetAtts [i]);
+                   var xml = XmlReader.Create (new StringReader (project_xml));
+                   var root = ProjectRootElement.Create (xml);
+                   var proj = new ProjectInstance (root);
+                               string [] expected = {"Foo"}; // Bar is not included
+                               Assert.AreEqual (expected, proj.DefaultTargets, "#1-" + i);
+                       }
+               }
+               
+               [Test]
+               public void MicrosoftCommonTargets ()
+               {
+                       string [] defaultTargetAtts = { string.Empty, "DefaultTargets=''" };
+                       
+                       for (int i = 0; i < defaultTargetAtts.Length; i++) {
+                               string project_xml = string.Format (@"<Project {0} xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+       <Import Project='$(MSBuildToolsPath)\Microsoft.Common.targets' />
+</Project>", defaultTargetAtts [i]);
+                               var xml = XmlReader.Create (new StringReader (project_xml));
+                               var root = ProjectRootElement.Create (xml);
+                               var proj = new ProjectInstance (root);
+                               Assert.AreEqual ("Build", proj.DefaultTargets.FirstOrDefault (), "#1-" + i);
+                       }
+               }
+               
+               [Test]
+               public void DefaultTargetsOverride ()
+               {
+            string project_xml = @"<Project DefaultTargets='Foo' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+       <Import Project='$(MSBuildToolsPath)\Microsoft.Common.targets' />
+</Project>";
+            var xml = XmlReader.Create (new StringReader (project_xml));
+            var root = ProjectRootElement.Create (xml);
+            var proj = new ProjectInstance (root);
+                       Assert.AreEqual ("Foo", proj.DefaultTargets.FirstOrDefault (), "#1");
+               }
+               
+               [Test]
+               public void MultipleDefaultTargets ()
+               {
+                       bool[] expected = { true, false, true };
+                       string [] defaultTargets = {"Foo", "Foo;Bar", "Foo;Bar"};
+                               string [] targets = { string.Empty, string.Empty, "<Target Name='Bar' />" };
+                       for (int i = 0; i < expected.Length; i++) {
+                               string project_xml = string.Format (@"<Project DefaultTargets='{0}' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+       <Import Project='$(MSBuildToolsPath)\Microsoft.Common.targets' />
+       <Target Name='Foo' />
+       {1}
+</Project>", defaultTargets [i], targets [i]);
+                               var xml = XmlReader.Create (new StringReader (project_xml));
+                               var root = ProjectRootElement.Create (xml);
+                               var proj = new ProjectInstance (root);
+                               Assert.AreEqual ("Foo", proj.DefaultTargets.FirstOrDefault (), "#1-" + i);
+                               Assert.AreEqual (expected [i], proj.Build (), "#2-" + i);
+                       }
                }
        }
 }