Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass the Jinja env to allow changing the variable_*_string values #1666

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions cookiecutter/find.py
Expand Up @@ -7,7 +7,7 @@
logger = logging.getLogger(__name__)


def find_template(repo_dir):
def find_template(repo_dir, env):
"""Determine which child directory of `repo_dir` is the project template.

:param repo_dir: Local directory of newly cloned repo.
Expand All @@ -19,7 +19,8 @@ def find_template(repo_dir):

project_template = None
for item in repo_dir_contents:
if 'cookiecutter' in item and '{{' in item and '}}' in item:
if 'cookiecutter' in item and env.variable_start_string in item \
and env.variable_end_string in item:
project_template = item
break

Expand Down
14 changes: 7 additions & 7 deletions cookiecutter/generate.py
Expand Up @@ -227,9 +227,9 @@ def render_and_create_dir(
return dir_to_create, not output_dir_exists


def ensure_dir_is_templated(dirname):
def ensure_dir_is_templated(dirname, env):
"""Ensure that dirname is a templated directory name."""
if '{{' in dirname and '}}' in dirname:
if env.variable_start_string in dirname and env.variable_end_string in dirname:
return True
else:
raise NonTemplatedInputDirException
Expand Down Expand Up @@ -278,15 +278,15 @@ def generate_files(
if it exists.
:param accept_hooks: Accept pre and post hooks if set to `True`.
"""
template_dir = find_template(repo_dir)
logger.debug('Generating project from %s...', template_dir)
context = context or OrderedDict([])

envvars = context.get('cookiecutter', {}).get('_jinja2_env_vars', {})
env = StrictEnvironment(context=context, keep_trailing_newline=True, **envvars)

template_dir = find_template(repo_dir, env)
logger.debug('Generating project from %s...', template_dir)

unrendered_dir = os.path.split(template_dir)[1]
ensure_dir_is_templated(unrendered_dir)
env = StrictEnvironment(context=context, keep_trailing_newline=True, **envvars)
ensure_dir_is_templated(unrendered_dir, env)
try:
project_dir, output_directory_created = render_and_create_dir(
unrendered_dir, context, output_dir, env, overwrite_if_exists
Expand Down
7 changes: 7 additions & 0 deletions tests/fake-repo-pre3/[[cookiecutter.repo_name]]/README.rst
@@ -0,0 +1,7 @@
============
Fake Project
============

Project name: **[[ cookiecutter.project_name ]]**

Blah!!!!
11 changes: 11 additions & 0 deletions tests/fake-repo-pre3/cookiecutter.json
@@ -0,0 +1,11 @@
{
"full_name": "Audrey Roy",
"email": "audreyr@gmail.com",
"github_username": "audreyr",
"project_name": "Fake Project",
"repo_name": "fake-project",
"project_short_description": "This is a fake project.",
"release_date": "2013-07-28",
"year": "2013",
"version": "0.1"
}
5 changes: 5 additions & 0 deletions tests/fake-repo-pre4/[[cookiecutter.repo_name]]/README.rst
@@ -0,0 +1,5 @@
============
Fake Project
============

Blah!!!!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this fake repo needed, it seems nearly identical to the first. What case is it covering that pre3 does not?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the pre-existing test used 2 fake repos so I just replicated the same thing to show it works the same, I can remove one of them if it was unnecessary

11 changes: 11 additions & 0 deletions tests/fake-repo-pre4/cookiecutter.json
@@ -0,0 +1,11 @@
{
"full_name": "Audrey Roy",
"email": "audreyr@gmail.com",
"github_username": "audreyr",
"project_name": "Fake Project",
"repo_name": "fake-project",
"project_short_description": "This is a fake project.",
"release_date": "2013-07-28",
"year": "2013",
"version": "0.1"
}
Empty file.
20 changes: 19 additions & 1 deletion tests/test_find.py
Expand Up @@ -4,6 +4,7 @@
import pytest

from cookiecutter import find
from cookiecutter.environment import StrictEnvironment


@pytest.fixture(params=['fake-repo-pre', 'fake-repo-pre2'])
Expand All @@ -12,9 +13,26 @@ def repo_dir(request):
return os.path.join('tests', request.param)


@pytest.fixture(params=['fake-repo-pre3', 'fake-repo-pre4'])
def repo_dir_variable_string(request):
"""Fixture returning path for `test_find_template` test."""
return os.path.join('tests', request.param)


def test_find_template(repo_dir):
"""Verify correctness of `find.find_template` path detection."""
template = find.find_template(repo_dir=repo_dir)
env = StrictEnvironment(context={}, keep_trailing_newline=True, **{})
template = find.find_template(repo_dir=repo_dir, env=env)

test_dir = os.path.join(repo_dir, '{{cookiecutter.repo_name}}')
assert template == test_dir


def test_find_template_variable_string(repo_dir_variable_string):
"""Verify correctness of `find.find_template` path detection."""
env_vars = {"variable_start_string": "[[", "variable_end_string": "]]"}
env = StrictEnvironment(context={}, keep_trailing_newline=True, **env_vars)
template = find.find_template(repo_dir=repo_dir_variable_string, env=env)

test_dir = os.path.join(repo_dir_variable_string, '[[cookiecutter.repo_name]]')
assert template == test_dir
2 changes: 1 addition & 1 deletion tests/test_generate_file.py
Expand Up @@ -118,7 +118,7 @@ def expected_msg():
"""Fixture. Used to ensure that exception generated text contain full data."""
msg = (
'Missing end of comment tag\n'
' File "./tests/files/syntax_error.txt", line 1\n'
' File "tests/files/syntax_error.txt", line 1\n'
' I eat {{ syntax_error }} {# this comment is not closed}'
)
return msg.replace("/", os.sep)
Expand Down
4 changes: 3 additions & 1 deletion tests/test_generate_files.py
Expand Up @@ -9,13 +9,15 @@
from binaryornot.check import is_binary

from cookiecutter import exceptions, generate
from cookiecutter.environment import StrictEnvironment


@pytest.mark.parametrize('invalid_dirname', ['', '{foo}', '{{foo', 'bar}}'])
def test_ensure_dir_is_templated_raises(invalid_dirname):
"""Verify `ensure_dir_is_templated` raises on wrong directories names input."""
env = StrictEnvironment(context={}, keep_trailing_newline=True)
with pytest.raises(exceptions.NonTemplatedInputDirException):
generate.ensure_dir_is_templated(invalid_dirname)
generate.ensure_dir_is_templated(invalid_dirname, env)


def test_generate_files_nontemplated_exception(tmp_path):
Expand Down