[xbuild] Override global properties before project Load.
authorAnkit Jain <radical@corewars.org>
Wed, 4 Aug 2010 11:08:56 +0000 (16:38 +0530)
committerAnkit Jain <radical@corewars.org>
Wed, 4 Aug 2010 11:08:56 +0000 (16:38 +0530)
MSBuild task can override properties for a project, and these
should be applied before the project file is loaded. This is to
allow the properties to be available for Imports. Eg.

 <Import Project="$(SolutionDir)\foo.targets"/>

$(SolutionDir) is generally set by the MSBuild task in a .sln.proj
file.
Bug reported by JB Evain.

    * Microsoft.Build.BuildEngine/Engine.cs:
    Apply global properties before the project load.

    * Test/*/EngineTest.cs (TestGlobalPropertiesImport*): New tests.

mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Engine.cs
mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/EngineTest.cs [changed mode: 0644->0755]

index 8c8a03b6145a44f84d71384b201094ca182bccaf..fd675a7d752d458c50f863623c82bd77ec00af54 100644 (file)
@@ -226,11 +226,10 @@ namespace Microsoft.Build.BuildEngine {
                {
                        Project project;
 
-                       if (projects.ContainsKey (projectFile)) {
-                               project = (Project) projects [projectFile];
-                       } else {
+                       bool newProject = false;
+                       if (!projects.TryGetValue (projectFile, out project)) {
                                project = CreateNewProject ();
-                               project.Load (projectFile);
+                               newProject = true;
                        }
 
                        BuildPropertyGroup engine_old_grp = null;
@@ -243,9 +242,14 @@ namespace Microsoft.Build.BuildEngine {
                                // ones explicitlcur_y specified here
                                foreach (BuildProperty bp in globalProperties)
                                        project.GlobalProperties.AddProperty (bp);
-                               project.NeedToReevaluate ();
+
+                               if (!newProject)
+                                       project.NeedToReevaluate ();
                        }
 
+                       if (newProject)
+                               project.Load (projectFile);
+
                        try {
                                string oldProjectToolsVersion = project.ToolsVersion;
                                if (String.IsNullOrEmpty (toolsVersion) && defaultToolsVersion != null)
old mode 100644 (file)
new mode 100755 (executable)
index 49f229e..acec0e9
@@ -720,7 +720,73 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                                        "(TargetB) foo: foofoo1 A:  External: ",
                                        "second"});
                }
+
+               // Check for global properties in case of Import
+
+               [Test]
+               public void TestGlobalPropertiesImport1 ()
+               {
+                       string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+                               <Target Name=""main"">
+                                       <MSBuild Projects=""first.proj"" Targets = ""1"" Properties='Prop=test'/>
+                               </Target>
+                       </Project>";
+
+                       string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+                               <Target Name = ""1"">
+                                       <Message Text='Prop: $(Prop)'/>
+                               </Target>
+                               <Import Project='$(Prop).proj'/>
+                       </Project>";
+
+                       CreateAndCheckGlobalPropertiesImportTest (mainProject, firstProject);
+               }
+
                [Test]
+               public void TestGlobalPropertiesImport2 ()
+               {
+                       string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+                               <Target Name=""main"">
+                                       <MSBuild Projects=""first.proj"" Targets = ""1"" Properties='Prop=test'/>
+                               </Target>
+                       </Project>";
+
+                       string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+                               <PropertyGroup>
+                                       <Prop>invalid</Prop>
+                               </PropertyGroup>
+                               <Target Name = ""1"">
+                                       <Message Text='Prop: $(Prop)'/>
+                               </Target>
+                               <Import Project='$(Prop).proj'/>
+                       </Project>";
+
+                       CreateAndCheckGlobalPropertiesImportTest (mainProject, firstProject);
+               }
+
+               [Test]
+               public void TestGlobalPropertiesImport3()
+               {
+                       string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+                               <Target Name=""main"">
+                                       <MSBuild Projects=""first.proj"" Targets = ""1""/>
+                               </Target>
+                       </Project>";
+
+                       string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+                               <PropertyGroup>
+                                       <Prop>test</Prop>
+                               </PropertyGroup>
+                               <Target Name = ""1"">
+                                       <Message Text='Prop: $(Prop)'/>
+                               </Target>
+                               <Import Project='$(Prop).proj'/>
+                       </Project>";
+
+                       CreateAndCheckGlobalPropertiesImportTest (mainProject, firstProject);
+               }
+
+               [Test]
                public void TestMSBuildOutputs ()
                {
                        string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
@@ -817,6 +883,41 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                        Assert.IsNull(project);
                }
 
+               void CreateAndCheckGlobalPropertiesImportTest (string main, string first)
+               {
+                       string basePath = Path.Combine ("Test", "resources");
+
+                       string testProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+</Project>";
+
+                       File.WriteAllText (Path.Combine (basePath, "main.proj"), main);
+                       File.WriteAllText (Path.Combine (basePath, "first.proj"), first);
+                       File.WriteAllText (Path.Combine (basePath, "test.proj"), testProject);
+
+                       try {
+                               Engine engine = new Engine ();
+                               MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+                                       new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+                               engine.RegisterLogger (logger);
+
+                               Project project = engine.CreateNewProject ();
+                               project.Load (Path.Combine (basePath, "main.proj"));
+
+                               bool result = project.Build ();
+                               if (!result) {
+                                       logger.DumpMessages ();
+                                       Assert.Fail ("Build failed");
+                               }
+
+                               logger.CheckAny ("Prop: test", MessageImportance.Normal);
+                               Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+                       } finally {
+                               File.Delete (Path.Combine (basePath, "main.proj"));
+                               File.Delete (Path.Combine (basePath, "first.proj"));
+                               File.Delete (Path.Combine (basePath, "test.proj"));
+                       }
+               }
+
                // Helper Methods for TestGlobalProperties*
 
                void CreateAndCheckGlobalPropertiesTest (string main, string first, string second,