DEV Community

Jeremy Abbott
Jeremy Abbott

Posted on

FAKE 5 Migration Cheat Sheet

FAKE 5 Migration Cheat Sheet

Happy holidays everyone!

Pikachu in a Santa hat

When you start migrating from FAKE 4 and FAKE 5, you'll find that a simply opening the FAKE namespace isn't enough. Also, if like me, deprecation warnings drive you mad, you'll want to get rid of them as quickly as possible. I made the following cheat sheet to expedite your FAKE migration (and to help me update the other scripts I still need to update.)

Function/Module changes

Below are the functions I've had to update more than once. Most of them at least require referencing a nuget package and/or opening a module that you didn't have to open before.

Each of the following headers is the name of a FAKE 4 function. The snippet that follows shows how it is used in FAKE 4 followed by how to accomplish the same task in FAKE 5.

Target

// ======================================= // Before // ======================================= Target "Foo" (fun _ -> printfn "Foo to the Bar" ) // ======================================= // After // ======================================= open Fake.Core // From the Fake.Core.Target nuget package Target.create "Foo" (fun _ -> printfn "Foo to the Bar" ) 
Enter fullscreen mode Exit fullscreen mode

Target Operators

All of the FAKE custom operators are in their own modules now.

open Fake.Core.TargetOperators // From the Fake.Core.Target nuget package "Clean" ==> "Restore" ==> "Build" 
Enter fullscreen mode Exit fullscreen mode

Important: FAKE 4 Target operators (from FakeLib) do not work with FAKE 5 targets (and vice versa). That means converting Targets to FAKE 5 means using the operators from FAKE 5.

FullName

// ======================================= // Before // ======================================= let path = "./foo" |> FullName // Auto-opened from Fake.FileSystemHelper // ======================================= // After // ======================================= open Fake.IO let path = "./foo" |> Path.getFullName // From the Fake.IO.FileSystem the nuget package  
Enter fullscreen mode Exit fullscreen mode

getBuildParam

// ======================================= // Before // ======================================= // In FAKE 4 getBuildParam implicitly called getBuildParamOrDefault with empty string as the default let userName = getBuildParam "userName" // Auto-opened from Fake.EnvironmentHelper // ======================================= // After // ======================================= open Fake.Core let userName = // From nuget package Fake.Core.Environment Environment.environVarOrDefault "UserName" "" 
Enter fullscreen mode Exit fullscreen mode

Some Extra Notes

Passing arguments to your FAKE script is a little different in FAKE 5. In FAKE 4 you may have had something like

./build.sh <targetName> <buildParam>=foo, you now have a couple of different options, depending on your use case:

# create an environment variable that's scoped to the current shell session. export myKey="my value" ./build.sh build 
Enter fullscreen mode Exit fullscreen mode
let myKey = Environment.environVarOrDefault "myKey" "" 
Enter fullscreen mode Exit fullscreen mode

If you want to pass arguments on the command line, you have to pass them with the following syntax:

# using the FAKE dotnet CLI tool fake run build.fsx -t build --arg 
Enter fullscreen mode Exit fullscreen mode

And then in build.fsx:

Target.create "Foo" (fun p -> printfn "args: %A" p.Context.Arguments printfn "%A " p ) Target.runOrDefaultWithArguments "Foo" 
Enter fullscreen mode Exit fullscreen mode

You need to use Target.runOrDefaultWithArguments instead of Target.runOrDefault to access arguments this way. Additionally, the target function signature is now string -> TargetParameter -> unit -> unit. You have to use the TargetParameter (p in the example above) to get access to it. Context.Arguments is a string list. You can use the module Fake.Core.CommandLineParsing to parse the target arguments.

parseAllReleaseNotes

// ======================================= // Before // ======================================= open Fake.ReleaseNotesHelper let releaseNotes = File.ReadAllLines "RELEASE_NOTES.md" let releaseNotesData = releaseNotes |> parseAllReleaseNotes let release = List.head releaseNotesData // ======================================= // After // ======================================= open Fake.Core let release = // From Fake.Core.ReleaseNotes nuget package ReleaseNotes.load "RELEASE_NOTES.md" 
Enter fullscreen mode Exit fullscreen mode

SemVerHelper.parse

// ======================================= // Before // ======================================= let packageVersion = SemVerHelper.parse release.NugetVersion // From Fake.SemVerHelper // ======================================= // After // ======================================= open Fake.Core let semVer = // From Fake.Core.SemVer nuget package SemVer.parse release.NugetVersion printfn "semver.Parse: %s" <| semVer.ToString() 
Enter fullscreen mode Exit fullscreen mode

isUnix

// ======================================= // Before // ======================================= let pathSep = if isUnix then """\""" else "/" // From Fake.EnvironmentHelper // ======================================= // After // ======================================= open Fake.Core let pathSep = // From the nuget package Fake.Core.Environment if Environment.isUnix then """\""" else "/" 
Enter fullscreen mode Exit fullscreen mode

ProcessHelper.tryFindFileOnPath

// ======================================= // Before // ======================================= let fooExe = ProcessHelper.tryFindFileOnPath "foo" // ======================================= // After // ======================================= open Fake.Core let fooExe = // From the nuget package Fake.Core.Process ProcessUtils.tryFindFileOnPath "foo" 
Enter fullscreen mode Exit fullscreen mode

DotNetCli.GetDotNetSDKVersionFromGlobalJson()

// ======================================= // Before // ======================================= let dotnetcliVersion = DotNetCli.GetDotNetSDKVersionFromGlobalJson() // ======================================= // After // ======================================= open Fake.DotNet // After // From the nuget package Fake.DotNet.Cli // In the namespace Fake.DotNet and module DotNet let dotnetcliVersion = DotNet.CliVersion.GlobalJson 
Enter fullscreen mode Exit fullscreen mode

CleanDirs

// ======================================= // Before // ======================================= // Auto-opened from Fake.FileHelper CleanDirs [exampleDir] // ======================================= // After // ======================================= open Fake.IO //From the nuget package Fake.IO.FileSystem Shell.cleanDirs [deployDir] 
Enter fullscreen mode Exit fullscreen mode

ExecProcess / Shell.Exec

// ======================================= // Before // ======================================= let result = Shell.Exec("foo", "--version") if result <> 0 failwith "boom" // ======================================= // After // ======================================= open Fake.Core let result = // From the NuGet Package Fake.Core.Process CreateProcess.fromRawCommand "dotnet" ["--info"] |> Proc.run if result.ExitCode <> 0 then failwith "boom" 
Enter fullscreen mode Exit fullscreen mode

build

// ======================================= // Before // ======================================= open Fake Target "MSBuild" (fun _ -> let setMsBuildParams defaultParams = { defaultParams with Targets=["Build"] Properties = ["Configuration", "Debug"] } // Auto-opened from Fake.MSBuildHelper build setMsBuildParams "Foo.sln" ) // ======================================= // After // ======================================= open Fake.DotNet Target.create "MSBuild" (fun _ -> let setMsBuildParams defaultParams = { defaultParams with Targets=["Build"] Properties = ["Configuration", "Debug"] } MSBuild.build setMsBuildParams "Foo.sln" ) 
Enter fullscreen mode Exit fullscreen mode

Top comments (3)

Collapse
 
thorium profile image
Tuomas Hietanen

Thanks great article. The only minor typo was in wrong pathSep, but you can get the correct one from Path.DirectorySeparatorChar (off-topic anyway). Is Fake5 focused for .NET Core, or should you consider migrating an old .NET Framework full application also?

Collapse
 
jeremyabbott profile image
Jeremy Abbott

Thank you for the feedback! I didn't know about Path.DirectorySeparatorChar

I would consider migrating regardless of which flavor of .NET you're using. FAKE 5 includes MSBuild and NuGet APIs. The FAKE runner is a dotnet SDK global tool, but that doesn't mean it can't be used with scripts written for .NET Framework applications.

Collapse
 
patriba profile image
Patricia dos Santos Pastorelli

Thanks, great article... It saved me hundreds of hours searching for the right migration

Patricia