GoBlog/pkgs/plugins/plugin.go

60 lines
1.4 KiB
Go

package plugins
import (
"fmt"
"path/filepath"
"reflect"
"github.com/traefik/yaegi/interp"
"github.com/traefik/yaegi/stdlib"
)
type plugin struct {
Config *PluginConfig
plugin reflect.Value
}
// PluginConfig is the configuration of the plugin.
type PluginConfig struct {
// Path is the storage path of the plugin.
Path string
// ImportPath is the module path i.e. "github.com/user/module".
ImportPath string
// PluginType is the type of plugin, this plugin is checked against that type.
// The available types are specified by the implementor of this package.
PluginType string
}
func (p *plugin) initPlugin(host *PluginHost) error {
const errText = "initPlugin: %w"
interpreter := interp.New(interp.Options{
GoPath: p.Config.Path,
})
if err := interpreter.Use(stdlib.Symbols); err != nil {
return fmt.Errorf(errText, err)
}
if err := interpreter.Use(host.Symbols); err != nil {
return fmt.Errorf(errText, err)
}
if _, err := interpreter.Eval(fmt.Sprintf(`import "%s"`, p.Config.ImportPath)); err != nil {
return fmt.Errorf(errText, err)
}
v, err := interpreter.Eval(filepath.Base(p.Config.ImportPath) + ".GetPlugin")
if err != nil {
return fmt.Errorf(errText, err)
}
result := v.Call([]reflect.Value{})
if len(result) > 1 {
return fmt.Errorf(errText+": function GetPlugin has more than one return value", ErrValidatingPlugin)
}
p.plugin = result[0]
return nil
}