From 69ffe8d8394872ab4b7d9bf12f5db935053c5f01 Mon Sep 17 00:00:00 2001 From: Lucas Bajolet Date: Thu, 24 Aug 2023 16:11:55 -0400 Subject: [PATCH] hcl2template: extract attr filter code from ds Datasources use their attribute's expressions to determine whether or not they depend on another datasource, in order to get the list of dependencies and execute them before executing a datasource. This code may be useful later on for figuring out the dependencies for any block, so we move this code to the utils.go file, and use this for datasources. --- hcl2template/types.packer_config.go | 31 ++++++++++------------------- hcl2template/utils.go | 20 +++++++++++++++++++ 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/hcl2template/types.packer_config.go b/hcl2template/types.packer_config.go index ef23c7db9..8664538ba 100644 --- a/hcl2template/types.packer_config.go +++ b/hcl2template/types.packer_config.go @@ -5,7 +5,6 @@ package hcl2template import ( "fmt" - "log" "sort" "strings" @@ -313,27 +312,17 @@ func (cfg *PackerConfig) evaluateDatasources(skipExecution bool) hcl.Diagnostics // with the datasources in its context. dependencies[ref] = []DatasourceRef{} - block := ds.block - body := block.Body - attrs, _ := body.JustAttributes() - - skipFirstEval := false - for _, attr := range attrs { - vars := attr.Expr.Variables() - for _, v := range vars { - // check whether the variable is a data source - if v.RootName() == "data" { - // construct, backwards, the data source type and name we - // need to evaluate before this one can be evaluated. - dependsOn := DatasourceRef{ - Type: v[1].(hcl.TraverseAttr).Name, - Name: v[2].(hcl.TraverseAttr).Name, - } - log.Printf("The data source %#v depends on datasource %#v", ref, dependsOn) - dependencies[ref] = append(dependencies[ref], dependsOn) - skipFirstEval = true - } + // Note: when looking at the expressions, we only need to care about + // attributes, as HCL2 expressions are not allowed in a block's labels. + vars := GetVarsByType(ds.block, "data") + for _, v := range vars { + // construct, backwards, the data source type and name we + // need to evaluate before this one can be evaluated. + dependsOn := DatasourceRef{ + Type: v[1].(hcl.TraverseAttr).Name, + Name: v[2].(hcl.TraverseAttr).Name, } + dependencies[ref] = append(dependencies[ref], dependsOn) } } diff --git a/hcl2template/utils.go b/hcl2template/utils.go index 1503eb35c..8c3b55ed5 100644 --- a/hcl2template/utils.go +++ b/hcl2template/utils.go @@ -186,3 +186,23 @@ func ConvertPluginConfigValueToHCLValue(v interface{}) (cty.Value, error) { } return buildValue, nil } + +func GetVarsByType(block *hcl.Block, topLevelLabels ...string) []hcl.Traversal { + attributes, _ := block.Body.JustAttributes() + + var vars []hcl.Traversal + + for _, attr := range attributes { + for _, variable := range attr.Expr.Variables() { + rootLabel := variable.RootName() + for _, label := range topLevelLabels { + if label == rootLabel { + vars = append(vars, variable) + break + } + } + } + } + + return vars +}