Skip to content

fix(v3/wake): propagate included Taskfile vars so preconditions expand correctly#5613

Open
leaanthony wants to merge 2 commits into
masterfrom
fix/wake-cross-image-var-resolution
Open

fix(v3/wake): propagate included Taskfile vars so preconditions expand correctly#5613
leaanthony wants to merge 2 commits into
masterfrom
fix/wake-cross-image-var-resolution

Conversation

@leaanthony

@leaanthony leaanthony commented Jun 15, 2026

Copy link
Copy Markdown
Member

Problem

When wake resolves includes:, it clones tasks from the included Taskfile into the parent but silently drops the included file's top-level vars: block. This caused two visible failures:

  1. Garbled error message{{.CROSS_IMAGE}} appeared literally in the error box instead of the image name wails-cross.
  2. Cross-compilation fully broken — The precondition shell command ran as docker image inspect {{.CROSS_IMAGE}}, which always fails regardless of whether the image exists. So even after running wails3 task setup:docker, the linux:build:docker task would refuse to run.

The same bug affects darwin/Taskfile.yml and windows/Taskfile.yml, which also define CROSS_IMAGE as a top-level var.

Root cause

resolveIncludes in parse/parse.go (line 468) only copies tasks:

for taskName, task := range tfResolved.Tasks {
    namespaced := name + ":" + taskName
    tf.Tasks[namespaced] = task.Clone()  // included file's Vars never propagated
}

mergeVars at execution time has three sources: root tf.Vars, depVars, and task.Vars. None of them contain the included file's CROSS_IMAGE.

Additionally, checkPreconditions was called before mergeVars ran, and used pc.Sh/pc.Msg raw without template expansion — so even if vars had been available, they wouldn't have been applied.

Changes

File Change
parse/parse.go Inject included file's top-level Vars into each cloned task's Vars map. Task-own vars have higher priority.
exec/runner.go checkPreconditions now accepts vars map[string]*ast.Var and calls parse.ExpandTemplates on both pc.Sh and pc.Msg.
exec/exec.go Move mergeVars call before checkPreconditions so the merged variable map is available for expansion.
parse/parse_test.go Regression test verifying top-level vars from included files propagate into all cloned tasks, and task-level vars still win.

Testing

go test ./internal/wake/...  # all pass

Summary by CodeRabbit

  • Bug Fixes
    • Precondition evaluation now uses merged task and dependency variables for more accurate conditional logic.
    • Precondition failure messages now support variable interpolation, using the expanded command/message.
    • Top-level variables from included taskfiles are now injected into cloned tasks, with task-local variables taking precedence.
  • Tests
    • Added a regression test to verify top-level vars propagation, precedence, and deep-copy isolation for included tasks.

…d correctly

When wake resolves `includes:`, it cloned tasks into the parent Taskfile but
dropped the included file's top-level `vars:` block entirely.  This caused any
template reference inside a cloned task's preconditions or commands — such as
`{{.CROSS_IMAGE}}` in the `linux:build:docker` precondition — to be rendered
literally rather than expanded.  The unexpanded shell command also made the
precondition fail on a literal string, so cross-compilation via Docker was
completely broken even after running `wails3 task setup:docker`.

Three coordinated changes:

* parse/parse.go: inject the included file's top-level vars into each cloned
  task's Vars map (included-file vars are defaults; task-own vars win).
* exec/runner.go: call parse.ExpandTemplates on both pc.Sh and pc.Msg before
  executing the precondition shell check or formatting the error message.
* exec/exec.go: move mergeVars before checkPreconditions so the fully-merged
  variable map is available for template expansion in preconditions.

Adds a regression test in parse_test.go that verifies top-level vars from an
included file propagate into all cloned tasks and that task-level vars still
take precedence.
Copilot AI review requested due to automatic review settings June 15, 2026 14:24
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e9963a6d-1e84-4603-a868-ec75d86b5158

📥 Commits

Reviewing files that changed from the base of the PR and between bc3fe88 and 011f378.

📒 Files selected for processing (3)
  • v3/internal/wake/exec/exec.go
  • v3/internal/wake/parse/parse.go
  • v3/internal/wake/parse/parse_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • v3/internal/wake/parse/parse.go
  • v3/internal/wake/parse/parse_test.go
  • v3/internal/wake/exec/exec.go

Walkthrough

Two variable-propagation fixes in the wake subsystem: resolveIncludes in parse.go now injects an included taskfile's top-level vars into every cloned task (task-local vars take precedence). In exec.go, mergedVars is computed before checkPreconditions, and runner.go expands precondition shell command and message templates against those merged variables.

Changes

Variable propagation for includes and preconditions

Layer / File(s) Summary
Inject included taskfile vars into cloned tasks
v3/internal/wake/parse/parse.go, v3/internal/wake/parse/parse_test.go
resolveIncludes clones each included task into cloned, merges the included taskfile's top-level vars into cloned.Vars with task-local vars taking priority, then stores the result. Regression test asserts CROSS_IMAGE propagates to linux:build and linux:build:docker while OWN_VAR is not overwritten, and verifies deep-copy isolation between cloned tasks.
Precondition evaluation with merged variables
v3/internal/wake/exec/exec.go, v3/internal/wake/exec/runner.go
mergedVars computation is moved before the checkPreconditions call in runTask only when preconditions are declared; lazy initialization after cache check avoids unnecessary expansion for pruned tasks. runner.go imports parse and calls parse.ExpandTemplates to expand the precondition shell command and message templates against the provided vars before running the command and forming the error string.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • wailsapp/wails#5612: Coordinates with this PR on precondition handling: both change how checkPreconditions expands templated shell commands and derives failure messages using merged task vars from runTask.

Poem

🐇 Hop, hop, the vars now flow,
Through includes high and preconditions low,
Templates expand with every merge,
No raw command strings shall diverge,
The taskfile vars in order aligned—
A tidy warren, well-designed! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: propagating included Taskfile variables to fix precondition template expansion.
Description check ✅ Passed The description is comprehensive, covering the problem, root cause, changes made, and testing. It includes all required template sections and provides clear context about the issue and solution.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/wake-cross-image-var-resolution
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch fix/wake-cross-image-var-resolution

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain modules listed in go.work or their selected dependencies"


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes wake’s Taskfile includes: handling so that variables defined at the top-level of an included Taskfile are available when executing the cloned, namespaced tasks—specifically enabling correct template expansion inside preconditions (e.g., {{.CROSS_IMAGE}}) and improving related error messages.

Changes:

  • Propagate included Taskfile top-level vars: into each cloned task during include resolution.
  • Expand templates in precondition sh and msg, and ensure merged vars are available before precondition checks.
  • Add a regression test covering var propagation and precedence.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
v3/internal/wake/parse/parse.go Injects included Taskfile vars into cloned tasks during ResolveIncludes.
v3/internal/wake/parse/parse_test.go Adds a regression test ensuring included vars propagate and task vars still win.
v3/internal/wake/exec/runner.go Expands templates in precondition shell commands/messages using a provided vars map.
v3/internal/wake/exec/exec.go Computes merged vars before running preconditions so expansion has full context.
Comments suppressed due to low confidence (1)

v3/internal/wake/exec/exec.go:214

  • mergeVars() is now executed before the up-to-date fast-path. Previously, tasks skipped by isUpToDate() avoided the (potentially non-trivial) fixed-point template expansion work in mergeVars(). If wake is frequently run with many cached tasks, this could introduce unnecessary overhead.
	mergedVars := e.mergeVars(task, depVars)

	if err := checkPreconditions(task, mergedVars); err != nil {
		return err
	}

	if !e.Force && isUpToDate(task, e.Dir) {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +474 to +483
if len(tfResolved.Vars) > 0 {
merged := make(map[string]*ast.Var, len(tfResolved.Vars)+len(cloned.Vars))
for k, v := range tfResolved.Vars {
merged[k] = v
}
for k, v := range cloned.Vars {
merged[k] = v
}
cloned.Vars = merged
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in 011f378. The injected included vars are now deep-copied (`vClone := *v`) just like `Task.Clone` does, so the in-place mutation in `ResolveVars`/`ResolveAllVarShells` no longer leaks across tasks that share an included file. Added a regression assertion (distinct pointers + mutation isolation) in `TestResolveIncludesInjectsTopLevelVarsIntoClonedTasks`.

…hed preconditionless tasks

Address PR review feedback:
- Deep-copy the included Taskfile's top-level vars when injecting them into
  cloned tasks (consistent with Task.Clone). Sharing *ast.Var by pointer let
  the in-place mutation in ResolveVars/ResolveAllVarShells leak across all
  tasks that include the same file. Regression test asserts distinct pointers
  and isolation under mutation.
- Compute mergedVars lazily: tasks without preconditions that are up-to-date
  no longer pay for the fixed-point template expansion.
@taliesin-ai

Copy link
Copy Markdown
Collaborator

Addressed review feedback in 011f378:

  1. Shared mutable state (Copilot inline) — the injected top-level include vars are now deep-copied into each cloned task (matching `Task.Clone`), so in-place mutation by `ResolveVars`/`ResolveAllVarShells` can no longer leak across tasks that share the same included file. The regression test now also asserts distinct pointers and isolation under mutation.

  2. `mergeVars` overhead for cached tasks (Copilot low-confidence note) — `mergedVars` is now computed lazily. Tasks with no preconditions that turn out to be up-to-date skip the fixed-point template expansion entirely; preconditions still get the merged map when present, before the up-to-date check.

go test ./internal/wake/... and go vet ./internal/wake/... both pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants