From 49ecfbf5e596792b29d0012676c6c889d1a4aab6 Mon Sep 17 00:00:00 2001 From: Patrick Stevens <3138005+Smaug123@users.noreply.github.com> Date: Thu, 12 Sep 2024 23:10:08 +0100 Subject: [PATCH] Fix includeFlagLike when arg doesn't have an equals (#257) --- ConsumePlugin/GeneratedArgs.fs | 6 ++++ .../TestArgParser/TestArgParser.fs | 14 +++++---- WoofWare.Myriad.Plugins/ArgParserGenerator.fs | 29 +++++++++++++++---- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/ConsumePlugin/GeneratedArgs.fs b/ConsumePlugin/GeneratedArgs.fs index 2a020e8..7a58e8c 100644 --- a/ConsumePlugin/GeneratedArgs.fs +++ b/ConsumePlugin/GeneratedArgs.fs @@ -3635,6 +3635,9 @@ module FlagsIntoPositionalArgsArgParse = | Error exc -> if setFlagValue key then go ParseState_FlagsIntoPositionalArgs.AwaitingKey (arg :: args) + else if true then + key |> arg_1.Add + go ParseState_FlagsIntoPositionalArgs.AwaitingKey (arg :: args) else match exc with | None -> @@ -3796,6 +3799,9 @@ module FlagsIntoPositionalArgs'ArgParse = | Error exc -> if setFlagValue key then go ParseState_FlagsIntoPositionalArgs'.AwaitingKey (arg :: args) + else if false then + key |> arg_1.Add + go ParseState_FlagsIntoPositionalArgs'.AwaitingKey (arg :: args) else match exc with | None -> diff --git a/WoofWare.Myriad.Plugins.Test/TestArgParser/TestArgParser.fs b/WoofWare.Myriad.Plugins.Test/TestArgParser/TestArgParser.fs index 5c2a75a..f255a81 100644 --- a/WoofWare.Myriad.Plugins.Test/TestArgParser/TestArgParser.fs +++ b/WoofWare.Myriad.Plugins.Test/TestArgParser/TestArgParser.fs @@ -623,30 +623,32 @@ Required argument '--exact' received no value""" let ``Can collect *all* non-help args into positional args with includeFlagLike`` () = let getEnvVar (_ : string) = failwith "do not call" - FlagsIntoPositionalArgs.parse' getEnvVar [ "--a" ; "foo" ; "--b=false" ; "--c=hi" ; "--" ; "--help" ] + FlagsIntoPositionalArgs.parse' getEnvVar [ "--a" ; "foo" ; "--b=false" ; "--c" ; "hi" ; "--" ; "--help" ] |> shouldEqual { A = "foo" - GrabEverything = [ "--b=false" ; "--c=hi" ; "--help" ] + GrabEverything = [ "--b=false" ; "--c" ; "hi" ; "--help" ] } // Users might consider this eccentric! // But we're only a simple arg parser; we don't look around to see whether this is "almost" // a valid parse. - FlagsIntoPositionalArgs.parse' getEnvVar [ "--a" ; "--b=false" ; "--c=hi" ; "--" ; "--help" ] + FlagsIntoPositionalArgs.parse' getEnvVar [ "--a" ; "--b=false" ; "--c" ; "hi" ; "--" ; "--help" ] |> shouldEqual { A = "--b=false" - GrabEverything = [ "--c=hi" ; "--help" ] + GrabEverything = [ "--c" ; "hi" ; "--help" ] } [] - let ``Can refuse to collect non-help args`` () = + let ``Can refuse to collect non-help args with PositionalArgs false`` () = let getEnvVar (_ : string) = failwith "do not call" let exc = Assert.Throws (fun () -> - FlagsIntoPositionalArgs'.parse' getEnvVar [ "--a" ; "foo" ; "--b=false" ; "--c=hi" ; "--" ; "--help" ] + FlagsIntoPositionalArgs'.parse' + getEnvVar + [ "--a" ; "foo" ; "--b=false" ; "--c" ; "hi" ; "--" ; "--help" ] |> ignore ) diff --git a/WoofWare.Myriad.Plugins/ArgParserGenerator.fs b/WoofWare.Myriad.Plugins/ArgParserGenerator.fs index f9d0711..34cc76a 100644 --- a/WoofWare.Myriad.Plugins/ArgParserGenerator.fs +++ b/WoofWare.Myriad.Plugins/ArgParserGenerator.fs @@ -1019,12 +1019,12 @@ module internal ArgParserGenerator = recurseKey ] - let notMatched = - let posAttr = - match leftoverArgAcc with - | ChoicePositional.Choice a - | ChoicePositional.Normal a -> a + let posAttr = + match leftoverArgAcc with + | ChoicePositional.Choice a + | ChoicePositional.Normal a -> a + let notMatched = let handleFailure = [ SynMatchClause.create (SynPat.named "None") fail @@ -1113,6 +1113,8 @@ module internal ArgParserGenerator = let processValue = // During failure, we've received an optional exception message that happened when we tried to parse // the value; it's in the variable `exc`. + // `fail` is for the case where we're genuinely emitting an error. + // If we're in `PositionalArgs true` mode, though, we won't call `fail`. let fail = [ SynExpr.createIdent "failwithf" @@ -1132,6 +1134,21 @@ module internal ArgParserGenerator = ] |> SynExpr.createMatch (SynExpr.createIdent "exc") + let onFailure = + match posAttr with + | None -> fail + | Some includeFlagLike -> + [ + SynExpr.createIdent "key" + |> SynExpr.pipeThroughFunction (SynExpr.createLongIdent' [ leftoverArgs ; Ident.create "Add" ]) + + SynExpr.createIdent "go" + |> SynExpr.applyTo (SynExpr.createLongIdent' [ parseState ; Ident.create "AwaitingKey" ]) + |> SynExpr.applyTo (SynExpr.listCons (SynExpr.createIdent "arg") (SynExpr.createIdent "args")) + ] + |> SynExpr.sequential + |> SynExpr.ifThenElse includeFlagLike fail + [ SynMatchClause.create (SynPat.nameWithArgs "Ok" [ SynPat.unit ]) @@ -1144,7 +1161,7 @@ module internal ArgParserGenerator = (SynPat.nameWithArgs "Error" [ SynPat.named "exc" ]) (SynExpr.ifThenElse (SynExpr.applyFunction (SynExpr.createIdent "setFlagValue") (SynExpr.createIdent "key")) - fail + onFailure (SynExpr.createIdent "go" |> SynExpr.applyTo (SynExpr.createLongIdent' [ parseState ; Ident.create "AwaitingKey" ]) |> SynExpr.applyTo (SynExpr.listCons (SynExpr.createIdent "arg") (SynExpr.createIdent "args"))))