diff --git a/CliWrap.FSharp.sln b/CliWrap.FSharp.sln
index a396a7f..286879c 100644
--- a/CliWrap.FSharp.sln
+++ b/CliWrap.FSharp.sln
@@ -1,4 +1,4 @@
-
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
@@ -25,6 +25,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "github", "github", "{FE346152-5716-4224-9B25-C6B3815C70CA}"
ProjectSection(SolutionItems) = preProject
.github\workflows\main.yml = .github\workflows\main.yml
+ .github\renovate.json = .github\renovate.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "config", "config", "{BC50591F-A365-4A92-9FDC-4CD2D75EE6A4}"
diff --git a/README.md b/README.md
index 564555e..5c6f680 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# CliWrap.FSharp
-Idiomatic F# support for CliWrap
+Idiomatic F# support for CliWrap.
## Usage
@@ -17,11 +17,59 @@ let main args =
cmd.ExecuteAsync()
```
+The computation expression also supports executing the command with `exec`.
+
+```fsharp
+let main args = task {
+ let! result = command "dotnet" {
+ args = [ "build" ]
+ workingDirectory = "~/src/CliWrap.FSharp"
+ exec
+ }
+
+ result.ExitCode
+}
+```
+
+Cancellation is also supported.
+
+```fsharp
+let main args = task {
+ use cts = new CancellationTokenSource()
+ let! result = command "dotnet" {
+ args = [ "build" ]
+ workingDirectory = "~/src/CliWrap.FSharp"
+ exec cts.Token
+ }
+
+ result.ExitCode
+}
+```
+
+CliWrap's buffered execution is supported with `buffered`.
+
+```fsharp
+let main args = task {
+ use cts = new CancellationTokenSource()
+ let! result = command "dotnet" {
+ args = [ "build" ]
+ workingDirectory = "~/src/CliWrap.FSharp"
+ buffered Encoding.UTF8 cts.Token
+ }
+
+ result.ExitCode
+}
+```
+
+Asynchrony with F#'s `Async<'T>` is supported with `async`.
+
```fsharp
let main args = async {
- let! result = exec "dotnet" {
+ use cts = new CancellationTokenSource()
+ let! result = command "dotnet" {
args = [ "build" ]
workingDirectory = "~/src/CliWrap.FSharp"
+ async cts.Token
}
result.ExitCode
@@ -38,10 +86,12 @@ let main args =
cmd.ExecuteAsync()
```
-## Idiomatic? This looks nothing like normal F# code!
+## Q/A
+
+### Idiomatic? This looks nothing like the F# I write!
-I've only recently been diving further into the F# ecosystem, if something looks off please open an issue!
+If something looks off please open an issue! I've only recently been diving further into the F# ecosystem.
-## Why not paket?
+### Why not paket?
If renovate ever [supports it](https://github.com/renovatebot/renovate/issues/11211)!
diff --git a/src/CliWrap.FSharp/CliWrap.FSharp.fsproj b/src/CliWrap.FSharp/CliWrap.FSharp.fsproj
index 058ae27..564fe55 100644
--- a/src/CliWrap.FSharp/CliWrap.FSharp.fsproj
+++ b/src/CliWrap.FSharp/CliWrap.FSharp.fsproj
@@ -12,7 +12,6 @@
-
diff --git a/src/CliWrap.FSharp/CommandBuilder.fs b/src/CliWrap.FSharp/CommandBuilder.fs
index 4363cee..8b10887 100644
--- a/src/CliWrap.FSharp/CommandBuilder.fs
+++ b/src/CliWrap.FSharp/CommandBuilder.fs
@@ -2,7 +2,9 @@
module UnMango.CliWrap.FSharp.CommandBuilder
open System.ComponentModel
+open System.Text
open CliWrap
+open CliWrap.Buffered
type CommandBuilder(target: string) =
[]
@@ -11,6 +13,12 @@ type CommandBuilder(target: string) =
[]
member _.Run(command: Command) = command
+ []
+ member _.Run<'T>(command: CommandTask<'T>) = command
+
+ []
+ member _.Run<'T>(task: Async<'T>) = task
+
[]
member _.Env(command: Command, env) = Cli.env env command
@@ -47,4 +55,31 @@ type CommandBuilder(target: string) =
[]
member _.Validation(command: Command, validation) = Cli.validation validation command
+ []
+ member _.Exec(command: Command) = command.ExecuteAsync()
+
+ []
+ member _.Exec(command: Command, cancellationToken) = command.ExecuteAsync(cancellationToken)
+
+ []
+ member _.Buffered(command: Command) = command.ExecuteBufferedAsync()
+
+ []
+ member _.Buffered(command: Command, encoding: Encoding) = command.ExecuteBufferedAsync(encoding)
+
+ []
+ member _.Buffered(command: Command, encoding, cancellationToken) =
+ command.ExecuteBufferedAsync(encoding, cancellationToken)
+
+ []
+ member _.Async<'T>(task: CommandTask<'T>) =
+ task |> CommandTask.op_Implicit |> Async.AwaitTask
+
+ []
+ member this.Async(command: Command) = this.Async(command.ExecuteAsync())
+
+ []
+ member this.Async(command: Command, cancellationToken) =
+ this.Async(command.ExecuteAsync(cancellationToken))
+
let command target = CommandBuilder(target)
diff --git a/src/CliWrap.FSharp/ExecBuilder.fs b/src/CliWrap.FSharp/ExecBuilder.fs
deleted file mode 100644
index 52a2ca6..0000000
--- a/src/CliWrap.FSharp/ExecBuilder.fs
+++ /dev/null
@@ -1,41 +0,0 @@
-[]
-module UnMango.CliWrap.FSharp.ExecBuilder
-
-open System
-open System.ComponentModel
-open System.Threading
-open CliWrap
-
-type State =
- { Command: Command
- Cts: CancellationTokenSource }
-
- interface IDisposable with
- member this.Dispose() = this.Cts.Dispose()
-
-module State =
- let initial name =
- { Command = Command(name)
- Cts = new CancellationTokenSource() }
-
-type ExecBuilder(name: string) =
- []
- member _.Yield(_: unit) = State.initial name
-
- []
- member _.Run(state: State) =
- state.Command.ExecuteAsync(state.Cts.Token)
- |> CommandTask.op_Implicit
- |> Async.AwaitTask
-
- []
- member _.Args(state: State, args: string) =
- { state with
- Command = state.Command.WithArguments(args) }
-
- []
- member _.Args(state: State, args: string seq) =
- { state with
- Command = state.Command.WithArguments(args) }
-
-let exec name = ExecBuilder(name)