Repository: opentofu/opentofu
File: internal/dag/dot.go (Go)

Code before:

	// use this to keep the cluster_ naming convention from the previous dot writer
	cluster bool
}

// 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 first parameter is the title of the node.
	// The second parameter includes user-specified options that affect the dot
	// graph. See GraphDotOpts below for details.
	DotNode(string, *DotOpts) *DotNode
}

// DotNode provides a structure for Vertices to return in order to specify their
// dot format.
type DotNode struct {
	Name  string
	Attrs map[string]string
}

// Returns the DOT representation of this Graph.
//
//nolint:errcheck // writing to the buffer does not produce an error
func (g *marshalGraph) Dot(opts *DotOpts) []byte {
	if opts == nil {
		opts = &DotOpts{
			DrawCycles: true,
			MaxDepth:   -1,
			Verbose:    true,
		}
	}

	var w indentWriter
	w.WriteString("digraph {\n")
	w.Indent()

	// some dot defaults
	w.WriteString(`compound = "true"` + "\n")
	w.WriteString(`newrank = "true"` + "\n")

	// the top level graph is written as the first subgraph
	w.WriteString(`subgraph "root" {` + "\n")
	g.writeBody(opts, &w)

	// cluster isn't really used other than for naming purposes in some graphs
	opts.cluster = opts.MaxDepth != 0
	maxDepth := opts.MaxDepth
	if maxDepth == 0 {

Review comment (bug):
Another nit and a personal preference.
I generally prefer not to ignore rules for entire methods.

We are only ignoring rules in this file, because `indentWrite.WriteString`(Which is only used here) returns an unnecessary error, which we always ignore (in 9 different places). So what if we wrap that function, ignore errors there, and use it instead?

Something like this
```go

// writeString is a helper function to write a string to the indentWriter without the need for handling errors.
// the errors are ignored here because writing to a bytes.Buffer should never fail
func writeString(w *indentWriter, s string) {
	_, _ = w.WriteString(s)
}
```
```go
writeString(&w, `compound = "true"`+"\n")
```

This would completely negate the need for the *nolint* comments, except one `w.Write`, which we can ignore with simple Go syntax.

Code after:

	// use this to keep the cluster_ naming convention from the previous dot writer
	cluster bool
}

// 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 first parameter is the title of the node.
	// The second parameter includes user-specified options that affect the dot
	// graph. See GraphDotOpts below for details.
	DotNode(string, *DotOpts) *DotNode
}

// DotNode provides a structure for Vertices to return in order to specify their
// dot format.
type DotNode struct {
	Name  string
	Attrs map[string]string
}

// Returns the DOT representation of this Graph.
func (g *marshalGraph) Dot(opts *DotOpts) []byte {
	if opts == nil {
		opts = &DotOpts{
			DrawCycles: true,
			MaxDepth:   -1,
			Verbose:    true,
		}
	}

	var w indentWriter
	w.writeString("digraph {\n")
	w.Indent()

	// some dot defaults
	w.writeString(`compound = "true"` + "\n")
	w.writeString(`newrank = "true"` + "\n")

	// the top level graph is written as the first subgraph
	w.writeString(`subgraph "root" {` + "\n")
	g.writeBody(opts, &w)

	// cluster isn't really used other than for naming purposes in some graphs
	opts.cluster = opts.MaxDepth != 0
	maxDepth := opts.MaxDepth
	if maxDepth == 0 {
		maxDepth = -1
	}