-
Notifications
You must be signed in to change notification settings - Fork 0
/
loader.go
87 lines (70 loc) · 1.62 KB
/
loader.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package build
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/micro/go-micro/v2/plugin"
"golang.org/x/tools/go/packages"
)
func buildSo(soPath string, parts []string) error {
// check if .so file exists
if _, err := os.Stat(soPath); os.IsExist(err) {
return nil
}
path := filepath.Join(append([]string{"github.com/micro/go-plugins"}, parts...)...)
pkgs, err := packages.Load(&packages.Config{Mode: packages.NeedName}, path)
if err != nil {
return err
}
// name and things
name := pkgs[0].Name
// type of plugin
typ := parts[0]
// new func signature
newfn := fmt.Sprintf("New%s", strings.Title(typ))
// micro has NewPlugin type def
if typ == "micro" {
newfn = "NewPlugin"
}
// now build the plugin
if err := plugin.Build(soPath, &plugin.Config{
Name: name,
Type: typ,
Path: path,
NewFunc: newfn,
}); err != nil {
return fmt.Errorf("Failed to build plugin %s: %v", name, err)
}
return nil
}
func load(p string) error {
p = strings.TrimSpace(p)
if len(p) == 0 {
return nil
}
parts := strings.Split(p, "/")
// 1 part means local plugin
// plugin/foobar
if len(parts) == 1 {
return fmt.Errorf("Unknown plugin %s", p)
}
// set soPath to specified path
soPath := p
// build on the fly if not .so
if !strings.HasSuffix(p, ".so") {
// set new so path
soPath = filepath.Join("plugin", p+".so")
// build new .so
if err := buildSo(soPath, parts); err != nil {
return err
}
}
// load the plugin
pl, err := plugin.Load(soPath)
if err != nil {
return fmt.Errorf("Failed to load plugin %s: %v", soPath, err)
}
// Initialise the plugin
return plugin.Init(pl)
}