Last active
January 29, 2018 13:01
-
-
Save vbfox/2eee346524d688af55ccc467e154e1b4 to your computer and use it in GitHub Desktop.
Allow to define FAKE targets with a syntax similar to Gulp tasks and typed !
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let clean = task "Clean" [] { | |
CleanDir "out" | |
} | |
let assemblyInfo = task "AssemblyInfo" [ clean.IfNeeded ] { | |
// ... | |
} | |
let build = task "Build" [ assemblyInfo ] { | |
!! "**/*.fsproj" |> MSBuildRelease "" "Rebuild" |> ignore | |
} | |
let runTests = task "RunTests" [ build ] { | |
!! "**/*Test.exe" |> Expecto id | |
} | |
let default = Task "Default" [ build; test.If(buildServer = AppVeyor) ] DoNothing | |
RunTaskOrDefault default |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Allow to define FAKE tasks with a syntax similar to Gulp tasks and using instances instead of strings | |
/// https://gist.github.com/vbfox/2eee346524d688af55ccc467e154e1b4 | |
module BlackFox.TypedTaskDefinitionHelper | |
open Fake | |
open System | |
type TaskMetadata = { | |
name: string | |
dependencies: TaskInfo list | |
} | |
and TaskInfo = { | |
metadata: TaskMetadata option | |
isSoft: bool | |
} | |
with | |
static member NoTask = | |
{ metadata = None; isSoft = false } | |
member this.Always | |
with get() = { this with isSoft = false } | |
member this.IfNeeded | |
with get() = { this with isSoft = true } | |
member this.If(condition: bool) = | |
if condition then this else TaskInfo.NoTask | |
let inline private applyTaskDependecies meta = | |
for dependency in meta.dependencies do | |
match dependency.metadata with | |
| Some dependencyMetadata -> | |
if dependency.isSoft then | |
dependencyMetadata.name ?=> meta.name |> ignore | |
else | |
dependencyMetadata.name ==> meta.name |> ignore | |
| None -> () | |
let inline private registerTask meta body = | |
Target meta.name body | |
applyTaskDependecies meta | |
let inline private infoFromMeta meta = | |
{ metadata = Some meta; isSoft = false } | |
type TaskBuilder(metadata: TaskMetadata) = | |
member __.TryFinally(f, compensation) = | |
try | |
f() | |
finally | |
compensation() | |
member __.TryWith(f, catchHandler) = | |
try | |
f() | |
with e -> catchHandler e | |
member __.Using(disposable: #IDisposable, f) = | |
try | |
f disposable | |
finally | |
match disposable with | |
| null -> () | |
| disp -> disp.Dispose() | |
member __.For(sequence, f) = | |
for i in sequence do f i | |
member __.Combine(f1, f2) = f2(); f1 | |
member __.Zero() = () | |
member __.Delay f = f | |
member __.Run f = | |
registerTask metadata f | |
infoFromMeta metadata | |
/// Define a task with it's dependencies | |
let Task name dependencies body = | |
let metadata = {name = name; dependencies = dependencies } | |
registerTask metadata body | |
infoFromMeta metadata | |
/// Define a task with it's dependencies | |
let task name dependencies = | |
let metadata = {name = name; dependencies = dependencies } | |
TaskBuilder(metadata) | |
/// Define a task without any body, only dependencies | |
let EmptyTask name dependencies = | |
let metadata = {name = name; dependencies = dependencies } | |
registerTask metadata (fun () -> ()) | |
infoFromMeta metadata | |
/// Run the task specified on the command line if there was one or the | |
/// default one otherwise. | |
let RunTaskOrDefault (taskInfo: TaskInfo) = | |
match taskInfo.metadata with | |
| Some metadata -> RunTargetOrDefault metadata.name | |
| None -> RunTarget () | |
let RunTask () = | |
RunTarget () |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment