Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get correct resolution folder of F# Type Provider when referencing assemblies via #load?

I'm writing a type provider which allows the user to supply a configuration file to it. I use the TP's internal configuration object to identify the ResolutionFolder, which I use to get the fully-qualfied path to the config file. Great.

However, when working with scripts, I use Paket's auto-generated load scripts to load in my dependencies. The file path looks like this: -

.paket
   |--.load
   |     |-- net452
   |           |-- main.group.fsx
   |--src
       |-- myscript.fsx
       |-- config.json

myscript.fsx contains my script code. config.json contains the configuration for the type provider instance that I'll create in the script.

Inside myscript.fsx I call #load "..\.paket\.load\net452\main.group.fsx" to load in all dependencies (including my TP itself) which works fine.

HOWEVER

When I then try to initialise the type provider further down in the script: -

type MyTPInstance = MyTp<myConfig = "config.json">

I get an error which my TP catches and shows: -

The type provider reported an error: Unable to locate config file
"C:\Users\Isaac\Source\Repos\myRepo\.paket\load\net452\config.json"

In other words - it appears that because I've referenced my TP assembly from a script living in another folder, that's the folder that's used by FSI as the resolution folder - and NOT the folder of the script that's being run. I can prove this is the problem because if I copy the contents of the main.group.fsx into myscript.fsx directly and (fixing the path to my packages of course), it all works fine.

How can I fix this? How are other people getting around this?

like image 485
Isaac Abraham Avatar asked Jan 05 '23 01:01

Isaac Abraham


1 Answers

I think I never managed to make relative path resolution work correctly in any of the type providers that I was involved with. If someone else can figure this out, that would be amazing.

Sooner or later, I just started to use [<Literal>] and __SOURCE_DIRECTORY__ to give the type provider an absolute path:

[<Literal>]
let MyConfig = __SOURCE_DIRECTORY__ + "/config.json"
type MyTPInstance = MyTp<myConfig = MyConfig>

This got a bit nicer with the const recently:

type MyTPInstance = MyTp<myConfig = const(__SOURCE_DIRECTORY__ + "/config.json")>

It is still pretty ugly, but at least it works reliably.

like image 60
Tomas Petricek Avatar answered May 10 '23 07:05

Tomas Petricek