diff --git a/dag/graph.go b/dag/graph.go index 5178648d2..b271339ba 100644 --- a/dag/graph.go +++ b/dag/graph.go @@ -177,6 +177,47 @@ func (g *Graph) Connect(edge Edge) { s.Add(source) } +// String outputs some human-friendly output for the graph structure. +func (g *Graph) StringWithNodeTypes() string { + var buf bytes.Buffer + + // Build the list of node names and a mapping so that we can more + // easily alphabetize the output to remain deterministic. + vertices := g.Vertices() + names := make([]string, 0, len(vertices)) + mapping := make(map[string]Vertex, len(vertices)) + for _, v := range vertices { + name := VertexName(v) + names = append(names, name) + mapping[name] = v + } + sort.Strings(names) + + // Write each node in order... + for _, name := range names { + v := mapping[name] + targets := g.downEdges[hashcode(v)] + + buf.WriteString(fmt.Sprintf("%s - %T\n", name, v)) + + // Alphabetize dependencies + deps := make([]string, 0, targets.Len()) + targetNodes := make([]Vertex, 0, targets.Len()) + for _, target := range targets.List() { + deps = append(deps, VertexName(target)) + targetNodes = append(targetNodes, target) + } + sort.Strings(deps) + + // Write dependencies + for i, d := range deps { + buf.WriteString(fmt.Sprintf(" %s - %T\n", d, targetNodes[i])) + } + } + + return buf.String() +} + // String outputs some human-friendly output for the graph structure. func (g *Graph) String() string { var buf bytes.Buffer diff --git a/terraform/graph_builder.go b/terraform/graph_builder.go index 17a18011c..abc9aca37 100644 --- a/terraform/graph_builder.go +++ b/terraform/graph_builder.go @@ -32,7 +32,7 @@ func (b *BasicGraphBuilder) Build(path []string) (*Graph, error) { log.Printf( "[TRACE] Graph after step %T:\n\n%s", - step, g.String()) + step, g.StringWithNodeTypes()) } // Validate the graph structure