@@ -112,34 +112,44 @@ type Registry []*Registration
112112// Graph computes the ordered list of registrations based on their dependencies,
113113// filtering out any plugins which match the provided filter.
114114func (registry Registry ) Graph (filter DisableFilter ) []Registration {
115- handled := make (map [* Registration ]bool , len (registry ))
115+ handled := make (map [* Registration ]struct {} , len (registry ))
116116 if filter != nil {
117117 for _ , r := range registry {
118118 if filter (r ) {
119- handled [r ] = true
119+ handled [r ] = struct {}{}
120120 }
121121 }
122122 }
123123
124124 ordered := make ([]Registration , 0 , len (registry )- len (handled ))
125+ stack := make ([]* Registration , 0 , cap (ordered ))
125126 for _ , r := range registry {
126- if handled [r ] {
127+ if _ , ok := handled [r ]; ok {
127128 continue
128129 }
129- handled [ r ] = true
130- children ( r , registry , handled , & ordered )
130+ children ( append ( stack , r ), registry , handled , & ordered )
131+ handled [ r ] = struct {}{}
131132 ordered = append (ordered , * r )
132133 }
133134 return ordered
134135}
135136
136- func children (reg * Registration , registry []* Registration , handled map [* Registration ]bool , ordered * []Registration ) {
137+ func children (stack []* Registration , registry []* Registration , handled map [* Registration ]struct {}, ordered * []Registration ) {
138+ reg := stack [len (stack )- 1 ]
137139 for _ , t := range reg .Requires {
138140 for _ , r := range registry {
139- if (t == "*" || r .Type == t ) && r != reg && ! handled [r ] {
140- handled [r ] = true
141- children (r , registry , handled , ordered )
142- * ordered = append (* ordered , * r )
141+ if (t == "*" || r .Type == t ) && r != reg {
142+ if _ , ok := handled [r ]; ! ok {
143+ // Ensure not in current stack
144+ for _ , p := range stack [:len (stack )- 1 ] {
145+ if p == r {
146+ panic (fmt .Errorf ("circular plugin dependency at %s: %w" , r .URI (), ErrPluginCircularDependency ))
147+ }
148+ }
149+ children (append (stack , r ), registry , handled , ordered )
150+ handled [r ] = struct {}{}
151+ * ordered = append (* ordered , * r )
152+ }
143153 }
144154 }
145155 }
0 commit comments