Skip to content

Commit cd31d68

Browse files
added .slnx support (#370)
close #365
1 parent 02469f2 commit cd31d68

File tree

5 files changed

+97
-30
lines changed

5 files changed

+97
-30
lines changed

global.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"sdk": {
3-
"version": "8.0.100",
4-
"rollForward": "latestMajor"
3+
"version": "9.0.200",
4+
"rollForward": "major"
55
}
66
}

src/Incrementalist.Tests/Commands/RunDotNetCommandTaskTests.cs

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -119,18 +119,20 @@ public async Task Should_Execute_Full_Solution_Build()
119119
var solutionPath = Path.Combine(_repository.BasePath, "test.sln");
120120

121121
// Create a minimal valid solution file
122-
var solutionContent = @"
123-
Microsoft Visual Studio Solution File, Format Version 12.00
124-
# Visual Studio Version 17
125-
VisualStudioVersion = 17.0.31903.59
126-
MinimumVisualStudioVersion = 10.0.40219.1
127-
Global
128-
GlobalSection(SolutionConfigurationPlatforms) = preSolution
129-
Debug|Any CPU = Debug|Any CPU
130-
Release|Any CPU = Release|Any CPU
131-
EndGlobalSection
132-
EndGlobal";
133-
File.WriteAllText(solutionPath, solutionContent);
122+
const string solutionContent = """
123+
124+
Microsoft Visual Studio Solution File, Format Version 12.00
125+
# Visual Studio Version 17
126+
VisualStudioVersion = 17.0.31903.59
127+
MinimumVisualStudioVersion = 10.0.40219.1
128+
Global
129+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
130+
Debug|Any CPU = Debug|Any CPU
131+
Release|Any CPU = Release|Any CPU
132+
EndGlobalSection
133+
EndGlobal
134+
""";
135+
await File.WriteAllTextAsync(solutionPath, solutionContent);
134136

135137
var task = new RunDotNetCommandTask(settings, _logger, new[] { "build", "-c", "Release", "--nologo" }, true, false);
136138

@@ -140,5 +142,39 @@ public async Task Should_Execute_Full_Solution_Build()
140142
// Assert
141143
Assert.Equal(0, result);
142144
}
145+
146+
[Fact] public async Task Should_Execute_Full_Slnx_Build()
147+
{
148+
// Arrange
149+
var settings = new BuildSettings("master", "test.slnx", _repository.BasePath);
150+
var solutionPath = Path.Combine(_repository.BasePath, "test.slnx");
151+
152+
// Create a minimal valid solution file
153+
const string solutionContent = """
154+
<Solution>
155+
<Project Path="src/Akka.Console/Akka.Console.csproj" />
156+
</Solution>
157+
""";
158+
await File.WriteAllTextAsync(solutionPath, solutionContent);
159+
Directory.CreateDirectory(Path.Combine(_repository.BasePath, "src"));
160+
Directory.CreateDirectory(Path.Combine(_repository.BasePath, "src", "Akka.Console"));
161+
var projectPath = Path.Combine(_repository.BasePath, "src", "Akka.Console", "Akka.Console.csproj");
162+
await File.WriteAllTextAsync(projectPath, """
163+
<Project Sdk="Microsoft.NET.Sdk">
164+
<PropertyGroup>
165+
<TargetFramework>net8.0</TargetFramework>
166+
<OutputType>Library</OutputType>
167+
</PropertyGroup>
168+
</Project>
169+
""");
170+
171+
var task = new RunDotNetCommandTask(settings, _logger, ["build", "-c", "Release", "--nologo"], true, false);
172+
173+
// Act
174+
var result = await task.Run(new FullSolutionBuildResult(solutionPath));
175+
176+
// Assert
177+
Assert.Equal(0, result);
178+
}
143179
}
144180
}

src/Incrementalist.Tests/Incrementalist.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net8.0</TargetFramework>
4+
<TargetFramework>net9.0</TargetFramework>
55
<IsPackable>false</IsPackable>
66
</PropertyGroup>
77

src/Incrementalist.Tests/ProjectSystem/SolutionFinderSpecs.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,35 @@ public void Should_Find_Single_Solution()
4444
Assert.Single(solutions ?? []);
4545
Assert.EndsWith("MySolution.sln", solutions.First());
4646
}
47+
48+
/// <summary>
49+
/// https://github.com/petabridge/Incrementalist/issues/365
50+
/// </summary>
51+
[Fact(DisplayName = "Should .slnx solution in root directory")]
52+
public void Should_Find_Slnx_Solution()
53+
{
54+
// Arrange
55+
const string solutionContent = """
56+
<Solution>
57+
<Folder Name="/build/">
58+
<File Path="Directory.Build.props" />
59+
<File Path="Directory.Packages.props" />
60+
<File Path="global.json" />
61+
<File Path="NuGet.Config" />
62+
<File Path="README.md" />
63+
</Folder>
64+
<Project Path="src/Akka.Console/Akka.Console.csproj" />
65+
</Solution>
66+
""";
67+
_repository.WriteFile("MySolution.slnx", solutionContent);
68+
69+
// Act
70+
var solutions = SolutionFinder.GetSolutions(_repository.BasePath).ToList();
71+
72+
// Assert
73+
Assert.Single(solutions ?? []);
74+
Assert.EndsWith("MySolution.slnx", solutions.First());
75+
}
4776

4877
[Fact(DisplayName = "Should find multiple solutions in root directory")]
4978
public void Should_Find_Multiple_Solutions()

src/Incrementalist/ProjectSystem/SolutionFinder.cs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,33 @@
1111
namespace Incrementalist.ProjectSystem
1212
{
1313
/// <summary>
14-
/// Used to look for .sln files in a given directory.
14+
/// Used to look for .sln and .slnx files in a given directory.
1515
/// </summary>
1616
public static class SolutionFinder
1717
{
1818
/// <summary>
19-
/// The default filter used to look for solutions in a given folder.
20-
/// </summary>
21-
public const string DefaultSolutionFilter = "*.sln";
22-
23-
/// <summary>
24-
/// Enumerate all of the MSBuild solution files in a given folder.
19+
/// Enumerate all of the MSBuild solution files (.sln and .slnx) in a given folder.
2520
/// </summary>
2621
/// <param name="folderPath">The top level path to search.</param>
27-
/// <param name="searchFilter">Optional. A wildcard filter in the form of "*.sln".</param>
28-
/// <param name="searchOption">Optional. Specifies whether to recurse sub-directories or not.</param>
29-
/// <returns>If any solutions are found, will return an enumerable list of them in order in which they are discovered.</returns>
22+
/// <param name="searchFilter">Optional. A wildcard filter, e.g., "*.sln". If null or empty, defaults to searching for both "*.sln" and "*.slnx".</param>
23+
/// <param name="searchOption">Optional. Specifies whether to recurse sub-directories or not. Defaults to <see cref="SearchOption.AllDirectories"/>.</param>
24+
/// <returns>If any solutions are found, will return an enumerable list of their paths, ordered by filename.</returns>
3025
public static IEnumerable<string> GetSolutions(string folderPath, string searchFilter = null,
3126
SearchOption? searchOption = null)
3227
{
33-
if (string.IsNullOrEmpty(searchFilter))
34-
return Directory.EnumerateFileSystemEntries(folderPath, DefaultSolutionFilter,
35-
searchOption ?? SearchOption.AllDirectories).OrderBy(Path.GetFileName);
28+
var finalSearchOption = searchOption ?? SearchOption.AllDirectories;
3629

37-
return Directory.EnumerateFileSystemEntries(folderPath, searchFilter,
38-
searchOption ?? SearchOption.AllDirectories).OrderBy(Path.GetFileName);
30+
if (string.IsNullOrEmpty(searchFilter))
31+
{
32+
// Search for both .sln and .slnx if no specific filter is provided
33+
var slnFiles = Directory.EnumerateFileSystemEntries(folderPath, "*.sln", finalSearchOption);
34+
var slnxFiles = Directory.EnumerateFileSystemEntries(folderPath, "*.slnx", finalSearchOption);
35+
return slnFiles.Concat(slnxFiles).OrderBy(Path.GetFileName);
36+
}
37+
38+
// Use the provided search filter
39+
return Directory.EnumerateFileSystemEntries(folderPath, searchFilter, finalSearchOption)
40+
.OrderBy(Path.GetFileName);
3941
}
4042
}
4143
}

0 commit comments

Comments
 (0)