prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Fix the repo regex to handle + in URLs
  The documentation said that you could do git+https:// or git+ssh:// but that was not, in fact, true.
  
  
  </issue>
  <code>
  [start of cookiecutter/main.py]
  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 logging
  16 import os
  17 import re
  18 
  19 from .config import get_user_config, USER_CONFIG_PATH
  20 from .exceptions import InvalidModeException, RepositoryNotFound
  21 from .prompt import prompt_for_config
  22 from .generate import generate_context, generate_files
  23 from .vcs import clone
  24 from .replay import dump, load
  25 
  26 logger = logging.getLogger(__name__)
  27 
  28 builtin_abbreviations = {
  29     'gh': 'https://github.com/{0}.git',
  30     'bb': 'https://bitbucket.org/{0}',
  31 }
  32 
  33 REPO_REGEX = """
  34 (
  35 ((git|ssh|https|http):(//)?)    # something like git:// ssh:// etc.
  36  |                              # or
  37  (\w+@[\w\.]+)                  # something like user@...
  38 )
  39 .*
  40 """
  41 
  42 
  43 def is_repo_url(value):
  44     """Return True if value is a repository URL."""
  45     return bool(re.match(REPO_REGEX, value, re.VERBOSE))
  46 
  47 
  48 def expand_abbreviations(template, config_dict):
  49     """
  50     Expand abbreviations in a template name.
  51 
  52     :param template: The project template name.
  53     :param config_dict: The user config, which will contain abbreviation
  54         definitions.
  55     """
  56 
  57     abbreviations = builtin_abbreviations.copy()
  58     abbreviations.update(config_dict.get('abbreviations', {}))
  59 
  60     if template in abbreviations:
  61         return abbreviations[template]
  62 
  63     # Split on colon. If there is no colon, rest will be empty
  64     # and prefix will be the whole template
  65     prefix, sep, rest = template.partition(':')
  66     if prefix in abbreviations:
  67         return abbreviations[prefix].format(rest)
  68 
  69     return template
  70 
  71 
  72 def cookiecutter(
  73         template, checkout=None, no_input=False, extra_context=None,
  74         replay=False, overwrite_if_exists=False, output_dir='.',
  75         config_file=USER_CONFIG_PATH):
  76     """
  77     API equivalent to using Cookiecutter at the command line.
  78 
  79     :param template: A directory containing a project template directory,
  80         or a URL to a git repository.
  81     :param checkout: The branch, tag or commit ID to checkout after clone.
  82     :param no_input: Prompt the user at command line for manual configuration?
  83     :param extra_context: A dictionary of context that overrides default
  84         and user configuration.
  85     :param: overwrite_if_exists: Overwrite the contents of output directory
  86         if it exists
  87     :param output_dir: Where to output the generated project dir into.
  88     :param config_file: User configuration file path.
  89     """
  90     if replay and ((no_input is not False) or (extra_context is not None)):
  91         err_msg = (
  92             "You can not use both replay and no_input or extra_context "
  93             "at the same time."
  94         )
  95         raise InvalidModeException(err_msg)
  96 
  97     # Get user config from ~/.cookiecutterrc or equivalent
  98     # If no config file, sensible defaults from config.DEFAULT_CONFIG are used
  99     config_dict = get_user_config(config_file=config_file)
  100 
  101     template = expand_abbreviations(template, config_dict)
  102 
  103     if is_repo_url(template):
  104         repo_dir = clone(
  105             repo_url=template,
  106             checkout=checkout,
  107             clone_to_dir=config_dict['cookiecutters_dir'],
  108             no_input=no_input
  109         )
  110     else:
  111         # If it's a local repo, no need to clone or copy to your
  112         # cookiecutters_dir
  113         repo_dir = template
  114 
  115     if not os.path.isdir(repo_dir):
  116         raise RepositoryNotFound(
  117             'The repository {0} could not be located.'.format(template)
  118         )
  119 
  120     template_name = os.path.basename(template)
  121 
  122     if replay:
  123         context = load(config_dict['replay_dir'], template_name)
  124     else:
  125         context_file = os.path.join(repo_dir, 'cookiecutter.json')
  126         logging.debug('context_file is {0}'.format(context_file))
  127 
  128         context = generate_context(
  129             context_file=context_file,
  130             default_context=config_dict['default_context'],
  131             extra_context=extra_context,
  132         )
  133 
  134         # prompt the user to manually configure at the command line.
  135         # except when 'no-input' flag is set
  136         context['cookiecutter'] = prompt_for_config(context, no_input)
  137 
  138         dump(config_dict['replay_dir'], template_name, context)
  139 
  140     # Create project from local context and project template.
  141     return generate_files(
  142         repo_dir=repo_dir,
  143         context=context,
  144         overwrite_if_exists=overwrite_if_exists,
  145         output_dir=output_dir
  146     )
  147
  [end of cookiecutter/main.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/cookiecutter/main.py b/cookiecutter/main.py
  --- a/cookiecutter/main.py
  +++ b/cookiecutter/main.py
  @@ -30,19 +30,18 @@
       'bb': 'https://bitbucket.org/{0}',
   }
   
  -REPO_REGEX = """
  -(
  -((git|ssh|https|http):(//)?)    # something like git:// ssh:// etc.
  - |                              # or
  - (\w+@[\w\.]+)                  # something like user@...
  +REPO_REGEX = re.compile(r"""
  +(?x)
  +((((git|hg)\+)?(git|ssh|https?):(//)?)  # something like git:// ssh:// etc.
  + |                                      # or
  + (\w+@[\w\.]+)                          # something like user@...
   )
  -.*
  -"""
  +""")
   
   
   def is_repo_url(value):
       """Return True if value is a repository URL."""
  -    return bool(re.match(REPO_REGEX, value, re.VERBOSE))
  +    return bool(REPO_REGEX.match(value))
   
   
   def expand_abbreviations(template, config_dict):
  
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@@ -30,19 +30,18 @@\n     'bb': 'https://bitbucket.org/{0}',\n }\n \n-REPO_REGEX = \"\"\"\n-(\n-((git|ssh|https|http):(//)?)    # something like git:// ssh:// etc.\n- |                              # or\n- (\\w+@[\\w\\.]+)                  # something like user@...\n+REPO_REGEX = re.compile(r\"\"\"\n+(?x)\n+((((git|hg)\\+)?(git|ssh|https?):(//)?)  # something like git:// ssh:// etc.\n+ |                                      # or\n+ (\\w+@[\\w\\.]+)                          # something like user@...\n )\n-.*\n-\"\"\"\n+\"\"\")\n \n \n def is_repo_url(value):\n     \"\"\"Return True if value is a repository URL.\"\"\"\n-    return bool(re.match(REPO_REGEX, value, re.VERBOSE))\n+    return bool(REPO_REGEX.match(value))\n \n \n def expand_abbreviations(template, config_dict):\n", "issue": "Fix the repo regex to handle + in URLs\nThe documentation said that you could do git+https:// or git+ssh:// but that was not, in fact, true.\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 logging\nimport os\nimport re\n\nfrom .config import get_user_config, USER_CONFIG_PATH\nfrom .exceptions import InvalidModeException, RepositoryNotFound\nfrom .prompt import prompt_for_config\nfrom .generate import generate_context, generate_files\nfrom .vcs import clone\nfrom .replay import dump, load\n\nlogger = logging.getLogger(__name__)\n\nbuiltin_abbreviations = {\n    'gh': 'https://github.com/{0}.git',\n    'bb': 'https://bitbucket.org/{0}',\n}\n\nREPO_REGEX = \"\"\"\n(\n((git|ssh|https|http):(//)?)    # something like git:// ssh:// etc.\n |                              # or\n (\\w+@[\\w\\.]+)                  # something like user@...\n)\n.*\n\"\"\"\n\n\ndef is_repo_url(value):\n    \"\"\"Return True if value is a repository URL.\"\"\"\n    return bool(re.match(REPO_REGEX, value, re.VERBOSE))\n\n\ndef expand_abbreviations(template, config_dict):\n    \"\"\"\n    Expand abbreviations in a template name.\n\n    :param template: 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 template in abbreviations:\n        return abbreviations[template]\n\n    # Split on colon. If there is no colon, rest will be empty\n    # and prefix will be the whole template\n    prefix, sep, rest = template.partition(':')\n    if prefix in abbreviations:\n        return abbreviations[prefix].format(rest)\n\n    return template\n\n\ndef cookiecutter(\n        template, checkout=None, no_input=False, extra_context=None,\n        replay=False, overwrite_if_exists=False, output_dir='.',\n        config_file=USER_CONFIG_PATH):\n    \"\"\"\n    API equivalent to using Cookiecutter at the command line.\n\n    :param template: A directory containing a project template directory,\n        or a URL to a git repository.\n    :param checkout: The branch, tag or commit ID to checkout after clone.\n    :param no_input: Prompt the user at command line for manual configuration?\n    :param extra_context: A dictionary of context that overrides default\n        and user configuration.\n    :param: overwrite_if_exists: Overwrite the contents of output directory\n        if it exists\n    :param output_dir: Where to output the generated project dir into.\n    :param config_file: User configuration file path.\n    \"\"\"\n    if replay and ((no_input is not False) or (extra_context is not None)):\n        err_msg = (\n            \"You can not use both replay and no_input or extra_context \"\n            \"at the same time.\"\n        )\n        raise InvalidModeException(err_msg)\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(config_file=config_file)\n\n    template = expand_abbreviations(template, config_dict)\n\n    if is_repo_url(template):\n        repo_dir = clone(\n            repo_url=template,\n            checkout=checkout,\n            clone_to_dir=config_dict['cookiecutters_dir'],\n            no_input=no_input\n        )\n    else:\n        # If it's a local repo, no need to clone or copy to your\n        # cookiecutters_dir\n        repo_dir = template\n\n    if not os.path.isdir(repo_dir):\n        raise RepositoryNotFound(\n            'The repository {0} could not be located.'.format(template)\n        )\n\n    template_name = os.path.basename(template)\n\n    if replay:\n        context = load(config_dict['replay_dir'], template_name)\n    else:\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            extra_context=extra_context,\n        )\n\n        # prompt the user to manually configure at the command line.\n        # except when 'no-input' flag is set\n        context['cookiecutter'] = prompt_for_config(context, no_input)\n\n        dump(config_dict['replay_dir'], template_name, context)\n\n    # Create project from local context and project template.\n    return generate_files(\n        repo_dir=repo_dir,\n        context=context,\n        overwrite_if_exists=overwrite_if_exists,\n        output_dir=output_dir\n    )\n", "path": "cookiecutter/main.py"}]}