github.com/rmenn/terraform@v0.3.8-0.20150225065417-fc84b3a78802/terraform/graph_dot.go (about) 1 package terraform 2 3 import ( 4 "bufio" 5 "bytes" 6 "fmt" 7 "strings" 8 9 "github.com/hashicorp/terraform/dag" 10 ) 11 12 // GraphNodeDotter can be implemented by a node to cause it to be included 13 // in the dot graph. The Dot method will be called which is expected to 14 // return a representation of this node. 15 type GraphNodeDotter interface { 16 // Dot is called to return the dot formatting for the node. 17 // The parameter must be the title of the node. 18 Dot(string) string 19 } 20 21 // GraphDotOpts are the options for generating a dot formatted Graph. 22 type GraphDotOpts struct{} 23 24 // GraphDot returns the dot formatting of a visual representation of 25 // the given Terraform graph. 26 func GraphDot(g *Graph, opts *GraphDotOpts) string { 27 buf := new(bytes.Buffer) 28 29 // Start the graph 30 buf.WriteString("digraph {\n") 31 buf.WriteString("\tcompound = true;\n") 32 33 // Go through all the vertices and draw it 34 vertices := g.Vertices() 35 dotVertices := make(map[dag.Vertex]struct{}, len(vertices)) 36 for _, v := range vertices { 37 if dn, ok := v.(GraphNodeDotter); !ok { 38 continue 39 } else if dn.Dot("fake") == "" { 40 continue 41 } 42 43 dotVertices[v] = struct{}{} 44 } 45 46 for v, _ := range dotVertices { 47 dn := v.(GraphNodeDotter) 48 scanner := bufio.NewScanner(strings.NewReader( 49 dn.Dot(dag.VertexName(v)))) 50 for scanner.Scan() { 51 buf.WriteString("\t" + scanner.Text() + "\n") 52 } 53 54 // Draw all the edges 55 for _, t := range g.DownEdges(v).List() { 56 target := t.(dag.Vertex) 57 if _, ok := dotVertices[target]; !ok { 58 continue 59 } 60 61 buf.WriteString(fmt.Sprintf( 62 "\t\"%s\" -> \"%s\";\n", 63 dag.VertexName(v), 64 dag.VertexName(target))) 65 } 66 } 67 68 // End the graph 69 buf.WriteString("}\n") 70 return buf.String() 71 }