opentofu/terraform/transform_expand.go
2015-02-19 12:07:57 -08:00

70 lines
1.7 KiB
Go

package terraform
import (
"fmt"
"github.com/hashicorp/terraform/dag"
)
// GraphNodeExapndable is an interface that nodes can implement to
// signal that they can be expanded. Expanded nodes turn into
// GraphNodeSubgraph nodes within the graph.
type GraphNodeExpandable interface {
Expand(GraphBuilder) (*Graph, error)
}
// GraphNodeDynamicExpandable is an interface that nodes can implement
// to signal that they can be expanded at eval-time (hence dynamic).
// These nodes are given the eval context and are expected to return
// a new subgraph.
type GraphNodeDynamicExpandable interface {
DynamicExpand(EvalContext) (*Graph, error)
}
// GraphNodeSubgraph is an interface a node can implement if it has
// a larger subgraph that should be walked.
type GraphNodeSubgraph interface {
Subgraph() *Graph
}
// ExpandTransform is a transformer that does a subgraph expansion
// at graph transform time (vs. at eval time). The benefit of earlier
// subgraph expansion is that errors with the graph build can be detected
// at an earlier stage.
type ExpandTransform struct {
Builder GraphBuilder
}
func (t *ExpandTransform) Transform(v dag.Vertex) (dag.Vertex, error) {
ev, ok := v.(GraphNodeExpandable)
if !ok {
// This isn't an expandable vertex, so just ignore it.
return v, nil
}
// Expand the subgraph!
g, err := ev.Expand(t.Builder)
if err != nil {
return nil, err
}
// Replace with our special node
return &graphNodeExpanded{
Graph: g,
OriginalName: dag.VertexName(v),
}, nil
}
type graphNodeExpanded struct {
Graph *Graph
OriginalName string
}
func (n *graphNodeExpanded) Name() string {
return fmt.Sprintf("%s (expanded)", n.OriginalName)
}
func (n *graphNodeExpanded) Subgraph() *Graph {
return n.Graph
}