Fli 1.1.0
See the version list below for details.
dotnet add package Fli --version 1.1.0
NuGet\Install-Package Fli -Version 1.1.0
<PackageReference Include="Fli" Version="1.1.0" />
paket add Fli --version 1.1.0
#r "nuget: Fli, 1.1.0"
// Install Fli as a Cake Addin #addin nuget:?package=Fli&version=1.1.0 // Install Fli as a Cake Tool #tool nuget:?package=Fli&version=1.1.0
Fli
Execute CLI commands from your F# code in F# style!
Fli is part of the F# Advent Calendar 2022: A little story about Fli
Features
- Starting processes easily
- Execute CLI commands in your favourite shell
- F# computation expression syntax
- Wrap authenticated CLI tools
- No external dependencies
Install
Get it from Nuget: dotnet add package Fli
Usage
open Fli
and start
For example:
cli {
Shell CMD
Command "echo Hello World!"
}
|> Command.execute
that starts CMD.exe
as Shell and echo Hello World!
is the command to execute.
Run a file with PowerShell from a specific directory:
cli {
Shell PWSH
Command "test.bat"
WorkingDirectory (Environment.GetFolderPath Environment.SpecialFolder.UserProfile)
}
|> Command.execute
Executing programs with arguments:
cli {
Exec "path/to/executable"
Arguments "--info"
}
|> Command.execute
an example with git
:
cli {
Exec "git"
Arguments ["commit"; "-m"; "Fixing issue #1337."]
}
|> Command.execute
Add a verb to your executing program:
cli {
Exec "adobe.exe"
Arguments (Path.Combine ((Environment.GetFolderPath Environment.SpecialFolder.UserProfile), "test.pdf"))
Verb "open"
}
|> Command.execute
Write output to a specific file:
cli {
Exec "dotnet"
Arguments "--list-sdks"
Output @"absolute\path\to\dotnet-sdks.txt"
}
|> Command.execute
Write output to a function (logging, printing, etc.):
let log (output: string) = Debug.Log($"CLI log: {output}")
cli {
Exec "dotnet"
Arguments "--list-sdks"
Output log
}
|> Command.execute
Add environment variables for the executing program:
cli {
Exec "git"
EnvironmentVariables [("GIT_AUTHOR_NAME", "Jon Doe"); ("GIT_AUTHOR_EMAIL", "jon.doe@domain.com")]
}
|> Command.execute
Add credentials to program:
cli {
Exec "program"
Credentials ("domain", "bobk", "password123")
}
|> Command.execute
Hint: Running a process as a different user is supported on all platforms. Other options (Domain, Password) are only available on Windows. As an alternative for not Windows based systems there is:
cli {
Exec "path/to/program"
Username "admin"
}
|> Command.execute
Command.execute
Command.execute
returns record: type Output = { Id: int; Text: string option; ExitCode: int; Error: string option }
which has getter methods to get only one value:
toId: Output -> int
toText: Output -> string
toExitCode: Output -> int
toError: Output -> string
example:
cli {
Shell CMD
Command "echo Hello World!"
}
|> Command.execute // { Id = 123; Text = Some "Hello World!"; ExitCode = 0; Error = None }
|> Output.toText // "Hello World!"
// same with Output.toId:
cli { ... }
|> Command.execute // { Id = 123; Text = Some "Hello World!"; ExitCode = 0; Error = None }
|> Output.toId // 123
// same with Output.toExitCode:
cli { ... }
|> Command.execute // { Id = 123; Text = Some "Hello World!"; ExitCode = 0; Error = None }
|> Output.toExitCode // 0
// in case of an error:
cli { ... }
|> Command.execute // { Id = 123; Text = None; ExitCode = 1; Error = Some "This is an error!" }
|> Output.toError // "This is an error!"
Printing Output
fields
There are printing methods in Output
too:
printId: Output -> unit
printText: Output -> unit
printExitCode: Output -> unit
printError: Output -> unit
Instead of writing:
cli { ... }
|> Command.execute
|> Output.toText
|> printfn "%s"
For a little shorter code you can use:
cli { ... }
|> Command.execute
|> Output.printText
Command.toString
Command.toString
concatenates only the the executing shell/program + the given commands/arguments:
cli {
Shell PS
Command "Write-Host Hello World!"
}
|> Command.toString // "powershell.exe -Command Write-Host Hello World!"
and:
cli {
Exec "cmd.exe"
Arguments [ "/C"; "echo"; "Hello World!" ]
}
|> Command.toString // "cmd.exe /C echo Hello World!"
Builder operations:
ShellContext
operations (cli { Shell ... }
):
| Operation | Type |
|------------------------|----------------------------|
| Shell
| Fli.Shells
|
| Command
| string
|
| Input
| string
|
| Output
| Outputs
(see below) |
| WorkingDirectory
| string
|
| EnvironmentVariable
| string * string
|
| EnvironmentVariables
| (string * string) list
|
| Encoding
| System.Text.Encoding
|
| CancelAfter
| int
|
ExecContext
operations (cli { Exec ... }
):
| Operation | Type |
|------------------------|----------------------------------------------------------|
| Exec
| string
|
| Arguments
| string
/ string seq
/ string list
/ string array
|
| Input
| string
|
| Output
| Outputs
(see below) |
| Verb
| string
|
| Username
| string
|
| Credentials
| string * string * string
|
| WorkingDirectory
| string
|
| EnvironmentVariable
| string * string
|
| EnvironmentVariables
| (string * string) list
|
| Encoding
| System.Text.Encoding
|
| CancelAfter
| int
|
Currently provided Fli.Shells
:
CMD
runscmd.exe /c ...
orcmd.exe /k ...
(depends ifInput
is provided or not)PS
runspowershell.exe -Command ...
PWSH
runspwsh.exe -Command ...
WSL
runswsl.exe -- ...
BASH
runsbash -c ...
CUSTOM (shell: string * flag: string)
runs the specifiedshell
with the specified starting argument (flag
)
Provided Fli.Outputs
:
File of string
a string with an absolute path of the output file.StringBuilder of StringBuilder
a StringBuilder which will be filled with the output text.Custom of Func<string, unit>
a custom function (string -> unit
) that will be called with the output string (logging, printing etc.).
Do you miss something?
Open an issue or start a discussion.
Inspiration
Use CE's for CLI commands came in mind while using FsHttp.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
- FSharp.Core (>= 6.0.7)
Version | Downloads | Last updated | |
---|---|---|---|
1.111.10 | 4,568 | 5/31/2024 | |
1.111.1 | 131 | 5/24/2024 | |
1.111.0 | 1,094 | 4/16/2024 | |
1.110.0 | 142 | 4/12/2024 | |
1.101.0 | 1,753 | 1/9/2024 | |
1.100.10 | 276 | 11/24/2023 | |
1.100.1 | 141 | 11/24/2023 | |
1.100.0 | 142 | 11/24/2023 | |
1.11.0 | 1,542 | 10/6/2023 | |
1.10.1 | 2,665 | 9/1/2023 | |
1.10.0 | 485 | 8/11/2023 | |
1.1.1 | 4,016 | 7/25/2023 | |
1.1.0 | 691 | 5/29/2023 | |
1.0.1 | 4,392 | 2/2/2023 | |
1.0.0 | 489 | 12/17/2022 | |
0.11.0 | 1,269 | 11/11/2022 | |
0.9.0 | 416 | 10/18/2022 | |
0.8.0 | 424 | 10/12/2022 | |
0.7.0 | 387 | 10/7/2022 | |
0.6.1 | 391 | 10/4/2022 | |
0.6.0 | 400 | 10/4/2022 | |
0.0.2 | 423 | 9/29/2022 |
- Slightly change signature of `Output` CustomOperation. (https://github.com/CaptnCodr/Fli/pull/51)
- Add `CancelAfter` CustomOperation for `executeAsync` to cancel after a specific amount of time (milliseconds). (https://github.com/CaptnCodr/Fli/pull/50)
(All release notes: https://github.com/CaptnCodr/Fli/blob/main/RELEASE_NOTES.md)