in Programming, Python, Technology, Tools

CookieCutter Contexts

CookieCutter Contexts

cookiecutter is an awesome command line utility created by Audrey Greenfeld, that is used to create projects from templates, especially useful if you create multiple projects with essentially the same boilerplate.

It is easy to take one of the many available templates that already exist, fork it, modify it to suit your specific needs and get reproducible, fast spin up of new projects.

Having only been using cookiecutter for a short time I was working with a new template I had created, and as I tested it with dummy projects, and tweaked it I was getting very fed up with continually entering the input context each time.

I brought out my Google-fu and was led to this question on Stack Overflow which had a similar problem to me, and was asking whether there existed a command flag that could be used to insert default context in the template at creation time, as in cookiecutter --no-input --context my-context.json <cookiecutter-template>.

Evaluation

Now – this initially makes sense to me as I sit there with my development hat on. A simple flag to add in some default context would do exactly what I need, but a cursory examination of the documentation indeed concludes that this is not part of the exposed user interface.

However after a deep dive into the documentations Advanced Usage section to find a solution that worked for me, and after some time and distance for reflection I can see the reasoning behind not exposing this kind of functionality.

For starters, it adds extra complexity to the command line tool, admittedly not much, but it is another option to consider when learning the tool. Also this use case tends to be I imagine fairly rare (The standard user grabs a template to spin up a project quickly, and projects then last some time: days, weeks, months etc, not multiple times in an hour. Those that do have this use case though are more likely to be able to easily implement the workaround being either developing a template themselves or automating a large number of project creations.

Multiple Solutions

There are two aspects to wanting reusable contexts, and cookiecutter has two methods implemented to handle these aspects. The first is standard/personal context values that are tied to the person creating the project, the user.

The other is reusing project context, or perhaps automatically generating context based on circumstances.

Standard/Personal Context Values

In the case where you have standard, usually personal context values you wish to use over multiple projects there is the option of adding a user specific configuration.

You can specify some default context settings into a .cookiecutterrc file in your home directory. (Current documentation can be found here). This is most aptly used for things such as email address, full name, GitHub account name etc. which are fairly static. You can also place these defaults in another file and use a command line flag or environment variable to direct cookiecutter to use that instead.

The format of the configuration file is YAML and an example structure would be as follows:

default_context:
    full_name: "Gavin Cooper"
    email: "xxxxxx@xxxxx.com"
    github_username: "gjcooper"

One caveat of this approach is that it replaces default values, without the --no-input option to the tool you still have to enter through each value to accept the default. The examples and documentation all make it clear it is really just for user specific contexts. I would also assume that this relies on fields such as name, email etc. being given standard names across most cookiecutter packages.

Project Specific Context Values

This solution is for when you have a project management software or some other script where you want to generate project specific values (ie app_name) into the cookiecutter JSON format and then automatically generate your project directory structure without user input.

There is no method to add extra context via the command line, but this functionality is exposed in the underlying python code. To access it we therefore need to write a small and simple python script. The documentation for the tool shows a useful method of adding a timestamp to the project instantiation, with some small edits and a simple JSON file we can use to the launch repeated project creations with no user input.

An basic example of this in action would be:

from cookiecutter.main import cookiecutter
import json

with open('<my context file>') as jfile:
	mycontext = json.load(jfile)

cookiecutter('<local or remote cookiecutter template file>',
	 extra_context=mycontext,
	 no_input=True)

This is a solution that I can verify has worked for me.

Leave a Reply