-// ModuleOrphans returns all the module orphans in this state by
-// returning their full paths. These paths can be used with ModuleByPath
-// to return the actual state.
-func (s *State) ModuleOrphans(path []string, c *config.Config) [][]string {
- s.Lock()
- defer s.Unlock()
-
- return s.moduleOrphans(path, c)
-
-}
-
-func (s *State) moduleOrphans(path []string, c *config.Config) [][]string {
- // direct keeps track of what direct children we have both in our config
- // and in our state. childrenKeys keeps track of what isn't an orphan.
- direct := make(map[string]struct{})
- childrenKeys := make(map[string]struct{})
- if c != nil {
- for _, m := range c.Modules {
- childrenKeys[m.Name] = struct{}{}
- direct[m.Name] = struct{}{}
- }
- }
-
- // Go over the direct children and find any that aren't in our keys.
- var orphans [][]string
- for _, m := range s.children(path) {
- key := m.Path[len(m.Path)-1]
-
- // Record that we found this key as a direct child. We use this
- // later to find orphan nested modules.
- direct[key] = struct{}{}
-
- // If we have a direct child still in our config, it is not an orphan
- if _, ok := childrenKeys[key]; ok {
- continue
- }
-
- orphans = append(orphans, m.Path)
- }
-
- // Find the orphans that are nested...
- for _, m := range s.Modules {
- if m == nil {
- continue
- }
-
- // We only want modules that are at least grandchildren
- if len(m.Path) < len(path)+2 {
- continue
- }
-
- // If it isn't part of our tree, continue
- if !reflect.DeepEqual(path, m.Path[:len(path)]) {
- continue
- }
-
- // If we have the direct child, then just skip it.
- key := m.Path[len(path)]
- if _, ok := direct[key]; ok {
- continue
- }
-
- orphanPath := m.Path[:len(path)+1]
-
- // Don't double-add if we've already added this orphan (which can happen if
- // there are multiple nested sub-modules that get orphaned together).
- alreadyAdded := false
- for _, o := range orphans {
- if reflect.DeepEqual(o, orphanPath) {
- alreadyAdded = true
- break
- }
- }
- if alreadyAdded {
- continue
- }
-
- // Add this orphan
- orphans = append(orphans, orphanPath)
- }
-
- return orphans
-}
-