Skip to content

Commit

Permalink
Refactored Runtime Framework detection
Browse files Browse the repository at this point in the history
  • Loading branch information
devlead committed Sep 17, 2019
1 parent d5d9fca commit 8a915d0
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 8 deletions.
3 changes: 2 additions & 1 deletion src/Cake.Core.Tests/Fixtures/ScriptRunnerFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,10 @@ public ScriptRunnerFixture(string fileName = "/Working/build.cake")
Engine = Substitute.For<IScriptEngine>();
Engine.CreateSession(Arg.Any<IScriptHost>()).Returns(Session);

var runtime = new CakeRuntime();
ScriptAnalyzer = new ScriptAnalyzer(FileSystem, Environment, Log, new[] { new FileLoadDirectiveProvider(Globber, Log) });
ScriptProcessor = Substitute.For<IScriptProcessor>();
ScriptConventions = new ScriptConventions(FileSystem, AssemblyLoader);
ScriptConventions = new ScriptConventions(FileSystem, AssemblyLoader, runtime);

var context = Substitute.For<ICakeContext>();
context.Environment.Returns(c => Environment);
Expand Down
18 changes: 17 additions & 1 deletion src/Cake.Core.Tests/Unit/CakeRuntimeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,23 @@ public void Should_Return_Correct_Result_For_CoreClr()
var framework = runtime.BuiltFramework;

// Then
Assert.Equal(".NETStandard,Version=v2.0", framework.FullName);
#if NETFRAMEWORK
Assert.Equal(".NETFramework,Version=v4.6.1",
#elif !NETCOREAPP
Assert.Equal(".NETStandard,Version=v2.0",
#else
Assert.Equal(".NETCoreApp,Version=v" +
#endif
#if NETCOREAPP2_0
"2.0",
#elif NETCOREAPP2_1
"2.1",
#elif NETCOREAPP2_2
"2.2",
#elif NETCOREAPP3_0
"3.0",
#endif
framework.FullName);
}
}

Expand Down
27 changes: 26 additions & 1 deletion src/Cake.Core/Polyfill/EnvironmentHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

using System;
#if NETCORE
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
#endif
using System.Runtime.Versioning;
Expand All @@ -15,7 +17,9 @@ internal static class EnvironmentHelper
#if !NETCORE
private static bool? _isRunningOnMac;
#else
private static readonly FrameworkName NetStandardFramework = new FrameworkName(".NETStandard,Version=v2.0");
private static bool? _isCoreClr;
private static FrameworkName netCoreAppFramwork;
#endif

public static bool Is64BitOperativeSystem()
Expand Down Expand Up @@ -119,7 +123,28 @@ public static Runtime GetRuntime()
public static FrameworkName GetBuiltFramework()
{
#if NETCORE
return new FrameworkName(".NETStandard,Version=v2.0");
if (netCoreAppFramwork != null)
{
return netCoreAppFramwork;
}

var assemblyPath = typeof(System.Runtime.GCSettings)?.GetTypeInfo()?.Assembly?.CodeBase;

if (string.IsNullOrEmpty(assemblyPath))
{
return NetStandardFramework;
}

var netCoreAppVersion = string.Concat(assemblyPath.Skip(assemblyPath.IndexOf("Microsoft.NETCore.App") + 22).Take(3));

if (string.IsNullOrEmpty(netCoreAppVersion))
{
return NetStandardFramework;
}

return netCoreAppFramwork = Version.TryParse(netCoreAppVersion, out var version)
? new FrameworkName(".NETCoreApp", version)
: NetStandardFramework;
#else
return new FrameworkName(".NETFramework,Version=v4.6.1");
#endif
Expand Down
6 changes: 6 additions & 0 deletions src/Cake.Core/Scripting/IScriptConventions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,11 @@ public interface IScriptConventions
/// <param name="root">The root to where to find Cake related assemblies.</param>
/// <returns>A list containing all default assemblies.</returns>
IReadOnlyList<Assembly> GetDefaultAssemblies(DirectoryPath root);

/// <summary>
/// Gets the default defines.
/// </summary>
/// <returns>A list containing all default defines.</returns>
IReadOnlyList<string> GetDefaultDefines();
}
}
43 changes: 42 additions & 1 deletion src/Cake.Core/Scripting/ScriptConventions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@ public sealed class ScriptConventions : IScriptConventions
{
private readonly IFileSystem _fileSystem;
private readonly IAssemblyLoader _loader;
private readonly ICakeRuntime _runtime;

/// <summary>
/// Initializes a new instance of the <see cref="ScriptConventions"/> class.
/// </summary>
/// <param name="fileSystem">The file system.</param>
/// <param name="loader">The assembly loader.</param>
public ScriptConventions(IFileSystem fileSystem, IAssemblyLoader loader)
/// <param name="runtime">The Cake runtime.</param>
public ScriptConventions(IFileSystem fileSystem, IAssemblyLoader loader, ICakeRuntime runtime)
{
_fileSystem = fileSystem;
_loader = loader;
_runtime = runtime;
}

/// <summary>
Expand Down Expand Up @@ -106,6 +109,44 @@ public IReadOnlyList<Assembly> GetDefaultAssemblies(DirectoryPath root)
return result.ToArray();
}

/// <summary>
/// Gets the default defines.
/// </summary>
/// <returns>A list containing all default defines.</returns>
public IReadOnlyList<string> GetDefaultDefines()
{
return new[]
{
"#define CAKE",
_runtime.IsCoreClr ? "#define NETCOREAPP" : "#define NETFRAMEWORK",
$"#define {GetFrameworkDefine()}"
};
}

private string GetFrameworkDefine()
{
switch (_runtime.BuiltFramework.FullName)
{
case ".NETFramework,Version=v4.6.1":
return "NET461";

case ".NETCoreApp,Version=v2.0":
return "NETCOREAPP2_0";

case ".NETCoreApp,Version=v2.1":
return "NETCOREAPP2_1";

case ".NETCoreApp,Version=v2.2":
return "NETCOREAPP2_2";

case ".NETCoreApp,Version=v3.0":
return "NETCOREAPP3_0";

default:
return "NETSTANDARD2_0";
}
}

private List<Assembly> LoadCakeAssemblies(DirectoryPath root)
{
var result = new List<Assembly>();
Expand Down
5 changes: 4 additions & 1 deletion src/Cake.Core/Scripting/ScriptRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,11 @@ public void Run(IScriptHost host, FilePath scriptPath, IDictionary<string, strin
session.ImportNamespace(@namespace);
}

var defines = new HashSet<string>(result.Defines, StringComparer.Ordinal);
defines.AddRange(_conventions.GetDefaultDefines());

// Execute the script.
var script = new Script(result.Namespaces, result.Lines, aliases, result.UsingAliases, result.UsingStaticDirectives, result.Defines);
var script = new Script(result.Namespaces, result.Lines, aliases, result.UsingAliases, result.UsingStaticDirectives, defines);
session.Execute(script);
}

Expand Down
39 changes: 38 additions & 1 deletion tests/integration/Cake.Core/Scripting/DefineDirective.cake
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,45 @@ Task("Cake.Core.Scripting.DefineDirective.NotDefined")
Assert.False(bar);
});

Task("Cake.Core.Scripting.DefineDirective.Runtime")
.Does(context =>
{
#if NETFRAMEWORK
Assert.Equal(".NETFramework,Version=v4.6.1",
#elif !NETCOREAPP
Assert.Equal(".NETStandard,Version=v2.0",
#else
Assert.Equal(".NETCoreApp,Version=v" +
#endif
#if NETCOREAPP2_0
"2.0",
#elif NETCOREAPP2_1
"2.1",
#elif NETCOREAPP2_2
"2.2",
#elif NETCOREAPP3_0
"3.0",
#endif
context.Environment.Runtime.BuiltFramework.FullName);
});

Task("Cake.Core.Scripting.DefineDirective.Cake")
.Does(() =>
{
bool cake;
#if (CAKE)
cake = true;
#else
cake = false;
#endif
Assert.True(cake);
});


//////////////////////////////////////////////////////////////////////////////

Task("Cake.Core.Scripting.DefineDirective")
.IsDependentOn("Cake.Core.Scripting.DefineDirective.Defined")
.IsDependentOn("Cake.Core.Scripting.DefineDirective.NotDefined");
.IsDependentOn("Cake.Core.Scripting.DefineDirective.NotDefined")
.IsDependentOn("Cake.Core.Scripting.DefineDirective.Runtime")
.IsDependentOn("Cake.Core.Scripting.DefineDirective.Cake");
5 changes: 3 additions & 2 deletions tests/integration/setup.cake
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ Setup<ScriptContext>(setupContext =>
// Output information from setup task
setupContext.Log.Information(
Verbosity.Quiet,
"Performing setup initated by {0} ({1} tasks to be executed beginning with {2}, performing {3} build)",
"Performing setup initated by {0} ({1} tasks to be executed beginning with {2}, performing {3} build on {4})",
setupContext.TargetTask?.Name,
setupContext.TasksToExecute?.Count,
setupContext.TasksToExecute?.Select(task => task.Name).FirstOrDefault(),
BuildSystem.Provider
BuildSystem.Provider,
setupContext.Environment.Runtime.BuiltFramework
);
// Perform artifact cleanup
Expand Down

0 comments on commit 8a915d0

Please sign in to comment.