terraform: Diff.String

This commit is contained in:
Mitchell Hashimoto 2014-06-10 11:22:32 -07:00
parent 061d96a08b
commit 32afc6dc70
4 changed files with 71 additions and 34 deletions

View File

@ -1,21 +1,58 @@
package terraform package terraform
import ( import (
"bytes"
"fmt"
"sort"
"sync" "sync"
) )
// Diff tracks the differences between resources to apply. // Diff tracks the differences between resources to apply.
type Diff struct { type Diff struct {
Resources map[string]map[string]*ResourceAttrDiff Resources map[string]*ResourceDiff
once sync.Once once sync.Once
} }
func (d *Diff) init() { func (d *Diff) init() {
d.once.Do(func() { d.once.Do(func() {
d.Resources = make(map[string]map[string]*ResourceAttrDiff) if d.Resources == nil {
d.Resources = make(map[string]*ResourceDiff)
}
}) })
} }
// String outputs the diff in a long but command-line friendly output
// format that users can read to quickly inspect a diff.
func (d *Diff) String() string {
var buf bytes.Buffer
names := make([]string, 0, len(d.Resources))
for name, _ := range d.Resources {
names = append(names, name)
}
sort.Strings(names)
for _, name := range names {
buf.WriteString(name + "\n")
rdiff := d.Resources[name]
for attrK, attrDiff := range rdiff.Attributes {
v := attrDiff.New
if attrDiff.NewComputed {
v = "<computed>"
}
buf.WriteString(fmt.Sprintf(
" %s: %#v => %#v\n",
attrK,
attrDiff.Old,
v))
}
}
return buf.String()
}
// ResourceDiff is the diff of a resource from some state to another. // ResourceDiff is the diff of a resource from some state to another.
type ResourceDiff struct { type ResourceDiff struct {
Attributes map[string]*ResourceAttrDiff Attributes map[string]*ResourceAttrDiff

View File

@ -1,37 +1,37 @@
package terraform package terraform
import ( import (
"bytes" "strings"
"fmt" "testing"
"sort"
) )
func testDiffStr(d *Diff) string { func TestDiff_String(t *testing.T) {
var buf bytes.Buffer diff := &Diff{
Resources: map[string]*ResourceDiff{
names := make([]string, len(d.Resources)) "nodeA": &ResourceDiff{
for n, _ := range d.Resources { Attributes: map[string]*ResourceAttrDiff{
names = append(names, n) "foo": &ResourceAttrDiff{
} Old: "foo",
sort.Strings(names) New: "bar",
},
for _, n := range names { "bar": &ResourceAttrDiff{
r := d.Resources[n] Old: "foo",
buf.WriteString(fmt.Sprintf("%s\n", n)) NewComputed: true,
for attr, attrDiff := range r { },
v := attrDiff.New },
if attrDiff.NewComputed { },
v = "<computed>" },
}
buf.WriteString(fmt.Sprintf(
" %s: %#v => %#v\n",
attr,
attrDiff.Old,
v,
))
}
} }
return buf.String() actual := strings.TrimSpace(diff.String())
expected := strings.TrimSpace(diffStrBasic)
if actual != expected {
t.Fatalf("bad:\n%s", actual)
}
} }
const diffStrBasic = `
nodeA
foo: "foo" => "bar"
bar: "foo" => "<computed>"
`

View File

@ -163,7 +163,7 @@ func (t *Terraform) diffWalkFn(
defer l.Unlock() defer l.Unlock()
// Update the resulting diff // Update the resulting diff
result.Resources[r.Id()] = diff.Attributes result.Resources[r.Id()] = diff
// Determine the new state and update variables // Determine the new state and update variables
rs = rs.MergeDiff(diff.Attributes, ComputedPlaceholder) rs = rs.MergeDiff(diff.Attributes, ComputedPlaceholder)

View File

@ -195,7 +195,7 @@ func TestTerraformDiff(t *testing.T) {
t.Fatalf("bad: %#v", diff.Resources) t.Fatalf("bad: %#v", diff.Resources)
} }
actual := strings.TrimSpace(testDiffStr(diff)) actual := strings.TrimSpace(diff.String())
expected := strings.TrimSpace(testTerraformDiffStr) expected := strings.TrimSpace(testTerraformDiffStr)
if actual != expected { if actual != expected {
t.Fatalf("bad:\n%s", actual) t.Fatalf("bad:\n%s", actual)
@ -226,7 +226,7 @@ func TestTerraformDiff_computed(t *testing.T) {
t.Fatalf("bad: %#v", diff.Resources) t.Fatalf("bad: %#v", diff.Resources)
} }
actual := strings.TrimSpace(testDiffStr(diff)) actual := strings.TrimSpace(diff.String())
expected := strings.TrimSpace(testTerraformDiffComputedStr) expected := strings.TrimSpace(testTerraformDiffComputedStr)
if actual != expected { if actual != expected {
t.Fatalf("bad:\n%s", actual) t.Fatalf("bad:\n%s", actual)