opentofu/dot/graph_writer.go
Paul Hinze ce49dd6080 core: graph command gets -verbose and -draw-cycles
When you specify `-verbose` you'll get the whole graph of operations,
which gives a better idea of the operations terraform performs and in
what order.

The DOT graph is now generated with a small internal library instead of
simple string building. This allows us to ensure the graph generation is
as consistent as possible, among other benefits.

We set `newrank = true` in the graph, which I've found does just as good
a job organizing things visually as manually attempting to rank the nodes
based on depth.

This also fixes `-module-depth`, which was broken post-AST refector.
Modules are now expanded into subgraphs with labels and borders. We
have yet to regain the plan graphing functionality, so I removed that
from the docs for now.

Finally, if `-draw-cycles` is added, extra colored edges will be drawn
to indicate the path of any cycles detected in the graph.

A notable implementation change included here is that
{Reverse,}DepthFirstWalk has been made deterministic. (Before it was
dependent on `map` ordering.) This turned out to be unnecessary to gain
determinism in the final DOT-level implementation, but it seemed
a desirable enough of a property that I left it in.
2015-04-27 09:23:47 -05:00

48 lines
853 B
Go

package dot
import (
"bytes"
"fmt"
)
// graphWriter wraps a bytes.Buffer and tracks indent level levels.
type graphWriter struct {
bytes.Buffer
indent int
indentStr string
}
// Returns an initialized graphWriter at indent level 0.
func newGraphWriter() *graphWriter {
w := &graphWriter{
indent: 0,
}
w.init()
return w
}
// Prints to the buffer at the current indent level.
func (w *graphWriter) Printf(s string, args ...interface{}) {
w.WriteString(w.indentStr + fmt.Sprintf(s, args...))
}
// Increase the indent level.
func (w *graphWriter) Indent() {
w.indent++
w.init()
}
// Decrease the indent level.
func (w *graphWriter) Unindent() {
w.indent--
w.init()
}
func (w *graphWriter) init() {
indentBuf := new(bytes.Buffer)
for i := 0; i < w.indent; i++ {
indentBuf.WriteString("\t")
}
w.indentStr = indentBuf.String()
}