Skip to content

Commit

Permalink
Use property values along with ConditionedProperties to determine the…
Browse files Browse the repository at this point in the history
… configurations/platforms to use (#18)

* Use property values along with ConditionedProperties to determine the configurations/platforms to use

* Update test file path

* Resolve test failure

* Attempt to fix unit tests

Sort actual to match sorted expected

Use a Hashset to dedupe values?

* Copy SampleProject to %TEMP% for isolation

* Remove/restore some environment variables (Platform/Configuration) because CI environment sets them
  • Loading branch information
amrmahdi authored Feb 26, 2018
1 parent a8c080c commit 43364a2
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<Name>Microsoft.Build.Framework</Name>
<Private>true</Private>
</Reference>
<Reference Include="Microsoft.Build.Utilities.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="System" />
<Reference Include="System.Xml" />
</ItemGroup>
Expand Down Expand Up @@ -76,5 +77,10 @@
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Content Include="TestFiles\SampleProject.csproj">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
110 changes: 110 additions & 0 deletions src/SlnGen.Build.Tasks.UnitTests/SlnProjectTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
using SlnGen.Build.Tasks.Internal;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SlnGen.Build.Tasks.UnitTests
{
using System.IO;

[TestFixture]
public class SlnProjectTests : TestBase
{
Expand Down Expand Up @@ -74,6 +77,57 @@ public void UseFileName()
CreateAndValidateProject(expectedGuid: "DE681393-7151-459D-862C-918CCD2CB371");
}

[Test]
public void ConfigurationsAndPlatforms()
{
using (TestProject testProject = TestProject.Create())
{
SlnProject slnProject = SlnProject.FromProject(testProject.Project, new Dictionary<string, string>(), true);

slnProject.Configurations.OrderBy(i => i).ShouldBe(new[]
{
"Debug",
"Release"
});

slnProject.Platforms.OrderBy(i => i).ShouldBe(new[]
{
"amd64",
"AnyCPU",
"x64"
});
}
}

[Test]
public void ConfigurationsAndPlatformsWithGlobalProperties()
{
Dictionary<string, string> globalProperties = new Dictionary<string, string>
{
["Configuration"] = "Mix",
["Platform"] = "x86"
};

using (TestProject testProject = TestProject.Create(globalProperties))
{
SlnProject slnProject = SlnProject.FromProject(testProject.Project, new Dictionary<string, string>(), true);

slnProject.Configurations.OrderBy(i => i).ShouldBe(new[]
{
"Debug",
"Mix",
"Release"
});

slnProject.Platforms.OrderBy(i => i).ShouldBe(new[]
{
"amd64",
"AnyCPU",
"x86",
});
}
}

private SlnProject CreateAndValidateProject(bool isMainProject = false, string expectedGuid = null, string expectedName = null, string extension = ".csproj", IDictionary<string, string> globalProperties = null)
{
Project expectedProject = CreateProject(expectedGuid, expectedName, extension, globalProperties);
Expand Down Expand Up @@ -123,5 +177,61 @@ private Project CreateProject(string projectGuid = null, string name = null, str

return MockProject.Create(fullPath, globalProperties);
}

private sealed class TestProject : IDisposable
{
private const string TemplateProjectPath = @"TestFiles\SampleProject.csproj";

private readonly Dictionary<string, string> _savedEnvironmentVariables = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

private TestProject(string fullPath, IDictionary<string, string> globalProperties)
{
SetEnvironmentVariables(new Dictionary<string, string>
{
{ "Configuration", null },
{ "Platform", null },
});

Project = new Project(
fullPath ?? throw new ArgumentNullException(nameof(fullPath)),
globalProperties,
toolsVersion: null);
}

public static TestProject Create(IDictionary<string, string> globalProperties = null)
{
string fullPath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid():N}.proj");

// Copy the template project to a temporary location
File.Copy(Path.Combine(TestContext.CurrentContext.TestDirectory, TemplateProjectPath), fullPath);

return new TestProject(fullPath, globalProperties);
}

private void SetEnvironmentVariables(Dictionary<string, string> variables)
{
foreach (KeyValuePair<string, string> variable in variables)
{
_savedEnvironmentVariables[variable.Key] = variable.Value;

Environment.SetEnvironmentVariable(variable.Key, variable.Value);
}
}

public Project Project { get; }

public void Dispose()
{
if (File.Exists(Project.FullPath))
{
File.Delete(Project.FullPath);
}

foreach (KeyValuePair<string, string> variable in _savedEnvironmentVariables)
{
Environment.SetEnvironmentVariable(variable.Key, variable.Value);
}
}
}
}
}
35 changes: 35 additions & 0 deletions src/SlnGen.Build.Tasks.UnitTests/TestFiles/SampleProject.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x64</Platform>
<ProjectGuid>{7DBBDCF0-30F5-4455-96DE-BF37D1949CB4}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SampleProject</RootNamespace>
<AssemblyName>SampleProject</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|amd64' " />

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
37 changes: 36 additions & 1 deletion 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.CodeDom;
using System.Collections;
using System.Collections.Generic;

internal static class ExtensionMethods
Expand Down Expand Up @@ -95,9 +97,39 @@ public static IEnumerable<string> GetConditionedPropertyValuesOrDefault(this Pro
return project.ConditionedProperties[name];
}

/// <summary>
/// Gets the value of the property value in addition to the 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> GetPossiblePropertyValuesOrDefault(this Project project, string name, string defaultValue)
{
HashSet<string> values = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

string propertyValue = project.GetPropertyValue(name);

// add the actual properties first
if (!string.IsNullOrEmpty(propertyValue))
{
values.Add(propertyValue);
}

// filter those that were already in the Properties
foreach (var conditionPropertyValue in project.GetConditionedPropertyValuesOrDefault(name, string.Empty))
{
values.Add(conditionPropertyValue);
}

return values.Any() ? values : (defaultValue?.Split(',') ?? Enumerable.Empty<string>());
}

/// <summary>
/// Returns the absolute path for the specified path string in the correct case according to the file system.
/// </summary>
/// <param name="str">The string.</param>
/// <returns>Full path in correct case.</returns>
public static string ToFullPathInCorrectCase(this string str)
{
string fullPath = Path.GetFullPath(str);
Expand All @@ -117,7 +149,10 @@ public static string ToFullPathInCorrectCase(this string str)
/// <summary>
/// Gets the current Guid as a string for use in a Visual Studio solution file.
/// </summary>
/// <returns>The current GUID in as a string with braces and in upper case.</returns>
/// <param name="guid">The unique identifier.</param>
/// <returns>
/// The current GUID in as a string with braces and in upper case.
/// </returns>
public static string ToSolutionString(this Guid guid)
{
return guid.ToString("B").ToUpperInvariant();
Expand Down
4 changes: 2 additions & 2 deletions src/SlnGen.Build.Tasks/Internal/SlnProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ 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");
IEnumerable<string> configurations = project.GetPossiblePropertyValuesOrDefault("Configuration", "Debug");
IEnumerable<string> platforms = project.GetPossiblePropertyValuesOrDefault("Platform", "AnyCPU");

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

Expand Down

0 comments on commit 43364a2

Please sign in to comment.