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