diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index a7b2c0ec687d..0225d6cff89b 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -136,15 +136,16 @@ private void AddProject(SolutionModel solution, string solutionRelativeProjectPa { // Open project instance to see if it is a valid project ProjectRootElement projectRootElement = ProjectRootElement.Open(fullPath); + ProjectInstance projectInstance = new ProjectInstance(projectRootElement); SolutionProjectModel project; try { project = solution.AddProject(solutionRelativeProjectPath, null, solutionFolder); } - catch (SolutionArgumentException ex) when (ex.ParamName == "projectTypeName") + catch (SolutionArgumentException ex) when (ex.Type == SolutionErrorType.InvalidProjectTypeReference) { // If guid is not identified by vs-solutionpersistence, check in project element itself - var guid = projectRootElement.GetProjectTypeGuid(); + var guid = projectRootElement.GetProjectTypeGuid() ?? projectInstance.GetDefaultProjectTypeGuid(); if (string.IsNullOrEmpty(guid)) { Reporter.Error.WriteLine(CommonLocalizableStrings.UnsupportedProjectType, fullPath); @@ -153,7 +154,6 @@ private void AddProject(SolutionModel solution, string solutionRelativeProjectPa project = solution.AddProject(solutionRelativeProjectPath, guid, solutionFolder); } // Add settings based on existing project instance - ProjectInstance projectInstance = new ProjectInstance(projectRootElement); string projectInstanceId = projectInstance.GetProjectId(); if (!string.IsNullOrEmpty(projectInstanceId) && serializer is ISolutionSerializer) { diff --git a/test/TestAssets/TestProjects/TestAppWithEmptySln/App.slnx b/test/TestAssets/TestProjects/TestAppWithEmptySln/App.slnx index 4e2253ddceed..ab94d1d554cc 100644 --- a/test/TestAssets/TestProjects/TestAppWithEmptySln/App.slnx +++ b/test/TestAssets/TestProjects/TestAppWithEmptySln/App.slnx @@ -1 +1 @@ - + \ No newline at end of file diff --git a/test/TestAssets/TestProjects/TestAppWithSlnAndDefaultProjectType/App.sln b/test/TestAssets/TestProjects/TestAppWithSlnAndDefaultProjectType/App.sln new file mode 100644 index 000000000000..8eca2536691f --- /dev/null +++ b/test/TestAssets/TestProjects/TestAppWithSlnAndDefaultProjectType/App.sln @@ -0,0 +1,5 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26006.2 +MinimumVisualStudioVersion = 10.0.40219.1 diff --git a/test/TestAssets/TestProjects/TestAppWithSlnAndDefaultProjectType/App.slnx b/test/TestAssets/TestProjects/TestAppWithSlnAndDefaultProjectType/App.slnx new file mode 100644 index 000000000000..ab94d1d554cc --- /dev/null +++ b/test/TestAssets/TestProjects/TestAppWithSlnAndDefaultProjectType/App.slnx @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/TestAssets/TestProjects/TestAppWithSlnAndDefaultProjectType/Unknown.unknownproj b/test/TestAssets/TestProjects/TestAppWithSlnAndDefaultProjectType/Unknown.unknownproj new file mode 100644 index 000000000000..56d04f3da929 --- /dev/null +++ b/test/TestAssets/TestProjects/TestAppWithSlnAndDefaultProjectType/Unknown.unknownproj @@ -0,0 +1,7 @@ + + + + {2F08BC15-189B-4804-B644-653F34C968A8} + + + diff --git a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs index ebb82381c743..4c0ce7c32ec9 100644 --- a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs +++ b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs @@ -18,6 +18,7 @@ public static class ProjectTypeGuids public const string VBProjectTypeGuid = "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}"; public const string SolutionFolderGuid = "{2150E333-8FDC-42A3-9474-1A3956D46DE8}"; public const string SharedProjectGuid = "{D954291E-2A0B-460D-934E-DC6B0785DB48}"; + public const string DefaultProjectGuid = "{130159A9-F047-44B3-88CF-0CF7F02ED50F}"; } public class GivenDotnetSlnAdd : SdkTest @@ -749,13 +750,13 @@ public void WhenPassedAnUnknownProjectTypeItFails(string solutionCommand) [InlineData("sln", "SlnFileWithNoProjectReferencesAndCSharpProject", "CSharpProject", "CSharpProject.csproj", ProjectTypeGuids.CSharpProjectTypeGuid)] [InlineData("sln", "SlnFileWithNoProjectReferencesAndFSharpProject", "FSharpProject", "FSharpProject.fsproj", ProjectTypeGuids.FSharpProjectTypeGuid)] [InlineData("sln", "SlnFileWithNoProjectReferencesAndVBProject", "VBProject", "VBProject.vbproj", ProjectTypeGuids.VBProjectTypeGuid)] - [InlineData("sln", "SlnFileWithNoProjectReferencesAndUnknownProjectWithSingleProjectTypeGuid", "UnknownProject", "UnknownProject.unknownproj", "{130159A9-F047-44B3-88CF-0CF7F02ED50F}")] - [InlineData("sln", "SlnFileWithNoProjectReferencesAndUnknownProjectWithMultipleProjectTypeGuids", "UnknownProject", "UnknownProject.unknownproj", "{130159A9-F047-44B3-88CF-0CF7F02ED50F}")] + [InlineData("sln", "SlnFileWithNoProjectReferencesAndUnknownProjectWithSingleProjectTypeGuid", "UnknownProject", "UnknownProject.unknownproj", ProjectTypeGuids.DefaultProjectGuid)] + [InlineData("sln", "SlnFileWithNoProjectReferencesAndUnknownProjectWithMultipleProjectTypeGuids", "UnknownProject", "UnknownProject.unknownproj", ProjectTypeGuids.DefaultProjectGuid)] [InlineData("solution", "SlnFileWithNoProjectReferencesAndCSharpProject", "CSharpProject", "CSharpProject.csproj", ProjectTypeGuids.CSharpProjectTypeGuid)] [InlineData("solution", "SlnFileWithNoProjectReferencesAndFSharpProject", "FSharpProject", "FSharpProject.fsproj", ProjectTypeGuids.FSharpProjectTypeGuid)] [InlineData("solution", "SlnFileWithNoProjectReferencesAndVBProject", "VBProject", "VBProject.vbproj", ProjectTypeGuids.VBProjectTypeGuid)] - [InlineData("solution", "SlnFileWithNoProjectReferencesAndUnknownProjectWithSingleProjectTypeGuid", "UnknownProject", "UnknownProject.unknownproj", "{130159A9-F047-44B3-88CF-0CF7F02ED50F}")] - [InlineData("solution", "SlnFileWithNoProjectReferencesAndUnknownProjectWithMultipleProjectTypeGuids", "UnknownProject", "UnknownProject.unknownproj", "{130159A9-F047-44B3-88CF-0CF7F02ED50F}")] + [InlineData("solution", "SlnFileWithNoProjectReferencesAndUnknownProjectWithSingleProjectTypeGuid", "UnknownProject", "UnknownProject.unknownproj", ProjectTypeGuids.DefaultProjectGuid)] + [InlineData("solution", "SlnFileWithNoProjectReferencesAndUnknownProjectWithMultipleProjectTypeGuids", "UnknownProject", "UnknownProject.unknownproj", ProjectTypeGuids.DefaultProjectGuid)] public async Task WhenPassedAProjectItAddsCorrectProjectTypeGuid( string solutionCommand, string testAsset, @@ -788,7 +789,7 @@ public async Task WhenPassedAProjectItAddsCorrectProjectTypeGuid( [InlineData("solution", ".sln")] [InlineData("sln", ".slnx")] [InlineData("solution", ".slnx")] - public void WhenPassedAProjectWithoutATypeGuidItErrors(string solutionCommand, string solutionExtension) + public void WhenPassedAProjectWithoutATypeGuidNorDefaultTypeGuidItErrors(string solutionCommand, string solutionExtension) { var solutionDirectory = _testAssetsManager .CopyTestAsset("SlnFileWithNoProjectReferencesAndUnknownProjectType", identifier: $"GivenDotnetSlnAdd-{solutionCommand}{solutionExtension}") @@ -814,6 +815,26 @@ public void WhenPassedAProjectWithoutATypeGuidItErrors(string solutionCommand, s .BeVisuallyEquivalentTo(contentBefore); } + [Theory] + [InlineData("sln", ".sln")] + [InlineData("solution", ".sln")] + [InlineData("sln", ".slnx")] + [InlineData("solution", ".slnx")] + public void WhenPassedAProjectWithDefaultProjectGuidItPasses(string solutionCommand, string solutionExtension) + { + var solutionDirectory = _testAssetsManager + .CopyTestAsset("TestAppWithSlnAndDefaultProjectType", identifier: $"GivenDotnetSlnAdd-{solutionCommand}{solutionExtension}") + .WithSource() + .Path; + + var cmd = new DotnetCommand(Log) + .WithWorkingDirectory(solutionDirectory) + .Execute(solutionCommand, $"App{solutionExtension}", "add", "Unknown.unknownproj"); + + cmd.Should().Pass(); + cmd.StdErr.Should().BeEmpty(); + } + [Theory] [InlineData("sln", ".sln")] [InlineData("solution", ".sln")]