Skip to content

Commit

Permalink
New OS aware intrinsic functions
Browse files Browse the repository at this point in the history
  • Loading branch information
cdmihai committed May 9, 2017
1 parent 7f5e580 commit aef9d65
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 15 deletions.
45 changes: 31 additions & 14 deletions src/Build.UnitTests/Evaluation/Expander_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -2601,6 +2602,10 @@ public void PropertyFunctionGetFolderPath()
"$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)",
"$$architecture$$"
)]
[InlineData(
"$([MSBuild]::IsOsPlatform($$platform$$))",
"True"
)]
public void PropertyFunctionRuntimeInformation(string propertyFunction, string expectedExpansion)
{
Func<string, string, string, string> formatString = (aString, platform, architecture) => aString
Expand All @@ -2610,20 +2615,7 @@ public void PropertyFunctionRuntimeInformation(string propertyFunction, string e
var pg = new PropertyDictionary<ProjectPropertyInstance>();
var expander = new Expander<ProjectPropertyInstance, ProjectItemInstance>(pg);

var currentPlatformString = string.Empty;

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
currentPlatformString = "Windows";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
currentPlatformString = "Linux";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
currentPlatformString = "OSX";
}
string currentPlatformString = Helpers.GetOSPlatformAsString();

var currentArchitectureString = RuntimeInformation.OSArchitecture.ToString();

Expand All @@ -2635,6 +2627,31 @@ public void PropertyFunctionRuntimeInformation(string propertyFunction, string e
Assert.Equal(expectedExpansion, result);
}

[Fact]
public void InvalidIsOsPlatformArgumentShouldPrintAvailablePlatforms()
{
var pg = new PropertyDictionary<ProjectPropertyInstance>();
var expander = new Expander<ProjectPropertyInstance, ProjectItemInstance>(pg);

var exception = Assert.Throws<InvalidProjectFileException>(
() => expander.ExpandIntoStringLeaveEscaped("$([MSBuild]::IsOsPlatform(Foo))", ExpanderOptions.ExpandProperties, MockElementLocation.Instance));

Assert.Contains("Linux, OSX, Windows", exception.Message);
}

[Fact]
public void IsOsPlatformShouldBeCaseInsensitiveToParameter()
{
var pg = new PropertyDictionary<ProjectPropertyInstance>();
var expander = new Expander<ProjectPropertyInstance, ProjectItemInstance>(pg);

var osPlatformLowerCase = Helpers.GetOSPlatformAsString().ToLower();

var result = expander.ExpandIntoStringLeaveEscaped($"$([MSBuild]::IsOsPlatform({osPlatformLowerCase}))", ExpanderOptions.ExpandProperties, MockElementLocation.Instance);

Assert.Equal("True", result);
}

/// <summary>
/// Expand property function that calls a method with an enum parameter
/// </summary>
Expand Down
42 changes: 42 additions & 0 deletions src/Build/Evaluation/IntrinsicFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;

using Microsoft.Build.Internal;
Expand All @@ -26,6 +28,14 @@ namespace Microsoft.Build.Evaluation
/// </summary>
internal static class IntrinsicFunctions
{
private static Lazy<string> _validOsPlatforms = new Lazy<string>(
() => typeof(OSPlatform).GetTypeInfo()
.GetProperties(BindingFlags.Static | BindingFlags.Public)
.Where(pi => pi.PropertyType == typeof(OSPlatform))
.Select(pi => pi.Name)
.Aggregate("", (a, b) => string.IsNullOrEmpty(a) ? b : $"{a}, {b}"),
true);

/// <summary>
/// Add two doubles
/// </summary>
Expand Down Expand Up @@ -418,6 +428,38 @@ internal static string NormalizePath(params string[] path)
return FileUtilities.NormalizePath(Path.Combine(path));
}

/// <summary>
/// Specify whether the current OS platform is <paramref name="platformString"/>
/// </summary>
/// <param name="platformString">The platform string. Must be a member of <see cref="OSPlatform"/>. Case Insensitive</param>
/// <returns></returns>
internal static bool IsOsPlatform(string platformString)
{
var typeInfo = typeof(OSPlatform).GetTypeInfo();
var propertyInfo = typeInfo.GetProperty(platformString, BindingFlags.Static | BindingFlags.Public | BindingFlags.IgnoreCase);

if (propertyInfo == null || propertyInfo.PropertyType != typeof(OSPlatform))
{

ErrorUtilities.ThrowArgument("UnsupportedOSPlatformString", platformString, _validOsPlatforms.Value);

return false;
}

var platform = (OSPlatform) propertyInfo.GetValue(typeof(OSPlatform));

return RuntimeInformation.IsOSPlatform(platform);
}

/// <summary>
/// True if current OS is a Unix system.
/// </summary>
/// <returns></returns>
internal static bool IsOsUnixLike()
{
return NativeMethodsShared.IsUnixLike;
}

public static string GetCurrentToolsDirectory()
{
return BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory;
Expand Down
8 changes: 7 additions & 1 deletion src/Build/Resources/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1603,13 +1603,19 @@ Utilization: {0} Average Utilization: {1:###.0}</value>
<value>MSB4231: ProjectRootElement can't reload if it contains unsaved changes.</value>
<comment>{StrBegin="MSB4231: "}</comment>
</data>

<data name="UnsupportedOSPlatformString">
<value>MSB4239: The provided argument {0} for [MSBuild]::IsOsPlatform is not supported. Supported values are: {1}</value>
<comment>{StrBegin="MSB4231: "} {0} is the name of an OS platform, like Windows, Linux, OSX; {1} is a comma separated enumeration of OS platforms</comment>
</data>

<!--
The engine message bucket is: MSB4001 - MSB4999
MSB4128 is being used in FileLogger.cs (can't be added here yet as strings are currently frozen)
MSB4129 is used by Shared\XmlUtilities.cs (can't be added here yet as strings are currently frozen)
Next message code should be MSB4239.
Next message code should be MSB4240.
Some unused codes which can also be reused (because their messages were deleted, and UE hasn't indexed the codes yet):
<none>
Expand Down
25 changes: 25 additions & 0 deletions src/Shared/UnitTests/ObjectModelHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml;

Expand Down Expand Up @@ -1022,6 +1023,30 @@ internal static string FormatProjectContentsWithItemGroupFragment(string fragmen
/// </summary>
internal static partial class Helpers
{
internal static string GetOSPlatformAsString()
{
var currentPlatformString = string.Empty;

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
currentPlatformString = "Windows";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
currentPlatformString = "Linux";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
currentPlatformString = "OSX";
}
else
{
Assert.True(false, "unrecognized current platform");
}

return currentPlatformString;
}

/// <summary>
/// Returns the count of objects returned by an enumerator
/// </summary>
Expand Down

0 comments on commit aef9d65

Please sign in to comment.