From 5381981f0659b4df092b86e3102e5a248c89d5ad Mon Sep 17 00:00:00 2001 From: Surayya Huseyn Zada Date: Thu, 27 Mar 2025 13:40:51 +0100 Subject: [PATCH 1/3] fix path of created project for SdkResult --- .../Evaluation/SdkResultEvaluation_Tests.cs | 35 +++++++++++++++++++ src/Build/Evaluation/Evaluator.cs | 9 +++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/Build.UnitTests/Evaluation/SdkResultEvaluation_Tests.cs b/src/Build.UnitTests/Evaluation/SdkResultEvaluation_Tests.cs index a5041d55fd6..e596bc05e8a 100644 --- a/src/Build.UnitTests/Evaluation/SdkResultEvaluation_Tests.cs +++ b/src/Build.UnitTests/Evaluation/SdkResultEvaluation_Tests.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Xml; using Microsoft.Build.Construction; using Microsoft.Build.Definition; using Microsoft.Build.Evaluation; @@ -137,6 +138,40 @@ public void SdkResolverCanReturnNoPaths(bool includePropertiesAndItems) _logger.WarningCount.ShouldBe(0); } + [Fact] + public void SuccessfullyEvaluatesSdkResultWithPropertiesForNullProjectRootElement() + { + Dictionary propertiesToAdd = null; + Dictionary itemsToAdd = null; + + CreateMockSdkResultPropertiesAndItems(out propertiesToAdd, out itemsToAdd); + + var projectOptions = SdkUtilities.CreateProjectOptionsWithResolver(new SdkUtilities.ConfigurableMockSdkResolver( + new Build.BackEnd.SdkResolution.SdkResult( + new SdkReference("TestPropsAndItemsFromResolverSdk", null, null), + Enumerable.Empty(), + version: null, + propertiesToAdd, + itemsToAdd, + warnings: null))); + + string projectContent = @" + + + "; + + string projectPath = Path.Combine(_testFolder, "project.proj"); + File.WriteAllText(projectPath, projectContent); + + using XmlReader xmlReader = XmlReader.Create(projectPath); + + projectOptions.ProjectCollection = _projectCollection; + + // Creating project from XmlReader results in null ProjectRootElement on Evaluation phase. + // In that case project created for SdkResult properties and items is given a unique file name {Guid}.SdkResolver.{propertiesAndItemsHash}.proj in the current directory + Project.FromXmlReader(xmlReader, projectOptions); + } + [Theory] [InlineData(true, true)] [InlineData(true, false)] diff --git a/src/Build/Evaluation/Evaluator.cs b/src/Build/Evaluation/Evaluator.cs index cba4152a3fc..880944d58c8 100644 --- a/src/Build/Evaluation/Evaluator.cs +++ b/src/Build/Evaluation/Evaluator.cs @@ -1926,8 +1926,13 @@ private ProjectRootElement CreateProjectForSdkResult(SdkResult sdkResult) propertiesAndItemsHash = hash.ToHashCode(); #endif - // Generate a unique filename for the generated project for each unique set of properties and items. - string projectPath = _projectRootElement.FullPath + ".SdkResolver." + propertiesAndItemsHash + ".proj"; + // Generate a unique filename for the generated project for each unique set of properties and items that ends like ".SdkResolver.{propertiesAndItemsHash}.proj". + // _projectRootElement.FullPath can be null. This can be in the case when Project is created from XmlReader. For that case we generate filename like "{Guid}.SdkResolver.{propertiesAndItemsHash}.proj in the current directory. + // Oterwise the project is in the same directory as _projectRootElement and has a name of the saem project and ends like ".SdkResolver.{propertiesAndItemsHash}.proj". + string projectNameEnding = $".SdkResolver.{propertiesAndItemsHash}.proj"; + string projectPath = _projectRootElement.FullPath != null ? + _projectRootElement.FullPath + projectNameEnding : + FileUtilities.NormalizePath(Guid.NewGuid() + projectNameEnding); ProjectRootElement InnerCreate(string _, ProjectRootElementCacheBase __) { From 70dc73ad71d65b6e46de5c8cf6017ec624c48635 Mon Sep 17 00:00:00 2001 From: Surayya Huseyn Zada Date: Thu, 27 Mar 2025 13:49:45 +0100 Subject: [PATCH 2/3] fiz typo --- src/Build/Evaluation/Evaluator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Build/Evaluation/Evaluator.cs b/src/Build/Evaluation/Evaluator.cs index 880944d58c8..1e388e9b0dd 100644 --- a/src/Build/Evaluation/Evaluator.cs +++ b/src/Build/Evaluation/Evaluator.cs @@ -1928,7 +1928,7 @@ private ProjectRootElement CreateProjectForSdkResult(SdkResult sdkResult) // Generate a unique filename for the generated project for each unique set of properties and items that ends like ".SdkResolver.{propertiesAndItemsHash}.proj". // _projectRootElement.FullPath can be null. This can be in the case when Project is created from XmlReader. For that case we generate filename like "{Guid}.SdkResolver.{propertiesAndItemsHash}.proj in the current directory. - // Oterwise the project is in the same directory as _projectRootElement and has a name of the saem project and ends like ".SdkResolver.{propertiesAndItemsHash}.proj". + // Otherwise the project is in the same directory as _projectRootElement and has a name of the saem project and ends like ".SdkResolver.{propertiesAndItemsHash}.proj". string projectNameEnding = $".SdkResolver.{propertiesAndItemsHash}.proj"; string projectPath = _projectRootElement.FullPath != null ? _projectRootElement.FullPath + projectNameEnding : From 2961a8ae8309dd2c79f452a1f312445c50d3fc38 Mon Sep 17 00:00:00 2001 From: Surayya Huseyn Zada Date: Thu, 27 Mar 2025 13:50:56 +0100 Subject: [PATCH 3/3] fix typo --- src/Build/Evaluation/Evaluator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Build/Evaluation/Evaluator.cs b/src/Build/Evaluation/Evaluator.cs index 1e388e9b0dd..ebd4e1a7383 100644 --- a/src/Build/Evaluation/Evaluator.cs +++ b/src/Build/Evaluation/Evaluator.cs @@ -1928,7 +1928,7 @@ private ProjectRootElement CreateProjectForSdkResult(SdkResult sdkResult) // Generate a unique filename for the generated project for each unique set of properties and items that ends like ".SdkResolver.{propertiesAndItemsHash}.proj". // _projectRootElement.FullPath can be null. This can be in the case when Project is created from XmlReader. For that case we generate filename like "{Guid}.SdkResolver.{propertiesAndItemsHash}.proj in the current directory. - // Otherwise the project is in the same directory as _projectRootElement and has a name of the saem project and ends like ".SdkResolver.{propertiesAndItemsHash}.proj". + // Otherwise the project is in the same directory as _projectRootElement and has a name of the same project and ends like ".SdkResolver.{propertiesAndItemsHash}.proj". string projectNameEnding = $".SdkResolver.{propertiesAndItemsHash}.proj"; string projectPath = _projectRootElement.FullPath != null ? _projectRootElement.FullPath + projectNameEnding :