I'm trying to prompt the user for his desired Python Version and then extract the major and minor version to be used in my cookiecutter template
My cookiecutter.json looks sth like this:
{
"repo_name": "template",
"description": "This is Luminovo's template repository.",
"author_name": "Your Name",
"author_email": "[email protected]",
"python_version": ["3.7.0", "3.6.6", "3.5.6"],
"_major_python_version": "{{ cookiecutter.python_version[0] }}",
"_minor_python_version": "{{ cookiecutter.python_version[2] }}"
}
unfortunately the {{ cookiecutter.python_version[0] }} part does not work (when running cookiecutter and using {{ cookiecutter._major_python_version }} it gets replaced with "{{ cookiecutter.python_version[0] }}" - not with "3")
it does work when not using an underscore in cookiecutter.json, but then it prompts the user for the major_python_version (and uses "3") as the default.
sorry if this is a very basic question, but i could not find anything about this in the documentation ^^
_ seems to be intended for things internal to cookie cutter rather than hidden things, subsequently {{}} expansion is not performed on _ variables, you can see this here:
https://github.com/audreyr/cookiecutter/blob/master/cookiecutter/prompt.py#L203
Then how can we prevent prompting the user on transformations we do like project_slug below?
{
"project_name": "my-project",
"git_project_name": "{{cookiecutter.project_name}}",
"owner_name": "owner",
"email": "[email protected]",
"project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}"
}
Afaik CookieCutter has no support for internal unprompted things. For the project I'm working on we've dealt with this by handling prompting ourselves and then running CookieCutter in no input mode. We can do this because we are invoking CookieCutter from within our own CLI. Incidentally that CLI is implemented with "click" which provides quite nice helpers for prompting.
It would really simplify things if we can have this behavior out of the box
You can do this in a slightly different way via Jinja + pre gen hooks. See my reply at - https://github.com/cookiecutter/cookiecutter/issues/364#issuecomment-678683237 and the demo repo https://github.com/samj1912/cookiecutter-advanced-demo
That allows you to modify the cookiecutter context from pre gen hooks on cookiecutter v0.7+ with some advanced jinja hackery.
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-demoThis demo shows how to do the following -
- 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.
- 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.
- 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.
{
"repo_name": "template",
"description": "This is Luminovo's template repository.",
"author_name": "Your Name",
"author_email": "[email protected]",
"python_version": ["3.7.0", "3.6.6", "3.5.6"],
"major_python_version": ["{{ cookiecutter.python_version[0] }}"],
"minor_python_version": ["{{ cookiecutter.python_version[2] }}"]
}
not a great solution - but the quickest I've found without having to do some Jinja wizardry if you don't want anyone modifying those last two lines...
Basically a list with only one option...
but also only using this in rough prototyping, not as an end solution
In the cookiecutter private variables documentation they note that you can use a double underscore to have the variable rendered.
I think what you want to do is as simple as renaming _minor_python_version to __minor_python_version
The docs are for an unreleased version of cookiecutter, although it has been merged to master, it has not been released on pypi.
ah good to know, thanks! looking forward to the release
Most helpful comment
It would really simplify things if we can have this behavior out of the box