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.ProcessOpen Axial.Process.DSL to build commands with cmd, configure them with pipeline helpers, and connect them
with =>. Configuration is lazy; toFlow, streaming terminals, and host runners choose how to execute it.
ProcessStream and Flow combinators live in the modules of their input types.
Supply stdin and connect stages
Text, bytes, and file shortcuts configure one command's stdin. Input.text, Input.bytes, and Input.file
provide equivalent InputSource endpoints for =>. A connected stage receives its predecessor's output; it cannot also
have an explicit stdin source.
Show page setup
open System
open System.IO
open System.Text
open Axial
open Axial.Process
open Axial.Process.DSL
let shouldEqual expected actual =
if actual <> expected then failwithf "Expected %A but got %A" expected actuallet upper =
Input.text "hello\n" => cmd $"tr '[:lower:]' '[:upper:]'"
=> cmd $"cat"
|> Process.run
shouldEqual "HELLO\n" upper.StdOut
cmd $"cat" |> stdinFromBytes [| 65uy; 66uy |] |> Process.run
|> _.StdOut |> shouldEqual "AB"
cmd $"cat" |> stdinFromText "inline" |> Process.run
|> _.StdOut |> shouldEqual "inline"
upper: ProcessResultAxial.Process.DSL.Inputtext: string -> InputSourceSupplies encoded text incrementally when execution begins.
(=>): ^source -> ^destination -> ^resultcmd: 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
Axial.Process.Processrun: ^source -> ^resultRuns with live services and returns the value; raises ProcessRunException on failure.
shouldEqual: 'a -> 'a -> unitStdOut: stringstdinFromBytes: byte array -> ProcessCommand -> ProcessCommand_arg1: ProcessResultstdinFromText: string -> ProcessCommand -> ProcessCommandRequires & types
Requires: open Axial.Process; open Axial.Process.DSL (packages: Axial.Process)val upper: ProcessResultInput.flowStream consumes a cold byte stream with backpressure. The process spec has no environment;
close over application services with Flow.localEnv (or Layer.provide) before passing the stream to the spec.
let generated =
[ "first\n"; "second\n" ]
|> List.map Encoding.UTF8.GetBytes
|> FlowStream.fromSeq
|> Input.flowStream
generated => cmd $"cat" |> Process.run |> _.StdOut
|> shouldEqual "first\nsecond\n"
generated: InputSource(|>): '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
Microsoft.FSharp.Collections.ListModuleContains operations for working with values of type . Operations for collections such as lists, arrays, sets, maps and sequences. See also F# Collection Types in the F# Language Guide.
map: ('T -> 'U) -> 'T list -> 'U listBuilds a new collection whose elements are the results of applying the given function to each of the elements of the collection. The function to transform elements from the input list. The input list. The list of transformed elements. let inputs = [ "a"; "bbb"; "cc" ] inputs |> List.map (fun x -> x.Length) Evaluates to [ 1; 3; 2 ] This is an O(n) operation, where n is the length of the list.
System.Text.EncodingRepresents a character encoding.
UTF8: EncodingGets an encoding for the UTF-8 format. An encoding for the UTF-8 format.
GetBytes: string -> byte arrayWhen overridden in a derived class, encodes all the characters in the specified string into a sequence of bytes. The string containing the characters to encode. A byte array containing the results of encoding the specified set of characters. is . A fallback occurred (see Character Encoding in .NET for complete explanation) -and- is set to .
Axial.FlowStreamModulefromSeq: 'value seq -> FlowStream<'env,'error,'value>Creates a stream from a synchronous sequence of values. The sequence of values to be emitted by the stream. A that yields each value from the sequence. FlowStream.fromSeq [1..10] |> FlowStream.runCollect |> Flow.run ()
Axial.Process.DSL.InputflowStream: FlowStream<unit,'error,byte array> -> InputSourceConsumes a cold byte stream with backpressure. Close over dependencies with Flow.localEnv (or Layer.provide) before building the spec.
(=>): ^source -> ^destination -> ^resultcmd: FormattableString -> ProcessCommandAxial.Process.Processrun: ^source -> ^resultRuns with live services and returns the value; raises ProcessRunException on failure.
_arg1: ProcessResultStdOut: stringshouldEqual: 'a -> 'a -> unitRequires & types
Requires: open Axial; open Axial.Process; open Axial.Process.DSL; open System.Text (packages: Axial, Axial.Process)val generated: InputSourceWrite files, append, and tee
Routing and capture are independent: stdoutToFile still captures stdout unless you choose captureNothing.
Configure a final command's route before connecting it, or use
Process.mapFinalCommand to adjust the final command on an existing topology.
An OutputTarget endpoint built by Output.* with => configures a single command; it does not execute it.
let inputPath = Path.GetTempFileName()
let outputPath = Path.GetTempFileName()
let errorPath = Path.GetTempFileName()
try
File.WriteAllText(inputPath, "source\n")
let copied =
cmd $"cat" |> stdinFromFile inputPath |> stdoutToFile outputPath
|> Process.run
shouldEqual "source\n" copied.StdOut
shouldEqual "source\n" (File.ReadAllText outputPath)
cmd $"printf appended" |> stdoutToAppendFile outputPath |> captureNothing
|> Process.run |> _.StdOut |> shouldEqual ""
shouldEqual "source\nappended" (File.ReadAllText outputPath)
sh $"printf warning >&2" |> stderrToFile errorPath |> captureStderrAll
|> Process.run |> _.StdErr |> shouldEqual "warning"
sh $"printf again >&2" |> stderrToAppendFile errorPath
|> Process.run |> ignore
shouldEqual "warningagain" (File.ReadAllText errorPath)
use writer = new StringWriter()
let teed =
cmd $"printf duplicated"
=> Output.tee [ Output.file outputPath; Output.textWriter Encoding.UTF8 writer ]
|> captureTail 4 |> Process.run
shouldEqual "duplicated" (File.ReadAllText outputPath)
shouldEqual "duplicated" (writer.ToString())
shouldEqual "ated" teed.StdOut
finally
File.Delete inputPath
File.Delete outputPath
File.Delete errorPath
inputPath: stringSystem.IO.PathPerforms operations on instances that contain file or directory path information. These operations are performed in a cross-platform manner.
GetTempFileName: unit -> stringCreates a uniquely named, zero-byte temporary file on disk and returns the full path of that file. The full path of the temporary file. An I/O error occurs, such as no unique temporary file name is available. -or- This method was unable to create a temporary file.
outputPath: stringerrorPath: stringSystem.IO.FileProvides static methods for the creation, copying, deletion, moving, and opening of a single file, and aids in the creation of objects.
WriteAllText: string * string -> unitCreates a new file, writes the specified string to the file, and then closes the file. If the target file already exists, it is overwritten. The file to write to. The string to write to the file. is a zero-length string, contains only white space, or contains one or more invalid characters as defined by . is . The specified path, file name, or both exceed the system-defined maximum length. The specified path is invalid (for example, it is on an unmapped drive). An I/O error occurred while opening the file. specified a file that is read-only. -or- specified a file that is hidden. -or- This operation is not supported on the current platform. -or- specified a directory. -or- The caller does not have the required permission. is in an invalid format. The caller does not have the required permission.
copied: 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
stdinFromFile: string -> ProcessCommand -> ProcessCommandstdoutToFile: string -> ProcessCommand -> ProcessCommandAxial.Process.Processrun: ^source -> ^resultRuns with live services and returns the value; raises ProcessRunException on failure.
shouldEqual: 'a -> 'a -> unitStdOut: stringReadAllText: string -> stringOpens a text file, reads all the text in the file, and then closes the file. The file to open for reading. A string containing all the text in the file. is a zero-length string, contains only white space, or contains one or more invalid characters as defined by . is . The specified path, file name, or both exceed the system-defined maximum length. The specified path is invalid (for example, it is on an unmapped drive). An I/O error occurred while opening the file. specified a file that is read-only. -or- This operation is not supported on the current platform. -or- specified a directory. -or- The caller does not have the required permission. The file specified in was not found. is in an invalid format. The caller does not have the required permission.
stdoutToAppendFile: string -> ProcessCommand -> ProcessCommandcaptureNothing: ^a -> 'bSame as Process.captureNothing. Omits stdout retention; stderr diagnostics remain.
_arg1: ProcessResultsh: FormattableString -> ProcessCommandBuilds a POSIX shell program with interpolation values passed as positional arguments.
stderrToFile: string -> ProcessCommand -> ProcessCommandcaptureStderrAll: ^a -> 'bSame as Process.captureStderrAll. Retains readable unmerged stderr completely.
_arg2: ProcessResultStdErr: stringstderrToAppendFile: string -> ProcessCommand -> ProcessCommandignore: 'T -> unitIgnore the passed value. This is often used to throw away results of a computation. The value to ignore. ignore 55555 // Evaluates to ()
writer: StringWriterSystem.IO.StringWriterImplements a for writing information to a string. The information is stored in an underlying .
teed: ProcessResult(=>): ^source -> ^destination -> ^resultAxial.Process.DSL.Outputtee: OutputTarget seq -> OutputTargetSends every byte chunk to each target in order.
file: string -> OutputTargetWrites output to a truncating file.
textWriter: Encoding -> TextWriter -> OutputTargetDecodes output incrementally into a .NET text writer.
System.Text.EncodingRepresents a character encoding.
UTF8: EncodingGets an encoding for the UTF-8 format. An encoding for the UTF-8 format.
captureTail: int -> ^a -> 'bSame as Process.captureTail. Bounds final stdout retention in bytes.
ToString: unit -> stringReturns a string containing the characters written to the current so far. The string containing the characters written to the current .
Delete: string -> unitDeletes the specified file. The name of the file to be deleted. Wildcard characters are not supported. is a zero-length string, contains only white space, or contains one or more invalid characters as defined by . is . The specified path is invalid (for example, it is on an unmapped drive). The specified file is in use. -or- There is an open handle on the file, and the operating system is Windows XP or earlier. This open handle can result from enumerating directories and files. For more information, see How to: Enumerate Directories and Files. is in an invalid format. The specified path, file name, or both exceed the system-defined maximum length. The caller does not have the required permission. -or- The file is an executable file that is in use. -or- is a directory. -or- specified a read-only file.
Requires & types
Requires: open Axial.Process; open Axial.Process.DSL; open System.IO; open System.Text (packages: Axial.Process)val inputPath: stringval outputPath: stringval errorPath: stringThe System.IO.File calls above are docs-test setup: they create and remove scratch files so the routing output can
be checked. In an application, model the filesystem with IFileSystem and a typed FileSystemError; see
FileSystem.
Output.callback receives exact bytes, while Output.stream and Output.textWriter adapt caller-owned .NET
objects. Axial flushes adapters without disposing those objects; a text-writer decoder is fresh for each execution.
do
use source = new MemoryStream(Encoding.UTF8.GetBytes "streamed")
use destination = new MemoryStream()
cmd $"cat" |> stdinFrom (Input.stream source) |> stdoutTo (Output.stream destination)
|> captureNothing |> Process.run |> ignore
shouldEqual "streamed" (Encoding.UTF8.GetString(destination.ToArray()))
shouldEqual true destination.CanWrite
let chunks = ResizeArray<byte>()
cmd $"printf callback"
|> stdoutTo (Output.callback (fun bytes -> Flow.fromAsync (async { chunks.AddRange bytes })))
|> captureNothing |> Process.run |> ignore
shouldEqual "callback" (Encoding.UTF8.GetString(chunks.ToArray()))
source: MemoryStreamSystem.IO.MemoryStreamCreates a stream whose backing store is memory.
System.Text.EncodingRepresents a character encoding.
UTF8: EncodingGets an encoding for the UTF-8 format. An encoding for the UTF-8 format.
GetBytes: string -> byte arrayWhen overridden in a derived class, encodes all the characters in the specified string into a sequence of bytes. The string containing the characters to encode. A byte array containing the results of encoding the specified set of characters. is . A fallback occurred (see Character Encoding in .NET for complete explanation) -and- is set to .
destination: MemoryStreamcmd: 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
stdinFrom: InputSource -> ProcessCommand -> ProcessCommandAxial.Process.DSL.Inputstream: Stream -> InputSourceAdapts a .NET stream into a backpressured input source.
stdoutTo: OutputTarget -> ProcessCommand -> ProcessCommandAxial.Process.DSL.Outputstream: Stream -> OutputTargetAdapts a writable .NET stream into an output target.
captureNothing: ^a -> 'bSame as Process.captureNothing. Omits stdout retention; stderr diagnostics remain.
Axial.Process.Processrun: ^source -> ^resultRuns with live services and returns the value; raises ProcessRunException on failure.
ignore: 'T -> unitIgnore the passed value. This is often used to throw away results of a computation. The value to ignore. ignore 55555 // Evaluates to ()
shouldEqual: 'a -> 'a -> unitGetString: byte array -> stringWhen overridden in a derived class, decodes all the bytes in the specified byte array into a string. The byte array containing the sequence of bytes to decode. A string that contains the results of decoding the specified sequence of bytes. The byte array contains invalid Unicode code points. is . A fallback occurred (see Character Encoding in .NET for complete explanation) -and- is set to .
ToArray: unit -> byte arrayWrites the stream contents to a byte array, regardless of the property. A new byte array.
CanWrite: boolGets a value indicating whether the current stream supports writing. if the stream supports writing; otherwise, .
chunks: ResizeArray<byte>``.ctor``: unit -> unitInitializes a new instance of the class that is empty and has the default initial capacity.
byteAn abbreviation for the CLI type . Basic Types
callback: (byte array -> Flow<unit,'error,unit>) -> OutputTargetSends exact byte chunks to a backpressured Flow callback using the process cancellation token.
bytes: byte arrayAxial.FlowfromAsync: Async<'value> -> Flow<'env,'error,'value>Creates a flow from a raw async operation. Thrown exceptions are recorded as defects (Cause.Die). Cancellation is recorded as interruption when the runtime token requested it, and as a defect otherwise. Use attemptAsync when expected exceptions should enter the typed error channel. Fable compatible
async: AsyncBuilderBuilds an asynchronous workflow using computation expression syntax. let sleepExample() = async { printfn "sleeping" do! Async.Sleep 10 printfn "waking up" return 6 } sleepExample() |> Async.RunSynchronously
AddRange: byte seq -> unitAdds the elements of the specified collection to the end of the . The collection whose elements should be added to the end of the . The collection itself cannot be , but it can contain elements that are , if type is a reference type. is .
ToArray: unit -> byte arrayCopies the elements of the to a new array. An array containing copies of the elements of the .
Requires & types
Requires: open Axial; open Axial.Process; open Axial.Process.DSL; open System.IO; open System.Text (packages: Axial, Axial.Process)stdoutToConsole and stderrToConsole forward redirected bytes through the injected console. The
*ToInheritHandles variants give the child native handles directly; inherited channels cannot be captured,
observed, or teed. stdoutToDiscard and stderrToDiscard drain without forwarding; capture remains independent.
let captured = cmd $"printf retained" |> stdoutToDiscard |> Process.run
shouldEqual "retained" captured.StdOut
let quiet =
sh $"printf warning >&2" |> stderrToDiscard |> captureStderrNothing
|> Process.run
shouldEqual "" quiet.StdErr
captured: 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
stdoutToDiscard: ProcessCommand -> ProcessCommandAxial.Process.Processrun: ^source -> ^resultRuns with live services and returns the value; raises ProcessRunException on failure.
shouldEqual: 'a -> 'a -> unitStdOut: stringquiet: ProcessResultsh: FormattableString -> ProcessCommandBuilds a POSIX shell program with interpolation values passed as positional arguments.
stderrToDiscard: ProcessCommand -> ProcessCommandcaptureStderrNothing: ^a -> 'bSame as Process.captureStderrNothing. Omits stderr diagnostic retention.
StdErr: stringRequires & types
Requires: open Axial.Process; open Axial.Process.DSL (packages: Axial.Process)val captured: ProcessResultval quiet: ProcessResultKeep stderr separate or explicitly merge it
Batch output defaults to full stdout and separate stderr tails. mergeStderr joins final stderr into the
observed stdout channel. pipeStdoutAndStderrTo instead feeds both native channels into the next command.
Order between independently written channels is not guaranteed.
let separated = sh $"printf data; printf warning >&2" |> Process.run
shouldEqual "data" separated.StdOut
shouldEqual "warning" separated.StdErr
let merged =
sh $"printf 'data\n'; printf 'warning\n' >&2" |> mergeStderr
|> Process.run
let words =
merged.StdOut.Split('\n', StringSplitOptions.RemoveEmptyEntries)
|> Array.sort
|> Array.toList
shouldEqual ["data"; "warning"] words
shouldEqual "" merged.StdErr
sh $"printf 'data\n'; printf 'warning\n' >&2"
|> pipeStdoutAndStderrTo (cmd $"sort") |> Process.run |> _.StdOut
|> shouldEqual "data\nwarning\n"
separated: ProcessResultsh: FormattableString -> ProcessCommandBuilds a POSIX shell program with interpolation values passed as positional arguments.
(|>): '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
Axial.Process.Processrun: ^source -> ^resultRuns with live services and returns the value; raises ProcessRunException on failure.
shouldEqual: 'a -> 'a -> unitStdOut: stringStdErr: stringmerged: ProcessResultmergeStderr: ^a -> ProcessSpecwords: string listSplit: char * StringSplitOptions -> string arraySystem.StringSplitOptionsSpecifies whether applicable method overloads include or omit empty substrings from the return value.
RemoveEmptyEntries: StringSplitOptionsThe return value does not include array elements that contain an empty string
Microsoft.FSharp.Collections.ArrayModuleContains operations for working with arrays. See also F# Language Guide - Arrays.
sort: 'T array -> 'T arraySorts the elements of an array, returning a new array. Elements are compared using . This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. For a stable sort, consider using . This is an O(n log n) operation, where n is the length of the array. The input array. The sorted array. Thrown when the input array is null. let input = [| 8; 4; 3; 1; 6; 1 |] Array.sort input Evaluates to [| 1; 1; 3; 4; 6; 8 |].
toList: 'T array -> 'T listBuilds a list from the given array. The input array. The list of array elements. Thrown when the input array is null. let inputs = [| 1; 2; 5 |] inputs |> Array.toList Evaluates to [ 1; 2; 5 ]. This is an O(n) operation, where n is the length of the array.
pipeStdoutAndStderrTo: ^a -> ^b -> ProcessSpeccmd: FormattableString -> ProcessCommand_arg1: ProcessResultRequires & types
Requires: open Axial.Process; open Axial.Process.DSL; open System (packages: Axial.Process)val separated: ProcessResultval merged: ProcessResultval words: string listFan in producers or capture independent commands
mergeStdout combines producers at line boundaries before a downstream consumer. Relative producer order
is unspecified, so sort when the result needs a stable order. mergeStdoutBytes forwards byte chunks without
line framing; use it when line preservation is unnecessary, rather than for independently structured binary files.
let ordered =
[cmd $"printf 'beta\n'"; cmd $"printf 'alpha\n'"]
|> mergeStdout |> pipeTo (cmd $"sort") |> Process.run
shouldEqual "alpha\nbeta\n" ordered.StdOut
let bytes =
[cmd $"printf A"; cmd $"printf B"]
|> mergeStdoutBytes |> pipeTo (cmd $"cat") |> Process.run
shouldEqual [65uy; 66uy] (bytes.StdOutCapture.Bytes |> Array.sort |> Array.toList)
let concurrentCaptures = [cmd $"printf first"; cmd $"printf second"] |> captureParallel 2
let results = concurrentCaptures |> Process.run
shouldEqual ["first"; "second"] (results |> List.map _.StdOut)
ordered: 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
mergeStdout: ^a seq -> ProcessSpecpipeTo: ^a -> ^b -> ProcessSpecAxial.Process.Processrun: ^source -> ^resultRuns with live services and returns the value; raises ProcessRunException on failure.
shouldEqual: 'a -> 'a -> unitStdOut: stringbytes: ProcessResultmergeStdoutBytes: ^a seq -> ProcessSpecBytes: byte arrayStdOutCapture: CapturedOutputMicrosoft.FSharp.Collections.ArrayModuleContains operations for working with arrays. See also F# Language Guide - Arrays.
sort: 'T array -> 'T arraySorts the elements of an array, returning a new array. Elements are compared using . This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. For a stable sort, consider using . This is an O(n log n) operation, where n is the length of the array. The input array. The sorted array. Thrown when the input array is null. let input = [| 8; 4; 3; 1; 6; 1 |] Array.sort input Evaluates to [| 1; 1; 3; 4; 6; 8 |].
toList: 'T array -> 'T listBuilds a list from the given array. The input array. The list of array elements. Thrown when the input array is null. let inputs = [| 1; 2; 5 |] inputs |> Array.toList Evaluates to [ 1; 2; 5 ]. This is an O(n) operation, where n is the length of the array.
concurrentCaptures: Flow<ProcessHostEnvironment,ProcessError,ProcessResult list>captureParallel: int -> ^a seq -> Flow<'b,ProcessError,ProcessResult list>Captures independent commands or specs with bounded workflow concurrency, preserving input order.
results: ProcessResult listMicrosoft.FSharp.Collections.ListModuleContains operations for working with values of type . Operations for collections such as lists, arrays, sets, maps and sequences. See also F# Collection Types in the F# Language Guide.
map: ('T -> 'U) -> 'T list -> 'U listBuilds a new collection whose elements are the results of applying the given function to each of the elements of the collection. The function to transform elements from the input list. The input list. The list of transformed elements. let inputs = [ "a"; "bbb"; "cc" ] inputs |> List.map (fun x -> x.Length) Evaluates to [ 1; 3; 2 ] This is an O(n) operation, where n is the length of the list.
_arg1: ProcessResultRequires & types
Requires: open Axial.Process; open Axial.Process.DSL (packages: Axial.Process)val ordered: ProcessResultval bytes: ProcessResultval concurrentCaptures: Flow<ProcessHostEnvironment,ProcessError,ProcessResult list>val results: ProcessResult listcaptureParallel limits concurrent workflows and preserves the input order of results. It does not connect
commands' streams. Homogeneous lists may contain commands or already connected specs.
Apply defaults and override the final stage
stageDefaults supplies fallbacks for every stage, including stages connected later. Explicit settings win;
withoutTimeout explicitly disables a fallback timeout. Destination topology defaults win when combining
policies. Environment defaults resolve per key: env overrides a fallback, and Process.removeEnvironment
removes a key even when the defaults supply it. Use Process.plan to inspect resolution and provenance without
starting processes.
let defaults = StageDefaults.empty |> StageDefaults.timeout (TimeSpan.FromSeconds 5.)
let pipeline =
cmd $"printf ready" |> stageDefaults defaults
|> pipeTo (cmd $"cat" |> withoutTimeout)
|> Process.mapFinalCommand (Process.captureTail 3)
let plan = Process.plan pipeline
shouldEqual (Some(TimeSpan.FromSeconds 5.)) plan.Stages[0].Timeout
shouldEqual None plan.Stages[1].Timeout
shouldEqual "command" plan.Stages[1].Provenance["timeout"]
pipeline |> Process.run |> _.StdOut |> shouldEqual "ady"
defaults: StageDefaultsAxial.Process.StageDefaultsModuleempty: StageDefaults(|>): '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
timeout: TimeSpan -> StageDefaults -> StageDefaultsSystem.TimeSpanRepresents a time interval.
FromSeconds: float -> TimeSpanReturns a that represents a specified number of seconds, where the specification is accurate to the nearest millisecond. A number of seconds, accurate to the nearest millisecond. An object that represents . is less than or greater than . -or- is . -or- is . is equal to .
pipeline: ProcessSpeccmd: FormattableString -> ProcessCommandstageDefaults: StageDefaults -> ^a -> ProcessSpecpipeTo: ^a -> ^b -> ProcessSpecwithoutTimeout: ProcessCommand -> ProcessCommandAxial.Process.ProcessmapFinalCommand: (ProcessCommand -> ProcessCommand) -> ProcessSpec -> ProcessSpecChanges settings on the unique final command; executable and arguments must remain unchanged.
captureTail: int -> ^source -> ^resultRetains the last size bytes of final stdout. Byte boundaries may split encoded characters.
plan: ProcessPlanplan: ^a -> ProcessPlanshouldEqual: 'a -> 'a -> unitSomeThe representation of "Value of type 'T" The input value. An option representing the value.
Stages: ProcessStagePlan listItem: ProcessStagePlanGets the element of the list at the given position. Lists are represented as linked lists so this is an O(n) operation. The index. The value at the given index.
Timeout: TimeSpan optionNoneThe representation of "No value"
Provenance: Map<string,string>Item: stringLookup an element in the map. Raise KeyNotFoundException if no binding exists in the map. The input key. Thrown when the key is not found. The value mapped to the key. Maps are represented as binary trees so this is an O(log n) operation, where n is the number of bindings in the map. let sample = Map [ (1, "a"); (2, "b") ] sample.[1] // evaluates to "a" sample.[3] // throws KeyNotFoundException
run: ^source -> ^resultRuns with live services and returns the value; raises ProcessRunException on failure.
_arg1: ProcessResultStdOut: stringRequires & types
Requires: open Axial.Process; open Axial.Process.DSL; open System (packages: Axial.Process)val defaults: StageDefaultsval pipeline: ProcessSpecval plan: ProcessPlanUse qualified command helpers where the DSL has no shortcut, such as Process.successCodes,
Process.removeEnvironment, Process.encoding, and Process.commandArgs.
let accepted = sh $"exit 3" |> Process.successCodes [0; 3] |> Process.run
shouldEqual 3 accepted.ExitCode
accepted: ProcessResultsh: FormattableString -> ProcessCommandBuilds a POSIX shell program with interpolation values passed as positional arguments.
(|>): '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
Axial.Process.ProcesssuccessCodes: int seq -> ProcessCommand -> ProcessCommandrun: ^source -> ^resultRuns with live services and returns the value; raises ProcessRunException on failure.
shouldEqual: 'a -> 'a -> unitExitCode: intRequires & types
Requires: open Axial.Process; open Axial.Process.DSL (packages: Axial.Process)val accepted: ProcessResultSequence commands and recover through Flow
=> connects native streams; it does not mean “run the next command after success.” Use flow { } for
sequential application work and Flow.orElseWith for typed recovery. Keep command failures in the application's
normal error channel until the host boundary decides its policy.
let sequential = flow {
let! first = cmd $"printf first" |> toFlow
let! second = cmd $"printf second" |> toFlow
return first.StdOut + ":" + second.StdOut
}
sequential |> Process.run |> shouldEqual "first:second"
let recovered =
sh $"exit 7" |> toFlow
|> Flow.orElseWith (fun _ -> cmd $"printf fallback" |> toFlow)
recovered |> Process.run |> _.StdOut |> shouldEqual "fallback"
sequential: Flow<ProcessHostEnvironment,ProcessError,string>flow: FlowBuilderThe universal flow { } computation expression.
first: 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>second: ProcessResultStdOut: string(+): ^T1 -> ^T2 -> ^T3Overloaded addition operator The first parameter. The second parameter. The result of the operation. 2 + 2 // Evaluates to 4 "Hello " + "World" // Evaluates to "Hello World"
Axial.Process.Processrun: ^source -> ^resultRuns with live services and returns the value; raises ProcessRunException on failure.
shouldEqual: 'a -> 'a -> unitrecovered: Flow<ProcessHostEnvironment,ProcessError,ProcessResult>sh: FormattableString -> ProcessCommandBuilds a POSIX shell program with interpolation values passed as positional arguments.
Axial.FloworElseWith: ('error -> Flow<'env,'error,'value>) -> Flow<'env,'error,'value> -> Flow<'env,'error,'value>Computes a fallback flow from the typed error when the source flow fails. The fallback runs only for expected typed failures represented by Cause.Fail. It does not catch interruption or defects. Use this for domain-level recovery, not for swallowing cancellation or unexpected exceptions. A function that produces a new flow from the error value. The source flow. A flow that recovers from errors using the fallback function. let flow = Flow.fail "error" |> Flow.orElseWith (fun err -> Flow.succeed "recovered")
_arg1: ProcessResultRequires & types
Requires: open Axial; open Axial.Process; open Axial.Process.DSL (packages: Axial, Axial.Process)val sequential: Flow<ProcessHostEnvironment,ProcessError,string>val recovered: Flow<ProcessHostEnvironment,ProcessError,ProcessResult>Use streaming output for completion-aware transformations and effectful consumers,
and scripts for safe shell interpolation and the Process.run boundary.

