A command-line utility that creates projects from project templates, e.g. creating a Python package project from a Python package project template.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Context generation, file rendering, and template discovery functionality that powers cookiecutter's core template processing capabilities. This module handles the transformation of template directories into fully-rendered project structures.
Generate template context from cookiecutter.json files and user input.
def generate_context(context_file='cookiecutter.json', default_context=None, extra_context=None):
"""
Generate context for template processing.
Parameters:
- context_file: str - Path to cookiecutter.json file
- default_context: dict, optional - Default context values
- extra_context: dict, optional - Additional context to override defaults
Returns:
dict - Generated context dictionary with 'cookiecutter' key containing template variables
"""
def apply_overwrites_to_context(context, overwrite_context, *, in_dictionary_variable=False):
"""
Modify context with overrides.
Parameters:
- context: dict - Original context dictionary
- overwrite_context: dict - Values to override in context
- in_dictionary_variable: bool - Whether we're inside a dictionary variable
Returns:
dict - Modified context with overrides applied
"""Core template rendering and file creation functionality.
def generate_files(
repo_dir,
context=None,
output_dir='.',
overwrite_if_exists=False,
skip_if_file_exists=False,
accept_hooks=True,
keep_project_on_failure=False
):
"""
Main function to render templates and save to files.
Parameters:
- repo_dir: str - Path to repository directory containing template
- context: dict, optional - Template context dictionary
- output_dir: str - Directory to output generated project
- overwrite_if_exists: bool - Overwrite existing output directory
- skip_if_file_exists: bool - Skip files that already exist
- accept_hooks: bool - Execute pre/post generation hooks
- keep_project_on_failure: bool - Keep project directory on failure
Returns:
str - Path to generated project directory
"""
def generate_file(project_dir, infile, context, env, skip_if_file_exists=False):
"""
Render and generate individual files.
Parameters:
- project_dir: str - Path to project directory
- infile: str - Input template file path
- context: dict - Template context
- env: Environment - Jinja2 environment for rendering
- skip_if_file_exists: bool - Skip if output file already exists
"""
def render_and_create_dir(dirname, context, output_dir, environment, overwrite_if_exists=False):
"""
Render directory name and create it.
Parameters:
- dirname: str - Template directory name to render
- context: dict - Template context
- output_dir: str - Output directory path
- environment: Environment - Jinja2 environment
- overwrite_if_exists: bool - Overwrite if directory exists
Returns:
str - Path to created directory
"""Locate and validate cookiecutter templates.
def find_template(repo_dir, env):
"""
Determine which directory is the project template.
Parameters:
- repo_dir: str - Repository directory to search
- env: Environment - Jinja2 environment for template validation
Returns:
str - Path to template directory
"""Control which files are copied vs rendered as templates.
def is_copy_only_path(path, context):
"""
Check if path should only be copied, not rendered.
Parameters:
- path: str - File or directory path to check
- context: dict - Template context containing copy settings
Returns:
bool - True if path should be copied without rendering
"""Cookiecutter templates follow a specific directory structure:
template-directory/
├── cookiecutter.json # Template configuration
├── hooks/ # Pre/post generation scripts (optional)
│ ├── pre_gen_project.py
│ └── post_gen_project.py
└── {{cookiecutter.project_name}}/ # Template directory
├── {{cookiecutter.module_name}}/
│ ├── __init__.py
│ └── {{cookiecutter.module_name}}.py
├── tests/
├── setup.py
└── README.mdfrom cookiecutter.generate import generate_context
# Generate context from cookiecutter.json
context = generate_context('path/to/cookiecutter.json')
# Context with defaults
default_ctx = {'author': 'Default Author', 'version': '1.0.0'}
context = generate_context(
'path/to/cookiecutter.json',
default_context=default_ctx
)
# Context with extra overrides
extra_ctx = {'project_name': 'my-awesome-project'}
context = generate_context(
'path/to/cookiecutter.json',
extra_context=extra_ctx
)from cookiecutter.generate import generate_files, find_template
from cookiecutter.environment import StrictEnvironment
# Find template directory
env = StrictEnvironment()
template_dir = find_template('./my-template-repo', env)
# Generate files from template
context = {
'cookiecutter': {
'project_name': 'my-project',
'author': 'Jane Developer',
'version': '1.0.0'
}
}
result_path = generate_files(
repo_dir=template_dir,
context=context,
output_dir='./output',
overwrite_if_exists=True
)from cookiecutter.generate import generate_files
import os
# Generate with custom settings
context = generate_context('./template/cookiecutter.json')
# Add runtime context
context['cookiecutter'].update({
'timestamp': '2024-01-01',
'user_home': os.path.expanduser('~')
})
# Generate with hooks disabled
result_path = generate_files(
repo_dir='./template',
context=context,
output_dir='./projects',
accept_hooks=False,
skip_if_file_exists=True
)
print(f"Project generated at: {result_path}")from cookiecutter.generate import generate_context, is_copy_only_path
# Set up context with copy-only patterns
context = generate_context('./template/cookiecutter.json')
# Check if specific files should be copied without rendering
binary_file = 'assets/logo.png'
config_file = 'config/app.json'
if is_copy_only_path(binary_file, context):
print(f"{binary_file} will be copied without rendering")
if is_copy_only_path(config_file, context):
print(f"{config_file} will be copied without rendering")from cookiecutter.generate import apply_overwrites_to_context, generate_context
# Generate base context
base_context = generate_context('./template/cookiecutter.json')
# Apply runtime overrides
overrides = {
'project_name': 'runtime-project',
'features': {
'database': True,
'authentication': True
}
}
final_context = apply_overwrites_to_context(
base_context,
overrides
)
# Context now includes runtime overrides
print(final_context['cookiecutter']['project_name']) # 'runtime-project'from cookiecutter.generate import generate_files, find_template
from cookiecutter.exceptions import (
UnknownTemplateDirException,
MissingProjectDir,
UndefinedVariableInTemplate
)
try:
# Find and validate template
template_dir = find_template('./template-repo', env)
# Generate files
result = generate_files(
repo_dir=template_dir,
context=context,
output_dir='./output'
)
except UnknownTemplateDirException:
print("Could not determine template directory")
except MissingProjectDir:
print("Generated project directory is missing")
except UndefinedVariableInTemplate as e:
print(f"Template uses undefined variable: {e}")Install with Tessl CLI
npx tessl i tessl/pypi-cookiecutter