1

I am currently writing a wrapper for git in python that allows to run certain git commands in multiple git repos. Now, I'd like to support all possible git commands, and I'd like to do it in the following way: I'd like argparse to only parse global options and the sub-command; everything that comes after the sub-command (which is a git-command) I'd just like to pass as-is to git.

Is this possible with argparse?

Example:

            Passed on to git as-is
            vvvvv
mgit -t add -p .
^^^^^^^^^^^
Parsed by argparse 

daniel kullmann
  • 13,653
  • 8
  • 51
  • 67
  • 1
    Have you tried using the `nargs` parameter of `add_argument()`?: https://docs.python.org/3/library/argparse.html#nargs – jjramsey Apr 30 '21 at 20:23
  • Hmm. I wanted to have as little knowledge about git internals in my script; so I don't want to list all git commands; I just want to accept any sub-command and any parameters it might have gotten. – daniel kullmann Apr 30 '21 at 20:29
  • ..but `nargs="*"` might be a partial solution to my problem.. – daniel kullmann Apr 30 '21 at 20:32
  • @jramsey Oh, this works almost perfectly! My only problem is that I want to use my own global arguments that collide with git arguments, and that messes up the argument parsing. – daniel kullmann Apr 30 '21 at 20:38
  • 1
    The double dash argument '--' may be useful, allowing you to parse all remaining arguments as plain strings even though they contain '-'. There is also a `argparse.REMINDER` nargs value, though that's not very robust. `parse_known_args` may also be useful. – hpaulj Apr 30 '21 at 20:51

1 Answers1

2

I've done something similar before! One less commonly used option to argparse is the ability to provide your own string array. By default it looks at sys.argv[1:], but you can handle argv differently depending on your needs. I'd suggest structuring the command like this:

mgit -t -- add -p .

Where the -- delimits where you want the subcommand to start. Example

parser = ArgumentParser(...)
...

delimit_index = sys.argv.index("--")
args = parser.parse_args(args=sys.argv[1:delimit_index])
subcommand_args = sys.argv[delimit_index + 1:]
flakes
  • 21,558
  • 8
  • 41
  • 88