I'm very new to F# and I'm trying to create a console application that takes parameters. I found the Argu library and have been trying to get a basic example to work. The following works as expection if passed the --commanda or --commandb arguments, but I get an exception if I try --help.
open System
open Argu
type CliArguments =
| CommandA
| CommandB
with
interface IArgParserTemplate with
member s.Usage =
match s with
| CommandA -> "CommandA - Do something"
| CommandB -> "CommandB - Do something"
[<EntryPoint>]
let main argv =
let parser = ArgumentParser.Create<CliArguments>()
let results = parser.Parse argv
results.GetAllResults()
|> List.iter (fun x ->
match x with
| CommandA -> printfn "CommandA"
| CommandB -> printfn "CommandB")
0
The exception is:
> .\Argu_sample.exe --help
Unhandled Exception: Argu.ArguParseException: USAGE: Argu_sample.exe [--help] [--commanda] [--commandb]
OPTIONS:
--commanda CommandA - Do something
--commandb CommandB - Do something
--help display this list of options.
at Argu.ExceptionExiter.Argu-IExiter-Exit[a](String msg, ErrorCode errorCode)
at Argu.ArgumentParser`1.Parse(FSharpOption`1 inputs, FSharpOption`1 configurationReader, FSharpOption`1 ignoreMissing, FSharpOption`1 ignoreUnrecognized, FSharpOption`1 raiseOnUsage)
at Program.main(String[] argv) in C:\Data\FSharp\Argu-sample\Argu-sample\Program.fs:line 18
What am I doing wrong?
Thanks.
UPDATED CODE WITH SOLUTION:
Based on AMieres comment, I ended up using try with:
open System
open Argu
type CliArguments =
| CommandA
| CommandB
with
interface IArgParserTemplate with
member s.Usage =
match s with
| CommandA -> "CommandA - Do something"
| CommandB -> "CommandB - Do something"
[<EntryPoint>]
let main argv =
let parser = ArgumentParser.Create<CliArguments>()
try
let results = parser.Parse argv
results.GetAllResults()
|> List.iter (fun x ->
match x with
| CommandA -> printfn "CommandA"
| CommandB -> printfn "CommandB")
0
with
| :? ArguParseException as ex ->
printfn "%s" ex.Message
1
| ex ->
printfn "Internal Error:"
printfn "%s" ex.Message
2
I seems to be an undocumented feature.
The --help is treated as an exception and you need to either handle it with try with or provide a handler.
Check out the sample in Github: https://github.com/fsprojects/Argu/blob/master/samples/Argu.Samples.LS/Program.fs.
In it, the parser is created with an error handler:
let errorHandler = ProcessExiter(colorizer = function ErrorCode.HelpText -> None | _ -> Some ConsoleColor.Red)
let parser = ArgumentParser.Create<LsArguments>(programName = "ls", errorHandler = errorHandler)
When in doubt consult the code: https://github.com/fsprojects/Argu/blob/b1569917af314dfd3b77fb79fec2a157a51324c7/src/Argu/Types.fs#L29
/// Error codes reported by Argu
type ErrorCode =
| HelpText = 0
| AppSettings = 1
| CommandLine = 2
| PostProcess = 3
You need to provide an error handler:
let errorHandler = ProcessExiter(colorizer = function ErrorCode.HelpText -> None | _ -> Some ConsoleColor.Red)
let parser = ArgumentParser.Create<CliArguments>(errorHandler = errorHandler)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With