Skip to content

Commit e13be35

Browse files
authored
Merge pull request #2 from dmcgowan/cleanup-plugin-interface
Cleanup plugin interface
2 parents 832b974 + 024f6f8 commit e13be35

2 files changed

Lines changed: 44 additions & 20 deletions

File tree

context.go

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,6 @@ func NewContext(ctx context.Context, plugins *Set, properties map[string]string)
5151
}
5252
}
5353

54-
// Get returns the first plugin by its type
55-
func (i *InitContext) Get(t Type) (interface{}, error) {
56-
return i.plugins.Get(t)
57-
}
58-
5954
// Meta contains information gathered from the registration and initialization
6055
// process.
6156
type Meta struct {
@@ -119,19 +114,41 @@ func (ps *Set) Add(p *Plugin) error {
119114
return nil
120115
}
121116

122-
// Get returns the first plugin by its type
123-
func (ps *Set) Get(t Type) (interface{}, error) {
124-
for _, v := range ps.byTypeAndID[t] {
125-
return v.Instance()
117+
// Get returns the plugin with the given type and id
118+
func (ps *Set) Get(t Type, id string) *Plugin {
119+
p, ok := ps.byTypeAndID[t]
120+
if !ok {
121+
return nil
126122
}
127-
return nil, fmt.Errorf("no plugins registered for %s: %w", t, ErrPluginNotFound)
123+
return p[id]
128124
}
129125

130126
// GetAll returns all initialized plugins
131127
func (ps *Set) GetAll() []*Plugin {
132128
return ps.ordered
133129
}
134130

131+
// GetSingle returns a plugin instance of the given type when only a single instance
132+
// of that type is expected. Throws an ErrPluginNotFound if no plugin is found and
133+
// ErrPluginMultipleInstances when multiple instances are found.
134+
// Since plugins are not ordered, if multiple instances is suported then
135+
// GetByType should be used. If only one is expected, then to switch plugins,
136+
// disable or remove the unused plugins of the same type.
137+
func (i *InitContext) GetSingle(t Type) (interface{}, error) {
138+
pt, ok := i.plugins.byTypeAndID[t]
139+
if !ok || len(pt) == 0 {
140+
return nil, fmt.Errorf("no plugins registered for %s: %w", t, ErrPluginNotFound)
141+
}
142+
if len(pt) > 1 {
143+
return nil, fmt.Errorf("multiple plugins registered for %s: %w", t, ErrPluginMultipleInstances)
144+
}
145+
var p *Plugin
146+
for _, v := range pt {
147+
p = v
148+
}
149+
return p.Instance()
150+
}
151+
135152
// Plugins returns plugin set
136153
func (i *InitContext) Plugins() *Set {
137154
return i.plugins
@@ -144,23 +161,28 @@ func (i *InitContext) GetAll() []*Plugin {
144161

145162
// GetByID returns the plugin of the given type and ID
146163
func (i *InitContext) GetByID(t Type, id string) (interface{}, error) {
147-
ps, err := i.GetByType(t)
148-
if err != nil {
149-
return nil, err
150-
}
151-
p, ok := ps[id]
152-
if !ok {
153-
return nil, fmt.Errorf("no %s plugins with id %s: %w", t, id, ErrPluginNotFound)
164+
p := i.plugins.Get(t, id)
165+
if p == nil {
166+
return nil, fmt.Errorf("no plugins registered for %s.%s: %w", t, id, ErrPluginNotFound)
154167
}
155168
return p.Instance()
156169
}
157170

158171
// GetByType returns all plugins with the specific type.
159-
func (i *InitContext) GetByType(t Type) (map[string]*Plugin, error) {
160-
p, ok := i.plugins.byTypeAndID[t]
172+
func (i *InitContext) GetByType(t Type) (map[string]interface{}, error) {
173+
pt, ok := i.plugins.byTypeAndID[t]
161174
if !ok {
162175
return nil, fmt.Errorf("no plugins registered for %s: %w", t, ErrPluginNotFound)
163176
}
164177

165-
return p, nil
178+
pi := make(map[string]interface{}, len(pt))
179+
for id, p := range pt {
180+
i, err := p.Instance()
181+
if err != nil {
182+
return nil, err
183+
}
184+
pi[id] = i
185+
}
186+
187+
return pi, nil
166188
}

plugin.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ var (
3737
ErrPluginInitialized = errors.New("plugin: already initialized")
3838
// ErrPluginNotFound is used when a plugin is looked up but not found
3939
ErrPluginNotFound = errors.New("plugin: not found")
40+
// ErrPluginMultipleInstances is used when a plugin is expected a single instance but has multiple
41+
ErrPluginMultipleInstances = errors.New("plugin: multiple instances")
4042

4143
// ErrInvalidRequires will be thrown if the requirements for a plugin are
4244
// defined in an invalid manner.

0 commit comments

Comments
 (0)