Is your feature request related to a problem? Please describe.
Trying to build a template for Terraform structure, which means a lot of the file tree structure depends on one or more of the inputs. Using a "choice" type here makes a lot more sense from a usability standpoint than using multiple competing boolean keys. For example:
Example copier.yaml
flavor:
type: str
choices:
- Docker
- Instances
- Kubernetes
- None
But that means having to do string comparison if-statements in directory names to create conditional directories. And everywhere else when this value is evaluated. If multiple answers are correct for some conditional directories then that results in even longer if-and statements:
Example filetree
.
├── {% if flavor == 'docker' %}ecs{% endif %}
├── {% if flavor == 'kubernetes' %}eks{% endif %}
├── {% if flavor == 'instance' %}bastion{% endif %}
├── {% if flavor == 'docker' or flavor == 'kubernetes' %}portainer{% endif %}
└── {% if flavor != 'none' %}vpc{% endif %}
This can make the directory names quite long and makes everything poorly readable. It also results in a lot of Jinja repetition across the template.
Describe the solution you'd like
I was hoping to create keys derived from the choice key behind the scenes, e.g. without prompting the user for input. In my scenario these would be booleans, but it could also be useful for concatenating strings or other post-input processing purposes that deduplicates a lot of code from the template files.
Example of how I'd love for this to work for my use case:
Future copier.yaml
flavor:
type: str
choices:
- Docker
- Instances
- Kubernetes
- None
# Internal variables
isContainer:
type: bool
value: "{% if flavor == 'docker' or flavor == 'kubernetes' %}true{% else %}false{% endif %}"
isDocker:
type: bool
value: "{% if flavor == 'docker' %}true{% else %}false{% endif %}"
isInstance:
type: bool
value: "{% if flavor == 'instance' %}true{% else %}false{% endif %}"
isKubernetes:
type: bool
value: "{% if flavor == 'kubernetes' %}true{% else %}false{% endif %}"
isLite:
type: bool
value: "{% if flavor == 'none' %}true{% else %}false{% endif %}"
Future filetree
.
├── {% if isDocker %}ecs{% endif %}
├── {% if isKubernetes %}eks{% endif %}
├── {% if isInstance %}bastion{% endif %}
├── {% if isContainer %}portainer{% endif %}
└── {% if isLite %}vpc{% endif %}
For this to work the value:
key would have to be added and if this key is set then prompting the user for input would always be skipped. Alternatively prompt: false
could be used in combination with setting the value using default:
similar to what was suggested in https://github.com/copier-org/copier/issues/229 before.
If preferred these "internal variables" could also be moved one layer down under an identifier:
flavor:
type: str
choices:
- Docker
- Instances
- Kubernetes
- None
_derived_keys:
isContainer:
type: bool
value: "{% if flavor == 'docker' or flavor == 'kubernetes' %}true{% else %}false{% endif %}"
isDocker:
type: bool
value: "{% if flavor == 'docker' %}true{% else %}false{% endif %}"
isInstance:
type: bool
value: "{% if flavor == 'instance' %}true{% else %}false{% endif %}"
isKubernetes:
type: bool
value: "{% if flavor == 'kubernetes' %}true{% else %}false{% endif %}"
isLite:
type: bool
value: "{% if flavor == 'none' %}true{% else %}false{% endif %}"
Describe alternatives you've considered
I've tried creating the variable like this, but setting when: false
doesn't set the variable at all, resulting in the boolean always resolving to true
:
isLite:
type: bool
when: false
default: "{% if flavor == 'none' %}true{% else %}false{% endif %}"
Additional context
enhancement