Copier compatibility
deckctl can apply an existing Copier template
without converting it. Point it at a template whose root contains a
copier.yml and it parses the questions, translates them into its own model,
and renders.
deckctl template apply my-copier-template ./out --source work --var project_name=billingHow the format is detected
Section titled “How the format is detected”Under the default --sidecar-format auto:
- An explicit
--sidecar-format deckctlor--sidecar-format copierwins. - A
--sidecar <filename>override implies the native format. - A
deckctl.yamlat the template root → native. - Otherwise a
copier.ymlat the template root → Copier. - Otherwise native, with built-in defaults.
Native wins when both files are present. Force the other one explicitly:
deckctl template apply my-template ./out --source work --sidecar-format copierBoth template apply and template variables accept --sidecar-format.
What is supported
Section titled “What is supported”Question forms
Section titled “Question forms”Both the shorthand and the full mapping form parse, and document order is preserved — which matters because computed defaults reference earlier answers.
project_name: myproject # shorthand: the value is the default
http_port: # full form type: int help: "Port to listen on" default: 8080
runtime: type: str help: "Runtime to target" choices: ["go", "python", "node"] default: "go"| Copier type | deckctl type |
|---|---|
str, or omitted | str |
int | int |
bool | bool |
| anything else | str, with a warning |
A question with choices becomes a choice variable regardless of its declared
type — matching Copier’s own behaviour. List-form choices are supported;
dict-form choices are reduced to their values with a warning.
Computed defaults
Section titled “Computed defaults”A default containing the variable-start delimiter is rendered as a Jinja expression against the answers resolved so far:
project_name: myprojectpackage_name: type: str default: "{{ project_name|lower|replace('-', '_') }}"module_path: type: str default: "gitlab.com/acme/{{ project_name }}"Rendered values are coerced back to the question’s declared type, so a computed
int default reaches the template as an integer and a computed bool as a
boolean.
when conditions
Section titled “when conditions”use_database: type: bool default: false
database_url: type: str when: "{{ use_database }}"A question whose when evaluates falsy is never prompted for. If it still
has a default, that default is recorded so later expressions can reference it.
A when that fails to evaluate produces a warning and the question is treated
as active.
Truthiness follows Copier/Jinja conventions: "", false, 0, none and
no (case-insensitive) are false; everything else is true.
Template settings
Section titled “Template settings”| Copier key | Mapped to |
|---|---|
_subdirectory | Sidecar subdirectory — the template tree is rendered from there |
_templates_suffix | Sidecar template_suffixes (replaces the whole list) |
_envops | Sidecar delimiters — see Custom delimiters |
Any other _-prefixed key produces a warning and is ignored — including
_exclude, _skip_if_exists, _tasks, _migrations and _answers_file.
What is not supported
Section titled “What is not supported”These produce a warning on stderr and are a no-op. Nothing blocks rendering.
| Copier feature | Behaviour |
|---|---|
validator | Ignored — no validation is performed |
secret | Ignored — input is not masked |
multiselect | Ignored |
placeholder | Ignored |
Dict-form choices | Values used, keys dropped |
_exclude, _tasks, _migrations, … | Ignored |
| Answers file / template updates | Not implemented — deckctl has no copier update equivalent |
Resolution order
Section titled “Resolution order”Slightly different from the native path, because Copier defaults can compute:
--var key=value— always wins, even over a falsywhen- The default — evaluated as a Jinja expression if it looks like one
- Interactive prompt — only if the question is active (
whentruthy or absent)
A question with a default is therefore never prompted for, even when you wanted to be asked. That is Copier’s behaviour too.
Inspecting a Copier template
Section titled “Inspecting a Copier template”deckctl template variables my-copier-template --source workThis shows the translated variables and prints every translation warning to stderr — the fastest way to see what deckctl will and won’t honour before you apply anything.
Worked example
Section titled “Worked example”_subdirectory: template_envops: variable_start_string: "[[" variable_end_string: "]]"
project_name: type: str help: "Human-readable project name" default: "My Project"
package_name: type: str default: "[[ project_name|lower|replace(' ', '_') ]]"
use_ci: type: bool default: true
ci_image: type: str default: "golang:1.26" when: "[[ use_ci ]]"deckctl template apply acme-service ./out --source work --var project_name="Billing Service"project_name→"Billing Service"(from--var)package_name→"billing_service"(computed)use_ci→true(default)ci_image→"golang:1.26"(active, default applies)- Everything under
template/is rendered with[[ ]]delimiters