github.com/graywolf-at-work-2/terraform-vendor@v1.4.5/internal/terraform/transform_root.go (about) 1 package terraform 2 3 import ( 4 "github.com/hashicorp/terraform/internal/dag" 5 ) 6 7 const rootNodeName = "root" 8 9 // RootTransformer is a GraphTransformer that adds a root to the graph. 10 type RootTransformer struct{} 11 12 func (t *RootTransformer) Transform(g *Graph) error { 13 addRootNodeToGraph(g) 14 return nil 15 } 16 17 // addRootNodeToGraph modifies the given graph in-place so that it has a root 18 // node if it didn't already have one and so that any other node which doesn't 19 // already depend on something will depend on that root node. 20 // 21 // After this function returns, the graph will have only one node that doesn't 22 // depend on any other nodes. 23 func addRootNodeToGraph(g *Graph) { 24 // We always add the root node. This is a singleton so if it's already 25 // in the graph this will do nothing and just retain the existing root node. 26 // 27 // Note that rootNode is intentionally added by value and not by pointer 28 // so that all root nodes will be equal to one another and therefore 29 // coalesce when two valid graphs get merged together into a single graph. 30 g.Add(rootNode) 31 32 // Everything that doesn't already depend on at least one other node will 33 // depend on the root node, except the root node itself. 34 for _, v := range g.Vertices() { 35 if v == dag.Vertex(rootNode) { 36 continue 37 } 38 39 if g.UpEdges(v).Len() == 0 { 40 g.Connect(dag.BasicEdge(rootNode, v)) 41 } 42 } 43 } 44 45 type graphNodeRoot struct{} 46 47 // rootNode is the singleton value representing all root graph nodes. 48 // 49 // The root node for all graphs should be this value directly, and in particular 50 // _not_ a pointer to this value. Using the value directly here means that 51 // multiple root nodes will always coalesce together when subsuming one graph 52 // into another. 53 var rootNode graphNodeRoot 54 55 func (n graphNodeRoot) Name() string { 56 return rootNodeName 57 } 58 59 // CloseRootModuleTransformer is a GraphTransformer that adds a root to the graph. 60 type CloseRootModuleTransformer struct{} 61 62 func (t *CloseRootModuleTransformer) Transform(g *Graph) error { 63 // close the root module 64 closeRoot := &nodeCloseModule{} 65 g.Add(closeRoot) 66 67 // since this is closing the root module, make it depend on everything in 68 // the root module. 69 for _, v := range g.Vertices() { 70 if v == closeRoot { 71 continue 72 } 73 74 // since this is closing the root module, and must be last, we can 75 // connect to anything that doesn't have any up edges. 76 if g.UpEdges(v).Len() == 0 { 77 g.Connect(dag.BasicEdge(closeRoot, v)) 78 } 79 } 80 81 return nil 82 }