import os
from argparse import ArgumentParser, Action, SUPPRESS

from argcomplete import autocomplete


class VersionAction(Action):
    """
    Custom VersionAction that prints the version of this package
    """

    def __init__(self,
                 option_strings,
                 dest=SUPPRESS,
                 default=SUPPRESS,
                 help="show program's version number and exit"):
        super(VersionAction, self).__init__(
            option_strings=option_strings,
            dest=dest,
            default=default,
            nargs=0,
            help=help)

    def __call__(self, parser, namespace, values, option_string=None):
        from . import __version__
        formatter = parser._get_formatter()
        formatter.add_text('%(prog)s version ' + __version__)
        parser.exit(message=formatter.format_help())


def main():
    parser = ArgumentParser()
    parser.add_argument('-v', '--verbose', action='store_true')
    parser.add_argument('--version', action=VersionAction)

    subparsers = parser.add_subparsers()

    subparser = subparsers.add_parser('install', help='install packages')
    subparser.set_defaults(func='install')
    subparser.add_argument('pkgs', nargs='+', metavar='pkg')

    subparser = subparsers.add_parser('update', help='update all packages in the workspace to the latest version')
    subparser.set_defaults(func='update')
    subparser.add_argument('--restore-versions', action='store_true',
                           help='Whether to restore the versions to the versions as defined in the rosdistro database')

    subparser = subparsers.add_parser('status', help='check if there are modified files in the workspace')
    subparser.set_defaults(func='status')

    subparser = subparsers.add_parser('list', help='List all available packages')
    subparser.set_defaults(func='list_packages')
    subparser.add_argument('--installed', action='store_true', help='Only list installed toplevel packages')

    subparser = subparsers.add_parser('remove', help='remove packages')
    subparser.set_defaults(func='remove')
    subparser.add_argument('pkgs', nargs='+', metavar='pkg')

    # workspace commands
    subparser = subparsers.add_parser(
        'ws-create',
        help='create a new workspace',
        description='Create a new catkin workspace where the packages are managed by ros-get')
    subparser.set_defaults(func='create')
    subparser.add_argument(
        'rosdistro_index_url',
        help='Custom rosdistro database url. This can be either a web url (http://) or local file url (file://).')
    subparser.add_argument(
        'extend_path',
        metavar='extend',
        help='Explicitly extend the result-space of another catkin workspace. Example: /opt/ros/kinetic')
    subparser.add_argument(
        '--dir',
        default=os.getcwd(),
        help='The directory to create the workspace in. Defaults to the current working directory')
    subparser.add_argument(
        '--name', help='give a name to the workspace, if not given, the name '
        'will be inferred by the directory name')

    subparser = subparsers.add_parser('ws-switch', help='switch to a workspace')
    subparser.set_defaults(func='switch')
    subparser.add_argument('name')

    subparser = subparsers.add_parser('ws-save', help='Saves the current workspace')
    subparser.set_defaults(func='save')
    subparser.add_argument('dir')
    subparser.add_argument(
        '--name', help='give a name to the workspace, if not given, the name will be inferred by the directory name')

    subparser = subparsers.add_parser('ws-list', help='list all saved workspaces')
    subparser.set_defaults(func='list_workspaces')

    subparser = subparsers.add_parser('ws-locate', help='prints the path to the current workspace')
    subparser.set_defaults(func='locate')

    subparser = subparsers.add_parser('ws-name', help='prints the name of the current workspace')
    subparser.set_defaults(func='name')

    subparser = subparsers.add_parser('ws-rosdistro-url', help='Prints the current rosdistro_index_url')
    subparser.set_defaults(func='rosdistro_url')

    autocomplete(parser)
    args = parser.parse_args()

    # computation has to be avoided before the 'autocomplete(parser)' call

    import logging.config
    logging.config.dictConfig({
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'colored': {
                '()': 'colorlog.ColoredFormatter',
                'format': "%(log_color)s[%(levelname)s] %(name)s: %(message)s",
            }
        },
        'handlers': {
            'stream': {
                'class': 'logging.StreamHandler',
                'formatter': 'colored',
            },
        },
        'root': {
            'handlers': ['stream'],
            'level': 'INFO',
        },
    })

    if args.verbose:
        logging.getLogger().setLevel(logging.DEBUG)

    from . import (install, update, status, list_packages, remove, create, switch, save, list_workspaces, locate, name,
                   rosdistro_url)

    # remove func from the namespace
    func = args.func
    del args.func

    # execute the function given in 'func'
    func = {
        'install': install,
        'update': update,
        'status': status,
        'list_packages': list_packages,
        'remove': remove,
        'create': create,
        'switch': switch,
        'save': save,
        'list_workspaces': list_workspaces,
        'locate': locate,
        'name': name,
        'rosdistro_url': rosdistro_url,
    }[func]
    exit(func(**vars(args)))


if __name__ == '__main__':
    main()

@@ -3,16 +3,27 @@
 port os%0A
+import sys%0A
 from arg
@@ -862,21 +862,31 @@
 )%0A%0A%0Adef 
-main(
+parse_args(argv
 ):%0A    p
@@ -1073,16 +1073,30 @@
 parsers(
+dest=%22command%22
 )%0A%0A    s
@@ -4225,16 +4225,20 @@
 se_args(
+argv
 )%0A%0A    #
@@ -4974,16 +4974,150 @@
 DEBUG)%0A%0A
+    # remove func from the namespace%0A    func = args.func%0A    del args.func%0A    del args.command%0A%0A    return func, args%0A%0A%0Adef main():%0A
     from
@@ -5271,80 +5271,45 @@
     
-# remove func from the namespace%0A    func = args.func%0A    del args.func%0A
+func, args = parse_args(sys.argv%5B1:%5D)
 %0A   
@@ -5729,21 +5729,23 @@
 nc%5D%0A    
-exit(
+return 
 func(**v
@@ -5754,17 +5754,16 @@
 s(args))
-)
 %0A%0A%0Aif __
@@ -5788,15 +5788,21 @@
 _':%0A    
+exit(
 main()
+)
 %0A

Reorganize argument parsing code to allow for testing