Skip to content

Commit

Permalink
feat(ParseResults): Add PostProcess aliases+overloads (#230)
Browse files Browse the repository at this point in the history
  • Loading branch information
bartelink committed Feb 19, 2024
1 parent 292b98f commit 1dc67c9
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 90 deletions.
2 changes: 2 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
### 6.2.0
* Add `ParseResults.ProgramName` [#229](https://github.com/fsprojects/Argu/pull/229)
* Add `ParseResults.GetResult(expr, 'Field -> 'R): 'R` as alias for `PostProcessResult`, `ParseResults.GetResults(expr, 'Field -> 'R): 'R list` as alias for `PostProcessResults`, `ParseResults.TryGetResult(expr, 'Field -> 'R): 'R option` as alias for `TryPostProcessResult` [#230](https://github.com/fsprojects/Argu/pull/230)
* Add `ParseResults.GetResult(expr, defThunk: unit -> 'Field, parse: 'Field -> 'R): 'R` and `ParseResults.GetResults(expr, def: 'Field, parse: 'Field -> 'R): 'R` that trap parse exceptions, mapping them to parse exit messages [#230](https://github.com/fsprojects/Argu/pull/230)

### 6.1.5
* Fix the regression of the [#127](https://github.com/fsprojects/Argu/pull/127) merged in 6.1.2 and fix Mandatory arguments in nested subcommands. [#220](https://github.com/fsprojects/Argu/issues/220) [@fpellet](https://github.com/fpellet)
Expand Down
48 changes: 25 additions & 23 deletions docs/index.fsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
(*** hide ***)
// This block of code is omitted in the generated HTML documentation. Use
// This block of code is omitted in the generated HTML documentation. Use
// it to define helpers that you do not want to show in the documentation.
#I "../src/Argu/bin/Release/netstandard2.0"
#r "Argu.dll"

open System
open Argu

type Args =
| Working_Directory of path:string
| Listener of host:string * port:int
| Log_Level of level:int
| Working_Directory of path: string
| Listener of host: string * port: int
| Log_Level of level: int
| Detach
with
interface IArgParserTemplate with
member _.Usage = ""
member _.Usage =
"(see the Tutorial for how this should be written)"

(**
Expand All @@ -35,22 +35,22 @@ It can be installed using <a href="https://nuget.org/packages/Argu">NuGet</a>.
## Basic Concepts
The library is based on the simple observation that
configuration parameters can be naturally described using discriminated unions.
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
| 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.
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
Expand All @@ -60,7 +60,7 @@ take the following command line input
and parse it into the list
*)

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

(**
Expand All @@ -82,36 +82,38 @@ 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)
let results = parser.Parse(argv, configurationReader = reader)

(**
## Who uses Argu?
* [MBrace](http://m-brace.net/)
* [FAKE](http://fsharp.github.io/FAKE/)
* [Paket](http://fsprojects.github.io/Paket/)
* [Logary](https://logary.tech)
* [Equinox + Propulsion](https://github.com/jet/Equinox)
## Documentation
* [Tutorial](tutorial.html) A short walkthrough of Argu features.
* [API Reference](reference/index.html) contains automatically generated documentation for all types,
* [API Reference](reference/index.html) contains automatically generated documentation for all types,
modules and functions in the library.
## Contributing and copyright
The project is hosted on [GitHub][gh] where you can [report issues][issues], fork
The project is hosted on [GitHub][gh] where you can [report issues][issues], fork
the project and submit pull requests.
The library is available under the MIT License.
For more information see the [License file][license] in the GitHub repository.
The library is available under the MIT License.
For more information see the [License file][license] in the GitHub repository.
[gh]: https://github.com/fsprojects/Argu
[issues]: https://github.com/fsprojects/Argu/issues
[license]: https://github.com/fsprojects/Argu/blob/master/License.md
[license]: https://github.com/fsprojects/Argu/blob/master/LICENSE.md
*)
2 changes: 1 addition & 1 deletion docs/perf.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ By default Argu checks that the discriminated union is well formed and only cont
This incur both the cost of the checks themselves but also the cost of materializing the whole argument graph that could
be loaded only if the corresponding arguments are used.
This check can easilly be bypassed either only in release builds :
This check can easily be bypassed either only in release builds :
*)

Expand Down
61 changes: 31 additions & 30 deletions docs/tutorial.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ For instance:
*)

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

(**
Expand Down Expand Up @@ -64,11 +64,11 @@ A minimal parser based on the above example can be created as follows:
open Argu

type CliArguments =
| Working_Directory of path:string
| Listener of host:string * port:int
| Data of base64:byte[]
| Port of tcp_port:int
| Log_Level of level:int
| Working_Directory of path: string
| Listener of host: string * port: int
| Data of base64: byte[]
| Port of tcp_port: int
| Log_Level of level: int
| Detach

interface IArgParserTemplate with
Expand All @@ -79,7 +79,7 @@ type CliArguments =
| Data _ -> "binary data in base64 encoding."
| Port _ -> "specify a primary port."
| Log_Level _ -> "set the log level."
| Detach _ -> "detach daemon from console."
| Detach -> "detach daemon from console."

(** We extract the argument parser from the template using the following command: *)

Expand Down Expand Up @@ -111,11 +111,11 @@ To parse a command line input:
*)

let results = parser.Parse [| "--detach" ; "--listener" ; "localhost" ; "8080" |]
let results = parser.Parse [| "--detach"; "--listener"; "localhost" ; "8080" |]

(** which gives *)

let all = results.GetAllResults() // [ Detach ; Listener ("localhost", 8080) ]
let all = results.GetAllResults() // [ Detach; Listener ("localhost", 8080) ]

(**
Expand All @@ -132,7 +132,7 @@ let listener = results.GetResults Listener
(** The following methods return the last observed result for given argument case *)

let dataOpt = results.TryGetResult Data
let logLevel = results.GetResult (Log_Level, defaultValue = 0)
let logLevel = results.GetResult(Log_Level, defaultValue = 0)

(**
Expand All @@ -147,12 +147,12 @@ can be customized by fixing attributes to the union cases:
*)

type Argument =
| [<Mandatory>] Cache_Path of path:string
| [<NoCommandLine>] Connection_String of conn:string
| [<Unique>] Listener of host:string * port:int
| [<EqualsAssignment>] Assignment of value:string
| [<EqualsAssignmentOrSpaced>] AssignmentOrSpace of value:string
| [<AltCommandLine("-p")>] Primary_Port of tcp_port:int
| [<Mandatory>] Cache_Path of path: string
| [<NoCommandLine>] Connection_String of conn: string
| [<Unique>] Listener of host: string * port: int
| [<EqualsAssignment>] Assignment of value: string
| [<EqualsAssignmentOrSpaced>] AssignmentOrSpace of value: string
| [<AltCommandLine("-p")>] Primary_Port of tcp_port: int

(**
Expand All @@ -165,7 +165,7 @@ In this case,
* [`AltCommandLine`](reference/argu-arguattributes-altcommandlineattribute.html): specifies an alternative command line switch.
* [`EqualsAssignment`](reference/argu-arguattributes-equalsassignmentattribute.html) : enforces `--assignment=value` and `--assignment key=value` CLI syntax.
* [`EqualsAssignmentOrSpaced`](reference/argu-arguattributes-equalsassignmentorspacedattribute.html) : enforces `--assignment=value` and `--assignment value` CLI syntax.
* [`Unique`](reference/argu-arguattributes-uniqueattribute.html) : parser will fail if CLI provides this argument more than once.
Expand Down Expand Up @@ -202,8 +202,8 @@ Additionally, it is possible to specify argument parameters that are either opti
*)

type VariadicParameters =
| [<EqualsAssignment>] Enable_Logging of path:string option
| Tcp_Ports of port:int list
| [<EqualsAssignment>] Enable_Logging of path: string option
| Tcp_Ports of port: int list

(**
Expand Down Expand Up @@ -261,7 +261,7 @@ These arguments can be passed without the need to specify a switch identifier.
type WGetArguments =
| Quiet
| No_Check_Certificate
| [<MainCommand; ExactlyOnce; Last>] Urls of url:string list
| [<MainCommand; ExactlyOnce; Last>] Urls of url: string list

(**
Expand Down Expand Up @@ -306,7 +306,7 @@ type CleanArgs =
and CommitArgs =
| Amend
| [<AltCommandLine("-p")>] Patch
| [<AltCommandLine("-m")>] Message of msg:string
| [<AltCommandLine("-m")>] Message of msg: string

interface IArgParserTemplate with
member this.Usage =
Expand Down Expand Up @@ -339,9 +339,8 @@ and the following console app entrypoint
let main argv =
try
parser.ParseCommandLine(inputs = argv, raiseOnUsage = true) |> ignore
with e ->
printfn "%s" e.Message
0
0
with :? ArguParseException as e -> eprintfn "%s" e.Message; 1

(**
Expand Down Expand Up @@ -406,15 +405,17 @@ which would make the aforementioned syntax valid.
It should be noted here that arbitrary unions are not supported by the parser.
Union cases can only contain fields of primitive types. This means that user-defined
parsers are not supported. For configuration inputs that are non-trivial,
a post-process facility is provided.
a post-process facility is provided
NOTE prior to version 6.2.0, these methods were called PostProcessResult, PostProcessResults, TryPostProcessResult
*)

let parsePort p =
if p < 0 || p > int UInt16.MaxValue then
failwith "invalid port number."
else p

let ports = results.PostProcessResults (<@ Port @>, parsePort)
let ports = results.GetResults(Port, parsePort)

(**
Expand All @@ -427,15 +428,15 @@ Argu is convenient when it comes to automated process spawning:

open System.Diagnostics

let arguments = parser.PrintCommandLineArgumentsFlat [ Port 42 ; Working_Directory "temp" ]
let arguments = parser.PrintCommandLineArgumentsFlat [ Port 42; Working_Directory "temp" ]

Process.Start("foo.exe", arguments)

(**
It can also be used to auto-generate a suitable `AppSettings` configuration file:
*)

let xml = parser.PrintAppSettingsArguments [ Port 42 ; Working_Directory "/tmp" ]
let xml = parser.PrintAppSettingsArguments [ Port 42; Working_Directory "/tmp" ]

(**
which would yield the following:
Expand Down
Loading

0 comments on commit 1dc67c9

Please sign in to comment.