Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#592 Support for generating a solution with all project not built by default #593

Merged
merged 1 commit into from
Aug 26, 2024
Merged
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
62 changes: 62 additions & 0 deletions src/Microsoft.VisualStudio.SlnGen.UnitTests/SlnFileTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,68 @@ public void PathsWorkForAllDirectorySeparatorChars()
actualSolutionText.ShouldBe(solutionText, StringCompareShould.IgnoreLineEndings);
}

[Fact]
public void ProjectsNotBuildable()
{
const string solutionText = @"Microsoft Visual Studio Solution File, Format Version 12.00
Project(""{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"") = ""ProjectA"", ""ProjectA\ProjectA.csproj"", ""{E859E866-96F9-474E-A1EA-6539385AD236}""
EndProject
Project(""{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"") = ""ProjectB"", ""ProjectB\ProjectB.csproj"", ""{893607F9-C204-4CB2-8BF2-1F71B4198CD2}""
EndProject
Project(""{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"") = ""ProjectC"", ""ProjectC\ProjectC.csproj"", ""{081A3445-4E74-4AE9-95B6-FF564FE70CA3}""
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E859E866-96F9-474E-A1EA-6539385AD236}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E859E866-96F9-474E-A1EA-6539385AD236}.Release|Any CPU.ActiveCfg = Release|Any CPU
{893607F9-C204-4CB2-8BF2-1F71B4198CD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{893607F9-C204-4CB2-8BF2-1F71B4198CD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{081A3445-4E74-4AE9-95B6-FF564FE70CA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{081A3445-4E74-4AE9-95B6-FF564FE70CA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AA784BCF-D76D-4DD7-91D2-79E6A14A4DE2}
EndGlobalSection
EndGlobal
";

string solutionFileFullPath = GetTempFileName(".sln");

File.WriteAllText(solutionFileFullPath, solutionText);

ProgramArguments programArguments = new ProgramArguments
{
LaunchVisualStudio = new[] { bool.FalseString },
SolutionFileFullPath = new[] { solutionFileFullPath },
Property = new[] { $"{MSBuildPropertyNames.SlnGenIsBuildable}={bool.FalseString};" },
};

Project[] projects =
{
ProjectCreator.Templates.SdkCsproj(path: GetTempProjectFile("ProjectA"))
.Save(),
ProjectCreator.Templates.SdkCsproj(path: GetTempProjectFile("ProjectB"))
.Save(),
ProjectCreator.Templates.SdkCsproj(path: GetTempProjectFile("ProjectC"))
.Save(),
};

TestLogger testLogger = new TestLogger();

(string _, int customProjectTypeGuidCount, int solutionItemCount, Guid solutionGuid) = SlnFile.GenerateSolutionFile(programArguments, projects, testLogger);

string actualSolutionText = File.ReadAllText(solutionFileFullPath);

actualSolutionText.ShouldBe(solutionText, StringCompareShould.IgnoreLineEndings);
}

[Fact]
public void TestSlnGenProjectNamePropertyForSolutionName()
{
Expand Down
14 changes: 12 additions & 2 deletions src/Microsoft.VisualStudio.SlnGen.UnitTests/SlnProjectTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ public void GetProjectGuidSdkProject()
Guid.TryParse(actualProject.ProjectGuid.ToSolutionString(), out _).ShouldBeTrue();
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void GetIsBuildable(bool isBuildable)
{
SlnProject actualProject = CreateAndValidateProject(isBuildable: isBuildable);

actualProject.IsBuildable.ShouldBe(isBuildable);
}

[Theory]
[InlineData("")]
[InlineData(ProjectFileExtensions.CSharp)]
Expand Down Expand Up @@ -394,7 +404,7 @@ private static void ValidateParseCustomProjectTypeGuids(Project project, string
actualProjectTypeGuid.Value.ShouldBe(expectedProjectTypeGuid);
}

private SlnProject CreateAndValidateProject(bool isMainProject = false, string expectedGuid = null, string extension = ProjectFileExtensions.CSharp, IDictionary<string, string> globalProperties = null, string isDeployable = null)
private SlnProject CreateAndValidateProject(bool isMainProject = false, string expectedGuid = null, string extension = ProjectFileExtensions.CSharp, IDictionary<string, string> globalProperties = null, string isDeployable = null, bool isBuildable = true)
{
if (!isDeployable.IsNullOrWhiteSpace())
{
Expand All @@ -405,7 +415,7 @@ private SlnProject CreateAndValidateProject(bool isMainProject = false, string e

Project expectedProject = CreateProject(expectedGuid, extension, globalProperties);

SlnProject actualProject = SlnProject.FromProject(expectedProject, new Dictionary<string, Guid>(), isMainProject);
SlnProject actualProject = SlnProject.FromProject(expectedProject, new Dictionary<string, Guid>(), isMainProject, isBuildable);

actualProject.FullPath.ShouldBe(expectedProject.FullPath);

Expand Down
5 changes: 5 additions & 0 deletions src/Microsoft.VisualStudio.SlnGen/MSBuildPropertyNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,5 +119,10 @@ public static class MSBuildPropertyNames
/// Represents the UsingMicrosoftNETSdk property.
/// </summary>
public const string UsingMicrosoftNETSdk = nameof(UsingMicrosoftNETSdk);

/// <summary>
/// Represents the SlnGenIsBuildable property.
/// </summary>
public const string SlnGenIsBuildable = nameof(SlnGenIsBuildable);
}
}
13 changes: 10 additions & 3 deletions src/Microsoft.VisualStudio.SlnGen/SlnFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,13 @@ public static (string solutionFileFullPath, int customProjectTypeGuidCount, int
arguments.LoadProjectsInVisualStudio = new[] { bool.TrueString };
}

solution.AddProjects(projectList, customProjectTypeGuids, arguments.IgnoreMainProject ? null : firstProject.FullPath);
bool isBuildable = true;
if (arguments.GetGlobalProperties().TryGetValue(MSBuildPropertyNames.SlnGenIsBuildable, out string isBuildableString))
{
isBuildable = bool.TrueString.Equals(isBuildableString, StringComparison.OrdinalIgnoreCase);
}

solution.AddProjects(projectList, customProjectTypeGuids, arguments.IgnoreMainProject ? null : firstProject.FullPath, isBuildable);

solution.AddSolutionItems(solutionItems);

Expand Down Expand Up @@ -333,12 +339,13 @@ public void AddProjects(IEnumerable<SlnProject> projects)
/// <param name="projects">An <see cref="IEnumerable{T}" /> of projects to add.</param>
/// <param name="customProjectTypeGuids">An <see cref="IReadOnlyDictionary{TKey,TValue}" /> containing any custom project type GUIDs to use.</param>
/// <param name="mainProjectFullPath">Optional full path to the main project.</param>
public void AddProjects(IEnumerable<Project> projects, IReadOnlyDictionary<string, Guid> customProjectTypeGuids, string mainProjectFullPath = null)
/// <param name="isBuildable">Indicates whether the projects are buildable.</param>
public void AddProjects(IEnumerable<Project> projects, IReadOnlyDictionary<string, Guid> customProjectTypeGuids, string mainProjectFullPath = null, bool isBuildable = true)
{
_projects.AddRange(
projects
.Distinct(new EqualityComparer<Project>((x, y) => string.Equals(x.FullPath, y.FullPath, StringComparison.OrdinalIgnoreCase), i => i.FullPath.GetHashCode()))
.Select(i => SlnProject.FromProject(i, customProjectTypeGuids, string.Equals(i.FullPath, mainProjectFullPath, StringComparison.OrdinalIgnoreCase)))
.Select(i => SlnProject.FromProject(i, customProjectTypeGuids, string.Equals(i.FullPath, mainProjectFullPath, StringComparison.OrdinalIgnoreCase), isBuildable))
.Where(i => i != null));
}

Expand Down
4 changes: 3 additions & 1 deletion src/Microsoft.VisualStudio.SlnGen/SlnProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,9 @@ public sealed class SlnProject
/// <param name="project">The <see cref="Project " /> from MSBuild to create a solution project for.</param>
/// <param name="customProjectTypeGuids"><see cref="IReadOnlyDictionary{String,Guid}" /> containing custom project type GUIDs.</param>
/// <param name="isMainProject">Indicates whether this project is the main project in the solution.</param>
/// <param name="isBuildable">Indicates whether this project is buildable.</param>
/// <returns>A <see cref="SlnProject" /> for the specified MSBuild project.</returns>
public static SlnProject FromProject(Project project, IReadOnlyDictionary<string, Guid> customProjectTypeGuids, bool isMainProject = false)
public static SlnProject FromProject(Project project, IReadOnlyDictionary<string, Guid> customProjectTypeGuids, bool isMainProject = false, bool isBuildable = true)
{
if (project == null)
{
Expand Down Expand Up @@ -193,6 +194,7 @@ public static SlnProject FromProject(Project project, IReadOnlyDictionary<string
ProjectTypeGuid = GetProjectTypeGuid(projectFileExtension, isUsingMicrosoftNETSdk, customProjectTypeGuids),
SharedProjectItems = sharedProjectItemPaths.Any() ? sharedProjectItemPaths : Array.Empty<string>(),
SolutionFolder = project.GetPropertyValueOrDefault(MSBuildPropertyNames.SlnGenSolutionFolder, string.Empty),
IsBuildable = isBuildable,
};
}

Expand Down