diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 40645174..e1920104 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,7 +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 aliases for `TryPostProcessResult` [#230](https://github.com/fsprojects/Argu/pull/230) -* Add `ParseResults.GetResult(expr, unit -> 'Field, 'Field -> 'R): 'R` and `ParseResults.GetResults(expr, 'Field, ''Field -> 'R): 'R` which trap parse exceptions and map them to exit messages [#230](https://github.com/fsprojects/Argu/pull/230) +* 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) diff --git a/src/Argu/ParseResults.fs b/src/Argu/ParseResults.fs index cbb03b00..6a900dd1 100644 --- a/src/Argu/ParseResults.fs +++ b/src/Argu/ParseResults.fs @@ -142,7 +142,7 @@ type ParseResults<[]'Template wh /// Optional source restriction: AppSettings or CommandLine. /// The error code to be returned. /// Print usage together with error message. Defaults to true - member r.GetResult([] expr : Expr<'Field -> 'Template>, defThunk : unit -> 'Field, parser : 'Field -> 'R, ?source : ParseSource, ?errorCode, ?showUsage) : 'R = + member r.GetResult([] expr: Expr<'Field -> 'Template>, defThunk: unit -> 'Field, parser: 'Field -> 'R, ?source: ParseSource, ?errorCode, ?showUsage) : 'R = match expr |> tryGetResult source |> Option.map (parseResult parser) with | Some x -> x | None -> r.Catch(defThunk >> parser, ?errorCode = errorCode, ?showUsage = showUsage) @@ -156,7 +156,7 @@ type ParseResults<[]'Template wh /// Optional source restriction: AppSettings or CommandLine. /// The error code to be returned. /// Print usage together with error message. - member r.GetResult([] expr : Expr<'Field -> 'Template>, defaultValue : 'Field, parser : 'Field -> 'R, ?source, ?errorCode : ErrorCode, ?showUsage : bool) : 'R = + member r.GetResult([] expr: Expr<'Field -> 'Template>, defaultValue: 'Field, parser: 'Field -> 'R, ?source, ?errorCode : ErrorCode, ?showUsage : bool) : 'R = match expr |> tryGetResult source |> Option.map (parseResult parser) with | Some x -> x | None -> r.Catch((fun () -> parser defaultValue), ?errorCode = errorCode, ?showUsage = showUsage) diff --git a/tests/Argu.Tests/Tests.fs b/tests/Argu.Tests/Tests.fs index 35fe7707..94b3d3df 100644 --- a/tests/Argu.Tests/Tests.fs +++ b/tests/Argu.Tests/Tests.fs @@ -1022,47 +1022,48 @@ module ``Argu Tests Main Primitive`` = test <@ results.Contains <@ Detach @> @> test <@ results.GetResult <@ Main @> = "main" @> - module ``Defaulting`` = + module ``Traps for defaulting and or post-processing functions`` = let results = parser.ParseCommandLine [| "--mandatory-arg" ; "true"; "command" |] - let failingDefThunk (): string = failwith "Defaulting Failed" [] let ``Trap defaulting function exceptions`` () = + let failingDefThunk (): string = failwith "Defaulting Failed" raisesWith <@ results.GetResult(Working_Directory, failingDefThunk, showUsage = false) @> <| fun e -> <@ e.Message = "Defaulting Failed" && e.ErrorCode = ErrorCode.PostProcess @> raisesWith - <@ results.GetResult(Working_Directory, failingDefThunk) @> + <@ results.GetResult(Working_Directory, failingDefThunk) @> (fun e -> <@ e.Message.StartsWith "Defaulting Failed" && e.Message.Contains "--working-directory" @>) - module ``Trap defaulting function exceptions and parse exceptions`` = + [] + let ``Trap defaulting function exceptions (for overloads with parse functions)`` () = + let parser (_ : string): string = failwith "should not be triggered" + let failingDefThunk (): string = failwith "Defaulting Failed" + raisesWith + <@ results.GetResult(Working_Directory, failingDefThunk, parser, showUsage = false) @> + <| fun e -> <@ e.Message = "Defaulting Failed" && e.ErrorCode = ErrorCode.PostProcess @> + raisesWith + <@ results.GetResult(Working_Directory, failingDefThunk, parser) @> + (fun e -> <@ e.Message.StartsWith "Defaulting Failed" && e.Message.Contains "--working-directory" @>) - let results = parser.ParseCommandLine [| "--mandatory-arg" ; "true"; "command" |] + [] + let ``Trap post processing exceptions for GetResult overloads with defaulting functions`` () = let parser value: string = if value = "default" then failwith "Parse Failed" else failwith "unexpected" + let okDefThunk (): string = "default" + raisesWith + <@ results.GetResult(Working_Directory, okDefThunk, parser, showUsage = false) @> + <| fun e -> <@ e.Message = "Parse Failed" && e.ErrorCode = ErrorCode.PostProcess @> + raisesWith + <@ results.GetResult(Working_Directory, okDefThunk, parser) @> + (fun e -> <@ e.Message.StartsWith "Parse Failed" && e.Message.Contains "--working-directory" @>) - [] - let ``Trap post processing exceptions and/or defaulting function exceptions`` () = - raisesWith - <@ results.GetResult(Working_Directory, failingDefThunk, parser, showUsage = false) @> - <| fun e -> <@ e.Message = "Defaulting Failed" && e.ErrorCode = ErrorCode.PostProcess @> - raisesWith - <@ results.GetResult(Working_Directory, failingDefThunk, parser) @> - (fun e -> <@ e.Message.StartsWith "Defaulting Failed" && e.Message.Contains "--working-directory" @>) - - let okDefThunk (): string = "default" - raisesWith - <@ results.GetResult(Working_Directory, okDefThunk, parser, showUsage = false) @> - <| fun e -> <@ e.Message = "Parse Failed" && e.ErrorCode = ErrorCode.PostProcess @> - raisesWith - <@ results.GetResult(Working_Directory, okDefThunk, parser) @> - (fun e -> <@ e.Message.StartsWith "Parse Failed" && e.Message.Contains "--working-directory" @>) - - [] - let ``Trap post processing exceptions for default values`` () = - let def: string = "default" - raisesWith - <@ results.GetResult(Working_Directory, def, parser, showUsage = false) @> - <| fun e -> <@ e.Message = "Parse Failed" && e.ErrorCode = ErrorCode.PostProcess @> - raisesWith - <@ results.GetResult(Working_Directory, def, parser) @> - (fun e -> <@ e.Message.StartsWith "Parse Failed" && e.Message.Contains "--working-directory" @>) + [] + let ``Trap post processing exceptions for GetResult overloads with default values`` () = + let def: string = "default" + let parser value: string = if value = "default" then failwith "Parse Failed" else failwith "unexpected" + raisesWith + <@ results.GetResult(Working_Directory, def, parser, showUsage = false) @> + <| fun e -> <@ e.Message = "Parse Failed" && e.ErrorCode = ErrorCode.PostProcess @> + raisesWith + <@ results.GetResult(Working_Directory, def, parser) @> + (fun e -> <@ e.Message.StartsWith "Parse Failed" && e.Message.Contains "--working-directory" @>)