terraform: sort the modules in the state [GH-318]
This commit is contained in:
parent
6ddcc2ebf8
commit
d2e836275b
|
@ -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]
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue