diff --git a/spork/argparse.janet b/spork/argparse.janet index cbc077b..051cbfd 100644 --- a/spork/argparse.janet +++ b/spork/argparse.janet @@ -33,7 +33,8 @@ * `:help` - Help text for the option, explaining what it is. * `:default` - Default value for the option. * `:required` - Whether or not an option is required. - * `:short-circuit` - Whether or not to stop parsing and fail if this option is hit. + * `:short-circuit` - Whether or not to stop parsing if this option is hit. + Result will also contain the rest of the arguments under the :rest key. * `:action` - A function that will be invoked when the option is parsed. * `:map` - A function that is applied to the value of the option to transform it @@ -46,7 +47,7 @@ Once parsed, values are accessible in the returned table by the name of the option. For example `(result "verbose")` will check if the verbose flag is enabled. - You may also use a custom args array when specified via the special option `:args` + You may also use a custom args array when specified via the special option `:args`. ``` [description &keys options] @@ -69,7 +70,7 @@ (def res @{:order @[]}) (def args (if-let [args (options :args)] (do (put options :args nil) args) (dyn :args))) (def arglen (length args)) - (var scanning true) + (var parsing true) (var bad false) (var i 1) (var process-options? true) @@ -80,7 +81,7 @@ # Only show usage once. (if bad (break)) (set bad true) - (set scanning false) + (set parsing false) (unless (empty? msg) (print "usage error: " ;msg)) (def flags @"") @@ -159,11 +160,11 @@ # Early exit for things like help (when (handler :short-circuit) - (set scanning false))) + (set parsing false))) # Iterate command line arguments and parse them # into the run table. - (while (and scanning (< i arglen)) + (while (and parsing (< i arglen)) (def arg (get args i)) (cond # `--` turns off option processing so that @@ -197,6 +198,9 @@ (handle-option :default handler) (usage "could not handle option " arg)))) + (when (and (not parsing) (not bad)) + (put res :rest (slice args (dec i) -1))) + # Handle defaults, required options (loop [[name handler] :pairs options] (when (nil? (res name)) diff --git a/test/suite0005.janet b/test/suite0005.janet index d0d0b75..f27b544 100644 --- a/test/suite0005.janet +++ b/test/suite0005.janet @@ -82,4 +82,32 @@ (assert (= ["echo" "-n" "ok"] (tuple ;cmd-args)) "unnamed arguments after `--` were not parsed correctly.")) +(def argparse-params-with-shortcircuit + ["A simple CLI tool. An example to show the capabilities of argparse." + "debug" {:kind :flag + :short "d" + :help "Set debug mode."} + "verbose" {:kind :multi + :short "v" + :help "Print debug information to stdout."} + "key" {:kind :option + :short "k" + :help "An API key for getting stuff from a server." + :required true} + "expr" {:kind :accumulate + :short "e" + :help "Search for all patterns given."} + "thing" {:kind :option + :help "Some option?" + :default "123"} + :default {:kind :accumulate + :short-circuit true}]) + +(with-dyns [:args @["testcase.janet" "-k" "100" "test" "--fake"]] + (def res (suppress-stdout (argparse/argparse ;argparse-params-with-shortcircuit))) + (assert (deep= res + @{"key" "100" "thing" "123" :default @["test"] :order @["key" :default] :rest ["test" "--fake"]}) + "argparse param :default {:short-circuit true} should not fail but return with res and :rest of arguments")) + + (end-suite)