(dagTopology *dag.Topology, blocktype string, vars map[string]*HelmfileHCLValue, additionalLocalContext map[string]map[string]cty.Value)
| 223 | } |
| 224 | |
| 225 | func (hl *HCLLoader) decodeGraph(dagTopology *dag.Topology, blocktype string, vars map[string]*HelmfileHCLValue, additionalLocalContext map[string]map[string]cty.Value) (map[string]cty.Value, error) { |
| 226 | values := map[string]cty.Value{} |
| 227 | helmfileHCLValuesValues := map[string]cty.Value{} |
| 228 | var diags hcl.Diagnostics |
| 229 | hclFunctions, err := HCLFunctions(nil) |
| 230 | if err != nil { |
| 231 | return nil, err |
| 232 | } |
| 233 | for groupIndex := 0; groupIndex < len(*dagTopology); groupIndex++ { |
| 234 | dagNodesInGroup := (*dagTopology)[groupIndex] |
| 235 | |
| 236 | for _, node := range dagNodesInGroup { |
| 237 | v := vars[node.String()] |
| 238 | if blocktype != LocalsBlockIdentifier && additionalLocalContext[v.Range.Filename] != nil { |
| 239 | values[localsAccessorPrefix] = additionalLocalContext[v.Range.Filename][localsAccessorPrefix] |
| 240 | } |
| 241 | ctx := &hcl.EvalContext{ |
| 242 | Variables: values, |
| 243 | Functions: hclFunctions, |
| 244 | } |
| 245 | |
| 246 | // Check if this variable has multiple definitions (overrides) for values blocks |
| 247 | if blocktype == ValuesBlockIdentifier && hl.allVariableDefs != nil { |
| 248 | varDefs := hl.allVariableDefs[node.String()] |
| 249 | if len(varDefs) > 1 { |
| 250 | // Evaluate and merge all definitions in file order |
| 251 | var mergedValue cty.Value |
| 252 | for i, varDef := range varDefs { |
| 253 | // Update local context for each file |
| 254 | if additionalLocalContext[varDef.Range.Filename] != nil { |
| 255 | ctx.Variables[localsAccessorPrefix] = additionalLocalContext[varDef.Range.Filename][localsAccessorPrefix] |
| 256 | } else { |
| 257 | // Ensure locals from a previous definition/file do not leak into this evaluation |
| 258 | ctx.Variables[localsAccessorPrefix] = cty.NilVal |
| 259 | } |
| 260 | evalValue, evalDiags := varDef.Expr.Value(ctx) |
| 261 | if len(evalDiags) > 0 { |
| 262 | return nil, fmt.Errorf("error when trying to evaluate variable %s at %s:%d : %s", |
| 263 | varDef.Name, varDef.Range.Filename, varDef.Range.Start.Line, evalDiags.Errs()[0]) |
| 264 | } |
| 265 | if i == 0 { |
| 266 | mergedValue = evalValue |
| 267 | } else { |
| 268 | mergedValue = ctyMergeValues(mergedValue, evalValue) |
| 269 | } |
| 270 | } |
| 271 | helmfileHCLValuesValues[node.String()] = mergedValue |
| 272 | // Reset local context |
| 273 | values[localsAccessorPrefix] = cty.NilVal |
| 274 | } else { |
| 275 | // Single definition, evaluate normally |
| 276 | helmfileHCLValuesValues[node.String()], diags = v.Expr.Value(ctx) |
| 277 | if len(diags) > 0 { |
| 278 | return nil, fmt.Errorf("error when trying to evaluate variable %s : %s", v.Name, diags.Errs()[0]) |
| 279 | } |
| 280 | } |
| 281 | } else { |
| 282 | // For locals or when no tracking available, evaluate normally |
no test coverage detected