github.com/kanishk98/terraform@v1.3.0-dev.0.20220917174235-661ca8088a6a/internal/terraform/graph_builder.go (about)

     1  package terraform
     2  
     3  import (
     4  	"log"
     5  
     6  	"github.com/hashicorp/terraform/internal/addrs"
     7  	"github.com/hashicorp/terraform/internal/logging"
     8  	"github.com/hashicorp/terraform/internal/tfdiags"
     9  )
    10  
    11  // GraphBuilder is an interface that can be implemented and used with
    12  // Terraform to build the graph that Terraform walks.
    13  type GraphBuilder interface {
    14  	// Build builds the graph for the given module path. It is up to
    15  	// the interface implementation whether this build should expand
    16  	// the graph or not.
    17  	Build(addrs.ModuleInstance) (*Graph, tfdiags.Diagnostics)
    18  }
    19  
    20  // BasicGraphBuilder is a GraphBuilder that builds a graph out of a
    21  // series of transforms and (optionally) validates the graph is a valid
    22  // structure.
    23  type BasicGraphBuilder struct {
    24  	Steps []GraphTransformer
    25  	// Optional name to add to the graph debug log
    26  	Name string
    27  }
    28  
    29  func (b *BasicGraphBuilder) Build(path addrs.ModuleInstance) (*Graph, tfdiags.Diagnostics) {
    30  	var diags tfdiags.Diagnostics
    31  	g := &Graph{Path: path}
    32  
    33  	var lastStepStr string
    34  	for _, step := range b.Steps {
    35  		if step == nil {
    36  			continue
    37  		}
    38  		log.Printf("[TRACE] Executing graph transform %T", step)
    39  
    40  		err := step.Transform(g)
    41  		if thisStepStr := g.StringWithNodeTypes(); thisStepStr != lastStepStr {
    42  			log.Printf("[TRACE] Completed graph transform %T with new graph:\n%s  ------", step, logging.Indent(thisStepStr))
    43  			lastStepStr = thisStepStr
    44  		} else {
    45  			log.Printf("[TRACE] Completed graph transform %T (no changes)", step)
    46  		}
    47  
    48  		if err != nil {
    49  			if nf, isNF := err.(tfdiags.NonFatalError); isNF {
    50  				diags = diags.Append(nf.Diagnostics)
    51  			} else {
    52  				diags = diags.Append(err)
    53  				return g, diags
    54  			}
    55  		}
    56  	}
    57  
    58  	if err := g.Validate(); err != nil {
    59  		log.Printf("[ERROR] Graph validation failed. Graph:\n\n%s", g.String())
    60  		diags = diags.Append(err)
    61  		return nil, diags
    62  	}
    63  
    64  	return g, diags
    65  }