这是indexloc提供的服务,不要输入任何密码
Skip to content

Conversation

@walteh
Copy link
Owner

@walteh walteh commented Aug 5, 2025

Summary

  • add HCLEvaluator with upper/lower/join/split/env functions
  • evaluate HCL variables and commands at runtime
  • test HCL expression evaluation

Testing

  • go test ./...

Prompt

Task 5: Integrate Template Evaluation for HCL Taskfiles

Purpose: Task currently supports Go templating in Taskfiles (e.g. using {{ }} for dynamic values or
injecting variables). We must ensure the same templating mechanism works for HCL files as it does for YAML
files. The challenge is that the HCL parser expects valid syntax, so template placeholders must be
resolved before parsing.
• Implementation:
• Locate where YAML Taskfile templating is handled. Typically, the process is: read file as text ->
run text/template (with Task’s custom functions/vars) -> then YAML decode. This templating step should be
reused for HCL: apply it to the raw HCL file content before handing off to the HCL parser.
• If not already abstracted, factor out a common function like ExecuteTemplates(input []byte)
([]byte, error) that takes the file content and applies the Go template engine. This function should be
called for both YAML and HCL loading. Use the same data context so that {{.VAR}}, {{.ENV}}, and Task’s
custom template functions work consistently.
• Be careful that template output yields syntactically correct HCL. For example, if a template
inserts a string without quotes into HCL, it could break parsing. In documentation, users likely will
quote their template expressions appropriately (just as in YAML). We should document or enforce that (e.g.
if template produces a bare word in HCL, it might be interpreted as identifier; ideally, encourage
templates to produce strings or numbers as needed).
• Update the HCL loader flow:
1. Read the file content ([]byte).
2. Run the template expansion on it (with proper context, e.g. environment variables, user-provided
vars, etc.).
3. Then parse the resulting content via HCL as implemented in Tasks 3-4.
4. If template rendering fails (syntax error in {{}}), report the error. If the rendered content
fails HCL parse, report it with context (it could be user error in template output).
• Add support for any template-specific functions that were YAML-only. For instance, Task provides
fromYaml and toYaml functions in templates ; we might introduce fromHCL/toHCL if needed. Initially, this
might not be necessary – templates can still use YAML functions, but it might make sense to offer fromHCL
if users want to parse an HCL snippet in a template. This can be a future enhancement – mention it in
documentation if not doing it now.
• Validation:
• Create a test HCL Taskfile that uses templates. For example:

{{ $msg := "Hello" }}
task "echo" {
cmds = ["echo {{ $msg }} world"]
}

After loading, the task’s command should be echo Hello world. Write a test to verify that the template is
evaluated and the command contains the injected value.

  •    Test that Task’s existing template functions work in HCL context. For instance, use {{env 

"HOME"}} or {{splitLines .VAR}} inside an HCL Taskfile and ensure they behave as expected. This ensures
the template engine context is the same for both formats.
• Ensure that a syntax error in a template inside an HCL file yields a clear error (ideally
mentioning it’s a template error). Similarly, an error in HCL content after template expansion should
still point to the correct location (which might be tricky if templates alter line numbers – as a stretch
goal, we could improve error messages by mapping them back to original file lines, but that may be outside
this scope).
• Verify that disabling templating (if Task has an option to turn it off) works uniformly for HCL.

✅ Task 5 (Corrected): Implement HCL Runtime Expression Evaluation

Goal:
Evaluate all previously captured HCL expressions at runtime — lazily — using an hcl.EvalContext. This
replaces Go templating for HCL Taskfiles.

🔧 Changes Required

  1. Create an HCL evaluation engine

Create a struct:

type HCLEvaluator struct {
EvalCtx *hcl.EvalContext
}

Populate it with:
• Task-level vars (cty.StringVal)
• Global vars
• Environment vars (via cty.StringVal(os.Getenv("FOO")))
• Add support for built-in functions via EvalCtx.Functions = map[string]function.Function{} —
consider adding:
• upper(string)
• lower(string)
• join(list, delimiter)
• split(string, delimiter)
• env(string) to fetch environment variables

Use cty from HashiCorp and follow examples from Terraform and Docker Bake.

  1. Integrate evaluator into task execution

Update the task execution logic (likely in internal/compiler or executor) to:
• If the task is HCL:
• For each cmd hcl.Expression, call expr.Value(ctx)
• For each var or env, call expr.Value(ctx)
• Set the resulting string into the actual cmd or shell env before execution

This runtime eval should mirror how templating is done in YAML, but via native HCL.

  1. Support dynamic variables (later optional)

To match YAML behavior with {sh: "echo hi"}, allow an HCL function like:

vars = {
COMMIT = sh("git rev-parse HEAD")
}

Register sh(string) string in EvalContext.Functions, and inside it run the shell command and return the
output.

For now, support only basic static HCL expressions and simple functions like upper.

✅ Acceptance Criteria
• Running this Taskfile:

task "build" {
vars = {
FOO = "bar"
}
cmds = ["echo ${upper(FOO)}"]
}

Should print:
echo BAR
• HCL expressions should resolve only at runtime, not during file load
• env("HOME") should fetch the actual environment variable
• If a variable or function is missing, runtime should return a clear error message with filename
and line

🧪 Tests
• ✅ Add tests that call expr.Value(ctx) and check output for:
• ${FOO}
• ${upper(FOO)}
• ${env("HOME")}
• ✅ Run task -t Taskfile.hcl hello and assert correct output of interpolated values
• ❌ Assert that YAML Taskfiles still use Go templates, not HCL
• ❌ Do not allow ${} expressions in YAML Taskfiles — ensure evaluator is only used for HCL tasks


https://chatgpt.com/codex/tasks/task_e_68920bfe9d64833089e812053af74717

@walteh walteh merged commit 3e86206 into codex/hcl Aug 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants