garden icon indicating copy to clipboard operation
garden copied to clipboard

$forEach template helper just looping over the first item of an array.

Open mattpolzin opened this issue 1 year ago • 3 comments

Bug

Current Behavior

      $forEach: ${inputs.array-of-things}
      $return:
        ${item.value}

Is producing an array containing the first item of array-of-things. It produces an array the same length as array-of-things, but every single item is the first element of the source array.

Expected behavior

${item.value} is each different item of the input array, not the first item over and over.

Reproducible example

If this problem does not always occur when using $forEach, then it may be specific to using $forEach in a Module template where I am generating an array of services based on an input array of objects.

Workaround

None known.

Additional context

Your environment

  • OS: macOS
  • How I'm running Kubernetes: Microsoft Azure

garden version: 0.12.43

mattpolzin avatar Aug 03 '22 21:08 mattpolzin

@mattpolzin thanks for reporting this! Could you try the following scenario as a workaround, please?

  • Declare a new variable and store the input of $forEach in that variable
  • Pass that single variable to $forEach

vvagaytsev avatar Aug 04 '22 09:08 vvagaytsev

I can try that if you'd like to know if it works for me, but I don't think it will help me work around the problem in my case. I am using variables in some of the values I am passing to the module template and in my experience values stored in variables won't expand out other variables.

mattpolzin avatar Aug 04 '22 15:08 mattpolzin

Ok, thank you, we'll have a look.

vvagaytsev avatar Aug 17 '22 11:08 vvagaytsev

@mattpolzin is this issue still valid? I tried to reproduce it using templated-k8s-container example, but I wasn't able to get the same error.

Could you, please, share your example configs if the issue is still reproducible?

vvagaytsev avatar Oct 19 '22 11:10 vvagaytsev

I can still reproduce this; let me see if I can come up with a minimal example.

mattpolzin avatar Oct 20 '22 20:10 mattpolzin

@vvagaytsev here's a repo with a pretty small amount of configuration in it: https://github.com/opallabs/garden-3091-repro

The project file itself should not be important, so you could copy all files except for project file into another project and see the error I imagine.

mattpolzin avatar Oct 20 '22 21:10 mattpolzin

Thanks, @mattpolzin! I'll take a look.

vvagaytsev avatar Oct 21 '22 10:10 vvagaytsev

It looks like the problem comes from https://github.com/garden-io/garden/blob/main/core/src/template-string/template-string.ts#L348 and https://github.com/garden-io/garden/blob/main/core/src/template-string/template-string.ts#L349:

// Have to override the cache in the parent context here
// TODO: make this a little less hacky :P
delete loopContext["_resolvedValues"]["item.key"]
delete loopContext["_resolvedValues"]["item.value"]

The cache state in the loopContext stays dirty. I tried to remove some values from it in the debugger and it helped:

delete loopContext["_resolvedValues"]["item.value.env-overrides"]
delete loopContext["_resolvedValues"]["item.value.service-props"]

@edvald should we always delete all values like loopContext["_resolvedValues"]["item.value.*"] in the hack above? Maybe it's time to find a better fix for it :)

I created a reproducible example in https://github.com/garden-io/garden/compare/main...repro/gh-3091-forEach-issue-in-module-templates - it is based on https://github.com/opallabs/garden-3091-repro.

vvagaytsev avatar Oct 24 '22 14:10 vvagaytsev