Skip to content

fix: run once with multiple levels of nested includes - #3097

Open
sainimal1ba-hue wants to merge 1 commit into
go-task:mainfrom
sainimal1ba-hue:fix/run-once-nested-includes
Open

sainimal1ba-hue wants to merge 1 commit into
go-task:mainfrom
sainimal1ba-hue:fix/run-once-nested-includes

Conversation

@sainimal1ba-hue

Copy link
Copy Markdown

Description

Fixes #3058

run: once should mean that a task is only run once per invocation regardless of how many include branches reach it. That only works if the hierarchy is one level deep at present. With two or more levels the same task runs once per branch:

task: [c:a:tools:exe] echo "building tool"
building tool
task: [c:b:tools:exe] echo "building tool"
building tool

Root cause: Task deduplicates by hashing the Taskfile location (the defining Taskfile location) plus the task's LocalName. LocalName strips off the Namespace from the full name, but Namespace only ever stored the last include namespace (not the full chain). In a deeper tree the middle namespaces survive the trim so c:a:tools:exe becomes tools/taskfile.yml:a:tools:exe and c:b:tools:exe becomes tools/taskfile.yml:b:tools:exe. Different hashes, no dedupe.

Fix: Tasks.Merge now accumulates the namespace at each level so the chain is always the full c:a:tools and LocalName just returns 'exe' (the name of the task relative to the Taskfile that defines it). Both branches hash to tools/taskfile.yml:exe and the second call simply joins the first execution rather than re-executing it.

Tests

  • New TestRunOnceNestedIncludes with a fixture in testdata/run_once_nested_includes which is a direct reproduction of the issue. It asserts that the shared task runs exactly once whilst both branches do run. Fails on main (2 matches) and passes with the fix.
  • The existing run once tests all pass unchanged (TestRunOnceSharedDeps, TestRunOnceSharedFailurePropagates, Testrunoncejoinerhonoursitsowntimeout).
  • Full 'go test ./...' passes.

AI disclosure

GLM 5.3 was the version used to build the solution. I reviewed all the implementation, verified the root cause and ran the tests myse

Checklist

  • I have read and adhered to the Contribution Guide.
  • I have disclosed the use of any AI generated content in this pull request in accordance with the AI Usage Policy.
  • I fully understand the changes and have hand-written the description (No AI) for this PR.

run: once deduplicates executions by hashing the defining Taskfile
location together with the task's LocalName. LocalName trims the task
Namespace off its full name, but Namespace only ever held the last
include namespace instead of the whole chain. With more than one level
of nesting, the intermediate namespaces survived the trim, so the same
task reached through different branches produced different hashes and
ran once per branch.

Accumulate the namespace at every merge level so LocalName always
returns the task name relative to the Taskfile that defines it. The
deduplication key is now the same for the same underlying task no
matter which path through the include tree reaches it.

Fixes go-task#3058

This branch has not been deployed

No deployments
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.

run: once does not work with multiple levels of hierarchy

1 participant