F#/Argu - 如何在不抛出异常的情况下显示两级命令树的帮助
F# / Argu - How to display help for two level command tree without throwing exception
我有一个两级 F#/Argu 命令树。它的缩写版本看起来像这样:
[<CliPrefix(CliPrefix.Dash)>]
type RunContGenArgs =
| [<Unique>] [<EqualsAssignment>] [<AltCommandLine("-ql")>] MaxQueueLength of int
with
interface IArgParserTemplate with
member this.Usage =
match this with
| MaxQueueLength _ -> "max queue length."
and
[<CliPrefix(CliPrefix.None)>]
ContGenArguments =
| [<Unique>] [<AltCommandLine("run")>] RunContGen of ParseResults<RunContGenArgs>
with
interface IArgParserTemplate with
member this.Usage =
match this with
| RunContGen _ -> "run Continuous Generation."
然后我使用如下:
[<EntryPoint>]
let main argv =
let parser = ArgumentParser.Create<ContGenArguments>(programName = "ContGen.exe")
let results = parser.Parse argv
match results.GetAllResults() |> ContGenTask.tryCreate with
| Some task -> task.run()
| None ->
printfn "%s" (parser.PrintUsage())
-1
如果我 运行 命令如 ContGen.exe run help
,那么它会正确显示命令 run
的帮助。然而,它随后崩溃并出现丑陋的异常:
Unhandled Exception: Argu.ArguParseException: USAGE: ContGen.exe runcontgen [help] [-maxqueuelength=<int>]
OPTIONS:
-maxqueuelength, -ql=<int>
max queue length.
help display this list of options.
at Argu.ExceptionExiter.Argu-IExiter-Exit[a](String msg, ErrorCode errorCode) in C:\Users\eirik.tsarpalis\devel\public\Argu\src\Argu\Types.fs:line 62
at Argu.ArgumentParser\`1.Parse(FSharpOption\`1 inputs, FSharpOption\`1 configurationReader, FSharpOption\`1 ignoreMissing, FSharpOption\`1 ignoreUnrecognized, FSharpOption\`1 raiseOnUsage) in C:\Users\eirik.tsarpalis\devel\public\Argu\src\Argu\ArgumentParser.fs:line 180
at Program.main(String[] argv) in C:\GitHub\ClmFSharp\Clm\ContGen\Program.fs:line 8
如果我将 let results = parser.Parse argv
更改为 let results = parser.Parse(argv, raiseOnUsage = false)
,则它不会崩溃但不会显示任何帮助消息。然后由于命令 run
可以 运行 没有任何第二级参数,程序只是继续运行而不是显示帮助并退出。
但是,我需要 ContGen.exe run help
只显示帮助信息然后退出。我怎样才能做到这一点?谢谢。
这是Argu的一个有点奇怪的行为;您需要提供自己的退出器以避免在那里抛出异常。
大致如下:
type NonThrowingExiter() =
interface IExiter with
member __.Name = "Exiter" // I don't know what this is used for; I have never seen it appear anywhere
member __.Exit (msg, code) =
if code = ErrorCode.HelpText then
printfn "%s" msg
exit 0
else
printfn "%s" msg // Maybe have code to color the console output red here
exit 1
To use this, create your `ArgumentParser` like this:
let argumentParser =
Argu.ArgumentParser.Create<ContGenArguments>(helpTextMessage = "Help requested",
errorHandler = NonThrowingExiter())
(当然,您实际上不需要为此创建 class;对象表达式也可以。)
我有一个两级 F#/Argu 命令树。它的缩写版本看起来像这样:
[<CliPrefix(CliPrefix.Dash)>]
type RunContGenArgs =
| [<Unique>] [<EqualsAssignment>] [<AltCommandLine("-ql")>] MaxQueueLength of int
with
interface IArgParserTemplate with
member this.Usage =
match this with
| MaxQueueLength _ -> "max queue length."
and
[<CliPrefix(CliPrefix.None)>]
ContGenArguments =
| [<Unique>] [<AltCommandLine("run")>] RunContGen of ParseResults<RunContGenArgs>
with
interface IArgParserTemplate with
member this.Usage =
match this with
| RunContGen _ -> "run Continuous Generation."
然后我使用如下:
[<EntryPoint>]
let main argv =
let parser = ArgumentParser.Create<ContGenArguments>(programName = "ContGen.exe")
let results = parser.Parse argv
match results.GetAllResults() |> ContGenTask.tryCreate with
| Some task -> task.run()
| None ->
printfn "%s" (parser.PrintUsage())
-1
如果我 运行 命令如 ContGen.exe run help
,那么它会正确显示命令 run
的帮助。然而,它随后崩溃并出现丑陋的异常:
Unhandled Exception: Argu.ArguParseException: USAGE: ContGen.exe runcontgen [help] [-maxqueuelength=<int>]
OPTIONS:
-maxqueuelength, -ql=<int>
max queue length.
help display this list of options.
at Argu.ExceptionExiter.Argu-IExiter-Exit[a](String msg, ErrorCode errorCode) in C:\Users\eirik.tsarpalis\devel\public\Argu\src\Argu\Types.fs:line 62
at Argu.ArgumentParser\`1.Parse(FSharpOption\`1 inputs, FSharpOption\`1 configurationReader, FSharpOption\`1 ignoreMissing, FSharpOption\`1 ignoreUnrecognized, FSharpOption\`1 raiseOnUsage) in C:\Users\eirik.tsarpalis\devel\public\Argu\src\Argu\ArgumentParser.fs:line 180
at Program.main(String[] argv) in C:\GitHub\ClmFSharp\Clm\ContGen\Program.fs:line 8
如果我将 let results = parser.Parse argv
更改为 let results = parser.Parse(argv, raiseOnUsage = false)
,则它不会崩溃但不会显示任何帮助消息。然后由于命令 run
可以 运行 没有任何第二级参数,程序只是继续运行而不是显示帮助并退出。
但是,我需要 ContGen.exe run help
只显示帮助信息然后退出。我怎样才能做到这一点?谢谢。
这是Argu的一个有点奇怪的行为;您需要提供自己的退出器以避免在那里抛出异常。
大致如下:
type NonThrowingExiter() =
interface IExiter with
member __.Name = "Exiter" // I don't know what this is used for; I have never seen it appear anywhere
member __.Exit (msg, code) =
if code = ErrorCode.HelpText then
printfn "%s" msg
exit 0
else
printfn "%s" msg // Maybe have code to color the console output red here
exit 1
To use this, create your `ArgumentParser` like this:
let argumentParser =
Argu.ArgumentParser.Create<ContGenArguments>(helpTextMessage = "Help requested",
errorHandler = NonThrowingExiter())
(当然,您实际上不需要为此创建 class;对象表达式也可以。)