I have an argument set like this (with more subcommands, of course):
open Argu
type SubcommandArguments =
| [<Unique>] Json
interface IArgParserTemplate with
member s.Usage =
match s with
| Json -> "write output in JSON format."
[<RequireQualifiedAccess>]
type MainArguments =
| [<CliPrefix(CliPrefix.None)>] Subcommand of ParseResults<SubcommandArguments>
And I want to achieve the following behavior:
My application should print the usage when it couldn't parse the arguments or if the user has explicitly requested usage (app.exe subcommand --help or app.exe --help)
Argument parse error should go to stderr; explicitly requested help message should go to stdout
My application should return 0 if it was explicitly requested to show help (e.g. app.exe --help → exit code 0)
My application should return 1 if there was an argument parse error (e.g. app.exe --blahblah → exit code 1)
Currently, I feel like Argu lacks the functionality I need to implement these requirements. Which is the best way to do it with Argu?
The approaches I've tried are listed below. So far, only option 3 works to fulfill all the requirements, and I don't like it.
1. raiseOnUsage = true
[<EntryPoint>]
let main _ =
let args = [|"subcommand"; "--help"|]
let parser = ArgumentParser.Create<MainArguments>()
try
let arguments = parser.ParseCommandLine(args, raiseOnUsage = true)
0
with
| :? ArguParseException as ex ->
eprintfn "%s" ex.Message
1
This example should return with exit code 0 (because it was asked for --help explicitly), but it has no way to differentiate the parse errors or explicit --help argument, so it returns 1.
2. Check IsUsageRequested
[<EntryPoint>]
let main _ =
let args = [|"subcommand"; "--help"|]
let parser = ArgumentParser.Create<MainArguments>()
try
let arguments = parser.ParseCommandLine(args, raiseOnUsage = false)
if arguments.IsUsageRequested
then printfn "%s" <| parser.PrintUsage()
0
with
| :? ArguParseException as ex ->
eprintfn "%s" ex.Message
1
This doesn't work properly, too, because arguments.IsUsageRequested is false if only subcommand has been requested for help.
3. Check IsUsageRequested for every subcommand
[<EntryPoint>]
let main _ =
let args = [|"subcommand"; "--help"|]
let parser = ArgumentParser.Create<MainArguments>()
try
let arguments = parser.ParseCommandLine(args, raiseOnUsage = false)
if arguments.IsUsageRequested
then printfn "%s" <| parser.PrintUsage()
let subcommandArguments = arguments.GetResult MainArguments.Subcommand
if subcommandArguments.IsUsageRequested
then printfn "%s" <| subcommandArguments.Parser.PrintUsage()
0
with
| :? ArguParseException as ex ->
eprintfn "%s" ex.Message
1
This one does work, but requires me to write the same boilerplate code for every subcommand, which I don't like to do.
Description
I have an argument set like this (with more subcommands, of course):
And I want to achieve the following behavior:
app.exe subcommand --help
orapp.exe --help
)0
if it was explicitly requested to show help (e.g.app.exe --help
→ exit code0
)1
if there was an argument parse error (e.g.app.exe --blahblah
→ exit code1
)Currently, I feel like Argu lacks the functionality I need to implement these requirements. Which is the best way to do it with Argu?
The approaches I've tried are listed below. So far, only option 3 works to fulfill all the requirements, and I don't like it.
1.
raiseOnUsage = true
This example should return with exit code
0
(because it was asked for--help
explicitly), but it has no way to differentiate the parse errors or explicit--help
argument, so it returns1
.2. Check
IsUsageRequested
This doesn't work properly, too, because
arguments.IsUsageRequested
isfalse
if only subcommand has been requested for help.3. Check
IsUsageRequested
for every subcommandThis one does work, but requires me to write the same boilerplate code for every subcommand, which I don't like to do.
Related information
Argu version used:
6.1.1
, platform: .NET Core.