Skip to content

Commit

Permalink
Added option for flat hierarchy. (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
jp2masa authored and jeffkl committed Aug 28, 2018
1 parent 762f77f commit ab1c3c4
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 44 deletions.
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Read more below to learn how to configure the behavior of SlnGen to fit your nee
| SlnGenUseShellExecute | Indicates whether or not the Visual Studio solution file should be opened by the registered file extension handler. You can disable this setting to use whatever `devenv.exe` is on your `PATH` or you can specify a full path to `devenve.exe` with the `SlnGenDevEnvFullPath` property. | `true` or `false` | `true` |
| SlnGenDevEnvFullPath | Specifies a full path to Visual Studio's `devenv.exe` to use when opening the solution file. By default, SlnGen will launch the program associated with the `.sln` file extension. However, in some cases you may want to specify a custom path to Visual Studio. | | |
| SlnGenCollectStats | If your projects are loading slowly, SlnGen can log a performance summary to help you understand why. You must specify an MSBuild logger verbosity of at least `Detailed` to see the summary in a log. | `true` or `false` | `false` |
| SlnGenFolders | Indicates whether or not solution folders should be created. | `true` or `false` | `true` |


Command-line argument
Expand Down
24 changes: 0 additions & 24 deletions src/SlnGen.Build.Tasks.UnitTests/ExtensionMethods.cs

This file was deleted.

22 changes: 18 additions & 4 deletions src/SlnGen.Build.Tasks.UnitTests/SlnFileTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,27 @@ public void SingleProject()
ValidateProjectInSolution(projectA);
}

private void ValidateProjectInSolution(Action<SlnProject, ProjectInSolution> customValidator, SlnProject[] projects)
[Fact]
public void NoFolders()
{
SlnProject[] projects = new SlnProject[]
{
new SlnProject(GetTempFileName(), "ProjectA", new Guid("C95D800E-F016-4167-8E1B-1D3FF94CE2E2"), new Guid("88152E7E-47E3-45C8-B5D3-DDB15B2F0435"), new[] { "Debug" }, new[] { "x64" }, isMainProject: true),
new SlnProject(GetTempFileName(), "ProjectB", new Guid("EAD108BE-AC70-41E6-A8C3-450C545FDC0E"), new Guid("F38341C3-343F-421A-AE68-94CD9ADCD32F"), new[] { "Debug" }, new[] { "x64" }, isMainProject: false),
new SlnProject(GetTempFileName(), "ProjectC", new Guid("00C5B0C0-E19C-48C5-818D-E8CD4FA2A915"), new Guid("F38341C3-343F-421A-AE68-94CD9ADCD32F"), new[] { "Debug" }, new[] { "x64" }, isMainProject: false)
};

ValidateProjectInSolution((s, p) => p.ParentProjectGuid.ShouldBe(null), projects, false);
}

private void ValidateProjectInSolution(Action<SlnProject, ProjectInSolution> customValidator, SlnProject[] projects, bool folders)
{
string solutionFilePath = GetTempFileName();

SlnFile slnFile = new SlnFile(projects);
SlnFile slnFile = new SlnFile();

slnFile.Save(solutionFilePath);
slnFile.AddProjects(projects);
slnFile.Save(solutionFilePath, folders);

MSBuildSolutionFile solutionFile = MSBuildSolutionFile.Parse(solutionFilePath);

Expand All @@ -86,7 +100,7 @@ private void ValidateProjectInSolution(Action<SlnProject, ProjectInSolution> cus

private void ValidateProjectInSolution(params SlnProject[] projects)
{
ValidateProjectInSolution(null, projects);
ValidateProjectInSolution(null, projects, false);
}
}
}
43 changes: 29 additions & 14 deletions src/SlnGen.Build.Tasks/Internal/SlnFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ internal sealed class SlnFile
/// <summary>
/// Gets the projects.
/// </summary>
private readonly IReadOnlyList<SlnProject> _projects;
private readonly List<SlnProject> _projects = new List<SlnProject>();

/// <summary>
/// A list of absolute paths to include as Solution Items.
Expand All @@ -36,18 +36,17 @@ internal sealed class SlnFile
/// </summary>
/// <param name="projects">The project collection.</param>
/// <param name="fileFormatVersion">The file format version.</param>
public SlnFile(IEnumerable<SlnProject> projects, string fileFormatVersion)
public SlnFile(string fileFormatVersion)
{
_projects = projects.ToList();
_fileFormatVersion = fileFormatVersion;
}

/// <summary>
/// Initializes a new instance of the <see cref="SlnFile" /> class.
/// </summary>
/// <param name="projects">The projects.</param>
public SlnFile(IEnumerable<SlnProject> projects)
: this(projects, "12.00")
public SlnFile()
: this("12.00")
{
}

Expand All @@ -56,6 +55,15 @@ public SlnFile(IEnumerable<SlnProject> projects)
/// </summary>
public IReadOnlyCollection<string> SolutionItems => _solutionItems;

/// <summary>
/// Adds the specified projects.
/// </summary>
/// <param name="projects">An <see cref="IEnumerable{SlnProject}"/> containing projects to add to the solution.</param>
public void AddProjects(IEnumerable<SlnProject> projects)
{
_projects.AddRange(projects);
}

/// <summary>
/// Adds the specified solution items.
/// </summary>
Expand All @@ -69,15 +77,16 @@ public void AddSolutionItems(IEnumerable<string> items)
/// Saves the Visual Studio solution to a file.
/// </summary>
/// <param name="path">The full path to the file to write to.</param>
public void Save(string path)
/// <param name="folders">Specifies if folders should be created.</param>
public void Save(string path, bool folders)
{
using (StreamWriter writer = File.CreateText(path))
{
Save(writer);
Save(writer, folders);
}
}

public void Save(TextWriter writer)
public void Save(TextWriter writer, bool folders)
{
writer.WriteLine(Header, _fileFormatVersion);

Expand All @@ -100,14 +109,19 @@ public void Save(TextWriter writer)
writer.WriteLine("EndProject");
}

SlnHierarchy hierarchy = SlnHierarchy.FromProjects(_projects);
SlnHierarchy hierarchy = null;

if (hierarchy.Folders.Count > 0)
if (folders)
{
foreach (SlnFolder folder in hierarchy.Folders)
hierarchy = SlnHierarchy.FromProjects(_projects);

if (hierarchy.Folders.Count > 0)
{
writer.WriteLine($@"Project(""{folder.ProjectTypeGuid.ToSolutionString()}"") = ""{folder.Name}"", ""{folder.FullPath}"", ""{folder.FolderGuid.ToSolutionString()}""");
writer.WriteLine("EndProject");
foreach (SlnFolder folder in hierarchy.Folders)
{
writer.WriteLine($@"Project(""{folder.ProjectTypeGuid.ToSolutionString()}"") = ""{folder.Name}"", ""{folder.FullPath}"", ""{folder.FolderGuid.ToSolutionString()}""");
writer.WriteLine("EndProject");
}
}
}

Expand Down Expand Up @@ -149,7 +163,8 @@ public void Save(TextWriter writer)

writer.WriteLine(" EndGlobalSection");

if (_projects.Count > 1)
if (folders
&& _projects.Count > 1)
{
writer.WriteLine(@" GlobalSection(NestedProjects) = preSolution");
foreach (KeyValuePair<Guid, Guid> nestedProject in hierarchy.Hierarchy)
Expand Down
13 changes: 11 additions & 2 deletions src/SlnGen.Build.Tasks/SlnGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ public class SlnGen : TaskBase
/// </summary>
public bool UseShellExecute { get; set; }

/// <summary>
/// Gets or sets a value indicating whether folders should be created.
/// </summary>
public bool Folders { get; set; }

/// <summary>
/// Checks whether a project should be included in the solution or not.
/// </summary>
Expand Down Expand Up @@ -213,11 +218,15 @@ private void GenerateSolutionFile(ICollection<Project> projects)
}
}

SlnFile solution = new SlnFile(projects.Where(ShouldIncludeInSolution).Select(p => SlnProject.FromProject(p, customProjectTypeGuids, p.FullPath == ProjectFullPath)));
SlnFile solution = new SlnFile();

solution.AddProjects(
projects.Where(ShouldIncludeInSolution)
.Select(p => SlnProject.FromProject(p, customProjectTypeGuids, p.FullPath == ProjectFullPath)));

solution.AddSolutionItems(GetSolutionItems());

solution.Save(SolutionFileFullPath);
solution.Save(SolutionFileFullPath, Folders);
}

private IDictionary<string, string> GetGlobalProperties()
Expand Down
1 change: 1 addition & 0 deletions src/SlnGen.Build.Tasks/build/SlnGen.targets
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
CollectStats="$([MSBuild]::ValueOrDefault('$(SlnGenCollectStats)', 'false'))"
CustomProjectTypeGuids="@(SlnGenCustomProjectTypeGuid)"
DevEnvFullPath="$(SlnGenDevEnvFullPath)"
Folders="$([MSBuild]::ValueOrDefault('$(SlnGenFolders)', 'true'))"
GlobalProperties="$(SlnGenGlobalProperties)"
GlobalPropertiesToRemove="$(SlnGenGlobalPropertiesToRemove)"
InheritGlobalProperties="$([MSBuild]::ValueOrDefault('$(SlnGenInheritGlobalProperties)', 'true'))"
Expand Down

0 comments on commit ab1c3c4

Please sign in to comment.