import argparse
import logging
import sys
from contextlib import ExitStack
from functools import partial

from startup import Startup, startup

from garage import components
from garage.startups.http import HttpComponent
from garage.startups.logging import LoggingComponent
from garage.startups.multiprocessing import Python2Component
from garage.startups.threads.executors import ExecutorComponent


def main(argv):
    parser = argparse.ArgumentParser(description="""Multi-entry command.""")
    parser.set_defaults(cmd=None)
    startup.set(components.PARSER, parser)

    component_startups = {}
    subparsers = parser.add_subparsers(title='commands')
    for cmd in ('A', 'B', 'C'):
        component_startup = Startup()
        component_startups[cmd] = component_startup
        parser_ = '%s:cmd_%s_parser' % (__name__, cmd.lower())
        subparser = subparsers.add_parser(cmd)
        subparser.set_defaults(cmd=cmd)
        startup.set(parser_, subparser)
        comps = (
            ExecutorComponent(),
            HttpComponent(),
            LoggingComponent(),
            Python2Component(),
        )
        for comp in comps:
            components.bind(
                comp,
                next_startup=component_startup,
                parser_=parser_,
            )

    def real_main(args, component_startup):
        with ExitStack() as exit_stack:
            component_startup.set(components.ARGS, args)
            component_startup.set(components.EXIT_STACK, exit_stack)
            component_startup.call()
            logging.info('complete of command %s', args.cmd)
        return 0

    @startup
    def select_main(
            parser: components.PARSER,
            args: components.ARGS,
        ) -> components.MAIN:
        if not args.cmd:
            parser.error('command is required')
        component_startup = component_startups[args.cmd]
        return partial(real_main, component_startup=component_startup)

    return components.main(argv)


if __name__ == '__main__':
    sys.exit(main(sys.argv))

import argparse
import logging
import sys
from contextlib import ExitStack

from startup import Startup, startup

from garage import components
from garage.startups.http import HttpComponent
from garage.startups.logging import LoggingComponent
from garage.startups.multiprocessing import Python2Component
from garage.startups.threads.executors import ExecutorComponent


def main(argv):
    parser = argparse.ArgumentParser(description="""Multi-entry command.""")
    parser.set_defaults(next_main=None, next_startup=None, cmd=None)
    startup.set(components.PARSER, parser)

    subparsers = parser.add_subparsers(title='commands')
    for cmd in ('A', 'B', 'C'):
        next_startup = Startup()
        parser_ = '%s:cmd_%s_parser' % (__name__, cmd.lower())
        subparser = subparsers.add_parser(cmd)
        subparser.set_defaults(
            next_main=next_main, next_startup=next_startup, cmd=cmd)
        startup.set(parser_, subparser)
        comps = (
            ExecutorComponent(),
            HttpComponent(),
            LoggingComponent(),
            Python2Component(),
        )
        for comp in comps:
            components.bind(
                comp,
                next_startup=next_startup,
                parser_=parser_,
            )

    @startup
    def select_main(
            parser: components.PARSER,
            args: components.ARGS,
        ) -> components.MAIN:
        if not args.next_main:
            parser.error('command is required')
        return args.next_main

    return components.main(argv)


def next_main(args):
    with ExitStack() as exit_stack:
        args.next_startup.set(components.ARGS, args)
        args.next_startup.set(components.EXIT_STACK, exit_stack)
        args.next_startup.call()
        logging.info('complete of command %s', args.cmd)
    return 0


if __name__ == '__main__':
    sys.exit(main(sys.argv))

Revise samples/multientry.py