8 "github.com/hashicorp/terraform/tfdiags"
10 "github.com/hashicorp/terraform/addrs"
13 // GraphBuilder is an interface that can be implemented and used with
14 // Terraform to build the graph that Terraform walks.
15 type GraphBuilder interface {
16 // Build builds the graph for the given module path. It is up to
17 // the interface implementation whether this build should expand
19 Build(addrs.ModuleInstance) (*Graph, tfdiags.Diagnostics)
22 // BasicGraphBuilder is a GraphBuilder that builds a graph out of a
23 // series of transforms and (optionally) validates the graph is a valid
25 type BasicGraphBuilder struct {
26 Steps []GraphTransformer
28 // Optional name to add to the graph debug log
32 func (b *BasicGraphBuilder) Build(path addrs.ModuleInstance) (*Graph, tfdiags.Diagnostics) {
33 var diags tfdiags.Diagnostics
34 g := &Graph{Path: path}
36 var lastStepStr string
37 for _, step := range b.Steps {
41 log.Printf("[TRACE] Executing graph transform %T", step)
43 stepName := fmt.Sprintf("%T", step)
44 dot := strings.LastIndex(stepName, ".")
46 stepName = stepName[dot+1:]
49 debugOp := g.DebugOperation(stepName, "")
50 err := step.Transform(g)
58 if thisStepStr := g.StringWithNodeTypes(); thisStepStr != lastStepStr {
59 log.Printf("[TRACE] Completed graph transform %T with new graph:\n%s------", step, thisStepStr)
60 lastStepStr = thisStepStr
62 log.Printf("[TRACE] Completed graph transform %T (no changes)", step)
66 if nf, isNF := err.(tfdiags.NonFatalError); isNF {
67 diags = diags.Append(nf.Diagnostics)
69 diags = diags.Append(err)
75 // Validate the graph structure
77 if err := g.Validate(); err != nil {
78 log.Printf("[ERROR] Graph validation failed. Graph:\n\n%s", g.String())
79 diags = diags.Append(err)