mirror of https://github.com/jlelse/GoBlog
60 lines
1.4 KiB
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
|
|
}
|