copier
copier copied to clipboard
Conditional argument ignored when updating
Describe the problem
Commandline data argument is ignored when commandline value is changed during update. Argument is not remembered in answers file.
Template
To Reproduce
Create a copier.yaml with an argument which is conditional based on another argument.
_min_copier_version: 9.0.0
_subdirectory: "template"
_exclude:
- "*~"
_message_before_copy: |
Hi
project_name:
type: str
default: X
# Hidden options used for testing
show_internal_test_options:
type: bool
help: "Show options for internal use for testing template."
default: false
when: false
with_internal1:
type: bool
help: "Internal opt 1"
default: false
when: "{{ show_internal_test_options }}"
Git commit template. Expand template with "hidden" data arg specified on commandline.
]$ mkdir ttt && cd ttt && copier copy ../copier_ignored_arg_bug . --defaults --data with_internal1=true
Value of with_internal1 is correctly expanded as True in template file, but is not store in answers file.
Commit subproject.
Make a change in template, e.g. the message. Commit.
Update subproject with new value of with_internal1
ttt]$ copier update -A --data with_internal1=false
Value of with_internal1 is unchanged and remains expanded as True in template file! The template file is unchanged, only answers file is update (with new git commit).
Logs
No response
Expected behavior
The template file should be updated with the value specified on commandline. Copier should save the value in the answers file.
Screenshots/screencasts/logs
No response
Operating system
Linux
Operating system distribution and version
Fedora
Copier version
9.3.1
Python version
3.11.8
Installation method
pip+pypi
Additional context
No response
Seems a theoretical valid case, but what's the real use case for such feature? I mean: why would you need an answer whose when evaluates to false to be actually stored? If it's changing the output, it's probably a template issue
In the simple example I could just specify the show_internal_test_options. But why should I have to? The show_internal_test_options is just for interactive UI usage to make sure the internal test options are not asked in interactive usage, the real option affecting the template expansion is with_internal1. In the actual template where I have the issue I have maybe 15 secret options affecting template expansion. If I set show_internal_test_options I will have to answer those or use --defaults, which then also affects all other options.
I don't understand what you mean by "it's probably a template issue". The --data with_internal1=false is silently ignored during update, unlike other options which are changable.
Sounds like hacking the answer system to customize the CLI interactivity. I sometimes wonder if Copier shouldn't provide some kind of wrapper around it to build more flexible CLIs/TUIs without having to twist its internals. Some kind of Textual form, for example.
I wonder whether we should disallow overriding answers to hidden questions (when: false with both literal false and Jinja expression evaluating as false) via --data/data= for better consistency across interactive and programmatic use of Copier. :thinking: In interactive mode, a hidden question cannot be answered by a user, so the default value will always be used. This default value can be either hardcoded or a computed value. So why should it be possible to override the answer in programmatic mode?
That makes sense @sisp. However, that won't fix the fact that skipped answers (when=false) won't be stored.
@lhupfeldt have you tried hacking the .copier-answers.yml.jinja file? Something like this:
# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY
{{ dict(_copier_answers, with_internal1=with_internal1) | to_nice_yaml -}}
This way you hardcode a key that's gonna be sometimes skipped in the questionary.
FWIW, keep in mind that, during updates, if you pass -A, you'll only be prompted for new questions. Old ones, already answered, won't ask you again.