copier icon indicating copy to clipboard operation
copier copied to clipboard

Add a variables section to the copier.yaml file

Open OhioDschungel6 opened this issue 1 year ago • 2 comments

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

OhioDschungel6 avatar Oct 10 '24 11:10 OhioDschungel6

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: false questions support parsing the rendered value according to type: <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.

sisp avatar Oct 10 '24 12:10 sisp

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))

pawamoy avatar Oct 10 '24 13:10 pawamoy