BT

Scripting in F# Using Fake and Paket

by Pierre-Luc Maheu on Dec 12, 2016 |

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
General Feedback
Bugs
Advertising
Editorial
Marketing
InfoQ.com and all content copyright © 2006-2016 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT

We notice you're using an ad blocker

We understand why you use ad blockers. However to keep InfoQ free we need your support. InfoQ will not provide your data to third parties without individual opt-in consent. We only work with advertisers relevant to our readers. Please consider whitelisting us.