Script
Extensions can provide actions to help performing a specific step. An extension can be implemented using an F# script:
extension say {
script = "say.fsx"
}
target build {
sayHello { who: "world" }
}
#if !TERRABUILD_SCRIPT
#r "<path-to>/Terrabuild.Extensibility.dll"
#endif
open Terrabuild.Extensibility
let sayHello (context: ActionContext) (who: string) =
let ops = [ shellOp "echo" $"Hello {who}" ]
execRequest Cacheability.Always ops
In this example, who
argument is used to invoke the sayHello
action (that’s just the name of the function).
When the script is runned in Terrabuild, TERRABUILD_SCRIPT
is defined as well a reference to Terrabuild.Extensibility.dll
assembly. Script is always compiled with this dependency.
If TERRABUILD_SCRIPT
is not defined, you have to reference the assembly. This can also be used to test script without running in Terrabuild.
Arguments
Functions accept arguments. Supported types are:
string
andstring option
bool
andbool option
List<string>
andList<string> option
Map<string, string>
andMap<string, string> option
ActionContext
for action functions (must be namedcontext
)InitContext
for action function (must be namedcontext
)
Dispatch
If you want to let the user define the verb, you can use the special function name __dispatch__
. If this function is defined, Terrabuild will used it to dispatch the command if the named one is not found. An action function must return an ActionExecutionRequest
record.
extension hello {
script = "hello.fsx"
}
target build {
hello { who = "world" }
}
#if !TERRABUILD_SCRIPT
#r "<path-to>/Terrabuild.Extensibility.dll"
#endif
open Terrabuild.Extensibility
let __dispatch__ (context: ActionContext) (who: string) =
let ops = [ shellOp "echo" $"{context.Command} {who}" ]
execRequest Cacheability.Always ops
context
argument name is required to pass the ActionContext
.Defaults
An extension can also provide a default configuration for a project by implementing __defaults__
function. This function must return a ProjectInfo
instance.
Here is a sample extension extracting projects from an sln
project file (Visual Studio Solution file):
extension {
script = "sln.fsx"
}
#if !TERRABUILD_SCRIPT
#r "<path-to>/Terrabuild.Extensibility.dll"
#endif
open Terrabuild.Extensibility
open System.IO
open System.Text.RegularExpressions
let private (|Regex|_|) pattern input =
let m = Regex.Match(input, pattern)
if m.Success then
List.tail [ for g in m.Groups -> g.Value ] |> Some
else
None
let private findProject = function
| Regex "^Project\(.*\) = \".*\", \"(.*)\", .*$" [projectFile] ->
Some projectFile
| _ ->
None
let __defaults__ (context: InitContext) =
let dependencies =
Directory.EnumerateFiles(context.Directory, "*.sln") |> Seq.head
|> File.ReadLines
|> Seq.choose findProject
{ ProjectInfo.Default
with Ignores = Set.empty
Outputs = Set.empty
Dependencies = Set dependencies }
context
argument name is required to pass the InitContext
.