Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
matthid committed Jul 29, 2016
1 parent 5a6ee1d commit 5803ae0
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 57 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,5 @@ paket-files/
# Ignore VS2015 folder
.vs/

mytemp
.fake
130 changes: 79 additions & 51 deletions src/app/Fake.Runtime/CoreCache.fs
Original file line number Diff line number Diff line change
Expand Up @@ -176,70 +176,98 @@ let prepareContext (config:FakeConfig) (cache:ICachingProvider) =
Hash = scriptHash }
cache.TryLoadCache context

let setupAssemblyResolver (context:FakeContext) =

#if NETSTANDARD1_5
let loadContext = AssemblyLoadContext.Default



#if !NETSTANDARD1_6
type AssemblyLoadContext () =
member x.LoadFromAssemblyPath (loc:string) =
Reflection.Assembly.LoadFrom(loc)
member x.LoadFromAssemblyName(fullname:AssemblyName)=
Reflection.Assembly.Load(fullname)
#endif

let loadAssembly printDetails (assemInfo:AssemblyInfo) =
try let assem =
if assemInfo.Location <> "" then
let loadAssembly (loadContext:AssemblyLoadContext) printDetails (assemInfo:AssemblyInfo) =
try let assem =
if assemInfo.Location <> "" then
try
Some assemInfo.Location, loadContext.LoadFromAssemblyPath(assemInfo.Location)
with :? FileLoadException as e ->
if printDetails then
Trace.tracefn "Error while loading assembly: %O" e
let assemblyName = new System.Reflection.AssemblyName(assemInfo.FullName)
let asem = System.Reflection.Assembly.Load(new System.Reflection.AssemblyName(assemblyName.Name))
if printDetails then
Trace.traceFAKE "recovered and used already loaded assembly '%s' instead of '%s' ('%s')" asem.FullName assemInfo.FullName assemInfo.Location
None, asem
else None, loadContext.LoadFromAssemblyName(new AssemblyName(assemInfo.FullName))
Some(assem)
with ex ->
if printDetails then tracef "Unable to find assembly %A. (Error: %O)" assemInfo ex
None

let findAndLoadInRuntimeDeps (loadContext:AssemblyLoadContext) (name:AssemblyName) printDetails (runtimeDependencies:AssemblyInfo list) =
let strName = name.FullName
if printDetails then tracefn "Trying to resolve: %s" strName
let isPerfectMatch, result =
match runtimeDependencies |> List.tryFind (fun r -> r.FullName = strName) with
| Some a ->
true, loadAssembly loadContext printDetails a
| _ ->
let token = name.GetPublicKeyToken()
match runtimeDependencies
|> Seq.map (fun r -> AssemblyName(r.FullName), r)
|> Seq.tryFind (fun (n, _) ->
n.Name = name.Name &&
(isNull token || // When null accept what we have.
n.GetPublicKeyToken() = token)) with
| Some (_, info) ->
false, loadAssembly loadContext printDetails info
| _ ->
false, None
match result with
| Some (location, a) ->
if isPerfectMatch then
if printDetails then tracefn "Redirect assembly load to known assembly: %s (%A)" strName location
else
traceFAKE "Redirect assembly from '%s' to '%s' (%A)" strName a.FullName location
a
| _ ->
if printDetails then tracefn "Could not resolve: %s" strName
null

#if NETSTANDARD1_6
// See https://github.com/dotnet/coreclr/issues/6411
type FakeLoadContext (printDetails:bool, dependencies:AssemblyInfo list) =
inherit AssemblyLoadContext()

override x.Load(assem:AssemblyName) =
findAndLoadInRuntimeDeps x assem printDetails dependencies
#endif

let setupAssemblyResolver (context:FakeContext) =

#if NETSTANDARD1_6
try
Some assemInfo.Location, loadContext.LoadFromAssemblyPath(assemInfo.Location)
with :? FileLoadException as e ->
if printDetails then
Trace.tracefn "Error while loading assembly: %O" e
let assemblyName = new System.Reflection.AssemblyName(assemInfo.FullName)
let asem = System.Reflection.Assembly.Load(new System.Reflection.AssemblyName(assemblyName.Name))
if printDetails then
Trace.traceFAKE "recovered and used already loaded assembly '%s' instead of '%s' ('%s')" asem.FullName assemInfo.FullName assemInfo.Location
None, asem
else None, loadContext.LoadFromAssemblyName(new AssemblyName(assemInfo.FullName))
let globalLoadContext = AssemblyLoadContext.Default
// See https://github.com/dotnet/coreclr/issues/6411
let fakeLoadContext = new FakeLoadContext(context.Config.PrintDetails, context.Config.CompileOptions.RuntimeDependencies)
#else
Some assemInfo.Location, Reflection.Assembly.LoadFrom(assemInfo.Location)
else None, Reflection.Assembly.Load(assemInfo.FullName)
let loadContext = new AssemblyLoadContext()
#endif
Some(assem)
with ex -> if printDetails then tracef "Unable to find assembly %A. (Error: %O)" assemInfo ex
None



#if NETSTANDARD1_6
loadContext.add_Resolving(new Func<AssemblyLoadContext, AssemblyName, Assembly>(fun _ name ->
globalLoadContext.add_Resolving(new Func<AssemblyLoadContext, AssemblyName, Assembly>(fun _ name ->
let strName = name.FullName
fakeLoadContext.LoadFromAssemblyName(name)
#else
AppDomain.CurrentDomain.add_AssemblyResolve(new ResolveEventHandler(fun _ ev ->
let strName = ev.Name
let name = AssemblyName(strName)
findAndLoadInRuntimeDeps loadContext name context.Config.PrintDetails context.Config.CompileOptions.RuntimeDependencies
#endif
if context.Config.PrintDetails then tracefn "Trying to resolve: %s" strName
let isPerfectMatch, result =
match context.Config.CompileOptions.RuntimeDependencies |> List.tryFind (fun r -> r.FullName = strName) with
| Some a ->
true, loadAssembly context.Config.PrintDetails a
| _ ->
let token = name.GetPublicKeyToken()
match context.Config.CompileOptions.RuntimeDependencies
|> Seq.map (fun r -> AssemblyName(r.FullName), r)
|> Seq.tryFind (fun (n, _) ->
n.Name = name.Name &&
(isNull token || // When null accept what we have.
n.GetPublicKeyToken() = token)) with
| Some (_, info) ->
false, loadAssembly context.Config.PrintDetails info
| _ ->
false, None
match result with
| Some (location, a) ->
if isPerfectMatch then
if context.Config.PrintDetails then tracefn "Redirect assembly load to known assembly: %s (%A)" strName location
else
traceFAKE "Redirect assembly from '%s' to '%s' (%A)" strName a.FullName location
a
| _ ->
if context.Config.PrintDetails then tracefn "Could not resolve: %s" strName
null))
))

let runScriptWithCacheProvider (config:FakeConfig) (cache:ICachingProvider) =
let newContext, cacheInfo = prepareContext config cache
Expand Down
10 changes: 5 additions & 5 deletions src/app/FakeLib/AssemblyInfo.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ open System.Runtime.InteropServices
[<assembly: InternalsVisibleToAttribute("Test.FAKECore")>]
[<assembly: GuidAttribute("d6dd5aec-636d-4354-88d6-d66e094dadb5")>]
[<assembly: AssemblyProductAttribute("FAKE - F# Make")>]
[<assembly: AssemblyVersionAttribute("4.31.1")>]
[<assembly: AssemblyInformationalVersionAttribute("4.31.1")>]
[<assembly: AssemblyFileVersionAttribute("4.31.1")>]
[<assembly: AssemblyVersionAttribute("4.34.5")>]
[<assembly: AssemblyInformationalVersionAttribute("4.34.5")>]
[<assembly: AssemblyFileVersionAttribute("4.34.5")>]
do ()

module internal AssemblyVersionInformation =
let [<Literal>] Version = "4.31.1"
let [<Literal>] InformationalVersion = "4.31.1"
let [<Literal>] Version = "4.34.5"
let [<Literal>] InformationalVersion = "4.34.5"
3 changes: 2 additions & 1 deletion src/test/Fake.Core.IntegrationTests/TestHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ let originalScenarioPath scenario = integrationTestPath @@ scenario @@ "before"
let prepare scenario =
let originalScenarioPath = originalScenarioPath scenario
let scenarioPath = scenarioTempPath scenario
Shell.CleanDir scenarioPath
Directory.Delete(scenarioPath, true)
Directory.ensure scenarioPath
Shell.CopyDir scenarioPath originalScenarioPath (fun _ -> true)

let directFakeInPath command scenarioPath =
Expand Down

0 comments on commit 5803ae0

Please sign in to comment.