cookiecutter icon indicating copy to clipboard operation
cookiecutter copied to clipboard

Alter context before creating project

Open italomaia opened this issue 10 years ago • 11 comments

It would be nice if cookiecutter could run a function into it's context before creating the project. Example:

project
-- {{ cookiecutter.repo_name }}/ ...
-- context.py

context.py

def update_context(context):
    # do stuff to context

italomaia avatar Jan 11 '15 10:01 italomaia

It could also, instead, allow cookiecutter to be initialized from a custom script. That could allow for a lot of flexibility.

italomaia avatar Jan 11 '15 14:01 italomaia

+1 on this.

Is not obvious how to inject dynamic context, ej. use the documentation snippet on the pre_gen_project hook may cause an 'infinite' prompt for values loop.

slothyrulez avatar Apr 11 '15 10:04 slothyrulez

I am also interested in that.

I couldn't find a way to dynamically add a context variable. So that I can add a secret_key context variable like mentioned in https://github.com/pydanny/cookiecutter-django/issues/3.

DanEEStar avatar Apr 21 '15 12:04 DanEEStar

+1 on this that will allow us to ask for additional questions, like is use_pusher="Y" then ask addition api keys to be generated inside config file.

dmitry-saritasa avatar Dec 23 '15 01:12 dmitry-saritasa

I'd also like to have this functionality. I'd like to be able to edit/add to the template context either as it's being processed (like how template variables are accessible within the cookiecutter.json file itself right after the user is prompted), or perhaps a hook before the project is generated.

For instance, the current problem (and have other similar problems) I'd like to solve is to dynamically create the version number depending on what the user inputs. An example json file:

{
    "dev_status": ["planning", "pre-alpha", "alpha", "beta", "stable", "mature", "inactive"]
    // then interpolate the project version based on the selection from above
    // currently I can do this:
    "version": "{% if cookiecutter.dev_status == 'alpha' -%}0.0.1a1{% else -%}0.0.1{% endif -%}",
}

If I were to do the full if/then for the version, it'd get quite long and unreadable. I'd prefer to do this a bit easier and outside of the JSON file, maybe like a jinja macro or something.

(/me waves hello to @audreyr and @pydanny )

econchick avatar Apr 14 '16 19:04 econchick

Yes, something like this would be very useful. Is there any other way to define global context variables?

goanpeca avatar Jan 17 '17 02:01 goanpeca

Hi guys,

Another way to alter context would be from pre hook script. The pre_gen_project could write a JSON object on stdout. Then Cookiecutter could read this object and (deep) merge it to input context.

Btw passing through stdin/stdout could be also an improvement in post_gen_project (instead of templating using Jinja).

This mechanism is used by softwares like Ansible to execute modules, hooks, plugins...

In this case, the context should be:

context = deep_merge(deep_merge(extra_context, user_input_context), pre_gen_project_context)

rmedaer avatar Mar 16 '17 12:03 rmedaer

I have been able to do this via some Jinja hackery and this helps a lot. See https://github.com/samj1912/cookiecutter-advanced-demo for a demo cookiecutter that can do this. I demo the following -

Advanced context modification for cookiecutter.

The above repo is an advanced example of a cookiecutter that can modify cookiecutter's context values from hooks. Read the pre_gen_project.py for examples and a demo on how to modify context.

To run this demo cookiecutter do -

cookiecutter https://github.com/samj1912/cookiecutter-advanced-demo

This demo shows how to do the following -

  1. Add values to the cookiecutter context.

The above is useful for a bunch of cases -

  • Being able to add values to the context independent of the user input - for eg. creating a valid project slug from a project name by escaping the values.
  • When you are sharing files between different cookiecutter directories and you want to define defaults in order to avoid Jinja from complaining the certain values are not defined.
  1. Modify existing values cookiecutter context values even after user input-

This is useful when you want to handle bad user input and instead of raising an error, set the cookiecutter context values correct. For eg modifying the project_slug from the user to be valid.

  1. Conditionally modify the above based on user input.

Note - You can also do this to change the name of the variable that is used to define the generated project directory. This is useful when handling inputs from the user that you want to escape.

sambhav avatar Aug 22 '20 19:08 sambhav

I wish this was in the tutorials at the readthedocs.

h-mayorquin avatar May 17 '22 17:05 h-mayorquin

If you are already writing a python function, you could call cookiecutter from python instead. https://cookiecutter.readthedocs.io/en/1.7.2/advanced/injecting_context.html

att14 avatar May 17 '22 17:05 att14

Does anyone know if this has been resolved? From what I can tell it would be relatively easy to implement and I would be happy to do it.

As @att14 stated we can just inject context and re-call cookiecutter. While it is possible to do this seperately within the hook, I see benefit to adding this functionality to the module. Forgive me if I am mistaken and this issue has already been resolved.

connewm avatar Jul 26 '23 03:07 connewm