Argu


Introduction

Argu (pronounced "Argue") is a declarative CLI argument parser for F# console applications. It allows modelling the command-line syntax using discriminated unions, which the library converts into a working parser using reflection.

Argu is a mature library that comes with many features

It can be installed using NuGet.

Basic Concepts

The library is based on the simple observation that configuration parameters can be naturally described using discriminated unions. For instance:

type Arguments =
    | Working_Directory of path:string
    | Listener of host:string * port:int
    | Log_Level of level:int
    | Detach

Argu takes such discriminated unions and generates a corresponding argument parsing scheme. For example, a parser generated from the above template would take the following command line input

--working-directory /var/run --listener localhost 8080 --detach

and parse it into the list

[ Working_Directory "/var/run" ; Listener("localhost", 8080) ; Detach ]

Argu is also capable of reading the AppSettings section of an application's configuration file:

<appSettings>
    <add key="working directory" value="C:\temp" />
    <add key="listener" value="192.168.0.3, 2675" />
    <add key="log level" value="3" />
    <add key="detach" value="true" />
</appSettings>

Furthermore, you can parse environment variables, by supplying the an EnvironmentVariableReader to the Parse call:

let argv = [| "--log-level"; "3" |]
let reader = EnvironmentVariableConfigurationReader() :> IConfigurationReader
let parser =  ArgumentParser.Create<Args>(programName = "rutta")
// pass the reader to the Parse call
let results = parser.Parse(argv, configurationReader=reader)

Who uses Argu?

Documentation

Contributing and copyright

The project is hosted on GitHub where you can report issues, fork the project and submit pull requests.

The library is available under the MIT License. For more information see the License file in the GitHub repository.

namespace System
namespace Argu
union case Args.Working_Directory: path: string -> Args
Multiple items
val string : value:'T -> string

--------------------
type string = String
union case Args.Listener: host: string * port: int -> Args
Multiple items
val int : value:'T -> int (requires member op_Explicit)

--------------------
type int = int32

--------------------
type int<'Measure> = int
union case Args.Log_Level: level: int -> Args
union case Args.Detach: Args
type IArgParserTemplate =
  interface
    abstract member Usage : string
  end
type Arguments =
  | Working_Directory of path: string
  | Listener of host: string * port: int
  | Log_Level of level: int
  | Detach
union case Arguments.Working_Directory: path: string -> Arguments
union case Arguments.Listener: host: string * port: int -> Arguments
union case Arguments.Log_Level: level: int -> Arguments
union case Arguments.Detach: Arguments
val argv : string []
val reader : IConfigurationReader
Multiple items
type EnvironmentVariableConfigurationReader =
  interface IConfigurationReader
  new : unit -> EnvironmentVariableConfigurationReader

--------------------
new : unit -> EnvironmentVariableConfigurationReader
type IConfigurationReader =
  interface
    abstract member GetValue : key:string -> string
    abstract member Name : string
  end
val parser : ArgumentParser<Args>
Multiple items
type ArgumentParser =
  private new : argInfo:UnionArgInfo * _programName:string * helpTextMessage:string option * _usageStringCharacterWidth:int * errorHandler:IExiter -> ArgumentParser
  abstract member Accept : visitor:IArgumentParserVisitor<'R> -> 'R
  member GetArgumentCases : unit -> ArgumentCaseInfo list
  member GetSubCommandParsers : unit -> ArgumentParser list
  member PrintCommandLineSyntax : ?programName:string * ?usageStringCharacterWidth:int -> string
  member PrintUsage : ?message:string * ?programName:string * ?hideSyntax:bool * ?usageStringCharacterWidth:int -> string
  member ErrorHandler : IExiter
  member HelpDescription : string
  member HelpFlags : string list
  member HelpTextMessage : string option
  ...

--------------------
type ArgumentParser<'Template (requires 'Template :> IArgParserTemplate)> =
  inherit ArgumentParser
  new : ?programName:string * ?helpTextMessage:string * ?usageStringCharacterWidth:int * ?errorHandler:IExiter * ?checkStructure:bool -> ArgumentParser<'Template>
  private new : argInfo:UnionArgInfo * _programName:string * helpTextMessage:string option * _usageStringCharacterWidth:int * errorHandler:IExiter -> ArgumentParser<'Template>
  override Accept : visitor:IArgumentParserVisitor<'a1> -> 'a1
  member GetArgumentCaseInfo : ctorExpr:Expr<('Fields -> 'Template)> -> ArgumentCaseInfo
  member GetArgumentCaseInfo : value:'Template -> ArgumentCaseInfo
  member GetSubCommandParser : expr:Expr<(ParseResults<'SubTemplate> -> 'Template)> -> ArgumentParser<'SubTemplate> (requires 'SubTemplate :> IArgParserTemplate)
  member GetTag : value:'Template -> int
  member Parse : ?inputs:string [] * ?configurationReader:IConfigurationReader * ?ignoreMissing:bool * ?ignoreUnrecognized:bool * ?raiseOnUsage:bool -> ParseResults<'Template>
  member ParseCommandLine : ?inputs:string [] * ?ignoreMissing:bool * ?ignoreUnrecognized:bool * ?raiseOnUsage:bool -> ParseResults<'Template>
  ...

--------------------
new : ?programName:string * ?helpTextMessage:string * ?usageStringCharacterWidth:int * ?errorHandler:IExiter * ?checkStructure:bool -> ArgumentParser<'Template>
static member ArgumentParser.Create : ?programName:string * ?helpTextMessage:string * ?usageStringCharacterWidth:int * ?errorHandler:IExiter * ?checkStructure:bool -> ArgumentParser<#IArgParserTemplate>
type Args =
  | Working_Directory of path: string
  | Listener of host: string * port: int
  | Log_Level of level: int
  | Detach
    interface IArgParserTemplate
val results : ParseResults<Args>