terraform: sort the modules in the state [GH-318]

This commit is contained in:
Mitchell Hashimoto 2014-10-11 12:47:06 -07:00
parent 6ddcc2ebf8
commit d2e836275b
2 changed files with 87 additions and 0 deletions

View File

@ -67,6 +67,7 @@ func (s *State) AddModule(path []string) *ModuleState {
m := &ModuleState{Path: path}
m.init()
s.Modules = append(s.Modules, m)
s.sort()
return m
}
@ -135,6 +136,11 @@ func (s *State) prune() {
}
}
// sort sorts the modules
func (s *State) sort() {
sort.Sort(moduleStateSort(s.Modules))
}
func (s *State) GoString() string {
return fmt.Sprintf("*%#v", *s)
}
@ -619,11 +625,18 @@ func ReadState(src io.Reader) (*State, error) {
return nil, fmt.Errorf("State version %d not supported, please update.",
state.Version)
}
// Sort it
state.sort()
return state, nil
}
// WriteState writes a state somewhere in a binary format.
func WriteState(d *State, dst io.Writer) error {
// Make sure it is sorted
d.sort()
// Ensure the version is set
d.Version = textStateVersion
@ -682,3 +695,28 @@ func upgradeV1State(old *StateV1) (*State, error) {
}
return s, nil
}
// moduleStateSort implements sort.Interface to sort module states
type moduleStateSort []*ModuleState
func (s moduleStateSort) Len() int {
return len(s)
}
func (s moduleStateSort) Less(i, j int) bool {
a := s[i]
b := s[j]
// If the lengths are different, then the shorter one always wins
if len(a.Path) != len(b.Path) {
return len(a.Path) < len(b.Path)
}
// Otherwise, compare by last path element
idx := len(a.Path) - 1
return a.Path[idx] < b.Path[idx]
}
func (s moduleStateSort) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}

View File

@ -10,6 +10,55 @@ import (
"github.com/hashicorp/terraform/config"
)
func TestStateAddModule(t *testing.T) {
cases := []struct{
In [][]string
Out [][]string
}{
{
[][]string{
[]string{"root"},
[]string{"root", "child"},
},
[][]string{
[]string{"root"},
[]string{"root", "child"},
},
},
{
[][]string{
[]string{"root", "foo", "bar"},
[]string{"root", "foo"},
[]string{"root"},
[]string{"root", "bar"},
},
[][]string{
[]string{"root"},
[]string{"root", "bar"},
[]string{"root", "foo"},
[]string{"root", "foo", "bar"},
},
},
}
for _, tc := range cases {
s := new(State)
for _, p := range tc.In {
s.AddModule(p)
}
actual := make([][]string, 0, len(tc.In))
for _, m := range s.Modules {
actual = append(actual, m.Path)
}
if !reflect.DeepEqual(actual, tc.Out) {
t.Fatalf("In: %#v\n\nOut: %#v", tc.In, actual)
}
}
}
func TestInstanceState_MergeDiff(t *testing.T) {
is := InstanceState{
ID: "foo",