Add a variables section to the copier.yaml file
Actual Situation
Sometimes it is useful to have a key available globally for all templates which is no user input. Examples:
- I want to have a version available as key everywhere, because if i update it i don't want to update it in 10 locations but only in one.
- I want to use an answer with more complex filters used in many places and i don't want to reapply the filters in every file.
Atm this can be done with a workaround:
version:
type: str
default: "1.0.0"
when: false
module_name_camelcase: #module_name is a key which was defined earlier as question.
type: str
default: "{{ module_name.split('_') | map('capitalize') | join('') }}"
when: false
While using when: false is a fix for the problem. It kinda mixes questions and variables and also uses confusing syntax.
Desired Situation
Add a new section to the copier.yml file: which allows defining variables and constants. E.g.
_variables:
- version: "0.2.0"
- module_name_camel: "{{ module_name.split('_') | map('capitalize') | join('') }}"
Proposed solution
No response
This topic has come up a couple of times; in fact, I myself suggested a similar idea some time ago, but we decided to make when: false an official feature instead.
I see a few downsides to your design proposal:
-
Templated variable values can only be strings whereas
when: falsequestions support parsing the rendered value according totype: <type>. -
We can't easily define computed values / variables between questions such that a computed value / variable depends on answers from previous questions and can be used in, e.g., default values of subsequent questions.
I share the perception of computed values / variables via when: false questions being a workaround, but there are some benefits of this approach.
This was discussed at lengths indeed, and the current solution works (even though some might find it unintuitive/confusing), so I don't think there will be consensus on implementing your suggestion.
If you really want to avoid when: false questions, you can also use a template extension to alter the rendering context:
_jinja_extensions:
- copier_templates_extensions.TemplateExtensionLoader
- extensions/context.py:ContextUpdater
# extensions/context.py
from copier_templates_extensions import ContextHook
class ContextUpdater(ContextHook):
def hook(self, context):
context["module_name_camelcase"] = "".join(map(context["module_name"].split("_"), str.capitalize))