prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Add aliases for cookiecutters
  Remembering the locations of cookiecutters can be a bit of a pain - even if it's just including the local path.
  
  It would be useful to have an extra section in `cookiecutterrc` for aliases to cookiecutter locations. Something like:
  
  ```
  aliases:
    python: https://github.com/audreyr/cookiecutter-pypackage
    django: https://github.com/marcofucci/cookiecutter-simple-django
    docs: ~/samples/templates/documentation
  ```
  
  The code would simply need to translate an alias into a path before doing any of the existing processing.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `cookiecutter/main.py`
  Content:
  ```
  1 #!/usr/bin/env python
  2 # -*- coding: utf-8 -*-
  3 
  4 """
  5 cookiecutter.main
  6 -----------------
  7 
  8 Main entry point for the `cookiecutter` command.
  9 
  10 The code in this module is also a good example of how to use Cookiecutter as a
  11 library rather than a script.
  12 """
  13 
  14 from __future__ import unicode_literals
  15 import argparse
  16 import logging
  17 import os
  18 import sys
  19 
  20 from . import __version__
  21 from .config import get_user_config
  22 from .prompt import prompt_for_config
  23 from .generate import generate_context, generate_files
  24 from .vcs import clone
  25 
  26 logger = logging.getLogger(__name__)
  27 
  28 
  29 def cookiecutter(input_dir, checkout=None, no_input=False):
  30     """
  31     API equivalent to using Cookiecutter at the command line.
  32 
  33     :param input_dir: A directory containing a project template dir,
  34         or a URL to git repo.
  35     :param checkout: The branch, tag or commit ID to checkout after clone
  36     """
  37 
  38     # Get user config from ~/.cookiecutterrc or equivalent
  39     # If no config file, sensible defaults from config.DEFAULT_CONFIG are used
  40     config_dict = get_user_config()
  41 
  42     # TODO: find a better way to tell if it's a repo URL
  43     if "git@" in input_dir or "https://" in input_dir:
  44         repo_dir = clone(
  45             repo_url=input_dir,
  46             checkout=checkout,
  47             clone_to_dir=config_dict['cookiecutters_dir']
  48         )
  49     else:
  50         # If it's a local repo, no need to clone or copy to your cookiecutters_dir
  51         repo_dir = input_dir
  52 
  53     context_file = os.path.join(repo_dir, 'cookiecutter.json')
  54     logging.debug('context_file is {0}'.format(context_file))
  55 
  56     context = generate_context(
  57         context_file=context_file,
  58         default_context=config_dict['default_context']
  59     )
  60 
  61     # prompt the user to manually configure at the command line.
  62     # except when 'no-input' flag is set
  63     if not no_input:
  64         cookiecutter_dict = prompt_for_config(context)
  65         context['cookiecutter'] = cookiecutter_dict
  66 
  67     # Create project from local context and project template.
  68     generate_files(
  69         repo_dir=repo_dir,
  70         context=context
  71     )
  72 
  73 
  74 def _get_parser():
  75     parser = argparse.ArgumentParser(
  76         description='Create a project from a Cookiecutter project template.'
  77     )
  78     parser.add_argument(
  79         '--no-input',
  80         action="store_true",
  81         help='Do not prompt for parameters and only use cookiecutter.json '
  82              'file content')
  83     parser.add_argument(
  84         'input_dir',
  85         help='Cookiecutter project dir, e.g. cookiecutter-pypackage/'
  86     )
  87     parser.add_argument(
  88         '-c', '--checkout',
  89         help='branch, tag or commit to checkout after git clone'
  90     )
  91     cookiecutter_pkg_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  92     parser.add_argument(
  93         '-V', '--version',
  94         help="Show version information and exit.",
  95         action='version',
  96         version='Cookiecutter %s from %s (Python %s)' % (
  97             __version__,
  98             cookiecutter_pkg_dir,
  99             sys.version[:3]
  100         )
  101     )
  102     parser.add_argument(
  103         '-v', '--verbose',
  104         help='Print debug information',
  105         action='store_true', default=False
  106     )
  107 
  108     return parser
  109 
  110 def parse_cookiecutter_args(args):
  111     """ Parse the command-line arguments to Cookiecutter. """
  112     parser = _get_parser()
  113     return parser.parse_args(args)
  114 
  115 
  116 def main():
  117     """ Entry point for the package, as defined in setup.py. """
  118 
  119     args = parse_cookiecutter_args(sys.argv[1:])
  120 
  121     if args.verbose:
  122         logging.basicConfig(format='%(levelname)s %(filename)s: %(message)s', level=logging.DEBUG)
  123     else:
  124         # Log info and above to console
  125         logging.basicConfig(
  126             format='%(levelname)s: %(message)s',
  127             level=logging.INFO
  128         )
  129 
  130     cookiecutter(args.input_dir, args.checkout, args.no_input)
  131 
  132 
  133 if __name__ == '__main__':
  134     main()
  135
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/cookiecutter/main.py b/cookiecutter/main.py
  --- a/cookiecutter/main.py
  +++ b/cookiecutter/main.py
  @@ -25,6 +25,34 @@
   
   logger = logging.getLogger(__name__)
   
  +builtin_abbreviations = {
  +    'gh': 'https://github.com/{0}.git',
  +    'bb': 'https://bitbucket.org/{0}',
  +}
  +
  +def expand_abbreviations(input_dir, config_dict):
  +    """
  +    Expand abbreviations in a template name.
  +
  +    :param input_dir: The project template name.
  +    :param config_dict: The user config, which will contain abbreviation
  +        definitions.
  +    """
  +
  +    abbreviations = builtin_abbreviations.copy()
  +    abbreviations.update(config_dict.get('abbreviations', {}))
  +
  +    if input_dir in abbreviations:
  +        return abbreviations[input_dir]
  +
  +    # Split on colon. If there is no colon, rest will be empty
  +    # and prefix will be the whole input_dir
  +    prefix, sep, rest = input_dir.partition(':')
  +    if prefix in abbreviations:
  +        return abbreviations[prefix].format(rest)
  +
  +    return input_dir
  +
   
   def cookiecutter(input_dir, checkout=None, no_input=False):
       """
  @@ -39,6 +67,8 @@
       # If no config file, sensible defaults from config.DEFAULT_CONFIG are used
       config_dict = get_user_config()
   
  +    input_dir = expand_abbreviations(input_dir, config_dict)
  +
       # TODO: find a better way to tell if it's a repo URL
       if "git@" in input_dir or "https://" in input_dir:
           repo_dir = clone(
  
verification_info: {"golden_diff": "diff --git a/cookiecutter/main.py b/cookiecutter/main.py\n--- a/cookiecutter/main.py\n+++ b/cookiecutter/main.py\n@@ -25,6 +25,34 @@\n \n logger = logging.getLogger(__name__)\n \n+builtin_abbreviations = {\n+    'gh': 'https://github.com/{0}.git',\n+    'bb': 'https://bitbucket.org/{0}',\n+}\n+\n+def expand_abbreviations(input_dir, config_dict):\n+    \"\"\"\n+    Expand abbreviations in a template name.\n+\n+    :param input_dir: The project template name.\n+    :param config_dict: The user config, which will contain abbreviation\n+        definitions.\n+    \"\"\"\n+\n+    abbreviations = builtin_abbreviations.copy()\n+    abbreviations.update(config_dict.get('abbreviations', {}))\n+\n+    if input_dir in abbreviations:\n+        return abbreviations[input_dir]\n+\n+    # Split on colon. If there is no colon, rest will be empty\n+    # and prefix will be the whole input_dir\n+    prefix, sep, rest = input_dir.partition(':')\n+    if prefix in abbreviations:\n+        return abbreviations[prefix].format(rest)\n+\n+    return input_dir\n+\n \n def cookiecutter(input_dir, checkout=None, no_input=False):\n     \"\"\"\n@@ -39,6 +67,8 @@\n     # If no config file, sensible defaults from config.DEFAULT_CONFIG are used\n     config_dict = get_user_config()\n \n+    input_dir = expand_abbreviations(input_dir, config_dict)\n+\n     # TODO: find a better way to tell if it's a repo URL\n     if \"git@\" in input_dir or \"https://\" in input_dir:\n         repo_dir = clone(\n", "issue": "Add aliases for cookiecutters\nRemembering the locations of cookiecutters can be a bit of a pain - even if it's just including the local path.\n\nIt would be useful to have an extra section in `cookiecutterrc` for aliases to cookiecutter locations. Something like:\n\n```\naliases:\n  python: https://github.com/audreyr/cookiecutter-pypackage\n  django: https://github.com/marcofucci/cookiecutter-simple-django\n  docs: ~/samples/templates/documentation\n```\n\nThe code would simply need to translate an alias into a path before doing any of the existing processing.\n\n", "before_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n\"\"\"\ncookiecutter.main\n-----------------\n\nMain entry point for the `cookiecutter` command.\n\nThe code in this module is also a good example of how to use Cookiecutter as a\nlibrary rather than a script.\n\"\"\"\n\nfrom __future__ import unicode_literals\nimport argparse\nimport logging\nimport os\nimport sys\n\nfrom . import __version__\nfrom .config import get_user_config\nfrom .prompt import prompt_for_config\nfrom .generate import generate_context, generate_files\nfrom .vcs import clone\n\nlogger = logging.getLogger(__name__)\n\n\ndef cookiecutter(input_dir, checkout=None, no_input=False):\n    \"\"\"\n    API equivalent to using Cookiecutter at the command line.\n\n    :param input_dir: A directory containing a project template dir,\n        or a URL to git repo.\n    :param checkout: The branch, tag or commit ID to checkout after clone\n    \"\"\"\n\n    # Get user config from ~/.cookiecutterrc or equivalent\n    # If no config file, sensible defaults from config.DEFAULT_CONFIG are used\n    config_dict = get_user_config()\n\n    # TODO: find a better way to tell if it's a repo URL\n    if \"git@\" in input_dir or \"https://\" in input_dir:\n        repo_dir = clone(\n            repo_url=input_dir,\n            checkout=checkout,\n            clone_to_dir=config_dict['cookiecutters_dir']\n        )\n    else:\n        # If it's a local repo, no need to clone or copy to your cookiecutters_dir\n        repo_dir = input_dir\n\n    context_file = os.path.join(repo_dir, 'cookiecutter.json')\n    logging.debug('context_file is {0}'.format(context_file))\n\n    context = generate_context(\n        context_file=context_file,\n        default_context=config_dict['default_context']\n    )\n\n    # prompt the user to manually configure at the command line.\n    # except when 'no-input' flag is set\n    if not no_input:\n        cookiecutter_dict = prompt_for_config(context)\n        context['cookiecutter'] = cookiecutter_dict\n\n    # Create project from local context and project template.\n    generate_files(\n        repo_dir=repo_dir,\n        context=context\n    )\n\n\ndef _get_parser():\n    parser = argparse.ArgumentParser(\n        description='Create a project from a Cookiecutter project template.'\n    )\n    parser.add_argument(\n        '--no-input',\n        action=\"store_true\",\n        help='Do not prompt for parameters and only use cookiecutter.json '\n             'file content')\n    parser.add_argument(\n        'input_dir',\n        help='Cookiecutter project dir, e.g. cookiecutter-pypackage/'\n    )\n    parser.add_argument(\n        '-c', '--checkout',\n        help='branch, tag or commit to checkout after git clone'\n    )\n    cookiecutter_pkg_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\n    parser.add_argument(\n        '-V', '--version',\n        help=\"Show version information and exit.\",\n        action='version',\n        version='Cookiecutter %s from %s (Python %s)' % (\n            __version__,\n            cookiecutter_pkg_dir,\n            sys.version[:3]\n        )\n    )\n    parser.add_argument(\n        '-v', '--verbose',\n        help='Print debug information',\n        action='store_true', default=False\n    )\n\n    return parser\n\ndef parse_cookiecutter_args(args):\n    \"\"\" Parse the command-line arguments to Cookiecutter. \"\"\"\n    parser = _get_parser()\n    return parser.parse_args(args)\n\n\ndef main():\n    \"\"\" Entry point for the package, as defined in setup.py. \"\"\"\n\n    args = parse_cookiecutter_args(sys.argv[1:])\n\n    if args.verbose:\n        logging.basicConfig(format='%(levelname)s %(filename)s: %(message)s', level=logging.DEBUG)\n    else:\n        # Log info and above to console\n        logging.basicConfig(\n            format='%(levelname)s: %(message)s',\n            level=logging.INFO\n        )\n\n    cookiecutter(args.input_dir, args.checkout, args.no_input)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "cookiecutter/main.py"}], "after_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n\"\"\"\ncookiecutter.main\n-----------------\n\nMain entry point for the `cookiecutter` command.\n\nThe code in this module is also a good example of how to use Cookiecutter as a\nlibrary rather than a script.\n\"\"\"\n\nfrom __future__ import unicode_literals\nimport argparse\nimport logging\nimport os\nimport sys\n\nfrom . import __version__\nfrom .config import get_user_config\nfrom .prompt import prompt_for_config\nfrom .generate import generate_context, generate_files\nfrom .vcs import clone\n\nlogger = logging.getLogger(__name__)\n\nbuiltin_abbreviations = {\n    'gh': 'https://github.com/{0}.git',\n    'bb': 'https://bitbucket.org/{0}',\n}\n\ndef expand_abbreviations(input_dir, config_dict):\n    \"\"\"\n    Expand abbreviations in a template name.\n\n    :param input_dir: The project template name.\n    :param config_dict: The user config, which will contain abbreviation\n        definitions.\n    \"\"\"\n\n    abbreviations = builtin_abbreviations.copy()\n    abbreviations.update(config_dict.get('abbreviations', {}))\n\n    if input_dir in abbreviations:\n        return abbreviations[input_dir]\n\n    # Split on colon. If there is no colon, rest will be empty\n    # and prefix will be the whole input_dir\n    prefix, sep, rest = input_dir.partition(':')\n    if prefix in abbreviations:\n        return abbreviations[prefix].format(rest)\n\n    return input_dir\n\n\ndef cookiecutter(input_dir, checkout=None, no_input=False):\n    \"\"\"\n    API equivalent to using Cookiecutter at the command line.\n\n    :param input_dir: A directory containing a project template dir,\n        or a URL to git repo.\n    :param checkout: The branch, tag or commit ID to checkout after clone\n    \"\"\"\n\n    # Get user config from ~/.cookiecutterrc or equivalent\n    # If no config file, sensible defaults from config.DEFAULT_CONFIG are used\n    config_dict = get_user_config()\n\n    input_dir = expand_abbreviations(input_dir, config_dict)\n\n    # TODO: find a better way to tell if it's a repo URL\n    if \"git@\" in input_dir or \"https://\" in input_dir:\n        repo_dir = clone(\n            repo_url=input_dir,\n            checkout=checkout,\n            clone_to_dir=config_dict['cookiecutters_dir']\n        )\n    else:\n        # If it's a local repo, no need to clone or copy to your cookiecutters_dir\n        repo_dir = input_dir\n\n    context_file = os.path.join(repo_dir, 'cookiecutter.json')\n    logging.debug('context_file is {0}'.format(context_file))\n\n    context = generate_context(\n        context_file=context_file,\n        default_context=config_dict['default_context']\n    )\n\n    # prompt the user to manually configure at the command line.\n    # except when 'no-input' flag is set\n    if not no_input:\n        cookiecutter_dict = prompt_for_config(context)\n        context['cookiecutter'] = cookiecutter_dict\n\n    # Create project from local context and project template.\n    generate_files(\n        repo_dir=repo_dir,\n        context=context\n    )\n\n\ndef _get_parser():\n    parser = argparse.ArgumentParser(\n        description='Create a project from a Cookiecutter project template.'\n    )\n    parser.add_argument(\n        '--no-input',\n        action=\"store_true\",\n        help='Do not prompt for parameters and only use cookiecutter.json '\n             'file content')\n    parser.add_argument(\n        'input_dir',\n        help='Cookiecutter project dir, e.g. cookiecutter-pypackage/'\n    )\n    parser.add_argument(\n        '-c', '--checkout',\n        help='branch, tag or commit to checkout after git clone'\n    )\n    cookiecutter_pkg_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\n    parser.add_argument(\n        '-V', '--version',\n        help=\"Show version information and exit.\",\n        action='version',\n        version='Cookiecutter %s from %s (Python %s)' % (\n            __version__,\n            cookiecutter_pkg_dir,\n            sys.version[:3]\n        )\n    )\n    parser.add_argument(\n        '-v', '--verbose',\n        help='Print debug information',\n        action='store_true', default=False\n    )\n\n    return parser\n\ndef parse_cookiecutter_args(args):\n    \"\"\" Parse the command-line arguments to Cookiecutter. \"\"\"\n    parser = _get_parser()\n    return parser.parse_args(args)\n\n\ndef main():\n    \"\"\" Entry point for the package, as defined in setup.py. \"\"\"\n\n    args = parse_cookiecutter_args(sys.argv[1:])\n\n    if args.verbose:\n        logging.basicConfig(format='%(levelname)s %(filename)s: %(message)s', level=logging.DEBUG)\n    else:\n        # Log info and above to console\n        logging.basicConfig(\n            format='%(levelname)s: %(message)s',\n            level=logging.INFO\n        )\n\n    cookiecutter(args.input_dir, args.checkout, args.no_input)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "cookiecutter/main.py"}]}