From d9259d6d12873360755f699d911ec8d0d3f680f9 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 c9beb67bd..c344aa7b0 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 98546a954..a542a2467 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 +}