feat: 插件自动发现 — plugins.json + 代码生成器
- plugins.json 配置文件列出所有插件及其import路径 - gen_plugins.go 读取配置生成 plugins_gen.go - main.go 调用 registerPlugins() 替代硬编码列表 - 新增 backend/plugins/ 第三方插件目录 - 插件开发文档: docs/api/plugin-development.md Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
//go:build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type PluginEntry struct {
|
||||
Name string `json:"name"`
|
||||
Import string `json:"import"`
|
||||
Struct string `json:"struct"`
|
||||
Constructor string `json:"constructor,omitempty"`
|
||||
}
|
||||
|
||||
type PluginConfig struct {
|
||||
Version string `json:"version"`
|
||||
Plugins []PluginEntry `json:"plugins"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
data, err := os.ReadFile("../plugins.json")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "read plugins.json: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
var cfg PluginConfig
|
||||
if err := json.Unmarshal(data, &cfg); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "parse plugins.json: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var sb strings.Builder
|
||||
sb.WriteString("// Code generated by gen_plugins.go; DO NOT EDIT.\n\n")
|
||||
sb.WriteString("package main\n\n")
|
||||
sb.WriteString("import (\n")
|
||||
sb.WriteString("\tplgSDK \"git.yeij.top/AskaEth/Cyrene-Plugins/sdk\"\n")
|
||||
|
||||
aliases := make(map[string]string)
|
||||
for _, p := range cfg.Plugins {
|
||||
alias := p.Name + "pkg"
|
||||
aliases[p.Name] = alias
|
||||
sb.WriteString(fmt.Sprintf("\t%s \"%s\"\n", alias, p.Import))
|
||||
}
|
||||
|
||||
sb.WriteString(")\n\n")
|
||||
sb.WriteString("func registerPlugins(registry interface{ Register(plgSDK.Tool) error }) {\n")
|
||||
|
||||
for _, p := range cfg.Plugins {
|
||||
alias := aliases[p.Name]
|
||||
if p.Constructor != "" {
|
||||
// Plugins with constructor (e.g. NewFilePlugin(dataDir))
|
||||
if p.Name == "file_ops" || p.Name == "http_request" {
|
||||
sb.WriteString(fmt.Sprintf("\tfor _, t := range %s.%s(nil).Tools() {\n", alias, p.Constructor))
|
||||
} else {
|
||||
sb.WriteString(fmt.Sprintf("\tfor _, t := range %s.%s().Tools() {\n", alias, p.Constructor))
|
||||
}
|
||||
} else {
|
||||
sb.WriteString(fmt.Sprintf("\tfor _, t := range (&%s.%s{}).Tools() {\n", alias, p.Struct))
|
||||
}
|
||||
sb.WriteString("\t\tregistry.Register(t)\n")
|
||||
sb.WriteString("\t}\n")
|
||||
}
|
||||
|
||||
sb.WriteString("}\n")
|
||||
|
||||
outPath := "plugins_gen.go"
|
||||
if err := os.WriteFile(outPath, []byte(sb.String()), 0644); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "write %s: %v\n", outPath, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("Generated %s with %d plugins\n", outPath, len(cfg.Plugins))
|
||||
}
|
||||
Reference in New Issue
Block a user