Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Proposal: two-stage NuGet-aware build scripts (Fake.Boot) #116
I have a proposal - draft currently implemented here:
The gist of it is to allow two-stage execution of FAKE scripts - first stage is BOOT, where F# code runs to resolve dependencies with NuGet, and second stage is as usual - and you can use the resolved dependencies there.
The downside - I pulled in a dependency on NuGet.Core into FakeLib - is this acceptable?
Also, how do I test this precisely? Will try on Mono myself, have not yet.
To elaborate, why this is useful: you can have a simple worflow:
With a script like this (https://gist.github.com/toyvo/8f1b541a051830b36a18), this pulls in the deps and you get a running website. You also do not mess with any explicit references inside build.fsx.
It also eases the pain of using NuGet repository for build automation. Extending FAKE is now easy - now people can just put their "tasks" on NuGet and then just use them.
How it works: FAKE first invokes the script with BOOT constant set - this stage uses NuGet API to resolve packages (in-process), this creates packages folder, then it computes the reference set using NuGet rules again, and generates a little F# script with "#r" directives. Then FAKE invokes the script again without the BOOT constant, and now the script can include the auto directive file and use the references resolved from NuGet.
Question from Steffen: can we do this without a compiler flag.
Good question. There are two options that do not involve a compiler flag:
The reason you cannot have a single script file and no compiler flags is hopefully very obvious - F# would complain that it cannot find the nuget-fetched references in the boot stage. I do not think there is currently (on stock FSI) a way to execute code in stages (feeding it to FSI in chunks), is there?
I am doing some further testing and fixes. Apparently, assembly references should be specified in the correct order to work at all. In addition, on Mono 3.0.6 and latest fsharpi, the references do not get loaded in correct order because of this bug:
In addition, current release of NuGet.Core does not work on Mono - it fails to find resolved assemblies in the local repository. However, using the alpha version of the latest NuGet.Core from NuGet resolves this.
I think I can get ordering fixed this week and also add an option to do this with two files instead of compiler flags in one file. Overall, my changes should not affect the existing FAKE users (only specially marked FAKE scripts will run in a two-stage bootstrapping way), except the change would put a dependency from FakeLib.dll to NuGet.Core.dll.
Does that sound good? Will this have a chance of being merged into FAKE then? If NuGet.Core.dll dependency is considered a serious problem, could introduce dynamic loading to try to feature-detect FakeLib.NuGet.dll depending on NuGet.Core.dll, but I would prefer not to go there unless there is a real benefit.
I now also added a dependency on Mono.Cecil to resolve in which order to reference assemblies. This is unfortunately needed - see fsharp/fsharp#119 for details. With the correct order, and my suggested fix to F# for Mono, references work now.
I added the separate file workflow as requested - conf.fsx and build.fsx instead of build.fsx with compiler flags. The previous form is also available.
I also added some command line support, run