terraform: GraphVertexTransformers
This commit is contained in:
parent
af8d33ddb8
commit
4d205ebcf6
|
@ -1,7 +1,21 @@
|
||||||
package terraform
|
package terraform
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform/dag"
|
||||||
|
)
|
||||||
|
|
||||||
// GraphTransformer is the interface that transformers implement. This
|
// GraphTransformer is the interface that transformers implement. This
|
||||||
// interface is only for transforms that need entire graph visibility.
|
// interface is only for transforms that need entire graph visibility.
|
||||||
type GraphTransformer interface {
|
type GraphTransformer interface {
|
||||||
Transform(*Graph) error
|
Transform(*Graph) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GraphVertexTransformer is an interface that transforms a single
|
||||||
|
// Vertex within with graph. This is a specialization of GraphTransformer
|
||||||
|
// that makes it easy to do vertex replacement.
|
||||||
|
//
|
||||||
|
// The GraphTransformer that runs through the GraphVertexTransformers is
|
||||||
|
// VertexTransformer.
|
||||||
|
type GraphVertexTransformer interface {
|
||||||
|
Transform(dag.Vertex) (dag.Vertex, error)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package terraform
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/dag"
|
||||||
|
)
|
||||||
|
|
||||||
|
// VertexTransformer is a GraphTransformer that transforms vertices
|
||||||
|
// using the GraphVertexTransformers. The Transforms are run in sequential
|
||||||
|
// order. If a transform replaces a vertex then the next transform will see
|
||||||
|
// the new vertex.
|
||||||
|
type VertexTransformer struct {
|
||||||
|
Transforms []GraphVertexTransformer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *VertexTransformer) Transform(g *Graph) error {
|
||||||
|
for _, v := range g.Vertices() {
|
||||||
|
for _, vt := range t.Transforms {
|
||||||
|
newV, err := vt.Transform(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the vertex didn't change, then don't do anything more
|
||||||
|
if newV == v {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vertex changed, replace it within the graph
|
||||||
|
if ok := g.Replace(v, newV); !ok {
|
||||||
|
// This should never happen, big problem
|
||||||
|
return fmt.Errorf(
|
||||||
|
"Failed to replace %s with %s!\n\nSource: %#v\n\nTarget: %#v",
|
||||||
|
dag.VertexName(v), dag.VertexName(newV), v, newV)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace v so that future transforms use the proper vertex
|
||||||
|
v = newV
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package terraform
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/dag"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestVertexTransformer_impl(t *testing.T) {
|
||||||
|
var _ GraphTransformer = new(VertexTransformer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestVertexTransformer(t *testing.T) {
|
||||||
|
var g Graph
|
||||||
|
g.Add(1)
|
||||||
|
g.Add(2)
|
||||||
|
g.Add(3)
|
||||||
|
g.Connect(dag.BasicEdge(1, 2))
|
||||||
|
g.Connect(dag.BasicEdge(2, 3))
|
||||||
|
|
||||||
|
{
|
||||||
|
tf := &VertexTransformer{
|
||||||
|
Transforms: []GraphVertexTransformer{
|
||||||
|
&testVertexTransform{Source: 2, Target: 42},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := tf.Transform(&g); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := strings.TrimSpace(g.String())
|
||||||
|
expected := strings.TrimSpace(testVertexTransformerStr)
|
||||||
|
if actual != expected {
|
||||||
|
t.Fatalf("bad: %s", actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type testVertexTransform struct {
|
||||||
|
Source, Target dag.Vertex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *testVertexTransform) Transform(v dag.Vertex) (dag.Vertex, error) {
|
||||||
|
if t.Source == v {
|
||||||
|
v = t.Target
|
||||||
|
}
|
||||||
|
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const testVertexTransformerStr = `
|
||||||
|
1
|
||||||
|
42
|
||||||
|
3
|
||||||
|
42
|
||||||
|
3
|
||||||
|
`
|
Loading…
Reference in New Issue