We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Choice prompts are disabled if there's a ~/.cookiecutterrc
Seems I don't get the nice prompts from https://github.com/audreyr/cookiecutter/pull/455 if I have a `~/.cookiecutterrc`


--- 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/generate.py`
Content:
```
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 
4 """
5 cookiecutter.generate
6 ---------------------
7 
8 Functions for generating a project from a project template.
9 """
10 from __future__ import unicode_literals
11 from collections import OrderedDict
12 import fnmatch
13 import io
14 import json
15 import logging
16 import os
17 import shutil
18 
19 from jinja2 import FileSystemLoader, Template
20 from jinja2.environment import Environment
21 from jinja2.exceptions import TemplateSyntaxError
22 from binaryornot.check import is_binary
23 
24 from .exceptions import (
25     NonTemplatedInputDirException,
26     ContextDecodingException,
27     OutputDirExistsException
28 )
29 from .find import find_template
30 from .utils import make_sure_path_exists, work_in
31 from .hooks import run_hook
32 
33 
34 def copy_without_render(path, context):
35     """
36     Returns True if `path` matches some pattern in the
37     `_copy_without_render` context setting.
38 
39     :param path: A file-system path referring to a file or dir that
40         should be rendered or just copied.
41     :param context: cookiecutter context.
42     """
43     try:
44         for dont_render in context['cookiecutter']['_copy_without_render']:
45             if fnmatch.fnmatch(path, dont_render):
46                 return True
47     except KeyError:
48         return False
49 
50     return False
51 
52 
53 def generate_context(context_file='cookiecutter.json', default_context=None,
54                      extra_context=None):
55     """
56     Generates the context for a Cookiecutter project template.
57     Loads the JSON file as a Python object, with key being the JSON filename.
58 
59     :param context_file: JSON file containing key/value pairs for populating
60         the cookiecutter's variables.
61     :param default_context: Dictionary containing config to take into account.
62     :param extra_context: Dictionary containing configuration overrides
63     """
64 
65     context = {}
66 
67     file_handle = open(context_file)
68     try:
69         obj = json.load(file_handle, object_pairs_hook=OrderedDict)
70     except ValueError as e:
71         # JSON decoding error.  Let's throw a new exception that is more
72         # friendly for the developer or user.
73         full_fpath = os.path.abspath(context_file)
74         json_exc_message = str(e)
75         our_exc_message = (
76             'JSON decoding error while loading "{0}".  Decoding'
77             ' error details: "{1}"'.format(full_fpath, json_exc_message))
78         raise ContextDecodingException(our_exc_message)
79 
80     # Add the Python object to the context dictionary
81     file_name = os.path.split(context_file)[1]
82     file_stem = file_name.split('.')[0]
83     context[file_stem] = obj
84 
85     # Overwrite context variable defaults with the default context from the
86     # user's global config, if available
87     if default_context:
88         obj.update(default_context)
89     if extra_context:
90         obj.update(extra_context)
91 
92     logging.debug('Context generated is {0}'.format(context))
93     return context
94 
95 
96 def generate_file(project_dir, infile, context, env):
97     """
98     1. Render the filename of infile as the name of outfile.
99     2. Deal with infile appropriately:
100 
101         a. If infile is a binary file, copy it over without rendering.
102         b. If infile is a text file, render its contents and write the
103            rendered infile to outfile.
104 
105     Precondition:
106 
107         When calling `generate_file()`, the root template dir must be the
108         current working directory. Using `utils.work_in()` is the recommended
109         way to perform this directory change.
110 
111     :param project_dir: Absolute path to the resulting generated project.
112     :param infile: Input file to generate the file from. Relative to the root
113         template dir.
114     :param context: Dict for populating the cookiecutter's variables.
115     :param env: Jinja2 template execution environment.
116     """
117 
118     logging.debug('Generating file {0}'.format(infile))
119 
120     # Render the path to the output file (not including the root project dir)
121     outfile_tmpl = Template(infile)
122     outfile = os.path.join(project_dir, outfile_tmpl.render(**context))
123     logging.debug('outfile is {0}'.format(outfile))
124 
125     # Just copy over binary files. Don't render.
126     logging.debug("Check {0} to see if it's a binary".format(infile))
127     if is_binary(infile):
128         logging.debug('Copying binary {0} to {1} without rendering'
129                       .format(infile, outfile))
130         shutil.copyfile(infile, outfile)
131     else:
132         # Force fwd slashes on Windows for get_template
133         # This is a by-design Jinja issue
134         infile_fwd_slashes = infile.replace(os.path.sep, '/')
135 
136         # Render the file
137         try:
138             tmpl = env.get_template(infile_fwd_slashes)
139         except TemplateSyntaxError as exception:
140             # Disable translated so that printed exception contains verbose
141             # information about syntax error location
142             exception.translated = False
143             raise
144         rendered_file = tmpl.render(**context)
145 
146         logging.debug('Writing {0}'.format(outfile))
147 
148         with io.open(outfile, 'w', encoding='utf-8') as fh:
149             fh.write(rendered_file)
150 
151     # Apply file permissions to output file
152     shutil.copymode(infile, outfile)
153 
154 
155 def render_and_create_dir(dirname, context, output_dir,
156                           overwrite_if_exists=False):
157     """
158     Renders the name of a directory, creates the directory, and
159     returns its path.
160     """
161 
162     name_tmpl = Template(dirname)
163     rendered_dirname = name_tmpl.render(**context)
164     logging.debug('Rendered dir {0} must exist in output_dir {1}'.format(
165         rendered_dirname,
166         output_dir
167     ))
168     dir_to_create = os.path.normpath(
169         os.path.join(output_dir, rendered_dirname)
170     )
171 
172     output_dir_exists = os.path.exists(dir_to_create)
173 
174     if overwrite_if_exists:
175         if output_dir_exists:
176             logging.debug('Output directory {} already exists,'
177                           'overwriting it'.format(dir_to_create))
178     else:
179         if output_dir_exists:
180             msg = 'Error: "{}" directory already exists'.format(dir_to_create)
181             raise OutputDirExistsException(msg)
182 
183     make_sure_path_exists(dir_to_create)
184     return dir_to_create
185 
186 
187 def ensure_dir_is_templated(dirname):
188     """
189     Ensures that dirname is a templated directory name.
190     """
191     if '{{' in dirname and '}}' in dirname:
192         return True
193     else:
194         raise NonTemplatedInputDirException
195 
196 
197 def generate_files(repo_dir, context=None, output_dir='.',
198                    overwrite_if_exists=False):
199     """
200     Renders the templates and saves them to files.
201 
202     :param repo_dir: Project template input directory.
203     :param context: Dict for populating the template's variables.
204     :param output_dir: Where to output the generated project dir into.
205     :param overwrite_if_exists: Overwrite the contents of the output directory
206         if it exists
207     """
208 
209     template_dir = find_template(repo_dir)
210     logging.debug('Generating project from {0}...'.format(template_dir))
211     context = context or {}
212 
213     unrendered_dir = os.path.split(template_dir)[1]
214     ensure_dir_is_templated(unrendered_dir)
215     project_dir = render_and_create_dir(unrendered_dir,
216                                         context,
217                                         output_dir,
218                                         overwrite_if_exists)
219 
220     # We want the Jinja path and the OS paths to match. Consequently, we'll:
221     #   + CD to the template folder
222     #   + Set Jinja's path to '.'
223     #
224     #  In order to build our files to the correct folder(s), we'll use an
225     # absolute path for the target folder (project_dir)
226 
227     project_dir = os.path.abspath(project_dir)
228     logging.debug('project_dir is {0}'.format(project_dir))
229 
230     # run pre-gen hook from repo_dir
231     with work_in(repo_dir):
232         run_hook('pre_gen_project', project_dir, context)
233 
234     with work_in(template_dir):
235         env = Environment(keep_trailing_newline=True)
236         env.loader = FileSystemLoader('.')
237 
238         for root, dirs, files in os.walk('.'):
239             # We must separate the two types of dirs into different lists.
240             # The reason is that we don't want ``os.walk`` to go through the
241             # unrendered directories, since they will just be copied.
242             copy_dirs = []
243             render_dirs = []
244 
245             for d in dirs:
246                 d_ = os.path.normpath(os.path.join(root, d))
247                 # We check the full path, because that's how it can be
248                 # specified in the ``_copy_without_render`` setting, but
249                 # we store just the dir name
250                 if copy_without_render(d_, context):
251                     copy_dirs.append(d)
252                 else:
253                     render_dirs.append(d)
254 
255             for copy_dir in copy_dirs:
256                 indir = os.path.normpath(os.path.join(root, copy_dir))
257                 outdir = os.path.normpath(os.path.join(project_dir, indir))
258                 logging.debug(
259                     'Copying dir {0} to {1} without rendering'
260                     ''.format(indir, outdir)
261                 )
262                 shutil.copytree(indir, outdir)
263 
264             # We mutate ``dirs``, because we only want to go through these dirs
265             # recursively
266             dirs[:] = render_dirs
267             for d in dirs:
268                 unrendered_dir = os.path.join(project_dir, root, d)
269                 render_and_create_dir(unrendered_dir, context, output_dir,
270                                       overwrite_if_exists)
271 
272             for f in files:
273                 infile = os.path.normpath(os.path.join(root, f))
274                 if copy_without_render(infile, context):
275                     outfile_tmpl = Template(infile)
276                     outfile_rendered = outfile_tmpl.render(**context)
277                     outfile = os.path.join(project_dir, outfile_rendered)
278                     logging.debug(
279                         'Copying file {0} to {1} without rendering'
280                         ''.format(infile, outfile)
281                     )
282                     shutil.copyfile(infile, outfile)
283                     shutil.copymode(infile, outfile)
284                     continue
285                 logging.debug('f is {0}'.format(f))
286                 generate_file(project_dir, infile, context, env)
287 
288     # run post-gen hook from repo_dir
289     with work_in(repo_dir):
290         run_hook('post_gen_project', project_dir, context)
291
```
--- 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()

```

diff --git a/cookiecutter/generate.py b/cookiecutter/generate.py
--- a/cookiecutter/generate.py
+++ b/cookiecutter/generate.py
@@ -50,6 +50,28 @@
     return False
 
 
+def apply_overwrites_to_context(context, overwrite_context):
+    """Modify the given context in place based on the overwrite_context."""
+    for variable, overwrite in overwrite_context.items():
+        if variable not in context:
+            # Do not include variables which are not used in the template
+            continue
+
+        context_value = context[variable]
+
+        if isinstance(context_value, list):
+            # We are dealing with a choice variable
+            if overwrite in context_value:
+                # This overwrite is actually valid for the given context
+                # Let's set it as default (by definition first item in list)
+                # see ``cookiecutter.prompt.prompt_choice_for_config``
+                context_value.remove(overwrite)
+                context_value.insert(0, overwrite)
+        else:
+            # Simply overwrite the value for this variable
+            context[variable] = overwrite
+
+
 def generate_context(context_file='cookiecutter.json', default_context=None,
                      extra_context=None):
     """
@@ -85,9 +107,9 @@
     # Overwrite context variable defaults with the default context from the
     # user's global config, if available
     if default_context:
-        obj.update(default_context)
+        apply_overwrites_to_context(obj, default_context)
     if extra_context:
-        obj.update(extra_context)
+        apply_overwrites_to_context(obj, extra_context)
 
     logging.debug('Context generated is {0}'.format(context))
     return context

{"golden_diff": "diff --git a/cookiecutter/generate.py b/cookiecutter/generate.py\n--- a/cookiecutter/generate.py\n+++ b/cookiecutter/generate.py\n@@ -50,6 +50,28 @@\n     return False\n \n \n+def apply_overwrites_to_context(context, overwrite_context):\n+    \"\"\"Modify the given context in place based on the overwrite_context.\"\"\"\n+    for variable, overwrite in overwrite_context.items():\n+        if variable not in context:\n+            # Do not include variables which are not used in the template\n+            continue\n+\n+        context_value = context[variable]\n+\n+        if isinstance(context_value, list):\n+            # We are dealing with a choice variable\n+            if overwrite in context_value:\n+                # This overwrite is actually valid for the given context\n+                # Let's set it as default (by definition first item in list)\n+                # see ``cookiecutter.prompt.prompt_choice_for_config``\n+                context_value.remove(overwrite)\n+                context_value.insert(0, overwrite)\n+        else:\n+            # Simply overwrite the value for this variable\n+            context[variable] = overwrite\n+\n+\n def generate_context(context_file='cookiecutter.json', default_context=None,\n                      extra_context=None):\n     \"\"\"\n@@ -85,9 +107,9 @@\n     # Overwrite context variable defaults with the default context from the\n     # user's global config, if available\n     if default_context:\n-        obj.update(default_context)\n+        apply_overwrites_to_context(obj, default_context)\n     if extra_context:\n-        obj.update(extra_context)\n+        apply_overwrites_to_context(obj, extra_context)\n \n     logging.debug('Context generated is {0}'.format(context))\n     return context\n", "issue": "Choice prompts are disabled if there's a ~/.cookiecutterrc\nSeems I don't get the nice prompts from https://github.com/audreyr/cookiecutter/pull/455 if I have a `~/.cookiecutterrc`\n\n", "before_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n\"\"\"\ncookiecutter.generate\n---------------------\n\nFunctions for generating a project from a project template.\n\"\"\"\nfrom __future__ import unicode_literals\nfrom collections import OrderedDict\nimport fnmatch\nimport io\nimport json\nimport logging\nimport os\nimport shutil\n\nfrom jinja2 import FileSystemLoader, Template\nfrom jinja2.environment import Environment\nfrom jinja2.exceptions import TemplateSyntaxError\nfrom binaryornot.check import is_binary\n\nfrom .exceptions import (\n    NonTemplatedInputDirException,\n    ContextDecodingException,\n    OutputDirExistsException\n)\nfrom .find import find_template\nfrom .utils import make_sure_path_exists, work_in\nfrom .hooks import run_hook\n\n\ndef copy_without_render(path, context):\n    \"\"\"\n    Returns True if `path` matches some pattern in the\n    `_copy_without_render` context setting.\n\n    :param path: A file-system path referring to a file or dir that\n        should be rendered or just copied.\n    :param context: cookiecutter context.\n    \"\"\"\n    try:\n        for dont_render in context['cookiecutter']['_copy_without_render']:\n            if fnmatch.fnmatch(path, dont_render):\n                return True\n    except KeyError:\n        return False\n\n    return False\n\n\ndef generate_context(context_file='cookiecutter.json', default_context=None,\n                     extra_context=None):\n    \"\"\"\n    Generates the context for a Cookiecutter project template.\n    Loads the JSON file as a Python object, with key being the JSON filename.\n\n    :param context_file: JSON file containing key/value pairs for populating\n        the cookiecutter's variables.\n    :param default_context: Dictionary containing config to take into account.\n    :param extra_context: Dictionary containing configuration overrides\n    \"\"\"\n\n    context = {}\n\n    file_handle = open(context_file)\n    try:\n        obj = json.load(file_handle, object_pairs_hook=OrderedDict)\n    except ValueError as e:\n        # JSON decoding error.  Let's throw a new exception that is more\n        # friendly for the developer or user.\n        full_fpath = os.path.abspath(context_file)\n        json_exc_message = str(e)\n        our_exc_message = (\n            'JSON decoding error while loading \"{0}\".  Decoding'\n            ' error details: \"{1}\"'.format(full_fpath, json_exc_message))\n        raise ContextDecodingException(our_exc_message)\n\n    # Add the Python object to the context dictionary\n    file_name = os.path.split(context_file)[1]\n    file_stem = file_name.split('.')[0]\n    context[file_stem] = obj\n\n    # Overwrite context variable defaults with the default context from the\n    # user's global config, if available\n    if default_context:\n        obj.update(default_context)\n    if extra_context:\n        obj.update(extra_context)\n\n    logging.debug('Context generated is {0}'.format(context))\n    return context\n\n\ndef generate_file(project_dir, infile, context, env):\n    \"\"\"\n    1. Render the filename of infile as the name of outfile.\n    2. Deal with infile appropriately:\n\n        a. If infile is a binary file, copy it over without rendering.\n        b. If infile is a text file, render its contents and write the\n           rendered infile to outfile.\n\n    Precondition:\n\n        When calling `generate_file()`, the root template dir must be the\n        current working directory. Using `utils.work_in()` is the recommended\n        way to perform this directory change.\n\n    :param project_dir: Absolute path to the resulting generated project.\n    :param infile: Input file to generate the file from. Relative to the root\n        template dir.\n    :param context: Dict for populating the cookiecutter's variables.\n    :param env: Jinja2 template execution environment.\n    \"\"\"\n\n    logging.debug('Generating file {0}'.format(infile))\n\n    # Render the path to the output file (not including the root project dir)\n    outfile_tmpl = Template(infile)\n    outfile = os.path.join(project_dir, outfile_tmpl.render(**context))\n    logging.debug('outfile is {0}'.format(outfile))\n\n    # Just copy over binary files. Don't render.\n    logging.debug(\"Check {0} to see if it's a binary\".format(infile))\n    if is_binary(infile):\n        logging.debug('Copying binary {0} to {1} without rendering'\n                      .format(infile, outfile))\n        shutil.copyfile(infile, outfile)\n    else:\n        # Force fwd slashes on Windows for get_template\n        # This is a by-design Jinja issue\n        infile_fwd_slashes = infile.replace(os.path.sep, '/')\n\n        # Render the file\n        try:\n            tmpl = env.get_template(infile_fwd_slashes)\n        except TemplateSyntaxError as exception:\n            # Disable translated so that printed exception contains verbose\n            # information about syntax error location\n            exception.translated = False\n            raise\n        rendered_file = tmpl.render(**context)\n\n        logging.debug('Writing {0}'.format(outfile))\n\n        with io.open(outfile, 'w', encoding='utf-8') as fh:\n            fh.write(rendered_file)\n\n    # Apply file permissions to output file\n    shutil.copymode(infile, outfile)\n\n\ndef render_and_create_dir(dirname, context, output_dir,\n                          overwrite_if_exists=False):\n    \"\"\"\n    Renders the name of a directory, creates the directory, and\n    returns its path.\n    \"\"\"\n\n    name_tmpl = Template(dirname)\n    rendered_dirname = name_tmpl.render(**context)\n    logging.debug('Rendered dir {0} must exist in output_dir {1}'.format(\n        rendered_dirname,\n        output_dir\n    ))\n    dir_to_create = os.path.normpath(\n        os.path.join(output_dir, rendered_dirname)\n    )\n\n    output_dir_exists = os.path.exists(dir_to_create)\n\n    if overwrite_if_exists:\n        if output_dir_exists:\n            logging.debug('Output directory {} already exists,'\n                          'overwriting it'.format(dir_to_create))\n    else:\n        if output_dir_exists:\n            msg = 'Error: \"{}\" directory already exists'.format(dir_to_create)\n            raise OutputDirExistsException(msg)\n\n    make_sure_path_exists(dir_to_create)\n    return dir_to_create\n\n\ndef ensure_dir_is_templated(dirname):\n    \"\"\"\n    Ensures that dirname is a templated directory name.\n    \"\"\"\n    if '{{' in dirname and '}}' in dirname:\n        return True\n    else:\n        raise NonTemplatedInputDirException\n\n\ndef generate_files(repo_dir, context=None, output_dir='.',\n                   overwrite_if_exists=False):\n    \"\"\"\n    Renders the templates and saves them to files.\n\n    :param repo_dir: Project template input directory.\n    :param context: Dict for populating the template's variables.\n    :param output_dir: Where to output the generated project dir into.\n    :param overwrite_if_exists: Overwrite the contents of the output directory\n        if it exists\n    \"\"\"\n\n    template_dir = find_template(repo_dir)\n    logging.debug('Generating project from {0}...'.format(template_dir))\n    context = context or {}\n\n    unrendered_dir = os.path.split(template_dir)[1]\n    ensure_dir_is_templated(unrendered_dir)\n    project_dir = render_and_create_dir(unrendered_dir,\n                                        context,\n                                        output_dir,\n                                        overwrite_if_exists)\n\n    # We want the Jinja path and the OS paths to match. Consequently, we'll:\n    #   + CD to the template folder\n    #   + Set Jinja's path to '.'\n    #\n    #  In order to build our files to the correct folder(s), we'll use an\n    # absolute path for the target folder (project_dir)\n\n    project_dir = os.path.abspath(project_dir)\n    logging.debug('project_dir is {0}'.format(project_dir))\n\n    # run pre-gen hook from repo_dir\n    with work_in(repo_dir):\n        run_hook('pre_gen_project', project_dir, context)\n\n    with work_in(template_dir):\n        env = Environment(keep_trailing_newline=True)\n        env.loader = FileSystemLoader('.')\n\n        for root, dirs, files in os.walk('.'):\n            # We must separate the two types of dirs into different lists.\n            # The reason is that we don't want ``os.walk`` to go through the\n            # unrendered directories, since they will just be copied.\n            copy_dirs = []\n            render_dirs = []\n\n            for d in dirs:\n                d_ = os.path.normpath(os.path.join(root, d))\n                # We check the full path, because that's how it can be\n                # specified in the ``_copy_without_render`` setting, but\n                # we store just the dir name\n                if copy_without_render(d_, context):\n                    copy_dirs.append(d)\n                else:\n                    render_dirs.append(d)\n\n            for copy_dir in copy_dirs:\n                indir = os.path.normpath(os.path.join(root, copy_dir))\n                outdir = os.path.normpath(os.path.join(project_dir, indir))\n                logging.debug(\n                    'Copying dir {0} to {1} without rendering'\n                    ''.format(indir, outdir)\n                )\n                shutil.copytree(indir, outdir)\n\n            # We mutate ``dirs``, because we only want to go through these dirs\n            # recursively\n            dirs[:] = render_dirs\n            for d in dirs:\n                unrendered_dir = os.path.join(project_dir, root, d)\n                render_and_create_dir(unrendered_dir, context, output_dir,\n                                      overwrite_if_exists)\n\n            for f in files:\n                infile = os.path.normpath(os.path.join(root, f))\n                if copy_without_render(infile, context):\n                    outfile_tmpl = Template(infile)\n                    outfile_rendered = outfile_tmpl.render(**context)\n                    outfile = os.path.join(project_dir, outfile_rendered)\n                    logging.debug(\n                        'Copying file {0} to {1} without rendering'\n                        ''.format(infile, outfile)\n                    )\n                    shutil.copyfile(infile, outfile)\n                    shutil.copymode(infile, outfile)\n                    continue\n                logging.debug('f is {0}'.format(f))\n                generate_file(project_dir, infile, context, env)\n\n    # run post-gen hook from repo_dir\n    with work_in(repo_dir):\n        run_hook('post_gen_project', project_dir, context)\n", "path": "cookiecutter/generate.py"}], "after_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n\"\"\"\ncookiecutter.generate\n---------------------\n\nFunctions for generating a project from a project template.\n\"\"\"\nfrom __future__ import unicode_literals\nfrom collections import OrderedDict\nimport fnmatch\nimport io\nimport json\nimport logging\nimport os\nimport shutil\n\nfrom jinja2 import FileSystemLoader, Template\nfrom jinja2.environment import Environment\nfrom jinja2.exceptions import TemplateSyntaxError\nfrom binaryornot.check import is_binary\n\nfrom .exceptions import (\n    NonTemplatedInputDirException,\n    ContextDecodingException,\n    OutputDirExistsException\n)\nfrom .find import find_template\nfrom .utils import make_sure_path_exists, work_in\nfrom .hooks import run_hook\n\n\ndef copy_without_render(path, context):\n    \"\"\"\n    Returns True if `path` matches some pattern in the\n    `_copy_without_render` context setting.\n\n    :param path: A file-system path referring to a file or dir that\n        should be rendered or just copied.\n    :param context: cookiecutter context.\n    \"\"\"\n    try:\n        for dont_render in context['cookiecutter']['_copy_without_render']:\n            if fnmatch.fnmatch(path, dont_render):\n                return True\n    except KeyError:\n        return False\n\n    return False\n\n\ndef apply_overwrites_to_context(context, overwrite_context):\n    \"\"\"Modify the given context in place based on the overwrite_context.\"\"\"\n    for variable, overwrite in overwrite_context.items():\n        if variable not in context:\n            # Do not include variables which are not used in the template\n            continue\n\n        context_value = context[variable]\n\n        if isinstance(context_value, list):\n            # We are dealing with a choice variable\n            if overwrite in context_value:\n                # This overwrite is actually valid for the given context\n                # Let's set it as default (by definition first item in list)\n                # see ``cookiecutter.prompt.prompt_choice_for_config``\n                context_value.remove(overwrite)\n                context_value.insert(0, overwrite)\n        else:\n            # Simply overwrite the value for this variable\n            context[variable] = overwrite\n\n\ndef generate_context(context_file='cookiecutter.json', default_context=None,\n                     extra_context=None):\n    \"\"\"\n    Generates the context for a Cookiecutter project template.\n    Loads the JSON file as a Python object, with key being the JSON filename.\n\n    :param context_file: JSON file containing key/value pairs for populating\n        the cookiecutter's variables.\n    :param default_context: Dictionary containing config to take into account.\n    :param extra_context: Dictionary containing configuration overrides\n    \"\"\"\n\n    context = {}\n\n    file_handle = open(context_file)\n    try:\n        obj = json.load(file_handle, object_pairs_hook=OrderedDict)\n    except ValueError as e:\n        # JSON decoding error.  Let's throw a new exception that is more\n        # friendly for the developer or user.\n        full_fpath = os.path.abspath(context_file)\n        json_exc_message = str(e)\n        our_exc_message = (\n            'JSON decoding error while loading \"{0}\".  Decoding'\n            ' error details: \"{1}\"'.format(full_fpath, json_exc_message))\n        raise ContextDecodingException(our_exc_message)\n\n    # Add the Python object to the context dictionary\n    file_name = os.path.split(context_file)[1]\n    file_stem = file_name.split('.')[0]\n    context[file_stem] = obj\n\n    # Overwrite context variable defaults with the default context from the\n    # user's global config, if available\n    if default_context:\n        apply_overwrites_to_context(obj, default_context)\n    if extra_context:\n        apply_overwrites_to_context(obj, extra_context)\n\n    logging.debug('Context generated is {0}'.format(context))\n    return context\n\n\ndef generate_file(project_dir, infile, context, env):\n    \"\"\"\n    1. Render the filename of infile as the name of outfile.\n    2. Deal with infile appropriately:\n\n        a. If infile is a binary file, copy it over without rendering.\n        b. If infile is a text file, render its contents and write the\n           rendered infile to outfile.\n\n    Precondition:\n\n        When calling `generate_file()`, the root template dir must be the\n        current working directory. Using `utils.work_in()` is the recommended\n        way to perform this directory change.\n\n    :param project_dir: Absolute path to the resulting generated project.\n    :param infile: Input file to generate the file from. Relative to the root\n        template dir.\n    :param context: Dict for populating the cookiecutter's variables.\n    :param env: Jinja2 template execution environment.\n    \"\"\"\n\n    logging.debug('Generating file {0}'.format(infile))\n\n    # Render the path to the output file (not including the root project dir)\n    outfile_tmpl = Template(infile)\n    outfile = os.path.join(project_dir, outfile_tmpl.render(**context))\n    logging.debug('outfile is {0}'.format(outfile))\n\n    # Just copy over binary files. Don't render.\n    logging.debug(\"Check {0} to see if it's a binary\".format(infile))\n    if is_binary(infile):\n        logging.debug('Copying binary {0} to {1} without rendering'\n                      .format(infile, outfile))\n        shutil.copyfile(infile, outfile)\n    else:\n        # Force fwd slashes on Windows for get_template\n        # This is a by-design Jinja issue\n        infile_fwd_slashes = infile.replace(os.path.sep, '/')\n\n        # Render the file\n        try:\n            tmpl = env.get_template(infile_fwd_slashes)\n        except TemplateSyntaxError as exception:\n            # Disable translated so that printed exception contains verbose\n            # information about syntax error location\n            exception.translated = False\n            raise\n        rendered_file = tmpl.render(**context)\n\n        logging.debug('Writing {0}'.format(outfile))\n\n        with io.open(outfile, 'w', encoding='utf-8') as fh:\n            fh.write(rendered_file)\n\n    # Apply file permissions to output file\n    shutil.copymode(infile, outfile)\n\n\ndef render_and_create_dir(dirname, context, output_dir,\n                          overwrite_if_exists=False):\n    \"\"\"\n    Renders the name of a directory, creates the directory, and\n    returns its path.\n    \"\"\"\n\n    name_tmpl = Template(dirname)\n    rendered_dirname = name_tmpl.render(**context)\n    logging.debug('Rendered dir {0} must exist in output_dir {1}'.format(\n        rendered_dirname,\n        output_dir\n    ))\n    dir_to_create = os.path.normpath(\n        os.path.join(output_dir, rendered_dirname)\n    )\n\n    output_dir_exists = os.path.exists(dir_to_create)\n\n    if overwrite_if_exists:\n        if output_dir_exists:\n            logging.debug('Output directory {} already exists,'\n                          'overwriting it'.format(dir_to_create))\n    else:\n        if output_dir_exists:\n            msg = 'Error: \"{}\" directory already exists'.format(dir_to_create)\n            raise OutputDirExistsException(msg)\n\n    make_sure_path_exists(dir_to_create)\n    return dir_to_create\n\n\ndef ensure_dir_is_templated(dirname):\n    \"\"\"\n    Ensures that dirname is a templated directory name.\n    \"\"\"\n    if '{{' in dirname and '}}' in dirname:\n        return True\n    else:\n        raise NonTemplatedInputDirException\n\n\ndef generate_files(repo_dir, context=None, output_dir='.',\n                   overwrite_if_exists=False):\n    \"\"\"\n    Renders the templates and saves them to files.\n\n    :param repo_dir: Project template input directory.\n    :param context: Dict for populating the template's variables.\n    :param output_dir: Where to output the generated project dir into.\n    :param overwrite_if_exists: Overwrite the contents of the output directory\n        if it exists\n    \"\"\"\n\n    template_dir = find_template(repo_dir)\n    logging.debug('Generating project from {0}...'.format(template_dir))\n    context = context or {}\n\n    unrendered_dir = os.path.split(template_dir)[1]\n    ensure_dir_is_templated(unrendered_dir)\n    project_dir = render_and_create_dir(unrendered_dir,\n                                        context,\n                                        output_dir,\n                                        overwrite_if_exists)\n\n    # We want the Jinja path and the OS paths to match. Consequently, we'll:\n    #   + CD to the template folder\n    #   + Set Jinja's path to '.'\n    #\n    #  In order to build our files to the correct folder(s), we'll use an\n    # absolute path for the target folder (project_dir)\n\n    project_dir = os.path.abspath(project_dir)\n    logging.debug('project_dir is {0}'.format(project_dir))\n\n    # run pre-gen hook from repo_dir\n    with work_in(repo_dir):\n        run_hook('pre_gen_project', project_dir, context)\n\n    with work_in(template_dir):\n        env = Environment(keep_trailing_newline=True)\n        env.loader = FileSystemLoader('.')\n\n        for root, dirs, files in os.walk('.'):\n            # We must separate the two types of dirs into different lists.\n            # The reason is that we don't want ``os.walk`` to go through the\n            # unrendered directories, since they will just be copied.\n            copy_dirs = []\n            render_dirs = []\n\n            for d in dirs:\n                d_ = os.path.normpath(os.path.join(root, d))\n                # We check the full path, because that's how it can be\n                # specified in the ``_copy_without_render`` setting, but\n                # we store just the dir name\n                if copy_without_render(d_, context):\n                    copy_dirs.append(d)\n                else:\n                    render_dirs.append(d)\n\n            for copy_dir in copy_dirs:\n                indir = os.path.normpath(os.path.join(root, copy_dir))\n                outdir = os.path.normpath(os.path.join(project_dir, indir))\n                logging.debug(\n                    'Copying dir {0} to {1} without rendering'\n                    ''.format(indir, outdir)\n                )\n                shutil.copytree(indir, outdir)\n\n            # We mutate ``dirs``, because we only want to go through these dirs\n            # recursively\n            dirs[:] = render_dirs\n            for d in dirs:\n                unrendered_dir = os.path.join(project_dir, root, d)\n                render_and_create_dir(unrendered_dir, context, output_dir,\n                                      overwrite_if_exists)\n\n            for f in files:\n                infile = os.path.normpath(os.path.join(root, f))\n                if copy_without_render(infile, context):\n                    outfile_tmpl = Template(infile)\n                    outfile_rendered = outfile_tmpl.render(**context)\n                    outfile = os.path.join(project_dir, outfile_rendered)\n                    logging.debug(\n                        'Copying file {0} to {1} without rendering'\n                        ''.format(infile, outfile)\n                    )\n                    shutil.copyfile(infile, outfile)\n                    shutil.copymode(infile, outfile)\n                    continue\n                logging.debug('f is {0}'.format(f))\n                generate_file(project_dir, infile, context, env)\n\n    # run post-gen hook from repo_dir\n    with work_in(repo_dir):\n        run_hook('post_gen_project', project_dir, context)\n", "path": "cookiecutter/generate.py"}]}