package worker import ( "complie-erlang/config" "complie-erlang/parser/zm_lib" "complie-erlang/parser/zm_proto" tm "complie-erlang/template" "errors" "fmt" "gopkg.in/yaml.v2" "log" "os" "path/filepath" "time" ) type ModWorker interface { Name() string LoadCfg(BaseSet, []string) error OutPutFiles() ([]string, error) } type BaseSet struct { ModConfigs *config.ModConfigs Conf config.ModConfig } func ModWorkerRun(name string, args []string) error { xmlPath, err := zm_lib.FindPathByExecutable("./mod_config.yaml") if err != nil { return fmt.Errorf("find xml path error: %v", err) } bytes, err := os.ReadFile(xmlPath) if err != nil { return fmt.Errorf("读取配置文件失败: %v", err) } var conf = config.ModConfigs{} if err = yaml.Unmarshal(bytes, &conf); err != nil { return fmt.Errorf("解析配置文件 %s 失败: %v", xmlPath, err) } var modWorkerName string var baseSet BaseSet baseSet.ModConfigs = &conf for _, modconfig := range conf.ModConfigs { if modconfig.Name == name { modWorkerName = modconfig.Worker baseSet.Conf = modconfig break } } if modWorkerName == "" { return fmt.Errorf("无效的 %s", name) } for _, worker := range AllWorkers() { if worker.Name() == modWorkerName { log.Printf("[info] 初始化开始。。。") if err := worker.LoadCfg(baseSet, args); err != nil { return fmt.Errorf("初始化 Err:%v", err) } log.Printf("[info] 初始化完成 开始生成输出。。。") outFiles, err := worker.OutPutFiles() if err != nil { return fmt.Errorf("生成输出 Err:%v", err) } log.Printf("[info] 生成完成: \n") for _, outFile := range outFiles { log.Printf(" - %s:0\n", outFile) } return nil } } return errors.New("worker not found") } func AllWorkers() []ModWorker { return []ModWorker{&ProtoModWorker{}} } type ProtoModWorker struct { set BaseSet Args []string DefaultArgs []config.DefaultArg templates *tm.Template // 模板 pluginPath string parsePort []zm_proto.Port proto *zm_proto.Proto } func (mod *ProtoModWorker) Name() string { return "proto" } func (mod *ProtoModWorker) LoadCfg(set BaseSet, Args []string) error { mod.set = set mod.Args = Args log.Println("[info] 加载配置 set:", set.Conf, "args:", Args) pluginPathByWd, err := zm_lib.GetPluginPathByWd(set.ModConfigs.Plugin) if err != nil { return err } log.Println("[info] 项目根目录:", pluginPathByWd) mod.pluginPath = pluginPathByWd // 加载模版 findPathByExecutable, err := zm_lib.FindPathByExecutable(set.ModConfigs.TemplateDir) if err != nil { return err } log.Println("[info] 加载模板:", findPathByExecutable) mod.templates = tm.NewTemplate() if err = mod.templates.ParseGlob(findPathByExecutable); err != nil { return err } protoFile := filepath.Join(mod.pluginPath, fmt.Sprintf(mod.set.Conf.ProtoName, mod.Args[0])) log.Printf("[info] 加载proto文件: %s:1\n", protoFile) proto := zm_proto.NewProto() proto.Include(filepath.Dir(protoFile)) if err = proto.ParseImport(filepath.Base(protoFile)); err != nil { return err } parsePort, err := zm_proto.ParsePort(proto, protoFile) if err != nil { return err } mod.proto = proto mod.parsePort = parsePort for _, p := range mod.parsePort { log.Printf("[info] 解析接口: %s 是否推送: %v \n", p.Cmd, p.IsPush) } return nil } func (mod *ProtoModWorker) OutPutFiles() ([]string, error) { for _, dir := range mod.set.Conf.MakeDir { dir.Path = filepath.Join(mod.pluginPath, fmt.Sprintf(dir.Path, mod.Args[0])) log.Println("[info] make outDir:", dir.Path) //if err := os.MkdirAll(dir.Path, os.ModePerm); err != nil { // return nil, err //} } for _, outFs := range mod.set.Conf.OutFiles { log.Println("[info] make file:", fmt.Sprintf(outFs.FileName, mod.Args[0])) template, err := mod.templates.ExecuteTemplate(outFs.ContentTemplate, mod.FormatArgs()) if err != nil { return nil, err } fmt.Printf("\n\n >:\n%s \n\n", template) } return nil, nil } func (mod *ProtoModWorker) FormatArgs() map[string]any { var templatesArgs = make(map[string]any) var defaultArgs = make(map[string]any) for _, defaultArg := range mod.DefaultArgs { defaultArgs[defaultArg.Key] = defaultArg.Value } templatesArgs["default"] = defaultArgs var ports []any for _, port := range mod.parsePort { if port.IsPush { continue } var portMap = map[string]any{ "Cmd": port.Cmd, "PortDesc": port.PortDesc, "ClientPB": port.ClientPB, "ServerPB": port.ServerPB, "ClientProto": mod.proto.MessageToErlMod(port.ClientPB), "ServerProto": mod.proto.MessageToErlMod(port.ServerPB), } ports = append(ports, portMap) } templatesArgs["ports"] = ports // 其他默认值 templatesArgs["CreateAt"] = time.Now().Format(time.DateTime) return templatesArgs }