Jaymon / captain

command line python scripts for humans
MIT License
13 stars 1 forks source link

Parsing unknown arguments #34

Closed Jaymon closed 6 years ago

Jaymon commented 7 years ago

I wrote this for another project but it should go in a utility method on this and have some way to be invoked from a captain method

class CommandLineTest(TestCase):
    def test_extra_args(self):
        extra_args = [
            "--foo=1",
            "--che",
            '--baz="this=that"',
            "--bar",
            "2",
            "--foo=2",
            "-z",
            "3",
            "4"
        ]

        d = parse_extra(extra_args)
        self.assertEqual(["1", "2"], d["foo"])
        self.assertEqual(["4"], d["*"])
        self.assertEqual(["2"], d["bar"])
        self.assertEqual(["3"], d["z"])
        self.assertEqual(["this=that"], d["baz"])
        self.assertEqual([True], d["che"])

def parse_extra(args):
    """handle parsing any extra args that are passed from ArgParser.parse_known_args

    args -- list -- the list of extra args returned from parse_known_args
    return -- dict -- key is the arg name (* for non positional args) and value is
        a list of found arguments (so --foo 1 --foo 2 is supported). The value is
        always a list
    """
    d = defaultdict(list)
    i = 0
    length = len(args)
    while i < length:
        if args[i].startswith("-"):
            s = args[i].lstrip("-")
            bits = s.split("=", 1)
            if len(bits) > 1:
                key = bits[0]
                val = bits[1].strip("\"'")
                d[key].append(val)

            else:
                if i + 1 < length:
                    if args[i + 1].startswith("-"):
                        d[s].append(True)

                    else:
                        d[s].append(args[i + 1])
                        i += 1

        else:
            d["*"].append(args[i])

        i += 1

    return d