diff --git a/eng/BootStrapMsBuild.targets b/eng/BootStrapMsBuild.targets
index dcff8617638..d4330ba658d 100644
--- a/eng/BootStrapMsBuild.targets
+++ b/eng/BootStrapMsBuild.targets
@@ -35,7 +35,8 @@
<_NuGetRuntimeDependencies Include="%(RuntimeCopyLocalItems.Identity)" Condition="'@(RuntimeCopyLocalItems->Contains('Newtonsoft.Json'))' == 'true'" />
<_NuGetRuntimeDependencies Include="%(RuntimeCopyLocalItems.Identity)" Condition="'@(RuntimeCopyLocalItems->Contains('NuGetSdkResolver'))' == 'true'" />
<_NuGetRuntimeDependencies Include="%(RuntimeCopyLocalItems.Identity)" Condition="'@(RuntimeCopyLocalItems->Contains('Microsoft.Extensions.'))' == 'true'" />
-
+ <_NuGetRuntimeDependencies Include="%(RuntimeCopyLocalItems.Identity)" Condition="'@(RuntimeCopyLocalItems->Contains('Microsoft.VisualStudio.SolutionPersistence'))' == 'true'" />
+
<_NuGetRuntimeDependencies Include="%(RuntimeTargetsCopyLocalItems.Identity)" Condition="'@(RuntimeTargetsCopyLocalItems->Contains('NuGet.'))' == 'true'" />
@@ -48,7 +49,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- @(BravoProjectOutputs)
- @(CharlieProjectOutputs)
- @(DeltaProjectOutputs)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Count())' != '3' ` Text='Overall sln outputs must include outputs of each referenced project (there should be 3).' />
- AnyHaveMetadataValue('Identity', '$(StringifiedBravoProjectOutputs)'))' != 'true'` Text='Overall sln outputs must include outputs of normal project build of project B.' />
- AnyHaveMetadataValue('Identity', '$(StringifiedCharlieProjectOutputs)'))' != 'true' ` Text='Overall sln outputs must include outputs of normal project build of project C.' />
- AnyHaveMetadataValue('Identity', '$(StringifiedDeltaProjectOutputs)'))' != 'true' ` Text='Overall sln outputs must include outputs of normal project build of project D.' />
-
-";
+ """;
+ const string automaticProjectFileContents =
+ """
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ @(BravoProjectOutputs)
+ @(CharlieProjectOutputs)
+ @(DeltaProjectOutputs)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Count())' != '3' ` Text='Overall sln outputs must include outputs of each referenced project (there should be 3).' />
+ AnyHaveMetadataValue('Identity', '$(StringifiedBravoProjectOutputs)'))' != 'true'` Text='Overall sln outputs must include outputs of normal project build of project B.' />
+ AnyHaveMetadataValue('Identity', '$(StringifiedCharlieProjectOutputs)'))' != 'true' ` Text='Overall sln outputs must include outputs of normal project build of project C.' />
+ AnyHaveMetadataValue('Identity', '$(StringifiedDeltaProjectOutputs)'))' != 'true' ` Text='Overall sln outputs must include outputs of normal project build of project D.' />
+
+
+ """;
#endregion
var logger = new MockLogger(output);
@@ -1039,11 +1080,13 @@ public void SolutionConfigurationWithDependenciesRelaysItsOutputs()
///
/// Test the SolutionProjectGenerator.AddPropertyGroupForSolutionConfiguration method
///
- [Fact]
- public void TestAddPropertyGroupForSolutionConfiguration()
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void TestAddPropertyGroupForSolutionConfiguration(bool useNewParser)
{
string solutionFileContents =
- @"
+ """
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project('{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}') = 'ClassLibrary1', 'ClassLibrary1\ClassLibrary1.csproj', '{6185CC21-BE89-448A-B3C0-D1C27112E595}'
@@ -1063,9 +1106,9 @@ public void TestAddPropertyGroupForSolutionConfiguration()
{A6F99D27-47B9-4EA4-BFC9-25157CBDC281}.Debug|Mixed Platforms.Build.0 = VCConfig1|Win32
EndGlobalSection
EndGlobal
- ";
+ """;
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser);
ProjectRootElement projectXml = ProjectRootElement.Create();
@@ -1112,11 +1155,13 @@ public void TestAddPropertyGroupForSolutionConfiguration()
///
/// Make sure that BuildProjectInSolution is set to true of the Build.0 entry is in the solution configuration.
///
- [Fact]
- public void TestAddPropertyGroupForSolutionConfigurationBuildProjectInSolutionSet()
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void TestAddPropertyGroupForSolutionConfigurationBuildProjectInSolutionSet(bool useNewParser)
{
string solutionFileContents =
- @"
+ """
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project('{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}') = 'ClassLibrary1', 'ClassLibrary1\ClassLibrary1.csproj', '{6185CC21-BE89-448A-B3C0-D1C27112E595}'
@@ -1131,9 +1176,9 @@ public void TestAddPropertyGroupForSolutionConfigurationBuildProjectInSolutionSe
{6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Mixed Platforms.Build.0 = CSConfig1|Any CPU
EndGlobalSection
EndGlobal
- ";
+ """;
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser);
ProjectRootElement projectXml = ProjectRootElement.Create();
@@ -1156,11 +1201,13 @@ public void TestAddPropertyGroupForSolutionConfigurationBuildProjectInSolutionSe
///
/// Make sure that BuildProjectInSolution is set to false of the Build.0 entry is in the solution configuration.
///
- [Fact]
- public void TestAddPropertyGroupForSolutionConfigurationBuildProjectInSolutionNotSet()
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void TestAddPropertyGroupForSolutionConfigurationBuildProjectInSolutionNotSet(bool useNewParser)
{
string solutionFileContents =
- @"
+ """
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project('{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}') = 'ClassLibrary1', 'ClassLibrary1\ClassLibrary1.csproj', '{6185CC21-BE89-448A-B3C0-D1C27112E595}'
@@ -1174,9 +1221,9 @@ public void TestAddPropertyGroupForSolutionConfigurationBuildProjectInSolutionNo
{6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Mixed Platforms.ActiveCfg = CSConfig1|Any CPU
EndGlobalSection
EndGlobal
- ";
+ """;
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser);
ProjectRootElement projectXml = ProjectRootElement.Create();
@@ -1200,10 +1247,12 @@ public void TestAddPropertyGroupForSolutionConfigurationBuildProjectInSolutionNo
/// In this bug, SkipNonexistentProjects was always set to 'Build'. It should be 'Build' for metaprojects and 'True' for everything else.
/// The repro below has one of each case. WebProjects can't build so they are set as SkipNonexistentProjects='Build'
///
- [Fact]
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
[Trait("Category", "netcore-osx-failing")]
[Trait("Category", "netcore-linux-failing")]
- public void Regress751742_SkipNonexistentProjects()
+ public void Regress751742_SkipNonexistentProjects(bool useNewParser)
{
if (FrameworkLocationHelper.PathToDotNetFrameworkV20 == null)
{
@@ -1212,7 +1261,7 @@ public void Regress751742_SkipNonexistentProjects()
}
var solutionFileContents =
- @"
+ """
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project('{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}') = 'ClassLibrary1', 'ClassLibrary1\ClassLibrary1.csproj', '{6185CC21-BE89-448A-B3C0-D1C27112E595}'
@@ -1232,39 +1281,43 @@ public void Regress751742_SkipNonexistentProjects()
{A6F99D27-47B9-4EA4-BFC9-25157CBDC281}.Debug|Mixed Platforms.Build.0 = VCConfig1|Win32
EndGlobalSection
EndGlobal
- ";
+ """;
- // We're not passing in a /tv:xx switch, so the solution project will have tools version 2.0
- var solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
+ // SolutionProjectGenerator.Generate calls SolutionFile.UseNewParser, so we need TestEnvironment with the environment variable available.
+ using (TestEnvironment testEnvironment = TestEnvironment.Create())
+ {
+ // We're not passing in a /tv:xx switch, so the solution project will have tools version 2.0
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser, testEnvironment);
- var instance = SolutionProjectGenerator.Generate(solution, null, ObjectModelHelpers.MSBuildDefaultToolsVersion, _buildEventContext, CreateMockLoggingService())[0];
+ var instance = SolutionProjectGenerator.Generate(solution, null, ObjectModelHelpers.MSBuildDefaultToolsVersion, _buildEventContext, CreateMockLoggingService())[0];
- foreach (ITaskItem item in instance.Items)
- {
- string skipNonexistentProjects = item.GetMetadata("SkipNonexistentProjects");
- if (item.ItemSpec.EndsWith("ClassLibrary1.csproj"))
- {
- Assert.Equal("False", skipNonexistentProjects);
- }
- else if (item.ItemSpec.EndsWith("MainApp.metaproj"))
+ foreach (ITaskItem item in instance.Items)
{
- Assert.Equal("Build", skipNonexistentProjects);
- }
- else if (item.ItemSpec == "Debug|Mixed Platforms")
- {
- Assert.Equal("Debug", item.GetMetadata("Configuration"));
- Assert.Equal("Mixed Platforms", item.GetMetadata("Platform"));
- Assert.Contains("", item.GetMetadata("Content"));
- }
- else if (item.ItemSpec == "Release|Any CPU")
- {
- Assert.Equal("Release", item.GetMetadata("Configuration"));
- Assert.Equal("Any CPU", item.GetMetadata("Platform"));
- Assert.Contains("", item.GetMetadata("Content"));
- }
- else
- {
- Assert.Fail("Unexpected project seen:" + item.ItemSpec);
+ string skipNonexistentProjects = item.GetMetadata("SkipNonexistentProjects");
+ if (item.ItemSpec.EndsWith("ClassLibrary1.csproj"))
+ {
+ Assert.Equal("False", skipNonexistentProjects);
+ }
+ else if (item.ItemSpec.EndsWith("MainApp.metaproj"))
+ {
+ Assert.Equal("Build", skipNonexistentProjects);
+ }
+ else if (item.ItemSpec == "Debug|Mixed Platforms")
+ {
+ Assert.Equal("Debug", item.GetMetadata("Configuration"));
+ Assert.Equal("Mixed Platforms", item.GetMetadata("Platform"));
+ Assert.Contains("", item.GetMetadata("Content"));
+ }
+ else if (item.ItemSpec == "Release|Any CPU")
+ {
+ Assert.Equal("Release", item.GetMetadata("Configuration"));
+ Assert.Equal("Any CPU", item.GetMetadata("Platform"));
+ Assert.Contains("", item.GetMetadata("Content"));
+ }
+ else
+ {
+ Assert.Fail("Unexpected project seen:" + item.ItemSpec);
+ }
}
}
}
@@ -1274,11 +1327,13 @@ public void Regress751742_SkipNonexistentProjects()
/// if set when building a solution, will be specified as the ToolsVersion on the MSBuild task when
/// building the projects contained within the solution.
///
- [Fact]
- public void ToolsVersionOverrideShouldBeSpecifiedOnMSBuildTaskInvocations()
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void ToolsVersionOverrideShouldBeSpecifiedOnMSBuildTaskInvocations(bool useNewParser)
{
string solutionFileContents =
- @"
+ """
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project('{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}') = 'ClassLibrary1', 'ClassLibrary1\ClassLibrary1.csproj', '{6185CC21-BE89-448A-B3C0-D1C27112E595}'
@@ -1298,41 +1353,45 @@ public void ToolsVersionOverrideShouldBeSpecifiedOnMSBuildTaskInvocations()
{A6F99D27-47B9-4EA4-BFC9-25157CBDC281}.Debug|Mixed Platforms.Build.0 = VCConfig1|Win32
EndGlobalSection
EndGlobal
- ";
+ """;
- // We're not passing in a /tv:xx switch, so the solution project will have tools version 2.0
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
+ // SolutionProjectGenerator.Generate calls SolutionFile.UseNewParser, so we need TestEnvironment with the environment variable available.
+ using (TestEnvironment testEnvironment = TestEnvironment.Create())
+ {
+ // We're not passing in a /tv:xx switch, so the solution project will have tools version 2.0
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser, testEnvironment);
- ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, ObjectModelHelpers.MSBuildDefaultToolsVersion, _buildEventContext, CreateMockLoggingService());
+ ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, ObjectModelHelpers.MSBuildDefaultToolsVersion, _buildEventContext, CreateMockLoggingService());
- int i = 0;
- foreach (ProjectInstance instance in instances)
- {
- if (i == 0)
+ int i = 0;
+ foreach (ProjectInstance instance in instances)
{
- continue;
- }
+ if (i == 0)
+ {
+ continue;
+ }
- foreach (ProjectTargetInstance target in instance.Targets.Values)
- {
- foreach (ProjectTaskInstance childNode in target.Tasks)
+ foreach (ProjectTargetInstance target in instance.Targets.Values)
{
- if (String.Equals(childNode.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
+ foreach (ProjectTaskInstance childNode in target.Tasks)
{
- string projectsParameter = childNode.GetParameter("Projects");
- if (projectsParameter != "@(ProjectReference)")
+ if (String.Equals(childNode.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
{
- // we found an MSBuild task invocation, now let's verify that it has the correct
- // ToolsVersion parameter set
- string toolsVersionParameter = childNode.GetParameter("ToolsVersion");
-
- Assert.Equal(toolsVersionParameter, instances[0].GetPropertyValue("ProjectToolsVersion"));
+ string projectsParameter = childNode.GetParameter("Projects");
+ if (projectsParameter != "@(ProjectReference)")
+ {
+ // we found an MSBuild task invocation, now let's verify that it has the correct
+ // ToolsVersion parameter set
+ string toolsVersionParameter = childNode.GetParameter("ToolsVersion");
+
+ Assert.Equal(toolsVersionParameter, instances[0].GetPropertyValue("ProjectToolsVersion"));
+ }
}
}
}
- }
- i++;
+ i++;
+ }
}
}
@@ -1340,68 +1399,74 @@ public void ToolsVersionOverrideShouldBeSpecifiedOnMSBuildTaskInvocations()
///
/// Make sure that whatever the solution ToolsVersion is, it gets mapped to all its metaprojs, too.
///
- [Fact]
- public void SolutionWithDependenciesHasCorrectToolsVersionInMetaprojs()
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void SolutionWithDependenciesHasCorrectToolsVersionInMetaprojs(bool useNewParser)
{
string solutionFileContents =
- @"
-Microsoft Visual Studio Solution File, Format Version 12.00
-Project('{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}') = 'ConsoleApplication2', 'ConsoleApplication2\ConsoleApplication2.csproj', '{5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}'
- ProjectSection(ProjectDependencies) = postProject
- {E0D295A1-CAFA-4E68-9929-468657DAAC6C} = {E0D295A1-CAFA-4E68-9929-468657DAAC6C}
- EndProjectSection
-EndProject
-Project('{F184B08F-C81C-45F6-A57F-5ABD9991F28F}') = 'ConsoleApplication1', 'ConsoleApplication1\ConsoleApplication1.vbproj', '{E0D295A1-CAFA-4E68-9929-468657DAAC6C}'
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}.Release|Any CPU.Build.0 = Release|Any CPU
- {E0D295A1-CAFA-4E68-9929-468657DAAC6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E0D295A1-CAFA-4E68-9929-468657DAAC6C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E0D295A1-CAFA-4E68-9929-468657DAAC6C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E0D295A1-CAFA-4E68-9929-468657DAAC6C}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
- ";
+ """
+ Microsoft Visual Studio Solution File, Format Version 12.00
+ Project('{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}') = 'ConsoleApplication2', 'ConsoleApplication2\ConsoleApplication2.csproj', '{5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}'
+ ProjectSection(ProjectDependencies) = postProject
+ {E0D295A1-CAFA-4E68-9929-468657DAAC6C} = {E0D295A1-CAFA-4E68-9929-468657DAAC6C}
+ EndProjectSection
+ EndProject
+ Project('{F184B08F-C81C-45F6-A57F-5ABD9991F28F}') = 'ConsoleApplication1', 'ConsoleApplication1\ConsoleApplication1.vbproj', '{E0D295A1-CAFA-4E68-9929-468657DAAC6C}'
+ EndProject
+ Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5B97A3C7-3DEE-47A4-870F-5CB6384FE6A4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E0D295A1-CAFA-4E68-9929-468657DAAC6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E0D295A1-CAFA-4E68-9929-468657DAAC6C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E0D295A1-CAFA-4E68-9929-468657DAAC6C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E0D295A1-CAFA-4E68-9929-468657DAAC6C}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ EndGlobal
+ """;
- // We're not passing in a /tv:xx switch, so the solution project will have tools version 2.0
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
+ // SolutionProjectGenerator.Generate calls SolutionFile.UseNewParser, so we need TestEnvironment with the environment variable available.
+ using (TestEnvironment testEnvironment = TestEnvironment.Create())
+ {
+ // We're not passing in a /tv:xx switch, so the solution project will have tools version 2.0
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser, testEnvironment);
- string[] solutionToolsVersions = { "4.0", ObjectModelHelpers.MSBuildDefaultToolsVersion };
+ string[] solutionToolsVersions = { "4.0", ObjectModelHelpers.MSBuildDefaultToolsVersion };
- foreach (string solutionToolsVersion in solutionToolsVersions)
- {
- ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, solutionToolsVersion, _buildEventContext, CreateMockLoggingService());
+ foreach (string solutionToolsVersion in solutionToolsVersions)
+ {
+ ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, solutionToolsVersion, _buildEventContext, CreateMockLoggingService());
- Assert.Equal(2, instances.Length);
+ Assert.Equal(2, instances.Length);
- // Solution metaproj
- Assert.Equal(solutionToolsVersion, instances[0].ToolsVersion);
+ // Solution metaproj
+ Assert.Equal(solutionToolsVersion, instances[0].ToolsVersion);
- ICollection projectReferences = instances[0].GetItems("ProjectReference");
+ ICollection projectReferences = instances[0].GetItems("ProjectReference");
- foreach (ProjectItemInstance projectReference in projectReferences)
- {
- // If this is the reference to the metaproj, its ToolsVersion metadata needs to match
- // the solution ToolsVersion -- that's how the build knows which ToolsVersion to use.
- if (projectReference.EvaluatedInclude.EndsWith(".metaproj", StringComparison.OrdinalIgnoreCase))
+ foreach (ProjectItemInstance projectReference in projectReferences)
{
- Assert.Equal(solutionToolsVersion, projectReference.GetMetadataValue("ToolsVersion"));
+ // If this is the reference to the metaproj, its ToolsVersion metadata needs to match
+ // the solution ToolsVersion -- that's how the build knows which ToolsVersion to use.
+ if (projectReference.EvaluatedInclude.EndsWith(".metaproj", StringComparison.OrdinalIgnoreCase))
+ {
+ Assert.Equal(solutionToolsVersion, projectReference.GetMetadataValue("ToolsVersion"));
+ }
}
- }
- // Project metaproj for project with dependencies
- Assert.Equal(solutionToolsVersion, instances[1].ToolsVersion);
+ // Project metaproj for project with dependencies
+ Assert.Equal(solutionToolsVersion, instances[1].ToolsVersion);
+ }
}
}
#endif
@@ -1409,11 +1474,13 @@ public void SolutionWithDependenciesHasCorrectToolsVersionInMetaprojs()
///
/// Test the SolutionProjectGenerator.Generate method has its toolset redirected correctly.
///
- [Fact]
- public void ToolsVersionOverrideCausesToolsetRedirect()
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void ToolsVersionOverrideCausesToolsetRedirect(bool useNewParser)
{
string solutionFileContents =
- @"
+ """
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project('{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}') = 'ClassLibrary1', 'ClassLibrary1\ClassLibrary1.csproj', '{6185CC21-BE89-448A-B3C0-D1C27112E595}'
@@ -1433,8 +1500,10 @@ public void ToolsVersionOverrideCausesToolsetRedirect()
{A6F99D27-47B9-4EA4-BFC9-25157CBDC281}.Debug|Mixed Platforms.Build.0 = VCConfig1|Win32
EndGlobalSection
EndGlobal
- ";
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
+ """;
+
+ // SolutionProjectGenerator.Generate calls SolutionFile.UseNewParser, so we need TestEnvironment with the environment variable available.
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser);
bool caughtException = false;
try
@@ -1454,11 +1523,13 @@ public void ToolsVersionOverrideCausesToolsetRedirect()
///
/// Test the SolutionProjectGenerator.AddPropertyGroupForSolutionConfiguration method
///
- [Fact]
- public void TestDisambiguateProjectTargetName()
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void TestDisambiguateProjectTargetName(bool useNewParser)
{
string solutionFileContents =
- @"
+ """
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project('{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}') = 'Build', 'Build\Build.csproj', '{21397922-C38F-4A0E-B950-77B3FBD51881}'
@@ -1478,55 +1549,59 @@ public void TestDisambiguateProjectTargetName()
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
- ";
-
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
-
- ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService());
-
- Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Build", StringComparison.OrdinalIgnoreCase)));
- Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Clean", StringComparison.OrdinalIgnoreCase)));
- Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Rebuild", StringComparison.OrdinalIgnoreCase)));
- Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Publish", StringComparison.OrdinalIgnoreCase)));
-
- ProjectTargetInstance buildTarget = instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Build", StringComparison.OrdinalIgnoreCase)).First().Value;
- ProjectTargetInstance cleanTarget = instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Clean", StringComparison.OrdinalIgnoreCase)).First().Value;
- ProjectTargetInstance rebuildTarget = instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Rebuild", StringComparison.OrdinalIgnoreCase)).First().Value;
- ProjectTargetInstance publishTarget = instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Publish", StringComparison.OrdinalIgnoreCase)).First().Value;
-
- // Check that the appropriate target is being passed to the child projects
- Assert.Null(buildTarget.Tasks.Where(
- task => String.Equals(task.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
- .First().GetParameter("Targets"));
+ """;
- Assert.Equal("Clean", cleanTarget.Tasks.Where(
- task => String.Equals(task.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
- .First().GetParameter("Targets"));
-
- Assert.Equal("Rebuild", rebuildTarget.Tasks.Where(
- task => String.Equals(task.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
- .First().GetParameter("Targets"));
-
- Assert.Equal("Publish", publishTarget.Tasks.Where(
- task => String.Equals(task.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
- .First().GetParameter("Targets"));
-
- // Check that the child projects in question are the members of the "ProjectReference" item group
- Assert.Equal("@(ProjectReference)", buildTarget.Tasks.Where(
- task => String.Equals(task.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
- .First().GetParameter("Projects"));
-
- Assert.Equal("@(ProjectReference->Reverse())", cleanTarget.Tasks.Where(
- task => String.Equals(task.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
- .First().GetParameter("Projects"));
+ // SolutionProjectGenerator.Generate calls SolutionFile.UseNewParser, so we need TestEnvironment with the environment variable available.
+ using (TestEnvironment testEnvironment = TestEnvironment.Create())
+ {
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser, testEnvironment);
- Assert.Equal("@(ProjectReference)", rebuildTarget.Tasks.Where(
- task => String.Equals(task.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
- .First().GetParameter("Projects"));
+ ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService());
- Assert.Equal("@(ProjectReference)", publishTarget.Tasks.Where(
- task => String.Equals(task.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
- .First().GetParameter("Projects"));
+ Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Build", StringComparison.OrdinalIgnoreCase)));
+ Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Clean", StringComparison.OrdinalIgnoreCase)));
+ Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Rebuild", StringComparison.OrdinalIgnoreCase)));
+ Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Publish", StringComparison.OrdinalIgnoreCase)));
+
+ ProjectTargetInstance buildTarget = instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Build", StringComparison.OrdinalIgnoreCase)).First().Value;
+ ProjectTargetInstance cleanTarget = instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Clean", StringComparison.OrdinalIgnoreCase)).First().Value;
+ ProjectTargetInstance rebuildTarget = instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Rebuild", StringComparison.OrdinalIgnoreCase)).First().Value;
+ ProjectTargetInstance publishTarget = instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Publish", StringComparison.OrdinalIgnoreCase)).First().Value;
+
+ // Check that the appropriate target is being passed to the child projects
+ Assert.Null(buildTarget.Tasks.Where(
+ task => String.Equals(task.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
+ .First().GetParameter("Targets"));
+
+ Assert.Equal("Clean", cleanTarget.Tasks.Where(
+ task => String.Equals(task.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
+ .First().GetParameter("Targets"));
+
+ Assert.Equal("Rebuild", rebuildTarget.Tasks.Where(
+ task => String.Equals(task.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
+ .First().GetParameter("Targets"));
+
+ Assert.Equal("Publish", publishTarget.Tasks.Where(
+ task => String.Equals(task.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
+ .First().GetParameter("Targets"));
+
+ // Check that the child projects in question are the members of the "ProjectReference" item group
+ Assert.Equal("@(ProjectReference)", buildTarget.Tasks.Where(
+ task => String.Equals(task.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
+ .First().GetParameter("Projects"));
+
+ Assert.Equal("@(ProjectReference->Reverse())", cleanTarget.Tasks.Where(
+ task => String.Equals(task.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
+ .First().GetParameter("Projects"));
+
+ Assert.Equal("@(ProjectReference)", rebuildTarget.Tasks.Where(
+ task => String.Equals(task.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
+ .First().GetParameter("Projects"));
+
+ Assert.Equal("@(ProjectReference)", publishTarget.Tasks.Where(
+ task => String.Equals(task.Name, "MSBuild", StringComparison.OrdinalIgnoreCase))
+ .First().GetParameter("Projects"));
+ }
// We should have only the four standard targets plus the two validation targets (ValidateSolutionConfiguration and ValidateToolsVersions).
}
@@ -1534,11 +1609,13 @@ public void TestDisambiguateProjectTargetName()
///
/// Tests the algorithm for choosing default configuration/platform values for solutions
///
+ /// This test would only work for the old parser. In the new parser SolutionConfigurations are not available,
+ /// and constructed from projects configurations.
[Fact]
public void TestConfigurationPlatformDefaults1()
{
string solutionFileContents =
- @"
+ """
Microsoft Visual Studio Solution File, Format Version 9.00
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -1550,9 +1627,9 @@ public void TestConfigurationPlatformDefaults1()
Release|Win32 = Release|Win32
EndGlobalSection
EndGlobal
- ";
+ """;
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
+ SolutionFile solution = SolutionFile_OldParser_Tests.ParseSolutionHelper(solutionFileContents);
// These used to exist on the engine, but now need to be passed in explicitly
IDictionary globalProperties = new Dictionary();
@@ -1572,11 +1649,13 @@ public void TestConfigurationPlatformDefaults1()
///
/// Tests the algorithm for choosing default configuration/platform values for solutions
///
+ /// This test would only work for the old parser. In the new parser SolutionConfigurations are not available,
+ /// and constructed from projects configurations.
[Fact]
public void TestConfigurationPlatformDefaults2()
{
string solutionFileContents =
- @"
+ """
Microsoft Visual Studio Solution File, Format Version 9.00
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -1586,9 +1665,9 @@ public void TestConfigurationPlatformDefaults2()
Other|Win32 = Other|Win32
EndGlobalSection
EndGlobal
- ";
+ """;
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
+ SolutionFile solution = SolutionFile_OldParser_Tests.ParseSolutionHelper(solutionFileContents);
ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService());
@@ -1602,10 +1681,12 @@ public void TestConfigurationPlatformDefaults2()
///
/// Tests the algorithm for choosing default Venus configuration values for solutions
///
- [Fact]
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
[Trait("Category", "netcore-osx-failing")]
[Trait("Category", "netcore-linux-failing")]
- public void TestVenusConfigurationDefaults()
+ public void TestVenusConfigurationDefaults(bool useNewParser)
{
if (FrameworkLocationHelper.PathToDotNetFrameworkV20 == null)
{
@@ -1615,13 +1696,13 @@ public void TestVenusConfigurationDefaults()
Dictionary globalProperties = new Dictionary();
globalProperties["Configuration"] = "Debug";
- ProjectInstance msbuildProject = CreateVenusSolutionProject(globalProperties);
+ ProjectInstance msbuildProject = CreateVenusSolutionProject(globalProperties, useNewParser);
// ASP.NET configuration should match the selected solution configuration
Assert.Equal("Debug", msbuildProject.GetPropertyValue("AspNetConfiguration"));
globalProperties["Configuration"] = "Release";
- msbuildProject = CreateVenusSolutionProject(globalProperties);
+ msbuildProject = CreateVenusSolutionProject(globalProperties, useNewParser);
Assert.Equal("Release", msbuildProject.GetPropertyValue("AspNetConfiguration"));
// Check that the two standard Asp.net configurations are represented on the targets
@@ -1632,10 +1713,12 @@ public void TestVenusConfigurationDefaults()
///
/// Tests that the correct value for TargetFrameworkVersion gets set when creating Venus solutions
///
- [Fact]
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
[Trait("Category", "netcore-osx-failing")]
[Trait("Category", "netcore-linux-failing")]
- public void VenusSolutionDefaultTargetFrameworkVersion()
+ public void VenusSolutionDefaultTargetFrameworkVersion(bool useNewParser)
{
if (FrameworkLocationHelper.PathToDotNetFrameworkV20 == null)
{
@@ -1644,7 +1727,7 @@ public void VenusSolutionDefaultTargetFrameworkVersion()
}
// v4.0 by default
- ProjectInstance msbuildProject = CreateVenusSolutionProject();
+ ProjectInstance msbuildProject = CreateVenusSolutionProject(useNewParser);
Assert.Equal("v4.0", msbuildProject.GetPropertyValue("TargetFrameworkVersion"));
if (FrameworkLocationHelper.PathToDotNetFrameworkV35 == null)
@@ -1654,34 +1737,36 @@ public void VenusSolutionDefaultTargetFrameworkVersion()
}
// v3.5 if MSBuildToolsVersion is 3.5
- msbuildProject = CreateVenusSolutionProject("3.5");
+ msbuildProject = CreateVenusSolutionProject("3.5", useNewParser);
Assert.Equal("v3.5", msbuildProject.GetPropertyValue("TargetFrameworkVersion"));
// v2.0 if MSBuildToolsVersion is 2.0
- msbuildProject = CreateVenusSolutionProject("2.0");
+ msbuildProject = CreateVenusSolutionProject("2.0", useNewParser);
Assert.Equal("v2.0", msbuildProject.GetPropertyValue("TargetFrameworkVersion"));
// may be user defined
IDictionary globalProperties = new Dictionary();
globalProperties.Add("TargetFrameworkVersion", "userdefined");
- msbuildProject = CreateVenusSolutionProject(globalProperties);
+ msbuildProject = CreateVenusSolutionProject(globalProperties, useNewParser);
Assert.Equal("userdefined", msbuildProject.GetPropertyValue("TargetFrameworkVersion"));
}
///
/// Tests the algorithm for choosing target framework paths for ResolveAssemblyReferences for Venus
///
- [Fact]
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
[Trait("Category", "netcore-osx-failing")]
[Trait("Category", "netcore-linux-failing")]
- public void TestTargetFrameworkPaths0()
+ public void TestTargetFrameworkPaths0(bool useNewParser)
{
if (FrameworkLocationHelper.PathToDotNetFrameworkSdkV20 != null)
{
IDictionary globalProperties = new Dictionary();
globalProperties.Add("TargetFrameworkVersion", "v2.0");
- ProjectInstance msbuildProject = CreateVenusSolutionProject("2.0");
+ ProjectInstance msbuildProject = CreateVenusSolutionProject("2.0", useNewParser);
// ToolsVersion is 2.0, TargetFrameworkVersion is v2.0 --> one item pointing to v2.0
Assert.Equal("2.0", msbuildProject.ToolsVersion);
@@ -1696,10 +1781,12 @@ public void TestTargetFrameworkPaths0()
///
/// Tests the algorithm for choosing target framework paths for ResolveAssemblyReferences for Venus
///
- [Fact]
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
[Trait("Category", "netcore-osx-failing")]
[Trait("Category", "netcore-linux-failing")]
- public void TestTargetFrameworkPaths1()
+ public void TestTargetFrameworkPaths1(bool useNewParser)
{
if (FrameworkLocationHelper.PathToDotNetFrameworkV20 == null)
{
@@ -1707,7 +1794,7 @@ public void TestTargetFrameworkPaths1()
return;
}
- ProjectInstance msbuildProject = CreateVenusSolutionProject();
+ ProjectInstance msbuildProject = CreateVenusSolutionProject(useNewParser);
// ToolsVersion is 4.0, TargetFrameworkVersion is v2.0 --> one item pointing to v2.0
msbuildProject.SetProperty("TargetFrameworkVersion", "v2.0");
@@ -1722,10 +1809,12 @@ public void TestTargetFrameworkPaths1()
///
/// Tests the algorithm for choosing target framework paths for ResolveAssemblyReferences for Venus
///
- [Fact]
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
[Trait("Category", "netcore-osx-failing")]
[Trait("Category", "netcore-linux-failing")]
- public void TestTargetFrameworkPaths2()
+ public void TestTargetFrameworkPaths2(bool useNewParser)
{
if (FrameworkLocationHelper.PathToDotNetFrameworkV20 == null)
{
@@ -1733,7 +1822,7 @@ public void TestTargetFrameworkPaths2()
return;
}
- ProjectInstance msbuildProject = CreateVenusSolutionProject();
+ ProjectInstance msbuildProject = CreateVenusSolutionProject(useNewParser);
// ToolsVersion is 4.0, TargetFrameworkVersion is v4.0 --> items for v2.0 and v4.0
msbuildProject.SetProperty("TargetFrameworkVersion", "v4.0");
@@ -1771,11 +1860,13 @@ public void TestTargetFrameworkPaths2()
///
/// Test the PredictActiveSolutionConfigurationName method
///
+ /// This test would only work for the old parser.
+ /// In the new parser SolutionConfigurations are not available, and constructed from projects configurations.
[Fact]
public void TestPredictSolutionConfigurationName()
{
string solutionFileContents =
- @"
+ """
Microsoft Visual Studio Solution File, Format Version 9.00
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -1785,9 +1876,9 @@ public void TestPredictSolutionConfigurationName()
Debug|Win32 = Debug|Win32
EndGlobalSection
EndGlobal
- ";
+ """;
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
+ SolutionFile solution = SolutionFile_OldParser_Tests.ParseSolutionHelper(solutionFileContents);
IDictionary globalProperties = new Dictionary();
@@ -1806,11 +1897,13 @@ public void TestPredictSolutionConfigurationName()
///
/// Verifies that the SolutionProjectGenerator will correctly escape project file paths
///
- [Fact]
- public void SolutionGeneratorEscapingProjectFilePaths()
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void SolutionGeneratorEscapingProjectFilePaths(bool useNewParser)
{
string solutionFileContents =
- @"
+ """
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project('{F184B08F-C81C-45F6-A57F-5ABD9991F28F}') = 'ConsoleApplication1', '%abtest\ConsoleApplication1.vbproj', '{AB3413A6-D689-486D-B7F0-A095371B3F13}'
@@ -1830,27 +1923,33 @@ public void SolutionGeneratorEscapingProjectFilePaths()
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
- ";
+ """;
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
+ // SolutionProjectGenerator.Generate calls SolutionFile.UseNewParser, so we need TestEnvironment with the environment variable available.
+ using (TestEnvironment testEnvironment = TestEnvironment.Create())
+ {
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser, testEnvironment);
- // Creating a ProjectRootElement shouldn't affect the ProjectCollection at all
- Assert.Empty(ProjectCollection.GlobalProjectCollection.LoadedProjects);
+ // Creating a ProjectRootElement shouldn't affect the ProjectCollection at all
+ Assert.Empty(ProjectCollection.GlobalProjectCollection.LoadedProjects);
- ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService());
+ ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService());
- Assert.Empty(ProjectCollection.GlobalProjectCollection.LoadedProjects);
+ Assert.Empty(ProjectCollection.GlobalProjectCollection.LoadedProjects);
- // Ensure that the value has been correctly stored in the ProjectReference item list
- // Since there is only one project in the solution, there will be only one project reference
- Assert.Contains("%abtest", instances[0].GetItems("ProjectReference").ElementAt(0).EvaluatedInclude);
+ // Ensure that the value has been correctly stored in the ProjectReference item list
+ // Since there is only one project in the solution, there will be only one project reference
+ Assert.Contains("%abtest", instances[0].GetItems("ProjectReference").ElementAt(0).EvaluatedInclude);
+ }
}
///
/// Verifies that the SolutionProjectGenerator will emit a solution file.
///
- [Fact]
- public void SolutionGeneratorCanEmitSolutions()
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void SolutionGeneratorCanEmitSolutions(bool useNewParser)
{
string oldValueForMSBuildEmitSolution = Environment.GetEnvironmentVariable("MSBuildEmitSolution");
@@ -1858,7 +1957,7 @@ public void SolutionGeneratorCanEmitSolutions()
ProjectCollection.GlobalProjectCollection.UnloadAllProjects();
string solutionFileContents =
- @"
+ """
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project('{F184B08F-C81C-45F6-A57F-5ABD9991F28F}') = 'ConsoleApplication1', 'ConsoleApplication1\ConsoleApplication1.vbproj', '{AB3413A6-D689-486D-B7F0-A095371B3F13}'
@@ -1878,7 +1977,7 @@ public void SolutionGeneratorCanEmitSolutions()
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
- ";
+ """;
SolutionFile solution = null;
using ProjectCollection collection = new ProjectCollection();
@@ -1887,12 +1986,16 @@ public void SolutionGeneratorCanEmitSolutions()
{
Environment.SetEnvironmentVariable("MSBuildEmitSolution", "1");
- solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
+ // SolutionProjectGenerator.Generate calls SolutionFile.UseNewParser, so we need TestEnvironment with the environment variable available.
+ using (TestEnvironment testEnvironment = TestEnvironment.Create())
+ {
+ solution = ParseSolutionHelper(solutionFileContents, useNewParser, testEnvironment);
- // Creating a ProjectRootElement shouldn't affect the ProjectCollection at all
- Assert.Empty(ProjectCollection.GlobalProjectCollection.LoadedProjects);
+ // Creating a ProjectRootElement shouldn't affect the ProjectCollection at all
+ Assert.Empty(ProjectCollection.GlobalProjectCollection.LoadedProjects);
- ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService());
+ ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService());
+ }
// Instantiating the
Assert.Empty(ProjectCollection.GlobalProjectCollection.LoadedProjects);
@@ -1919,16 +2022,18 @@ public void SolutionGeneratorCanEmitSolutions()
/// Make sure that we output a warning and don't build anything when we're given an invalid
/// solution configuration and SkipInvalidConfigurations is set to true.
///
- [Fact]
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
[Trait("Category", "netcore-osx-failing")]
[Trait("Category", "netcore-linux-failing")]
- public void TestSkipInvalidConfigurationsCase()
+ public void TestSkipInvalidConfigurationsCase(bool useNewParser)
{
string tmpFileName = FileUtilities.GetTemporaryFileName();
string projectFilePath = tmpFileName + ".sln";
- string solutionContents =
- @"
+ string solutionFileContents =
+ """
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2005
Project('{E24C65DC-7377-472B-9ABA-BC803B73C61A}') = 'C:\solutions\WebSite2\', '..\..\solutions\WebSite2\', '{F90528C4-6989-4D33-AFE8-F53173597CC2}'
@@ -1959,7 +2064,8 @@ public void TestSkipInvalidConfigurationsCase()
{F90528C4-6989-4D33-AFE8-F53173597CC2}.Debug|Any CPU.ActiveCfg = Debug|.NET
{F90528C4-6989-4D33-AFE8-F53173597CC2}.Debug|Any CPU.Build.0 = Debug|.NET
EndGlobalSection
- EndGlobal";
+ EndGlobal
+ """;
try
{
@@ -1969,12 +2075,16 @@ public void TestSkipInvalidConfigurationsCase()
globalProperties["Configuration"] = "Nonexistent";
globalProperties["SkipInvalidConfigurations"] = "true";
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionContents.Replace('\'', '"'));
- ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, globalProperties, null, BuildEventContext.Invalid, CreateMockLoggingService());
- ProjectInstance msbuildProject = instances[0];
+ // SolutionProjectGenerator.Generate calls SolutionFile.UseNewParser, so we need TestEnvironment with the environment variable available.
+ using (TestEnvironment testEnvironment = TestEnvironment.Create())
+ {
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser, testEnvironment);
+ ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, globalProperties, null, BuildEventContext.Invalid, CreateMockLoggingService());
+ ProjectInstance msbuildProject = instances[0];
- // Build should complete successfully even with an invalid solution config if SkipInvalidConfigurations is true
- Assert.True(msbuildProject.Build(new ILogger[] { logger }));
+ // Build should complete successfully even with an invalid solution config if SkipInvalidConfigurations is true
+ Assert.True(msbuildProject.Build(new ILogger[] { logger }));
+ }
// We should get the invalid solution configuration warning
Assert.Single(logger.Warnings);
@@ -2173,50 +2283,52 @@ public void BadFrameworkMonkierExpectBuildToFail2()
/// Bug indicated that when a target framework version greater than 4.0 was used then the solution project generator would crash.
/// this test is to make sure the fix is not regressed.
///
- [Fact]
- public void TestTargetFrameworkVersionGreaterThan4()
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void TestTargetFrameworkVersionGreaterThan4(bool useNewParser)
{
string tmpFileName = FileUtilities.GetTemporaryFileName();
string projectFilePath = tmpFileName + ".sln";
string solutionFileContents =
- @"
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project('{E24C65DC-7377-472B-9ABA-BC803B73C61A}') = 'WebSite1', '..\WebSite1\', '{6B8F98F2-C976-4029-9321-5CCD73A174DA}'
- ProjectSection(WebsiteProperties) = preProject
- TargetFrameworkMoniker = '.NETFramework,Version=v4.34'
- Debug.AspNetCompiler.VirtualPath = '/WebSite1'
- Debug.AspNetCompiler.PhysicalPath = '..\WebSite1\'
- Debug.AspNetCompiler.TargetPath = 'PrecompiledWeb\WebSite1\'
- Debug.AspNetCompiler.Updateable = 'true'
- Debug.AspNetCompiler.ForceOverwrite = 'true'
- Debug.AspNetCompiler.FixedNames = 'false'
- Debug.AspNetCompiler.Debug = 'True'
- Release.AspNetCompiler.VirtualPath = '/WebSite1'
- Release.AspNetCompiler.PhysicalPath = '..\WebSite1\'
- Release.AspNetCompiler.TargetPath = 'PrecompiledWeb\WebSite1\'
- Release.AspNetCompiler.Updateable = 'true'
- Release.AspNetCompiler.ForceOverwrite = 'true'
- Release.AspNetCompiler.FixedNames = 'false'
- Release.AspNetCompiler.Debug = 'False'
- VWDPort = '45602'
- DefaultWebSiteLanguage = 'Visual Basic'
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {6B8F98F2-C976-4029-9321-5CCD73A174DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6B8F98F2-C976-4029-9321-5CCD73A174DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
- ";
+ """
+ Microsoft Visual Studio Solution File, Format Version 11.00
+ # Visual Studio 2010
+ Project('{E24C65DC-7377-472B-9ABA-BC803B73C61A}') = 'WebSite1', '..\WebSite1\', '{6B8F98F2-C976-4029-9321-5CCD73A174DA}'
+ ProjectSection(WebsiteProperties) = preProject
+ TargetFrameworkMoniker = '.NETFramework,Version=v4.34'
+ Debug.AspNetCompiler.VirtualPath = '/WebSite1'
+ Debug.AspNetCompiler.PhysicalPath = '..\WebSite1\'
+ Debug.AspNetCompiler.TargetPath = 'PrecompiledWeb\WebSite1\'
+ Debug.AspNetCompiler.Updateable = 'true'
+ Debug.AspNetCompiler.ForceOverwrite = 'true'
+ Debug.AspNetCompiler.FixedNames = 'false'
+ Debug.AspNetCompiler.Debug = 'True'
+ Release.AspNetCompiler.VirtualPath = '/WebSite1'
+ Release.AspNetCompiler.PhysicalPath = '..\WebSite1\'
+ Release.AspNetCompiler.TargetPath = 'PrecompiledWeb\WebSite1\'
+ Release.AspNetCompiler.Updateable = 'true'
+ Release.AspNetCompiler.ForceOverwrite = 'true'
+ Release.AspNetCompiler.FixedNames = 'false'
+ Release.AspNetCompiler.Debug = 'False'
+ VWDPort = '45602'
+ DefaultWebSiteLanguage = 'Visual Basic'
+ EndProjectSection
+ EndProject
+ Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6B8F98F2-C976-4029-9321-5CCD73A174DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6B8F98F2-C976-4029-9321-5CCD73A174DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ EndGlobal
+ """;
try
{
@@ -2226,18 +2338,22 @@ public void TestTargetFrameworkVersionGreaterThan4()
globalProperties["Configuration"] = "Release";
globalProperties["SkipInvalidConfigurations"] = "true";
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents.Replace('\'', '"'));
- using ProjectCollection collection = new ProjectCollection();
- collection.RegisterLogger(logger);
+ // SolutionProjectGenerator.Generate calls SolutionFile.UseNewParser, so we need TestEnvironment with the environment variable available.
+ using (TestEnvironment testEnvironment = TestEnvironment.Create())
+ {
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser, testEnvironment);
+
+ using ProjectCollection collection = new ProjectCollection();
+ collection.RegisterLogger(logger);
#pragma warning disable format
#if !FEATURE_ASPNET_COMPILER
- Assert.Throws(() =>
- {
+ Assert.Throws(() =>
+ {
#endif
- ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, globalProperties, null, BuildEventContext.Invalid, collection.LoggingService);
+ ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, globalProperties, null, BuildEventContext.Invalid, collection.LoggingService);
#if !FEATURE_ASPNET_COMPILER
- });
+ });
#endif
#pragma warning restore format
@@ -2246,6 +2362,7 @@ public void TestTargetFrameworkVersionGreaterThan4()
string message = ResourceUtilities.FormatResourceStringStripCodeAndKeyword("AspNetCompiler.TargetingHigherFrameworksDefaultsTo40", solution.ProjectsInOrder[0].ProjectName, ver.ToString());
logger.AssertLogContains(message);
#endif
+ }
}
finally
{
@@ -2256,14 +2373,16 @@ public void TestTargetFrameworkVersionGreaterThan4()
///
/// Verifies that when target names are specified they end up in the metaproj.
///
- [Fact]
- public void CustomTargetNamesAreInInMetaproj()
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void CustomTargetNamesAreInInMetaproj(bool useNewParser)
{
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(
- @"
- Microsoft Visual Studio Solution File, Format Version 14.00
+ string solutionFileContents =
+ """
+ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2015
- Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ClassLibrary1"", ""ClassLibrary1.csproj"", ""{6185CC21-BE89-448A-B3C0-D1C27112E595}""
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibrary1", "ClassLibrary1.csproj", "{6185CC21-BE89-448A-B3C0-D1C27112E595}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -2275,43 +2394,51 @@ public void CustomTargetNamesAreInInMetaproj()
{6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.ActiveCfg = CSConfig2|Any CPU
EndGlobalSection
EndGlobal
- ");
+ """;
- ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService(), new List { "One" });
+ // SolutionProjectGenerator.Generate calls SolutionFile.UseNewParser, so we need TestEnvironment with the environment variable available.
+ using (TestEnvironment testEnvironment = TestEnvironment.Create())
+ {
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser, testEnvironment);
- Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "One", StringComparison.OrdinalIgnoreCase)));
+ ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService(), new List { "One" });
- instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService(), new List { "Two", "Three", "Four" });
+ Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "One", StringComparison.OrdinalIgnoreCase)));
- Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Two", StringComparison.OrdinalIgnoreCase)));
- Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Three", StringComparison.OrdinalIgnoreCase)));
- Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Four", StringComparison.OrdinalIgnoreCase)));
+ instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService(), new List { "Two", "Three", "Four" });
- instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService(), new List { "Build" });
+ Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Two", StringComparison.OrdinalIgnoreCase)));
+ Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Three", StringComparison.OrdinalIgnoreCase)));
+ Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Four", StringComparison.OrdinalIgnoreCase)));
- Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Build", StringComparison.OrdinalIgnoreCase)));
+ instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService(), new List { "Build" });
- instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService(), new List { "Five", "Rebuild" });
+ Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Build", StringComparison.OrdinalIgnoreCase)));
- Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Five", StringComparison.OrdinalIgnoreCase)));
- Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Rebuild", StringComparison.OrdinalIgnoreCase)));
+ instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService(), new List { "Five", "Rebuild" });
- instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService(), new List { "My_Project:Six" });
+ Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Five", StringComparison.OrdinalIgnoreCase)));
+ Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Rebuild", StringComparison.OrdinalIgnoreCase)));
- Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Six", StringComparison.OrdinalIgnoreCase)));
+ instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService(), new List { "My_Project:Six" });
+
+ Assert.Single(instances[0].Targets.Where(target => String.Equals(target.Value.Name, "Six", StringComparison.OrdinalIgnoreCase)));
+ }
}
///
/// Verifies that disambiguated target names are used when a project name matches a standard solution entry point.
///
- [Fact]
- public void DisambiguatedTargetNamesAreInInMetaproj()
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void DisambiguatedTargetNamesAreInMetaproj(bool useNewParser)
{
- foreach(string projectName in ProjectInSolution.projectNamesToDisambiguate)
+ foreach (string projectName in ProjectInSolution.projectNamesToDisambiguate)
{
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(
- $$"""
- Microsoft Visual Studio Solution File, Format Version 14.00
+ string solutionFileContents =
+ $$"""
+ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2015
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "{{projectName}}", "{{projectName}}.csproj", "{6185CC21-BE89-448A-B3C0-D1C27112E595}"
EndProject
@@ -2326,21 +2453,27 @@ public void DisambiguatedTargetNamesAreInInMetaproj()
{6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
- """);
+ """;
- ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService(), null);
-
- foreach (string targetName in ProjectInSolution.projectNamesToDisambiguate)
+ // SolutionProjectGenerator.Generate calls SolutionFile.UseNewParser, so we need TestEnvironment with the environment variable available.
+ using (TestEnvironment testEnvironment = TestEnvironment.Create())
{
- // The entry point still exists normally.
- Assert.True(instances[0].Targets.ContainsKey(targetName));
-
- // The traversal target should be disambiguated with a "Solution:" prefix.
- // Note: The default targets are used instead of "Build".
- string traversalTargetName = targetName.Equals("Build", StringComparison.OrdinalIgnoreCase)
- ? $"Solution:{projectName}"
- : $"Solution:{projectName}:{targetName}";
- Assert.True(instances[0].Targets.ContainsKey(traversalTargetName));
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser, testEnvironment);
+
+ ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService(), null);
+
+ foreach (string targetName in ProjectInSolution.projectNamesToDisambiguate)
+ {
+ // The entry point still exists normally.
+ Assert.True(instances[0].Targets.ContainsKey(targetName));
+
+ // The traversal target should be disambiguated with a "Solution:" prefix.
+ // Note: The default targets are used instead of "Build".
+ string traversalTargetName = targetName.Equals("Build", StringComparison.OrdinalIgnoreCase)
+ ? $"Solution:{projectName}"
+ : $"Solution:{projectName}:{targetName}";
+ Assert.True(instances[0].Targets.ContainsKey(traversalTargetName));
+ }
}
}
}
@@ -2349,73 +2482,81 @@ public void DisambiguatedTargetNamesAreInInMetaproj()
/// Verifies that illegal user target names (the ones already used internally) don't crash the SolutionProjectGenerator
///
[Theory]
- [InlineData(false)]
- [InlineData(true)]
- public void IllegalUserTargetNamesDoNotThrow(bool forceCaseDifference)
+ [InlineData(false, false)]
+ [InlineData(true, false)]
+ [InlineData(false, true)]
+ [InlineData(true, true)]
+ public void IllegalUserTargetNamesDoNotThrow(bool forceCaseDifference, bool useNewParser)
{
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(
- @"
- Microsoft Visual Studio Solution File, Format Version 14.00
+ string solutionFileContents =
+ """
+ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2015
- Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ClassLibrary1"", ""ClassLibrary1.csproj"", ""{6185CC21-BE89-448A-B3C0-D1C27112E595}""
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibrary1", "ClassLibrary1.csproj", "{6185CC21-BE89-448A-B3C0-D1C27112E595}"
EndProject
Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
EndGlobal
- ");
+ """;
- ProjectInstance[] instances;
+ // SolutionProjectGenerator.Generate calls SolutionFile.UseNewParser, so we need TestEnvironment with the environment variable available.
+ using (TestEnvironment testEnvironment = TestEnvironment.Create())
+ {
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser, testEnvironment);
- // Avoid any unexpected targets getting pulled in
- var globalProperties = new Dictionary { { "ImportByWildcardBeforeSolution", "false" } };
+ ProjectInstance[] instances;
- foreach (string builtInTargetName in new[]
- {
- null,
- "Build",
- "Rebuild",
- "Clean",
- "Publish",
- "ClassLibrary1",
- "ClassLibrary1:Clean",
- "ClassLibrary1:Rebuild",
- "GetSolutionConfigurationContents",
- "ValidateProjects",
- })
- {
- string[] targetNames;
+ // Avoid any unexpected targets getting pulled in
+ var globalProperties = new Dictionary { { "ImportByWildcardBeforeSolution", "false" } };
- if (builtInTargetName == null)
+ foreach (string builtInTargetName in new[]
{
- targetNames = null;
- }
- else
+ null,
+ "Build",
+ "Rebuild",
+ "Clean",
+ "Publish",
+ "ClassLibrary1",
+ "ClassLibrary1:Clean",
+ "ClassLibrary1:Rebuild",
+ "GetSolutionConfigurationContents",
+ "ValidateProjects",
+ })
{
- string targetName = forceCaseDifference ? builtInTargetName.ToUpperInvariant() : builtInTargetName;
- targetNames = new[] { targetName };
- }
+ string[] targetNames;
- instances = SolutionProjectGenerator.Generate(solution, globalProperties, null, BuildEventContext.Invalid, CreateMockLoggingService(), targetNames);
+ if (builtInTargetName == null)
+ {
+ targetNames = null;
+ }
+ else
+ {
+ string targetName = forceCaseDifference ? builtInTargetName.ToUpperInvariant() : builtInTargetName;
+ targetNames = new[] { targetName };
+ }
- Assert.Single(instances);
+ instances = SolutionProjectGenerator.Generate(solution, globalProperties, null, BuildEventContext.Invalid, CreateMockLoggingService(), targetNames);
- Assert.Equal(12, instances[0].TargetsCount);
- }
+ Assert.Single(instances);
- instances = SolutionProjectGenerator.Generate(solution, globalProperties, null, BuildEventContext.Invalid, CreateMockLoggingService(), new[] { "Foo" });
+ Assert.Equal(12, instances[0].TargetsCount);
+ }
+
+ instances = SolutionProjectGenerator.Generate(solution, globalProperties, null, BuildEventContext.Invalid, CreateMockLoggingService(), new[] { "Foo" });
- Assert.Single(instances);
+ Assert.Single(instances);
- Assert.Equal(14, instances[0].TargetsCount);
+ Assert.Equal(14, instances[0].TargetsCount);
+ }
}
///
@@ -2426,31 +2567,34 @@ public void AfterTargetsComeFromImport()
{
string baseDirectory = Guid.NewGuid().ToString("N");
- string solutionFilePath = ObjectModelHelpers.CreateFileInTempProjectDirectory(Path.Combine(baseDirectory, $"{Guid.NewGuid():N}.sln"), @"
- Microsoft Visual Studio Solution File, Format Version 14.00
+ string solutionFilePath = ObjectModelHelpers.CreateFileInTempProjectDirectory(Path.Combine(baseDirectory, $"{Guid.NewGuid():N}.sln"),
+ """
+ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2015
- Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ClassLibrary1"", ""ClassLibrary1.csproj"", ""{6185CC21-BE89-448A-B3C0-D1C27112E595}""
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibrary1", "ClassLibrary1.csproj", "{6185CC21-BE89-448A-B3C0-D1C27112E595}"
EndProject
Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
EndGlobal
- ");
+ """);
- ObjectModelHelpers.CreateFileInTempProjectDirectory(Path.Combine(baseDirectory, $"after.{Path.GetFileName(solutionFilePath)}.targets"), @"
-
-
+ ObjectModelHelpers.CreateFileInTempProjectDirectory(Path.Combine(baseDirectory, $"after.{Path.GetFileName(solutionFilePath)}.targets"),
+ """
+
+
- ");
+
+ """);
try
{
@@ -2482,31 +2626,34 @@ public void BeforeTargetsFromImportCanHookDynamicTarget()
{
string baseDirectory = Guid.NewGuid().ToString("N");
- string solutionFilePath = ObjectModelHelpers.CreateFileInTempProjectDirectory(Path.Combine(baseDirectory, $"{Guid.NewGuid():N}.sln"), @"
- Microsoft Visual Studio Solution File, Format Version 14.00
+ string solutionFilePath = ObjectModelHelpers.CreateFileInTempProjectDirectory(Path.Combine(baseDirectory, $"{Guid.NewGuid():N}.sln"),
+ """
+ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2015
- Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ClassLibrary1"", ""ClassLibrary1.csproj"", ""{6185CC21-BE89-448A-B3C0-D1C27112E595}""
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibrary1", "ClassLibrary1.csproj", "{6185CC21-BE89-448A-B3C0-D1C27112E595}"
EndProject
Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
EndGlobal
- ");
+ """);
- ObjectModelHelpers.CreateFileInTempProjectDirectory(Path.Combine(baseDirectory, $"after.{Path.GetFileName(solutionFilePath)}.targets"), @"
-
-
-
+ ObjectModelHelpers.CreateFileInTempProjectDirectory(Path.Combine(baseDirectory, $"after.{Path.GetFileName(solutionFilePath)}.targets"),
+ """
+
+
+
- ");
+
+ """);
try
{
@@ -2557,48 +2704,55 @@ public void DirectorySolutionPropsTest(string projectName, bool enable)
string baseDirectory = Guid.NewGuid().ToString("N");
- string solutionFilePath = ObjectModelHelpers.CreateFileInTempProjectDirectory(Path.Combine(baseDirectory, $"{Guid.NewGuid():N}.sln"), @"
- Microsoft Visual Studio Solution File, Format Version 14.00
+ string solutionFilePath = ObjectModelHelpers.CreateFileInTempProjectDirectory(Path.Combine(baseDirectory, $"{Guid.NewGuid():N}.sln"),
+ """
+ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2015
- Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ClassLibrary1"", ""ClassLibrary1.csproj"", ""{6185CC21-BE89-448A-B3C0-D1C27112E595}""
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibrary1", "ClassLibrary1.csproj", "{6185CC21-BE89-448A-B3C0-D1C27112E595}"
EndProject
Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
EndGlobal
- ");
+ """);
- string projectPath = ObjectModelHelpers.CreateFileInTempProjectDirectory(Path.Combine(baseDirectory, projectName), $@"
-
+ string projectPath = ObjectModelHelpers.CreateFileInTempProjectDirectory(Path.Combine(baseDirectory, projectName),
+ $$"""
+
- {expectedPropertyValue}
+ {{expectedPropertyValue}}
- ");
+
+ """);
if (projectPath.StartsWith("Custom", StringComparison.OrdinalIgnoreCase))
{
// If a custom file name was given, create a Directory.Solution.props and Directory.Build.targets to ensure that they aren't imported
- ObjectModelHelpers.CreateFileInTempProjectDirectory(Path.Combine(baseDirectory, "Directory.Solution.props"), $@"
-
-
- This file should not be imported
-
- ");
-
- ObjectModelHelpers.CreateFileInTempProjectDirectory(Path.Combine(baseDirectory, "Directory.Solution.targets"), $@"
-
-
- This file should not be imported
-
- ");
+ ObjectModelHelpers.CreateFileInTempProjectDirectory(Path.Combine(baseDirectory, "Directory.Solution.props"),
+ """
+
+
+ This file should not be imported
+
+
+ """);
+
+ ObjectModelHelpers.CreateFileInTempProjectDirectory(Path.Combine(baseDirectory, "Directory.Solution.targets"),
+ """
+
+
+ This file should not be imported
+
+
+ """);
}
try
@@ -2640,20 +2794,23 @@ public void DirectorySolutionPropsTest(string projectName, bool enable)
/// Regression test for https://github.com/dotnet/msbuild/issues/6236
///
[Theory]
- [InlineData("http://localhost:8080")]
- [InlineData("a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-")]
- public void AbsolutePathWorksForUnsupportedPaths(string relativePath)
+ [InlineData("http://localhost:8080", false)]
+ [InlineData("http://localhost:8080", true)]
+ [InlineData(_longLineString, false)]
+ [InlineData(_longLineString, true)]
+ public void AbsolutePathWorksForUnsupportedPaths(string relativePath, bool useNewParser)
{
string solutionFileContents =
- $@"
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.31025.194
-MinimumVisualStudioVersion = 10.0.40219.1
-Project(""{{E24C65DC-7377-472B-9ABA-BC803B73C61A}}"") = ""WebSite1"", ""{relativePath}"", ""{{{{96E0707C-2E9C-4704-946F-FA583147737F}}}}""
-EndProject";
+ $$"""
+ Microsoft Visual Studio Solution File, Format Version 12.00
+ # Visual Studio Version 16
+ VisualStudioVersion = 16.0.31025.194
+ MinimumVisualStudioVersion = 10.0.40219.1
+ Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "WebSite1", "{{relativePath}}", "{96E0707C-2E9C-4704-946F-FA583147737F}"
+ EndProject
+ """;
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser);
ProjectInSolution projectInSolution = solution.ProjectsInOrder.ShouldHaveSingleItem();
@@ -2665,25 +2822,25 @@ public void AbsolutePathWorksForUnsupportedPaths(string relativePath)
///
/// Create a Project derived from a Venus solution
///
- private ProjectInstance CreateVenusSolutionProject()
+ private ProjectInstance CreateVenusSolutionProject(bool useNewParser)
{
- return CreateVenusSolutionProject(null, null);
+ return CreateVenusSolutionProject(null, null, useNewParser);
}
///
/// Create a Project derived from a Venus solution
///
- private ProjectInstance CreateVenusSolutionProject(IDictionary globalProperties)
+ private ProjectInstance CreateVenusSolutionProject(IDictionary globalProperties, bool useNewParser)
{
- return CreateVenusSolutionProject(globalProperties, null);
+ return CreateVenusSolutionProject(globalProperties, null, useNewParser);
}
///
/// Create a Project derived from a Venus solution
///
- private ProjectInstance CreateVenusSolutionProject(string toolsVersion)
+ private ProjectInstance CreateVenusSolutionProject(string toolsVersion, bool useNewParser)
{
- return CreateVenusSolutionProject(null, toolsVersion);
+ return CreateVenusSolutionProject(null, toolsVersion, useNewParser);
}
///
@@ -2692,10 +2849,10 @@ private ProjectInstance CreateVenusSolutionProject(string toolsVersion)
///
/// The dictionary of global properties. May be null.
/// The ToolsVersion override value. May be null.
- private ProjectInstance CreateVenusSolutionProject(IDictionary globalProperties, string toolsVersion)
+ private ProjectInstance CreateVenusSolutionProject(IDictionary globalProperties, string toolsVersion, bool useNewParser)
{
string solutionFileContents =
- @"
+ """
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project('{E24C65DC-7377-472B-9ABA-BC803B73C61A}') = 'C:\solutions\WebSite2\', '..\..\solutions\WebSite2\', '{F90528C4-6989-4D33-AFE8-F53173597CC2}'
@@ -2727,14 +2884,18 @@ private ProjectInstance CreateVenusSolutionProject(IDictionary g
{F90528C4-6989-4D33-AFE8-F53173597CC2}.Debug|Any CPU.Build.0 = Debug|.NET
EndGlobalSection
EndGlobal
- ";
+ """;
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
+ // SolutionProjectGenerator.Generate calls SolutionFile.UseNewParser, so we need TestEnvironment with the environment variable available.
+ using (TestEnvironment testEnvironment = TestEnvironment.Create())
+ {
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser, testEnvironment);
- ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, globalProperties, toolsVersion, BuildEventContext.Invalid, CreateMockLoggingService());
+ ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, globalProperties, toolsVersion, BuildEventContext.Invalid, CreateMockLoggingService());
- // Index 0 is the traversal project, which will reference the sole Venus project.
- return instances[1];
+ // Index 0 is the traversal project, which will reference the sole Venus project.
+ return instances[1];
+ }
}
private ILoggingService CreateMockLoggingService()
@@ -2776,6 +2937,25 @@ private void AssertProjectItemNameCount(ProjectInstance msbuildProject, string i
Assert.Equal(count, itemGroup.Count());
}
+ private static SolutionFile ParseSolutionHelper(string solutionFileContents, bool isOptInSlnParsingWithNewParser)
+ {
+ using (TestEnvironment testEnvironment = TestEnvironment.Create())
+ {
+ return ParseSolutionHelper(solutionFileContents, isOptInSlnParsingWithNewParser, testEnvironment);
+ }
+ }
+
+ private static SolutionFile ParseSolutionHelper(string solutionFileContents, bool isOptInSlnParsingWithNewParser, TestEnvironment testEnvironment)
+ {
+ solutionFileContents = solutionFileContents.Replace('\'', '"');
+ if (isOptInSlnParsingWithNewParser)
+ {
+ testEnvironment.SetEnvironmentVariable("MSBUILD_PARSE_SLN_WITH_SOLUTIONPERSISTENCE", "1");
+ }
+ TransientTestFile sln = testEnvironment.CreateFile(FileUtilities.GetTemporaryFileName(".sln"), solutionFileContents);
+ return SolutionFile.Parse(sln.Path);
+ }
+
#endregion // Helper Functions
}
}
diff --git a/src/Build.UnitTests/Graph/GetCompatiblePlatformGraph_Tests.cs b/src/Build.UnitTests/Graph/GetCompatiblePlatformGraph_Tests.cs
index b941649ad74..d6344240f1a 100644
--- a/src/Build.UnitTests/Graph/GetCompatiblePlatformGraph_Tests.cs
+++ b/src/Build.UnitTests/Graph/GetCompatiblePlatformGraph_Tests.cs
@@ -402,14 +402,14 @@ public void SolutionWithoutAllConfigurations()
// Slashes here (and in the .slnf) are hardcoded as backslashes intentionally to support the common case.
TransientTestFile solutionFile = testEnvironment.CreateFile(folder, "SimpleProject.sln",
- @"
+ """
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29326.124
MinimumVisualStudioVersion = 10.0.40219.1
- Project(""{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"") = ""Project1"", ""1\1\1.csproj"", ""{79B5EBA6-5D27-4976-BC31-14422245A59A}""
+ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Project1", "1\1\1.csproj", "{79B5EBA6-5D27-4976-BC31-14422245A59A}"
EndProject
- Project(""{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"") = ""2"", ""2\2\2.proj"", ""{8EFCCA22-9D51-4268-90F7-A595E11FCB2D}""
+ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "2", "2\2\2.proj", "{8EFCCA22-9D51-4268-90F7-A595E11FCB2D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -434,7 +434,7 @@ public void SolutionWithoutAllConfigurations()
SolutionGuid = {DE7234EC-0C4D-4070-B66A-DCF1B4F0CFEF}
EndGlobalSection
EndGlobal
- ");
+ """);
ProjectCollection projectCollection = testEnvironment.CreateProjectCollection().Collection;
MockLogger logger = new();
diff --git a/src/Build.UnitTests/Graph/GraphLoadedFromSolution_tests.cs b/src/Build.UnitTests/Graph/GraphLoadedFromSolution_tests.cs
index 431ea412875..6d535479b1e 100644
--- a/src/Build.UnitTests/Graph/GraphLoadedFromSolution_tests.cs
+++ b/src/Build.UnitTests/Graph/GraphLoadedFromSolution_tests.cs
@@ -59,7 +59,8 @@ public void GraphConstructionFailsOnNonExistentSolution()
new ProjectGraph("nonExistent.sln");
});
- exception.Message.ShouldContain("The project file could not be loaded. Could not find file");
+ exception.Message.ShouldContain("The project file could not be loaded.");
+ exception.Message.ShouldContain("Could not find file");
}
[Fact]
@@ -646,28 +647,6 @@ IEnumerable GetIncomingEdgeItemsToNode(ProjectGraphNode nod
}
}
- [Fact]
- public void GraphConstructionShouldThrowOnMissingSolutionDependencies()
- {
- var solutionContents = SolutionFileBuilder.FromGraphEdges(
- _env,
- new Dictionary { { 1, null }, { 2, null } },
- new[] { ("1", new[] { Guid.NewGuid().ToString("B") }) }).BuildSolution();
-
- var solutionFile = _env.CreateFile(
- "solution.sln",
- solutionContents)
- .Path;
-
- var exception = Should.Throw(
- () =>
- {
- new ProjectGraph(solutionFile);
- });
-
- exception.Message.ShouldContain("but a project with this GUID was not found in the .SLN file");
- }
-
private static bool IsSolutionItemReference(ProjectItemInstance edgeItem)
{
return edgeItem.ItemType == GraphBuilder.SolutionItemReference;
diff --git a/src/Build/Construction/Solution/SolutionFile.cs b/src/Build/Construction/Solution/SolutionFile.cs
index b549e97da5a..d472078d160 100644
--- a/src/Build/Construction/Solution/SolutionFile.cs
+++ b/src/Build/Construction/Solution/SolutionFile.cs
@@ -193,7 +193,7 @@ internal int VisualStudioVersion
internal bool UseNewParser => ShouldUseNewParser(_solutionFile);
- internal static bool ShouldUseNewParser(string solutionFile) => FileUtilities.IsSolutionXFilename(solutionFile);
+ internal static bool ShouldUseNewParser(string solutionFile) => Traits.Instance.SlnParsingWithSolutionPersistenceOptIn || FileUtilities.IsSolutionXFilename(solutionFile);
///
/// All projects in this solution, in the order they appeared in the solution file
@@ -221,6 +221,10 @@ internal string FullPath
set
{
+ if (ChangeWaves.AreFeaturesEnabled(ChangeWaves.Wave17_14) && string.IsNullOrEmpty(value))
+ {
+ throw new ArgumentNullException(nameof(FullPath));
+ }
// Should already be canonicalized to a full path
ErrorUtilities.VerifyThrowInternalRooted(value);
// To reduce code duplication, this should be
diff --git a/src/Framework/Traits.cs b/src/Framework/Traits.cs
index 046933f38f0..bcdc4ac195c 100644
--- a/src/Framework/Traits.cs
+++ b/src/Framework/Traits.cs
@@ -145,6 +145,7 @@ public Traits()
// for VS17.14
public readonly bool TelemetryOptIn = IsEnvVarOneOrTrue("MSBUILD_TELEMETRY_OPTIN");
+ public readonly bool SlnParsingWithSolutionPersistenceOptIn = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("MSBUILD_PARSE_SLN_WITH_SOLUTIONPERSISTENCE"));
public static void UpdateFromEnvironment()
{