Skip to content

Commit

Permalink
Respect user specified platform and configuration #11 (#17)
Browse files Browse the repository at this point in the history
* Respect user specified platform and configuration #11

* Fix extension method name

* remove unused code

* Revert sln.cmd change
  • Loading branch information
amrmahdi authored Feb 16, 2018
1 parent 4eceb2b commit a8c080c
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 28 deletions.
26 changes: 20 additions & 6 deletions src/SlnGen.Build.Tasks.UnitTests/SlnFileTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,32 @@

namespace SlnGen.Build.Tasks.UnitTests
{
using System.Collections;
using System.Collections.Generic;
using System.Linq;

[TestFixture]
public class SlnFileTests : TestBase
{
// TODO: Test hierarchy
// TODO: Test configurations and platforms

[Test]
public void LotsOfProjects()
{
const int projectCount = 1000;

SlnProject[] projects = new SlnProject[projectCount];

var configurations = new[] { "Debug", "Release" };
var platforms = new[] { "x64", "x86", "Any CPU", "amd64" };

var randomGenerator = new Random(Guid.NewGuid().GetHashCode());

for (int i = 0; i < projectCount; i++)
{
projects[i] = new SlnProject(GetTempFileName(), $"Project{i:D6}", Guid.NewGuid().ToSolutionString(), Guid.NewGuid().ToSolutionString(), isMainProject: i == 0);
// pick random and shuffled configurations and platforms
var projectConfigurations = configurations.OrderBy(a => Guid.NewGuid()).Take(randomGenerator.Next(1, configurations.Length)).ToList();
var projectPlatforms = platforms.OrderBy(a => Guid.NewGuid()).Take(randomGenerator.Next(1, platforms.Length)).ToList();
projects[i] = new SlnProject(GetTempFileName(), $"Project{i:D6}", Guid.NewGuid().ToSolutionString(), Guid.NewGuid().ToSolutionString(), projectConfigurations, projectPlatforms, isMainProject: i == 0);
}

ValidateProjectInSolution(projects);
Expand All @@ -31,16 +41,16 @@ public void LotsOfProjects()
[Test]
public void MultipleProjects()
{
SlnProject projectA = new SlnProject(GetTempFileName(), "ProjectA", "C95D800E-F016-4167-8E1B-1D3FF94CE2E2", "88152E7E-47E3-45C8-B5D3-DDB15B2F0435", isMainProject: true);
SlnProject projectB = new SlnProject(GetTempFileName(), "ProjectB", "EAD108BE-AC70-41E6-A8C3-450C545FDC0E", "F38341C3-343F-421A-AE68-94CD9ADCD32F", isMainProject: false);
SlnProject projectA = new SlnProject(GetTempFileName(), "ProjectA", "C95D800E-F016-4167-8E1B-1D3FF94CE2E2", "88152E7E-47E3-45C8-B5D3-DDB15B2F0435", new[] { "Debug" }, new[] { "x64" }, isMainProject: true);
SlnProject projectB = new SlnProject(GetTempFileName(), "ProjectB", "EAD108BE-AC70-41E6-A8C3-450C545FDC0E", "F38341C3-343F-421A-AE68-94CD9ADCD32F", new[] { "Debug" }, new[] { "x64" }, isMainProject: false);

ValidateProjectInSolution(projectA, projectB);
}

[Test]
public void SingleProject()
{
SlnProject projectA = new SlnProject(GetTempFileName(), "ProjectA", "C95D800E-F016-4167-8E1B-1D3FF94CE2E2", "88152E7E-47E3-45C8-B5D3-DDB15B2F0435", isMainProject: true);
SlnProject projectA = new SlnProject(GetTempFileName(), "ProjectA", "C95D800E-F016-4167-8E1B-1D3FF94CE2E2", "88152E7E-47E3-45C8-B5D3-DDB15B2F0435", new[] { "Debug" }, new[] { "x64" }, isMainProject: true);

ValidateProjectInSolution(projectA);
}
Expand All @@ -65,6 +75,10 @@ private void ValidateProjectInSolution(Action<SlnProject, ProjectInSolution> cus
projectInSolution.ProjectGuid.ShouldBe(slnProject.ProjectGuid);
projectInSolution.ProjectName.ShouldBe(slnProject.Name);

var configurationPlatforms = from configuration in slnProject.Configurations from platform in slnProject.Platforms select $"{configuration}|{platform}";

CollectionAssert.AreEquivalent(projectInSolution.ProjectConfigurations.Keys, configurationPlatforms);

customValidator?.Invoke(slnProject, projectInSolution);
}
}
Expand Down
19 changes: 19 additions & 0 deletions src/SlnGen.Build.Tasks/ExtensionMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

namespace SlnGen.Build.Tasks
{
using System.Collections.Generic;

internal static class ExtensionMethods
{
#region Types used for getting to internal properties of the MSBuild API
Expand Down Expand Up @@ -76,6 +78,23 @@ public static string GetPropertyValueOrDefault(this Project project, string name
return value == String.Empty ? defaultValue : value;
}

/// <summary>
/// Gets the value of the given conditioned property in this project.
/// </summary>
/// <param name="project">The <see cref="Project"/> to get the property value from.</param>
/// <param name="name">The name of the property to get the value of.</param>
/// <param name="defaultValue">A default values comma separated to return in the case when the property has no value.</param>
/// <returns>The values of the property if one exists, otherwise the default value specified.</returns>
public static IEnumerable<string> GetConditionedPropertyValuesOrDefault(this Project project, string name, string defaultValue)
{
if (!project.ConditionedProperties.ContainsKey(name))
{
return defaultValue.Split(',');
}

return project.ConditionedProperties[name];
}

/// <summary>
/// Returns the absolute path for the specified path string in the correct case according to the file system.
/// </summary>
Expand Down
35 changes: 15 additions & 20 deletions src/SlnGen.Build.Tasks/Internal/SlnFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,11 @@ internal sealed class SlnFile
/// </summary>
private const string Header = "Microsoft Visual Studio Solution File, Format Version {0}";

/// <summary>
/// The configurations
/// </summary>
private readonly string[] _configurations;

/// <summary>
/// The file format version
/// </summary>
private readonly string _fileFormatVersion;

/// <summary>
/// The platforms
/// </summary>
private readonly string[] _platforms;

/// <summary>
/// Gets the projects.
/// </summary>
Expand All @@ -41,23 +31,20 @@ internal sealed class SlnFile
/// Initializes a new instance of the <see cref="SlnFile" /> class.
/// </summary>
/// <param name="projects">The project collection.</param>
/// <param name="configurations">The configurations.</param>
/// <param name="platforms">The platforms.</param>
/// <param name="fileFormatVersion">The file format version.</param>
public SlnFile(IEnumerable<SlnProject> projects, string[] configurations, string[] platforms, string fileFormatVersion)
public SlnFile(IEnumerable<SlnProject> projects, string fileFormatVersion)
{
_projects = projects.ToList();
_configurations = configurations;
_platforms = platforms;
_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, new[] {"Debug", "Release"}, new[] {"Any CPU"}, "12.00")
: this(projects, "12.00")
{
}

Expand Down Expand Up @@ -104,6 +91,7 @@ public void Save(TextWriter writer)
{
writer.WriteLine($" {solutionItem} = {solutionItem}");
}

writer.WriteLine(" EndProjectSection");
writer.WriteLine("EndProject");
}
Expand All @@ -122,27 +110,33 @@ public void Save(TextWriter writer)
writer.WriteLine("Global");

writer.WriteLine(" GlobalSection(SolutionConfigurationPlatforms) = preSolution");
foreach (string configuration in _configurations)

IEnumerable<string> globalConfigurations = new HashSet<string>(_projects.SelectMany(p => p.Configurations)).Distinct();
IEnumerable<string> globalPlatforms = new HashSet<string>(_projects.SelectMany(p => p.Platforms)).Distinct();

foreach (string configuration in globalConfigurations)
{
foreach (string platform in _platforms)
foreach (string platform in globalPlatforms)
{
writer.WriteLine($" {configuration}|{platform} = {configuration}|{platform}");
}
}

writer.WriteLine(" EndGlobalSection");

writer.WriteLine(" GlobalSection(ProjectConfigurationPlatforms) = preSolution");
foreach (SlnProject project in _projects)
{
foreach (string configuration in _configurations)
foreach (string configuration in project.Configurations)
{
foreach (string platform in _platforms)
foreach (string platform in project.Platforms)
{
writer.WriteLine($@" {project.ProjectGuid}.{configuration}|{platform}.ActiveCfg = {configuration}|{platform}");
writer.WriteLine($@" {project.ProjectGuid}.{configuration}|{platform}.Build.0 = {configuration}|{platform}");
}
}
}

writer.WriteLine(" EndGlobalSection");

if (_projects.Count > 1)
Expand All @@ -152,6 +146,7 @@ public void Save(TextWriter writer)
{
writer.WriteLine($@" {nestedProject.Key} = {nestedProject.Value}");
}

writer.WriteLine(" EndGlobalSection");
}

Expand Down
13 changes: 11 additions & 2 deletions src/SlnGen.Build.Tasks/Internal/SlnProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ internal sealed class SlnProject
{".wixproj", "930C7802-8A8C-48F9-8165-68863BCCD9DD"},
};

public SlnProject([NotNull] string fullPath, [NotNull] string name, [NotNull] string projectGuid, [NotNull] string projectTypeGuid, bool isMainProject)
public SlnProject([NotNull] string fullPath, [NotNull] string name, [NotNull] string projectGuid, [NotNull] string projectTypeGuid, [NotNull] IEnumerable<string> configurations, [NotNull] IEnumerable<string> platforms, bool isMainProject)
{
FullPath = fullPath ?? throw new ArgumentNullException(nameof(fullPath));
Name = name ?? throw new ArgumentNullException(nameof(name));
ProjectGuid = projectGuid ?? throw new ArgumentNullException(nameof(projectGuid));
ProjectTypeGuid = projectTypeGuid ?? throw new ArgumentNullException(nameof(projectTypeGuid));
IsMainProject = isMainProject;
Configurations = configurations;
Platforms = platforms;
}

public string FullPath { get; }
Expand All @@ -46,6 +48,10 @@ public SlnProject([NotNull] string fullPath, [NotNull] string name, [NotNull] st

public string ProjectTypeGuid { get; }

public IEnumerable<string> Configurations { get; }

public IEnumerable<string> Platforms { get; }

[NotNull]
public static SlnProject FromProject([NotNull] Project project, [NotNull] IReadOnlyDictionary<string, string> customProjectTypeGuids, bool isMainProject = false)
{
Expand All @@ -72,9 +78,12 @@ public static SlnProject FromProject([NotNull] Project project, [NotNull] IReadO
projectTypeGuid = DefaultProjectTypeGuid;
}

IEnumerable<string> configurations = project.GetConditionedPropertyValuesOrDefault("Configuration", "Debug");
IEnumerable<string> platforms = project.GetConditionedPropertyValuesOrDefault("Platform", "x64");

string projectGuid = isLegacyProjectSystem ? project.GetPropertyValueOrDefault(ProjectGuidPropertyName, Guid.NewGuid().ToSolutionString()) : Guid.NewGuid().ToSolutionString();

return new SlnProject(project.FullPath, name, projectGuid, projectTypeGuid, isMainProject);
return new SlnProject(project.FullPath, name, projectGuid, projectTypeGuid, configurations, platforms, isMainProject);
}
}
}

0 comments on commit a8c080c

Please sign in to comment.