3030 ErrNoType = errors .New ("plugin: no type" )
3131 // ErrNoPluginID is returned when no id is specified
3232 ErrNoPluginID = errors .New ("plugin: no id" )
33-
33+ // ErrIDRegistered is returned when a duplicate id is already registered
34+ ErrIDRegistered = errors .New ("plugin: id already registered" )
3435 // ErrSkipPlugin is used when a plugin is not initialized and should not be loaded,
3536 // this allows the plugin loader differentiate between a plugin which is configured
3637 // not to load and one that fails to load.
@@ -100,6 +101,8 @@ type Registration struct {
100101 // context are passed in. The init function may modify the registration to
101102 // add exports, capabilities and platform support declarations.
102103 InitFn func (* InitContext ) (interface {}, error )
104+ // Disable the plugin from loading
105+ Disable bool
103106}
104107
105108// Init the registered plugin
@@ -157,12 +160,16 @@ func Load(path string) (err error) {
157160func Register (r * Registration ) {
158161 register .Lock ()
159162 defer register .Unlock ()
163+
160164 if r .Type == "" {
161165 panic (ErrNoType )
162166 }
163167 if r .ID == "" {
164168 panic (ErrNoPluginID )
165169 }
170+ if err := checkUnique (r ); err != nil {
171+ panic (err )
172+ }
166173
167174 var last bool
168175 for _ , requires := range r .Requires {
@@ -177,24 +184,36 @@ func Register(r *Registration) {
177184 register .r = append (register .r , r )
178185}
179186
187+ func checkUnique (r * Registration ) error {
188+ for _ , registered := range register .r {
189+ if r .URI () == registered .URI () {
190+ return errors .Wrap (ErrIDRegistered , r .URI ())
191+ }
192+ }
193+ return nil
194+ }
195+
196+ // DisableFilter filters out disabled plugins
197+ type DisableFilter func (r * Registration ) bool
198+
180199// Graph returns an ordered list of registered plugins for initialization.
181200// Plugins in disableList specified by id will be disabled.
182- func Graph (disableList [] string ) (ordered []* Registration ) {
201+ func Graph (filter DisableFilter ) (ordered []* Registration ) {
183202 register .RLock ()
184203 defer register .RUnlock ()
185- for _ , d := range disableList {
186- for i , r := range register .r {
187- if r .ID == d {
188- register .r = append (register .r [:i ], register .r [i + 1 :]... )
189- break
190- }
204+
205+ for _ , r := range register .r {
206+ if filter (r ) {
207+ r .Disable = true
191208 }
192209 }
193210
194211 added := map [* Registration ]bool {}
195212 for _ , r := range register .r {
196-
197- children (r .ID , r .Requires , added , & ordered )
213+ if r .Disable {
214+ continue
215+ }
216+ children (r , added , & ordered )
198217 if ! added [r ] {
199218 ordered = append (ordered , r )
200219 added [r ] = true
@@ -203,11 +222,13 @@ func Graph(disableList []string) (ordered []*Registration) {
203222 return ordered
204223}
205224
206- func children (id string , types [] Type , added map [* Registration ]bool , ordered * []* Registration ) {
207- for _ , t := range types {
225+ func children (reg * Registration , added map [* Registration ]bool , ordered * []* Registration ) {
226+ for _ , t := range reg . Requires {
208227 for _ , r := range register .r {
209- if r .ID != id && (t == "*" || r .Type == t ) {
210- children (r .ID , r .Requires , added , ordered )
228+ if ! r .Disable &&
229+ r .URI () != reg .URI () &&
230+ (t == "*" || r .Type == t ) {
231+ children (r , added , ordered )
211232 if ! added [r ] {
212233 * ordered = append (* ordered , r )
213234 added [r ] = true
0 commit comments