Repository F# setup
open System
open System.IO
open System.Threading
open System.Threading.Tasks
open Axial
open Axial.Console
open Axial.FileSystem
open Axial.PlatformService
open Axial.ProcessWorked examples
Each command is a value until a Flow runner reaches the host boundary.
A command-line tool that shows progress
A command-line entry point can forward output through the console and choose its status from Exit.
Process.tryRun preserves the cause so the entry point can report startup failures and interruptions.
Show page setup
// Setup for the checked examples on this page.
open Axial
open Axial.Process
open Axial.Process.DSL
/// Fails the docs test when an example's result differs from the value shown.
let shouldEqual expected actual =
if actual <> expected then failwithf "Expected %A but got %A" expected actualopen Axial.Process.DSL
// In a program, mark this [<EntryPoint>].
let main _ =
let outcome =
cmd $"dotnet --info"
|> stdoutToConsole
|> Process.tryRun
match outcome with
| Exit.Success result -> result.ExitCode
| Exit.Failure(Cause.Fail error) ->
eprintfn "%s" (ProcessError.describe error)
ProcessError.exitCode error
| Exit.Failure cause ->
eprintfn "%A" cause
1
AxialProcessAxial.Process.DSLmain: 'a -> intoutcome: Exit<ProcessResult,ProcessError>cmd: FormattableString -> ProcessCommand(|>): 'T1 -> ('T1 -> 'U) -> 'UApply a function to a value, the value being on the left, the function on the right The argument. The function. The function result. let doubleIt x = x * 2 3 |> doubleIt // Evaluates to 6
stdoutToConsole: ProcessCommand -> ProcessCommandAxial.Process.ProcesstryRun: ^source -> ^resultRuns with live services and returns Exit, including typed failures and interruptions.
Axial.Exit`2Represents the final outcome of a workflow execution. The type of the success value. The type of the domain-specific failure value.
SuccessThe workflow completed successfully.
result: ProcessResultExitCode: intFailureThe workflow failed due to a specific cause.
Axial.Cause`1Represents the cause of a failed workflow. The type of the domain-specific failure value.
FailAn expected domain-specific failure.
error: ProcessErroreprintfn: Printf.TextWriterFormat<'T> -> 'TPrint to stderr using the given format, and add a newline. The formatter. The formatted result. See Printf.eprintfn (link: ) for examples.
Axial.Process.ProcessErrorModuledescribe: ProcessError -> stringexitCode: ProcessError -> intcause: Cause<ProcessError>Requires & types
Requires: open Axial; open Axial.Process; open Axial.Process.DSL (packages: Axial, Axial.Process)val main: 'a -> intConsole forwarding is configured lazily; Process.tryRun starts the command.
Use a command as one step in an application
Use toFlow when the command is one step among other application work. The application supplies its own IProcess
service and decides how to use the result. git rev-parse --short HEAD reads the enclosing Git checkout, so this
example needs a reachable HEAD; replace it with a deterministic command such as cmd $"printf v1.2.3" in a
project without Git.
let gitRevision : Flow<#IHasProcess, ProcessError, string> =
flow {
let! result =
cmd $"git rev-parse --short HEAD"
|> toFlow
return result.StdOut.Trim()
}
let buildLabel =
flow {
let! revision = gitRevision
return $"build-{revision}"
}
let appEnvironment = ProcessHostEnvironment.live
gitRevision: Flow<ProcessHostEnvironment,ProcessError,string>Axial.Flow`3Axial.Process.IHasProcessAxial.Process.ProcessErrorExpected process errors. Runtime cancellation remains Cause.Interrupt.
stringAn abbreviation for the CLI type . Basic Types
flow: FlowBuilderThe universal flow { } computation expression.
result: ProcessResultcmd: FormattableString -> ProcessCommand(|>): 'T1 -> ('T1 -> 'U) -> 'UApply a function to a value, the value being on the left, the function on the right The argument. The function. The function result. let doubleIt x = x * 2 3 |> doubleIt // Evaluates to 6
toFlow: ^a -> Flow<'b,ProcessError,ProcessResult>Trim: unit -> stringRemoves all leading and trailing white-space characters from the current object. The string that remains after all white-space characters are removed from the start and end of the current string. If no characters can be trimmed from the current instance, the method returns the current instance unchanged.
StdOut: stringbuildLabel: Flow<ProcessHostEnvironment,ProcessError,string>revision: stringappEnvironment: ProcessHostEnvironmentAxial.Process.ProcessHostEnvironmentModulelive: ProcessHostEnvironmentRequires & types
Requires: open Axial; open Axial.Process; open Axial.Process.DSL (packages: Axial, Axial.Process)val gitRevision: Flow<ProcessHostEnvironment,ProcessError,string>val buildLabel: Flow<ProcessHostEnvironment,ProcessError,string>val appEnvironment: ProcessHostEnvironmentmatch Flow.run appEnvironment buildLabel with
| Exit.Success label -> label.StartsWith "build-" |> shouldEqual true
| other -> failwithf "unexpected %A" other
Axial.Flowrun: 'env -> Flow<'env,'error,'value> -> Exit<'value,'error>Runs the workflow and blocks until the final exit is available. The environment used by the workflow. The workflow to run. The final workflow exit. let exit = workflow |> Flow.run environment
appEnvironment: ProcessHostEnvironmentbuildLabel: Flow<ProcessHostEnvironment,ProcessError,string>Axial.Exit`2Represents the final outcome of a workflow execution. The type of the success value. The type of the domain-specific failure value.
SuccessThe workflow completed successfully.
label: stringStartsWith: string -> boolDetermines whether the beginning of this string instance matches the specified string. The string to compare. if matches the beginning of this string; otherwise, . is .
(|>): 'T1 -> ('T1 -> 'U) -> 'UApply a function to a value, the value being on the left, the function on the right The argument. The function. The function result. let doubleIt x = x * 2 3 |> doubleIt // Evaluates to 6
shouldEqual: 'a -> 'a -> unitother: Exit<string,ProcessError>failwithf: Printf.StringFormat<'T,'Result> -> 'TPrint to a string buffer and raise an exception with the given result. Helper printers must return strings. The formatter. The formatted result. See Printf.failwithf (link: ) for examples.
Requires & types
Requires: open Axial (packages: Axial)toFlow uses batch capture defaults. Flow.run executes the enclosing application workflow with its explicit
environment.
Stream lines into workflow decisions
streamStdoutLines yields only stdout lines. Its terminal returns values and completion separately.
let collectEvents =
cmd $"printf '{{\"event\":\"ready\"}}\n{{\"event\":\"done\"}}\n'"
|> streamStdoutLines
|> ProcessStream.runCollect
|> Flow.map fst
collectEvents: Flow<ProcessHostEnvironment,ProcessError,string list>cmd: FormattableString -> ProcessCommand(|>): 'T1 -> ('T1 -> 'U) -> 'UApply a function to a value, the value being on the left, the function on the right The argument. The function. The function result. let doubleIt x = x * 2 3 |> doubleIt // Evaluates to 6
streamStdoutLines: ^a -> ProcessStream<'b,string>Axial.Process.ProcessStreamrunCollect: ProcessStream<'a,'b> -> Flow<'a,ProcessError,('b list * ProcessCompletion)>Collects every selected value plus completion. The collected list can grow without bound.
Axial.Flowmap: ('value -> 'next) -> Flow<'env,'error,'value> -> Flow<'env,'error,'next>Transforms the successful value of a flow. If the source fails, the is not executed. The original failure cause is preserved, including typed failures, interruption, and defects. Use map for pure value transformations after an effect has succeeded. A function of type 'value -> 'next to transform the successful value. The source flow of type to transform. A new with the transformed success value of type 'next. let flow = Flow.succeed 1 |> Flow.map (fun x -> x + 1)
fst: 'T1 * 'T2 -> 'T1Return the first element of a tuple, fst (a,b) = a. The input tuple. The first value. fst ("first", 2) // Evaluates to "first"
Requires & types
Requires: open Axial; open Axial.Process; open Axial.Process.DSL (packages: Axial, Axial.Process)val collectEvents: Flow<ProcessHostEnvironment,ProcessError,string list>Flow.run appEnvironment collectEvents
|> shouldEqual (Exit.Success [ """{"event":"ready"}"""; """{"event":"done"}""" ])
Axial.Flowrun: 'env -> Flow<'env,'error,'value> -> Exit<'value,'error>Runs the workflow and blocks until the final exit is available. The environment used by the workflow. The workflow to run. The final workflow exit. let exit = workflow |> Flow.run environment
appEnvironment: ProcessHostEnvironmentcollectEvents: Flow<ProcessHostEnvironment,ProcessError,string list>(|>): 'T1 -> ('T1 -> 'U) -> 'UApply a function to a value, the value being on the left, the function on the right The argument. The function. The function result. let doubleIt x = x * 2 3 |> doubleIt // Evaluates to 6
shouldEqual: 'a -> 'a -> unitAxial.Exit`2Represents the final outcome of a workflow execution. The type of the success value. The type of the domain-specific failure value.
SuccessThe workflow completed successfully.
Requires & types
Requires: open Axial (packages: Axial)The consumer pulls the stream with backpressure. Interrupting the enclosing Flow interrupts the native process
topology and waits for its cleanup. Only ProcessStream.take and ProcessStream.takeWhile stop the process early
and report the stop as ProcessCompletion.StoppedEarly; after ProcessStream.toFlowStream, process completion is
discarded, so a consumer that stops early there simply ends the stream. See streaming output.
For more checked command-line patterns, see DSL recipes.
For command construction and pipelines, continue with commands, input, and pipelines. For output destinations and bounded capture, see output capture and destinations.

