mpeterv / argparse

Feature-rich command line parser for Lua
MIT License
251 stars 43 forks source link

Support for trailing '--' to indicate remaining options to be captured/forwarded verbatim #17

Closed ewmailing closed 5 years ago

ewmailing commented 6 years ago

Some wrapper tools adopt the convention of using -- as a marker to denote that all the arguments preceding that marker are for the wrapper tool, and everything after goes verbatim to the tool being wrapped.

So for example, CMake is a wrapper to different build tools. Say for example, I am currently using CMake to drive xcodebuild.

cmake --build /path/to/my/builddir -- -arch armv7s

So the --build goes to cmake, and -arch armv7s goes to xcodebuild.

Writing my own wrapper tools, I would like to do something like that, where argparse does the normal thing which I can use for my tool.

But for the -- I would like either an (ordered) array or all the remaining arguments, or a flat string. Then I could just forward that to the tool I'm calling.

Is there something already in argparse that can do this? If not, this would be a feature request. Thank you.

mpeterv commented 6 years ago

Argparse interprets everything after -- as positional arguments, even when they start with -. You could use a positional argument with variable args (:args "*") to collect them:

local parser = require "argparse"()
parser:flag "--wrapper-flag"
parser:argument "tail"
   :args "*"
local args = parser:parse()

Given --wrapper-flag -- --tool-flag a b c, args ends up as

{
  tail = { "--tool-flag", "a", "b", "c" },
  wrapper_flag = true
}

However, this will also put positional arguments before -- into args.tail. Given a -- b, args is

{
  tail = { "a", "b" }
}
ewmailing commented 6 years ago

Hmmm, I'm in an unfortunate position where the wrapper tool has optional positional arguments. It's tricky to distinguish if they are also in args.tail

mpeterv commented 6 years ago

I've commited a change to master branch that makes -- a valid option name, working like any other option, except it also doesn't interpret anything after -- as an option, as normal --. So this is possible:

local argparse = require "argparse"
local parser = argparse()
parser:argument "wrapper_argument"
   :args "?"
parser:flag "--wrapper-flag"
parser:option "--"
   :args "*"
   :target "tool_arguments"
   :argname "<arg>"
local args = parser:parse()

And when given arg -- --tool-flag a b c, args is

{
  tool_arguments = { "--tool-flag", "a", "b", "c" },
  wrapper_argument = "arg"
}

Note that it's necessary to set up target and argname property, or it will be strange by default (an empty string and <>).

daurnimator commented 5 years ago

@ewmailing could you close this issue? this repository is no longer in use.