diff --git a/documentation/wiki/ChangeWaves.md b/documentation/wiki/ChangeWaves.md
index 09e7ca1394c..5df8c06508f 100644
--- a/documentation/wiki/ChangeWaves.md
+++ b/documentation/wiki/ChangeWaves.md
@@ -23,6 +23,9 @@ A wave of features is set to "rotate out" (i.e. become standard functionality) t
## Current Rotation of Change Waves
+### 17.14
+- [.SLNX support - use the new parser for .sln and .slnx](https://github.com/dotnet/msbuild/pull/10836)
+
### 17.12
- [Log TaskParameterEvent for scalar parameters](https://github.com/dotnet/msbuild/pull/9908)
- [Convert.ToString during a property evaluation uses the InvariantCulture for all types](https://github.com/dotnet/msbuild/pull/9874)
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 +1065,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 +1091,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 +1140,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 +1161,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 +1186,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 +1206,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 +1232,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 +1246,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,10 +1266,10 @@ 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);
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser);
var instance = SolutionProjectGenerator.Generate(solution, null, ObjectModelHelpers.MSBuildDefaultToolsVersion, _buildEventContext, CreateMockLoggingService())[0];
@@ -1274,11 +1308,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,10 +1334,10 @@ 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);
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser);
ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, ObjectModelHelpers.MSBuildDefaultToolsVersion, _buildEventContext, CreateMockLoggingService());
@@ -1340,42 +1376,44 @@ 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);
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser);
string[] solutionToolsVersions = { "4.0", ObjectModelHelpers.MSBuildDefaultToolsVersion };
@@ -1409,11 +1447,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 +1473,8 @@ public void ToolsVersionOverrideCausesToolsetRedirect()
{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);
bool caughtException = false;
try
@@ -1454,11 +1494,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,9 +1520,9 @@ public void TestDisambiguateProjectTargetName()
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
- ";
+ """;
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser);
ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService());
@@ -1534,11 +1576,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 +1594,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 +1616,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 +1632,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 +1648,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 +1663,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 +1680,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 +1694,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 +1704,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 +1748,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 +1761,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 +1776,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 +1789,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 +1827,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 +1843,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 +1864,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,9 +1890,9 @@ public void SolutionGeneratorEscapingProjectFilePaths()
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
- ";
+ """;
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser);
// Creating a ProjectRootElement shouldn't affect the ProjectCollection at all
Assert.Empty(ProjectCollection.GlobalProjectCollection.LoadedProjects);
@@ -1849,8 +1909,10 @@ public void SolutionGeneratorEscapingProjectFilePaths()
///
/// 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 +1920,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 +1940,7 @@ public void SolutionGeneratorCanEmitSolutions()
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
- ";
+ """;
SolutionFile solution = null;
using ProjectCollection collection = new ProjectCollection();
@@ -1887,7 +1949,7 @@ public void SolutionGeneratorCanEmitSolutions()
{
Environment.SetEnvironmentVariable("MSBuildEmitSolution", "1");
- solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);
+ solution = ParseSolutionHelper(solutionFileContents, useNewParser);
// Creating a ProjectRootElement shouldn't affect the ProjectCollection at all
Assert.Empty(ProjectCollection.GlobalProjectCollection.LoadedProjects);
@@ -1919,16 +1981,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 +2023,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,7 +2034,7 @@ public void TestSkipInvalidConfigurationsCase()
globalProperties["Configuration"] = "Nonexistent";
globalProperties["SkipInvalidConfigurations"] = "true";
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionContents.Replace('\'', '"'));
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser);
ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, globalProperties, null, BuildEventContext.Invalid, CreateMockLoggingService());
ProjectInstance msbuildProject = instances[0];
@@ -2173,50 +2238,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,7 +2293,9 @@ public void TestTargetFrameworkVersionGreaterThan4()
globalProperties["Configuration"] = "Release";
globalProperties["SkipInvalidConfigurations"] = "true";
- SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents.Replace('\'', '"'));
+
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser);
+
using ProjectCollection collection = new ProjectCollection();
collection.RegisterLogger(logger);
@@ -2256,14 +2325,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,7 +2346,9 @@ public void CustomTargetNamesAreInInMetaproj()
{6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.ActiveCfg = CSConfig2|Any CPU
EndGlobalSection
EndGlobal
- ");
+ """;
+
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser);
ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService(), new List { "One" });
@@ -2304,14 +2377,16 @@ public void CustomTargetNamesAreInInMetaproj()
///
/// 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,7 +2401,9 @@ public void DisambiguatedTargetNamesAreInInMetaproj()
{6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
- """);
+ """;
+
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser);
ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, CreateMockLoggingService(), null);
@@ -2349,29 +2426,33 @@ 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
- ");
+ """;
+
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser);
ProjectInstance[] instances;
@@ -2426,31 +2507,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 +2566,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 +2644,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 +2734,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 +2762,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 +2789,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,9 +2824,9 @@ 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);
+ SolutionFile solution = ParseSolutionHelper(solutionFileContents, useNewParser);
ProjectInstance[] instances = SolutionProjectGenerator.Generate(solution, globalProperties, toolsVersion, BuildEventContext.Invalid, CreateMockLoggingService());
@@ -2776,6 +2873,12 @@ private void AssertProjectItemNameCount(ProjectInstance msbuildProject, string i
Assert.Equal(count, itemGroup.Count());
}
+ private SolutionFile ParseSolutionHelper(string solutionFileContents, bool useNewParser)
+ {
+ return useNewParser ? SolutionFile_NewParser_Tests.ParseSolutionHelper(solutionFileContents) :
+ SolutionFile_OldParser_Tests.ParseSolutionHelper(solutionFileContents);
+ }
+
#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 983cd691d0d..909feaf74a6 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) => ChangeWaves.AreFeaturesEnabled(ChangeWaves.Wave17_14) || 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/ChangeWaves.cs b/src/Framework/ChangeWaves.cs
index 1d682c4fc75..8e58f93835c 100644
--- a/src/Framework/ChangeWaves.cs
+++ b/src/Framework/ChangeWaves.cs
@@ -27,7 +27,8 @@ internal static class ChangeWaves
{
internal static readonly Version Wave17_10 = new Version(17, 10);
internal static readonly Version Wave17_12 = new Version(17, 12);
- internal static readonly Version[] AllWaves = { Wave17_10, Wave17_12 };
+ internal static readonly Version Wave17_14 = new Version(17, 14);
+ internal static readonly Version[] AllWaves = { Wave17_10, Wave17_12, Wave17_14 };
///
/// Special value indicating that all features behind all Change Waves should be enabled.