-
-
Notifications
You must be signed in to change notification settings - Fork 564
/
Copy pathplugin.go
126 lines (116 loc) Β· 4.07 KB
/
plugin.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package codegen
import "goa.design/goa/eval"
type (
// GenerateFunc makes it possible to modify the files generated by the
// goa code generators and other plugins. A GenerateFunc accepts the Go
// import path of the "gen" package, the design roots as well as the
// currently generated files (produced initially by the goa generators
// and potentially modified by previously run plugins) and returns a new
// set of files.
GenerateFunc func(genpkg string, roots []eval.Root, files []*File) ([]*File, error)
// PrepareFunc makes it possible to modify the design roots before
// the files being generated by the goa code generators or other plugins.
PrepareFunc func(genpkg string, roots []eval.Root) error
// plugin is a plugin that has been registered with a given command.
plugin struct {
// PrepareFunc is the plugin preparation function.
PrepareFunc
// GenerateFunc is the plugin generator function.
GenerateFunc
// name is the plugin name.
name string
// cmd is the name of cmd to run.
cmd string
// if first is set the plugin cmd must run before all other plugins.
first bool
// if last is set the plugin cmd must run after all other plugins.
last bool
}
)
// plugins keeps track of the registered plugins sorted by their first/last bools,
// names, or registration order.
var plugins []*plugin
// RegisterPlugin adds the plugin to the list of plugins to be invoked with the
// given command.
func RegisterPlugin(name string, cmd string, pre PrepareFunc, p GenerateFunc) {
np := &plugin{name: name, PrepareFunc: pre, GenerateFunc: p, cmd: cmd}
var inserted bool
for i, plgn := range plugins {
if plgn.last || (!plgn.first && np.name < plgn.name) {
plugins = append(plugins[:i], append([]*plugin{np}, plugins[i:]...)...)
inserted = true
break
}
}
if !inserted {
plugins = append(plugins, np)
}
}
// RegisterPluginFirst adds the plugin to the beginning of the list of plugins
// to be invoked with the given command. If more than one plugins are registered
// using this, the plugins will be sorted alphabetically by their names. If two
// plugins have same names, then they are sorted by registration order.
func RegisterPluginFirst(name string, cmd string, pre PrepareFunc, p GenerateFunc) {
np := &plugin{name: name, PrepareFunc: pre, GenerateFunc: p, cmd: cmd, first: true}
var inserted bool
for i, plgn := range plugins {
if !plgn.first || np.name < plgn.name {
plugins = append(plugins[:i], append([]*plugin{np}, plugins[i:]...)...)
inserted = true
break
}
}
if !inserted {
plugins = append(plugins, np)
}
}
// RegisterPluginLast adds the plugin to the end of the list of plugins
// to be invoked with the given command. If more than one plugins are registered
// using this, the plugins will be sorted alphabetically by their names. If two
// plugins have same names, then they are sorted by registration order.
func RegisterPluginLast(name string, cmd string, pre PrepareFunc, p GenerateFunc) {
np := &plugin{name: name, PrepareFunc: pre, GenerateFunc: p, cmd: cmd, last: true}
var inserted bool
for i := len(plugins) - 1; i >= 0; i-- {
plgn := plugins[i]
if !plgn.last || plgn.name < np.name {
plugins = append(plugins[:i+1], append([]*plugin{np}, plugins[i+1:]...)...)
inserted = true
break
}
}
if !inserted {
plugins = append(plugins, np)
}
}
// RunPluginsPrepare executes the plugins prepare functions in the order
// they were registered.
func RunPluginsPrepare(cmd, genpkg string, roots []eval.Root) error {
for _, plugin := range plugins {
if plugin.cmd != cmd {
continue
}
if plugin.PrepareFunc != nil {
err := plugin.PrepareFunc(genpkg, roots)
if err != nil {
return err
}
}
}
return nil
}
// RunPlugins executes the plugins registered with the given command in the order
// they were registered.
func RunPlugins(cmd, genpkg string, roots []eval.Root, genfiles []*File) ([]*File, error) {
for _, plugin := range plugins {
if plugin.cmd != cmd {
continue
}
gs, err := plugin.GenerateFunc(genpkg, roots, genfiles)
if err != nil {
return nil, err
}
genfiles = gs
}
return genfiles, nil
}