Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/Cli/dotnet/Commands/Solution/Add/SolutionAddCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,17 @@ public override int Execute()
relativeSolutionFolderPath = _solutionFolderPath;
}

return string.IsNullOrEmpty(relativeSolutionFolderPath)
? null
: solution.AddFolder(GetSolutionFolderPathWithForwardSlashes(relativeSolutionFolderPath));
if (string.IsNullOrEmpty(relativeSolutionFolderPath))
{
return null;
}

// Check if a solution folder with this path already exists
// Solution folder paths should be unique, so use SingleOrDefault
var solutionFolderPath = GetSolutionFolderPathWithForwardSlashes(relativeSolutionFolderPath);
var existingFolder = solution.SolutionFolders.SingleOrDefault(f => f.Path == solutionFolderPath);

return existingFolder ?? solution.AddFolder(solutionFolderPath);
}

private async Task AddProjectsToSolutionAsync(IEnumerable<string> projectPaths, CancellationToken cancellationToken)
Expand Down
40 changes: 40 additions & 0 deletions test/dotnet.Tests/CommandTests/Solution/Add/GivenDotnetSlnAdd.cs
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,46 @@ public void WhenDirectoryContainsMultipleProjectsItCancelsWholeOperation(string
.Should().BeVisuallyEquivalentTo(contentBefore);
}

[Theory]
[InlineData("sln", ".sln")]
[InlineData("solution", ".sln")]
[InlineData("sln", ".slnx")]
[InlineData("solution", ".slnx")]
public async Task WhenMultipleProjectsFromSameDirectoryAreAddedSolutionFolderIsNotDuplicated(string solutionCommand, string solutionExtension)
{
var projectDirectory = _testAssetsManager
.CopyTestAsset("TestAppWithSlnAndCsprojFiles", identifier: $"GivenDotnetSlnAdd-{solutionCommand}{solutionExtension}")
.WithSource()
.Path;

var firstProject = Path.Combine("Multiple", "First.csproj");
var secondProject = Path.Combine("Multiple", "Second.csproj");
var cmd = new DotnetCommand(Log)
.WithWorkingDirectory(projectDirectory)
.Execute(solutionCommand, $"App{solutionExtension}", "add", firstProject, secondProject);
cmd.Should().Pass();

ISolutionSerializer serializer = SolutionSerializers.GetSerializerByMoniker(Path.Combine(projectDirectory, $"App{solutionExtension}"));
SolutionModel solution = await serializer.OpenAsync(Path.Combine(projectDirectory, $"App{solutionExtension}"), CancellationToken.None);

// The solution already has App project, plus we added First and Second = 3 total
var projectsInSolution = solution.SolutionProjects.ToList();
projectsInSolution.Count.Should().Be(3);
projectsInSolution.Should().Contain(p => p.FilePath.Contains("First.csproj"));
projectsInSolution.Should().Contain(p => p.FilePath.Contains("Second.csproj"));

// Should only have one solution folder for "Multiple", not two
var solutionFolders = solution.SolutionFolders.ToList();
solutionFolders.Count.Should().Be(1);
solutionFolders.Single().Path.Should().Contain("Multiple");

// Both new projects should be in the same solution folder
var solutionFolder = solutionFolders.Single();
var multipleProjects = projectsInSolution.Where(p => p.FilePath.Contains("Multiple")).ToList();
multipleProjects.Count.Should().Be(2);
multipleProjects.All(p => p.Parent?.Id == solutionFolder.Id).Should().BeTrue();
}

[Theory]
[InlineData("sln", ".sln")]
[InlineData("solution", ".sln")]
Expand Down
Loading