You can have Python or Shell scripts that run before and/or after your project is generated.
Put them in hooks/ like this:
cookiecutter-something/
├── {{cookiecutter.repo_name}}/
├── hooks
│ ├── pre_gen_project.py
│ └── post_gen_project.py
└── cookiecutter.json
Shell scripts work similarly:
cookiecutter-something/
├── {{cookiecutter.repo_name}}/
├── hooks
│ ├── pre_gen_project.sh
│ └── post_gen_project.sh
└── cookiecutter.json
It shouldn’t be too hard to extend Cookiecutter to work with other types of scripts too. Pull requests are welcome.
For portability, you should use Python scripts (with extension .py) for your hooks, as these can be run on any platform. However, if you intend for your template to only be run on a single platform, a shell script (or .bat file on Windows) can be a quicker alternative.
If you use Cookiecutter a lot, you’ll find it useful to have a .cookiecutterrc file in your home directory like this:
default_context:
full_name: "Audrey Roy"
email: "audreyr@gmail.com"
github_username: "audreyr"
cookiecutters_dir: "/home/audreyr/my-custom-cookiecutters-dir/"
abbreviations:
pp: https://github.com/audreyr/cookiecutter-pypackage.git
gh: https://github.com/{0}.git
bb: https://bitbucket.org/{0}
Possible settings are:
You can use Cookiecutter from Python:
from cookiecutter.main import cookiecutter
# Create project from the cookiecutter-pypackage/ template
cookiecutter('cookiecutter-pypackage/')
# Create project from the cookiecutter-pypackage.git repo template
cookiecutter('https://github.com/audreyr/cookiecutter-pypackage.git')
This is useful if, for example, you’re writing a web framework and need to provide developers with a tool similar to django-admin.py startproject or npm init.
You can specify an extra_context dictionary that will override values from cookiecutter.json or .cookiecutterrc:
cookiecutter('cookiecutter-pypackage/',
extra_context={'project_name': 'TheGreatest'})
This is a sample Python script that dynamically injects a timestamp value as a project is generated:
from cookiecutter.main import cookiecutter
from datetime import datetime
cookiecutter(
'cookiecutter-django',
extra_context={'timestamp': datetime.utcnow().isoformat()}
)
How this works:
To suppress the prompts asking for input, use no_input.
TODO: document no_input:
TODO: document where context values come from in this example (cookiecutter.json and .cookiecutterrc)
If you combine an extra_context dict with the no_input argument, you can programmatically create the project with a set list of context parameters and without any command line prompts:
cookiecutter('cookiecutter-pypackage/',
no_input=True,
extra_context={'project_name': 'TheGreatest'})
See the API Reference for more details.
The values (but not the keys!) of cookiecutter.json are also Jinja2 templates. Values from user prompts are added to the context immediately, such that one context value can be derived from previous values. This approach can potentially save your user a lot of keystrokes by providing more sensible defaults.
Python packages show some patterns for their naming conventions:
Here is a cookiecuttter.json with templated values for this pattern:
{
"project_name": "My New Project",
"repo_name": "{{ cookiecutter.project_name|lower|replace(' ', '-') }}",
"pkg_name": "{{ cookiecutter.repo_name|replace('-', '') }}"
}
If the user takes the defaults, or uses no_input, the templated values will be:
Or, if the user gives Yet Another New Project, the values will be: