BT

Scripting in F# Using Fake and Paket

| by Pierre-Luc Maheu on Dec 12, 2016. Estimated reading time: 2 minutes |

Scripting in F# is usually done using .fsx files and F# Interactive (Fsi). For scripts that will be reused, Paket and Fake bring several features to handle different uses cases. Fake can be used to structure complex scripts, while Paket brings dependency management.

Fake
While Fake is, at its core, a build tool, its target system can also be used to structure scripts. Targets can be defined in relation to each other, which is common in scripts. Using Fake also allows the use of any .Net library. The following snippet shows the definition of two targets to run FluentMigrator migrations:

open System.Management.Automation

Target "BuildMigrations" (fun _ ->
    !! "src/app/**/migrations.csproj"
      |> MSBuildRelease buildDir "Build"
)

Target "RunMigrations" (fun _ ->
    MigrateToLatest connectionString [assembly] options
)

// Dependencies
"BuildMigrations"
  ==> "RunMigrations"

A desirable property of scripting languages is the ability to run small snippets code without prior compilation. F# can meet that requirement through F# Interactive (Fsi), although this mean installing Fsi on all machines where the script will run. Fake, on the other hand, can run scripts without prior compilation. It also doesn’t need the F# compiler on the machine where it runs. This capability comes from the F# Compiler Services project, embedding the compiler directly into Fake.

It is also possible to run Powershell scripts from Fake, allowing to mix and match F# and Powershell when needed.

open System.Management.Automation

Target "Powershell" (fun _ ->
    PowerShell.Create()
      .AddScript("& 'configure-server.ps1'")
      .AddParameter("Verbose", "")
      .Invoke())

Paket
Some scripts, especially when dealing with external services, require additional libraries. Albeit it is less common for scripting, dependencies can also be managed with a package manager. Using Paket, it is possible to reference individual files, another common case when scripting.

// Reference a nuget package
nuget FSharp.Management
// Reference a single file from GitHub
github myRepo/aProject dependency.dll 

Paket also provides the ability to group dependencies so that it doesn’t need to fetch all packages when only a subset is needed. This is well-suited for scripts, where several scripts may use the same dependencies file.

// Shared dependencies
nuget Newtonsoft.Json
nuget FSharp.Core

group Web
    nuget Fake.IIS
    nuget Suave

group Database
    nuget FluentMigrator
    nuget SQLProvider

Packages in F# scripts are referenced directly by path to the dynamic library. The references must be added and maintained manually, which can be time consuming with bigger scripts. Paket has the ability to generate a file including all the dependencies, removing the step of keeping in sync #r directives and referenced packages.

This post is part of the F# advent calendar, an initiative of the F# community.

Rate this Article

Relevance
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread
Community comments

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Discuss
BT