def main(argv=None):
    """fastfood command line interface."""
    # pylint: disable=missing-docstring
    import argparse
    import traceback

    class HelpfulParser(argparse.ArgumentParser):
        def error(self, message, print_help=False):
            if 'too few arguments' in message:
                sys.argv.insert(0, os.path.basename(sys.argv.pop(0)))
                message = ("%s. Try getting help with `%s -h`"
                           % (message, " ".join(sys.argv)))
            if print_help:
                self.print_help()
            sys.stderr.write('\nerror: %s\n' % message)
            sys.exit(2)

    parser = HelpfulParser(
        prog=NAMESPACE,
        description=__doc__.splitlines()[0],
        epilog="\n".join(__doc__.splitlines()[1:]),
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        )

    version_string = 'version %s' % fastfood.__version__
    parser.description = '%s ( %s )' % (parser.description, version_string)

    # version_group = subparsers.add_group()
    version_group = parser.add_argument_group(
        title='version info',
        description='Use these arguments to get version info.')

    vers_arg = version_group.add_argument(
        '-V', '--version', action='version',
        help="Return the current fastfood version.",
        version='%s %s' % (parser.prog, version_string))

    class LatestVersionAction(vers_arg.__class__):
        def __call__(self, prsr, *args, **kw):
            info = _release_info()
            vers = info['info']['version']
            release = info['releases'][vers][0]
            uploaded = datetime.strptime(
                release['upload_time'], '%Y-%m-%dT%H:%M:%S')
            sym = EXCLAIM if vers != fastfood.__version__ else CHECK
            message = u"{}  fastfood version {} uploaded {}\n"
            message = message.format(sym, vers, uploaded.ctime())
            prsr.exit(message=message)

    version_group.add_argument(
        '-L', '--latest', action=LatestVersionAction,
        help="Lookup the latest relase from PyPI.")

    verbose = parser.add_mutually_exclusive_group()
    verbose.add_argument('-v', dest='loglevel', action='store_const',
                         const=logging.INFO,
                         help="Set log-level to INFO.")
    verbose.add_argument('-vv', dest='loglevel', action='store_const',
                         const=logging.DEBUG,
                         help="Set log-level to DEBUG.")
    parser.set_defaults(loglevel=logging.WARNING)
    home = os.getenv('HOME') or os.path.expanduser('~') or os.getcwd()
    parser.add_argument(
        '--template-pack', help='template pack location',
        default=getenv(
            'template_pack', os.path.join(home, '.fastfood')))
    parser.add_argument(
        '--cookbooks', help='cookbooks directory',
        default=getenv(
            'cookbooks', os.path.join(home, 'cookbooks')))

    subparsers = parser.add_subparsers(
        dest='_subparsers', title='fastfood commands',
        description='operations...',
        help='...')

    #
    # `fastfood list`
    #
    list_parser = subparsers.add_parser(
        'list', help='List available stencils',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    list_parser.add_argument('stencil_set', nargs='?',
                             help="Stencil set to list stencils from")
    list_parser.set_defaults(func=_fastfood_list)

    #
    # `fastfood show <stencil_set>`
    #
    show_parser = subparsers.add_parser(
        'show', help='Show stencil set information',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    show_parser.add_argument('stencil_set',
                             help="Stencil set to list stencils from")
    show_parser.set_defaults(func=_fastfood_show)

    #
    # `fastfood build`
    #
    build_parser = subparsers.add_parser(
        'build', help='Create or update a cookbook using a config',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    build_parser.add_argument('config_file',
                              help="JSON config file")
    build_parser.add_argument('--force', '-f', action='store_true',
                              default=False, help="Overwrite existing files.")

    build_parser.set_defaults(func=_fastfood_build)

    setattr(_LOCAL, 'argparser', parser)
    if not argv:
        argv = None
    args = parser.parse_args(args=argv)
    if hasattr(args, 'options'):
        args.options = {k: v for k, v in args.options}

    logging.basicConfig(level=args.loglevel)

    try:
        args.func(args)
    except exc.FastfoodError as err:
        title = exc.get_friendly_title(err)
        print('%s  %s: %s' % (RED_X, title, str(err)),
              file=sys.stderr)
        sys.stderr.flush()
        sys.exit(1)
    except Exception as err:
        print('%s  Unexpected error. Please report this traceback.'
              % INTERROBANG,
              file=sys.stderr)
        traceback.print_exc()
        # todo: tracack in -v or -vv mode?
        sys.stderr.flush()
        sys.exit(1)
    except KeyboardInterrupt:
        sys.exit("\nStahp")