Skip to content

Commit

Permalink
Merge pull request #8872 from dfederm/graph-sln-props
Browse files Browse the repository at this point in the history
Add solution global properties for solution-based graphs
  • Loading branch information
JanKrivanek authored Jun 15, 2023
2 parents ccb9421 + 97bbae3 commit 605dde6
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 8 deletions.
35 changes: 27 additions & 8 deletions src/Build.UnitTests/Graph/GraphLoadedFromSolution_tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -524,18 +524,37 @@ public void SolutionsCanInjectEdgesIntoTheProjectGraph(Dictionary<int, int[]> ed

var graphFromSolutionEdges = graphFromSolution.TestOnly_Edges.TestOnly_AsConfigurationMetadata();

// Solutions add the CurrentSolutionConfigurationContents global property for platform resolution
foreach ((ConfigurationMetadata, ConfigurationMetadata) graphFromSolutionEdge in graphFromSolutionEdges.Keys)
// These are global properties added by GraphBuilder when building a solution
HashSet<string> propertiesToIgnore = new(StringComparer.OrdinalIgnoreCase)
{
graphFromSolutionEdge.Item1.GlobalProperties.ShouldContainKey("CurrentSolutionConfigurationContents");
graphFromSolutionEdge.Item2.GlobalProperties.ShouldContainKey("CurrentSolutionConfigurationContents");
"CurrentSolutionConfigurationContents",
"BuildingSolutionFile",
"SolutionDir",
"SolutionExt",
"SolutionFileName",
"SolutionName",
SolutionProjectGenerator.SolutionPathPropertyName
};

// Solutions add these global properties
foreach (string propertyToIgnore in propertiesToIgnore)
{
foreach ((ConfigurationMetadata, ConfigurationMetadata) graphFromSolutionEdge in graphFromSolutionEdges.Keys)
{
graphFromSolutionEdge.Item1.GlobalProperties.ShouldContainKey(propertyToIgnore);
graphFromSolutionEdge.Item2.GlobalProperties.ShouldContainKey(propertyToIgnore);
}
}

// Remove CurrentSolutionConfigurationContents for comparison purposes. This is done as a separate pass since some edges may be sharing an instance.
foreach ((ConfigurationMetadata, ConfigurationMetadata) graphFromSolutionEdge in graphFromSolutionEdges.Keys)
// Remove some properties for comparison purposes as we are comparing a graph created from a solution against the graph (without solution properties) used to make the solution.
// This is done as a separate pass since some edges may be sharing an instance.
foreach (string propertyToIgnore in propertiesToIgnore)
{
graphFromSolutionEdge.Item1.GlobalProperties.Remove("CurrentSolutionConfigurationContents");
graphFromSolutionEdge.Item2.GlobalProperties.Remove("CurrentSolutionConfigurationContents");
foreach ((ConfigurationMetadata, ConfigurationMetadata) graphFromSolutionEdge in graphFromSolutionEdges.Keys)
{
graphFromSolutionEdge.Item1.GlobalProperties.Remove(propertyToIgnore);
graphFromSolutionEdge.Item2.GlobalProperties.Remove(propertyToIgnore);
}
}

// Original edges get preserved.
Expand Down
15 changes: 15 additions & 0 deletions src/Build/Graph/GraphBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
Expand Down Expand Up @@ -280,8 +281,22 @@ private static void AddEdgesFromSolution(IReadOnlyDictionary<ConfigurationMetada

SolutionConfigurationInSolution currentSolutionConfiguration = SelectSolutionConfiguration(solution, solutionEntryPoint.GlobalProperties);

// Mimic behavior of SolutionProjectGenerator
string solutionConfigurationXml = SolutionProjectGenerator.GetSolutionConfiguration(solution, currentSolutionConfiguration);
solutionGlobalPropertiesBuilder["CurrentSolutionConfigurationContents"] = solutionConfigurationXml;
solutionGlobalPropertiesBuilder["BuildingSolutionFile"] = "true";

string solutionDirectoryName = solution.SolutionFileDirectory;
if (!solutionDirectoryName.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
{
solutionDirectoryName += Path.DirectorySeparatorChar;
}

solutionGlobalPropertiesBuilder["SolutionDir"] = EscapingUtilities.Escape(solutionDirectoryName);
solutionGlobalPropertiesBuilder["SolutionExt"] = EscapingUtilities.Escape(Path.GetExtension(solution.FullPath));
solutionGlobalPropertiesBuilder["SolutionFileName"] = EscapingUtilities.Escape(Path.GetFileName(solution.FullPath));
solutionGlobalPropertiesBuilder["SolutionName"] = EscapingUtilities.Escape(Path.GetFileNameWithoutExtension(solution.FullPath));
solutionGlobalPropertiesBuilder[SolutionProjectGenerator.SolutionPathPropertyName] = EscapingUtilities.Escape(Path.Combine(solution.SolutionFileDirectory, Path.GetFileName(solution.FullPath)));

// Project configurations are reused heavily, so cache the global properties for each
Dictionary<string, ImmutableDictionary<string, string>> globalPropertiesForProjectConfiguration = new(StringComparer.OrdinalIgnoreCase);
Expand Down

0 comments on commit 605dde6

Please sign in to comment.