terraform: ExpandTransform
This commit is contained in:
parent
4d205ebcf6
commit
e5fd7c9e84
|
@ -0,0 +1,61 @@
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package terraform
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/dag"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestExpandTransform_impl(t *testing.T) {
|
||||||
|
var _ GraphVertexTransformer = new(ExpandTransform)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExpandTransform(t *testing.T) {
|
||||||
|
var g Graph
|
||||||
|
g.Add(1)
|
||||||
|
g.Add(2)
|
||||||
|
g.Connect(dag.BasicEdge(1, 2))
|
||||||
|
|
||||||
|
tf := &ExpandTransform{}
|
||||||
|
out, err := tf.Transform(&testExpandable{
|
||||||
|
Result: &g,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sn, ok := out.(GraphNodeSubgraph)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("not subgraph: %#v", out)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := strings.TrimSpace(sn.Subgraph().String())
|
||||||
|
expected := strings.TrimSpace(testExpandTransformStr)
|
||||||
|
if actual != expected {
|
||||||
|
t.Fatalf("bad: %s", actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExpandTransform_nonExpandable(t *testing.T) {
|
||||||
|
tf := &ExpandTransform{}
|
||||||
|
out, err := tf.Transform(42)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
if out != 42 {
|
||||||
|
t.Fatalf("bad: %#v", out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type testExpandable struct {
|
||||||
|
// Inputs
|
||||||
|
Result *Graph
|
||||||
|
ResultError error
|
||||||
|
|
||||||
|
// Outputs
|
||||||
|
Builder GraphBuilder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *testExpandable) Expand(b GraphBuilder) (*Graph, error) {
|
||||||
|
n.Builder = b
|
||||||
|
return n.Result, n.ResultError
|
||||||
|
}
|
||||||
|
|
||||||
|
const testExpandTransformStr = `
|
||||||
|
1
|
||||||
|
2
|
||||||
|
2
|
||||||
|
`
|
Loading…
Reference in New Issue