You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Duplicate dynamic variables in multiple included taskfiles are overwritten #830
I have a monorepo that I haven't touched for around 6 or more months. I upgraded and narrowed down the version that the issue was introduced (v3.2.1). Each project is in its own folder with a taskfile that declare dynamic variables. There's a root Taskfile.yml that includes each project's Taskfile.yml and sets the directory to the project's directory.
The behavior in v3.2.0 is that dynamic variable's working directory is scoped to whatever directory the parent Taskfile set in the includes statement. I've found this isn't the case in >= v3.2.1.
I've included the folder structure along with all file contents and the command line output to recreate the issue.
It is quite hard to match the source and the output. The source prints the version, but the output shows paths.
Global variables (even in multiple files) share the same namespace (scope) and overwrite each other. So you will always get the last definition of VERSION.
The reason for this different between echo "{{.PROJECT_DIR}}" and pwd in task project1:whereami is as @MarioSchwalbe described: Global variables (even in multiple files) share the same namespace (scope) and overwrite each other.
I am wondering if there has been a decision to keep global variables of included Taskfiles in the same namespace rather, or if scope these variables has not yet been implemented.
From a user of task, I had the intuition that global variables are scoped, similar to scoped task names when including in a parent Taskfile.
In fact, both use cases do make sense. If it is the same global scope, included taskfiles can overwrite variables of their parent taskfile to allow further customization. For instance, my taskfiles are usually structured linke this:
version: '3'# Default config.vars:
VAR1: 1VAR2: 2# ...includes:
# Local override if present.my:
taskfile: local.ymloptional: yestasks:
# ...
With respect to composability, however, this might become a problem.
@MarioSchwalbe I understand that in the use case you presented, you want to optionally override global variables in a parent Taskfile by global variables in an included Taskfile. For this case, overrides make sense
In contrast, in the use case, in which two Taskfiles are included in a parent Taskfile, the overrides should not occur.
I want to share some additional findings:
Dynamic variable values are overridden across two included Taskfiles if and only if the sh command is identical.
Static variable values are not override across two included Taskfiles.
It seems that the result of the command in the dynamic variable is cached and then reused across the scope. The issue did not occur with dynamic variables, which have the same name but use a different sh command. As a workaround, I have added a unique comment at the end of the command.
Therefore, I would argue that this issue is actually a duplicate of #524.
Exactly same issue issue as well. Although I cannot reproduce it with directly set variables, only with dynamic variables. And it does not seem to be a race condition, as using sleep 0.$((1 + $RANDOM % 10)) && cat .version does not appear to solve the problem.
This really does seem to be identical to #524 I can confirm that adding a comment or some other meaningless string after the variable definition solves the issue. I think this can be closed then, no? Effort should be in #524 to fix the problem
This really does seem to be identical to #524 I can confirm that adding a comment or some other meaningless string after the variable definition solves the issue. I think this can be closed then, no? Effort should be in #524 to fix the problem
The example in #830 (comment) is different IIUC — no need for sh:. Is that correct?
This really does seem to be identical to #524 I can confirm that adding a comment or some other meaningless string after the variable definition solves the issue. I think this can be closed then, no? Effort should be in #524 to fix the problem
The example in #830 (comment) is different IIUC — no need for sh:. Is that correct?
Well like I said, I cannot repro this without the sh: at least. If you can, then sure this is different (unless the caching logic in #524 also applies to static vars).
Well like I said, I cannot repro this without the sh: at least. If you can, then sure this is different (unless the caching logic in #524 also applies to static vars).
@max-sixty i did not get notification for this, so tagging so you get the notification. Yes, I was able to repro the issue with your second "simpler repro" steps (without sh and without the nested foldas). I suppose the trick here is to have the dynamic value (i.e. something evaluated). I suspect maybe the cache keys are just using the variable name or just the yaml line contents, without taking the taskfile into consideration, so thats why this happens.
Would be nice if someone familiar with the project internals took a look at this because if the issue is this easy to reproduce, then this should be relatively simple to find a fix, if you know where the code that is responsible for this lies, no?
Would be nice if someone familiar with the project internals took a look at this because if the issue is this easy to reproduce, then this should be relatively simple to find a fix, if you know where the code that is responsible for this lies, no?
Not necessarily — but feel free to take a look — the number of people who are familiar with the code is not fixed...
Activity
MarioSchwalbe commentedon Aug 23, 2022
Some remarks:
VERSION.dominik-lekse commentedon Aug 31, 2022
@dkryptr Thanks for describing the issue precisely.
I have encountered the issue recently in a similar structured repository. Tracking it down was not straightforward.
The
Taskfile.ymlof each sub project is included in the rootTaskfile.ymlwhile thedirattribute points to path of a sub project.Within this context, the observed behaviour is as follows.
The reason for this different between
echo "{{.PROJECT_DIR}}"andpwdintask project1:whereamiis as @MarioSchwalbe described: Global variables (even in multiple files) share the same namespace (scope) and overwrite each other.I am wondering if there has been a decision to keep global variables of included Taskfiles in the same namespace rather, or if scope these variables has not yet been implemented.
From a user of
task, I had the intuition that global variables are scoped, similar to scoped task names when including in a parent Taskfile.MarioSchwalbe commentedon Aug 31, 2022
In fact, both use cases do make sense. If it is the same global scope, included taskfiles can overwrite variables of their parent taskfile to allow further customization. For instance, my taskfiles are usually structured linke this:
With respect to composability, however, this might become a problem.
dominik-lekse commentedon Aug 31, 2022
@MarioSchwalbe I understand that in the use case you presented, you want to optionally override global variables in a parent Taskfile by global variables in an included Taskfile. For this case, overrides make sense
In contrast, in the use case, in which two Taskfiles are included in a parent Taskfile, the overrides should not occur.
I want to share some additional findings:
Dynamic variable values are overridden across two included Taskfiles if and only if the
shcommand is identical.Static variable values are not override across two included Taskfiles.
It seems that the result of the command in the dynamic variable is cached and then reused across the scope. The issue did not occur with dynamic variables, which have the same name but use a different
shcommand. As a workaround, I have added a unique comment at the end of the command.Therefore, I would argue that this issue is actually a duplicate of #524.
Example
max-sixty commentedon Jan 10, 2023
I hit I have an even simpler reproduction of this, no need for
sh:Without any include statement:
But only by including the second taskfile (uncommenting the
includesabove), we get a different result:...which seems quite wrong — that we can change the default variable just by including another Taskfile.
toddlerya commentedon Sep 5, 2023
I also encountered the same problem
megakoresh commentedon Feb 7, 2024
Exactly same issue issue as well. Although I cannot reproduce it with directly set variables, only with dynamic variables. And it does not seem to be a race condition, as using
sleep 0.$((1 + $RANDOM % 10)) && cat .versiondoes not appear to solve the problem.megakoresh commentedon May 9, 2024
This really does seem to be identical to #524 I can confirm that adding a comment or some other meaningless string after the variable definition solves the issue. I think this can be closed then, no? Effort should be in #524 to fix the problem
max-sixty commentedon May 9, 2024
The example in #830 (comment) is different IIUC — no need for
sh:. Is that correct?megakoresh commentedon May 9, 2024
Well like I said, I cannot repro this without the
sh:at least. If you can, then sure this is different (unless the caching logic in #524 also applies to static vars).max-sixty commentedon May 9, 2024
What output do you get from my repro above?
megakoresh commentedon Jun 24, 2024
@max-sixty i did not get notification for this, so tagging so you get the notification. Yes, I was able to repro the issue with your second "simpler repro" steps (without sh and without the nested foldas). I suppose the trick here is to have the dynamic value (i.e. something evaluated). I suspect maybe the cache keys are just using the variable name or just the yaml line contents, without taking the taskfile into consideration, so thats why this happens.
Would be nice if someone familiar with the project internals took a look at this because if the issue is this easy to reproduce, then this should be relatively simple to find a fix, if you know where the code that is responsible for this lies, no?
max-sixty commentedon Jun 24, 2024
OK, thanks for repro-ing.
Not necessarily — but feel free to take a look — the number of people who are familiar with the code is not fixed...
feat(config): add cache to reuse a dynamic var output (#403)