plugins
packageAPI reference for the plugins
package.
Imports
(4)Plugin
Plugin defines the minimal interface that build plugins must implement.
type Plugin interface
Methods
PreBuilder
PreBuilder is implemented by plugins that run before the build.
type PreBuilder interface
Methods
Builder
Builder is implemented by plugins that participate in the build step.
type Builder interface
Methods
PostBuilder
PostBuilder is implemented by plugins that run after the build completes.
type PostBuilder interface
Methods
entry
type entry struct
Fields
| Name | Type | Description |
|---|---|---|
| Plugin | Plugin | |
| cfg | json.RawMessage |
Uses
Info
Info reports the name and configuration of an active plugin.
type Info struct
Fields
| Name | Type | Description |
|---|---|---|
| Name | string | json:"name" |
| Config | json.RawMessage | json:"config" |
Active
Active returns the list of configured plugins in execution order.
Returns
func Active() []Info
{
out := make([]Info, len(active))
for i, e := range active {
out[i] = Info{Name: e.Plugin.Name(), Config: e.cfg}
}
return out
}
Register
Register adds a plugin to the registry.
Parameters
func Register(p Plugin)
{ registry[p.Name()] = p }
Uses
Install
Install activates a single plugin by name.
Parameters
Returns
func Install(name string, raw json.RawMessage) error
{
if p, ok := registry[name]; ok {
active = append(active, entry{Plugin: p, cfg: raw})
return nil
}
return fmt.Errorf("plugin %s not found", name)
}
Configure
Configure installs plugins from the provided configuration map.
Parameters
Returns
func Configure(cfg map[string]json.RawMessage) error
{
active = active[:0]
for name, raw := range cfg {
if err := Install(name, raw); err != nil {
return err
}
}
sort.SliceStable(active, func(i, j int) bool {
return active[i].Plugin.Priority() < active[j].Plugin.Priority()
})
return nil
}
NeedsRebuild
NeedsRebuild reports whether any active plugin requires a rebuild for the given path.
Parameters
Returns
func NeedsRebuild(path string) bool
{
for _, e := range active {
if e.Plugin.ShouldRebuild(path) {
return true
}
}
return false
}
PreBuild
PreBuild calls PreBuild on all plugins that implement PreBuilder.
Returns
func PreBuild() error
{
for _, e := range active {
if pb, ok := e.Plugin.(PreBuilder); ok {
if err := pb.PreBuild(e.cfg); err != nil {
return fmt.Errorf("%s prebuild: %w", e.Plugin.Name(), err)
}
}
}
return nil
}
Build
Build calls Build on all plugins that implement Builder.
Returns
func Build() error
{
for _, e := range active {
if b, ok := e.Plugin.(Builder); ok {
if err := b.Build(e.cfg); err != nil {
return fmt.Errorf("%s build: %w", e.Plugin.Name(), err)
}
}
}
return nil
}
PostBuild
PostBuild calls PostBuild on all plugins that implement PostBuilder.
Returns
func PostBuild() error
{
for _, e := range active {
if pb, ok := e.Plugin.(PostBuilder); ok {
if err := pb.PostBuild(e.cfg); err != nil {
return fmt.Errorf("%s postbuild: %w", e.Plugin.Name(), err)
}
}
}
return nil
}
mockPlugin
mockPlugin is a simple implementation of the Plugin interface used for
testing the plugin registry and lifecycle.
type mockPlugin struct
Methods
Parameters
Returns
func (*mockPlugin) ShouldRebuild(p string) bool
{ return p == m.rebuild }
Parameters
Returns
func (*mockPlugin) PreBuild(json.RawMessage) error
{
m.pre = true
return nil
}
Parameters
Returns
func (*mockPlugin) Build(json.RawMessage) error
{
m.build = true
return nil
}
Parameters
Returns
func (*mockPlugin) PostBuild(json.RawMessage) error
{
m.post = true
return nil
}
Fields
| Name | Type | Description |
|---|---|---|
| name | string | |
| priority | int | |
| rebuild | string | |
| pre | bool | |
| build | bool | |
| post | bool |
TestLifecycle
TestLifecycle verifies registration, ordering and lifecycle invocation of
plugins as well as the NeedsRebuild helper.
Parameters
func TestLifecycle(t *testing.T)
{
// Reset global state.
registry = map[string]Plugin{}
active = nil
p1 := &mockPlugin{name: "p1", priority: 1, rebuild: "a.go"}
p0 := &mockPlugin{name: "p0", priority: 0}
Register(p1)
Register(p0)
cfg := map[string]json.RawMessage{"p1": nil, "p0": nil}
if err := Configure(cfg); err != nil {
t.Fatalf("configure: %v", err)
}
if len(active) != 2 || active[0].Plugin != p0 || active[1].Plugin != p1 {
t.Fatalf("plugins not sorted by priority: %#v", active)
}
if err := PreBuild(); err != nil {
t.Fatalf("prebuild: %v", err)
}
if !p1.pre || !p0.pre {
t.Fatalf("prebuild not invoked")
}
if err := Build(); err != nil {
t.Fatalf("build: %v", err)
}
if !p1.build || !p0.build {
t.Fatalf("build not invoked")
}
if err := PostBuild(); err != nil {
t.Fatalf("postbuild: %v", err)
}
if !p1.post || !p0.post {
t.Fatalf("postbuild not invoked")
}
if !NeedsRebuild("a.go") {
t.Fatalf("expected rebuild for a.go")
}
if NeedsRebuild("b.go") {
t.Fatalf("unexpected rebuild for b.go")
}
}
TestActive
Parameters
func TestActive(t *testing.T)
{
registry = map[string]Plugin{}
active = nil
p := &mockPlugin{name: "p", priority: 0}
Register(p)
cfg := map[string]json.RawMessage{"p": json.RawMessage("{\"x\":1}")}
if err := Configure(cfg); err != nil {
t.Fatalf("configure: %v", err)
}
list := Active()
if len(list) != 1 || list[0].Name != "p" || string(list[0].Config) != "{\"x\":1}" {
t.Fatalf("unexpected active list: %#v", list)
}
}