优化缓存机制 补充错误码
This commit is contained in:
Vendored
+78
@@ -0,0 +1,78 @@
|
|||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Cache interface {
|
||||||
|
Get(key string) (any, bool)
|
||||||
|
GetDefault(key string, defaultValue any) (any, error)
|
||||||
|
Set(key string, val any) error
|
||||||
|
Iteration(func(key string, val any))
|
||||||
|
}
|
||||||
|
|
||||||
|
type cache struct {
|
||||||
|
filename string
|
||||||
|
data map[string]any
|
||||||
|
mu sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cache) Get(key string) (any, bool) {
|
||||||
|
c.mu.Lock()
|
||||||
|
defer c.mu.Unlock()
|
||||||
|
|
||||||
|
val, ok := c.data[key]
|
||||||
|
return val, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cache) GetDefault(key string, defaultVal any) (any, error) {
|
||||||
|
c.mu.Lock()
|
||||||
|
defer c.mu.Unlock()
|
||||||
|
val, ok := c.data[key]
|
||||||
|
if ok {
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c.data[key] = defaultVal
|
||||||
|
bytes, err := json.Marshal(c.data)
|
||||||
|
if err != nil {
|
||||||
|
return defaultVal, err
|
||||||
|
}
|
||||||
|
err = os.WriteFile(c.filename, bytes, 0666)
|
||||||
|
|
||||||
|
return defaultVal, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cache) Set(key string, val any) error {
|
||||||
|
c.mu.Lock()
|
||||||
|
defer c.mu.Unlock()
|
||||||
|
c.data[key] = val
|
||||||
|
bytes, err := json.Marshal(c.data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return os.WriteFile(c.filename, bytes, 0666)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cache) Iteration(f func(key string, val any)) {
|
||||||
|
for k, v := range c.data {
|
||||||
|
f(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCache(filename string) (Cache, error) {
|
||||||
|
var c = &cache{
|
||||||
|
filename: filename,
|
||||||
|
data: make(map[string]any),
|
||||||
|
}
|
||||||
|
bytes, err := os.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
if err = json.Unmarshal(bytes, &c.data); err != nil {
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"complie-erlang/cache"
|
||||||
|
"complie-erlang/parser/zm_lib"
|
||||||
|
"fmt"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
type cacheSet struct {
|
||||||
|
Path string
|
||||||
|
debug bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cacheSet) Run(cmd *cobra.Command, args []string) {
|
||||||
|
if len(args) == 0 {
|
||||||
|
fmt.Println("No command specified.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.run(args); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Done.")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cacheSet) run(args []string) error {
|
||||||
|
pathByExecutable, err := zm_lib.FindPathByExecutable(c.Path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
newCache, err := cache.NewCache(pathByExecutable)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch args[0] {
|
||||||
|
case "set":
|
||||||
|
return newCache.Set(args[1], args[2])
|
||||||
|
case "get":
|
||||||
|
val, is := newCache.Get(args[1])
|
||||||
|
if is {
|
||||||
|
fmt.Printf("%s : %s \n", args[0], val)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("%s : nil \n", args[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown command: %s", args[0])
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
var singleSet = new(cacheSet)
|
||||||
|
var logsCmd = &cobra.Command{
|
||||||
|
Use: "global",
|
||||||
|
Short: "缓存数据模版",
|
||||||
|
Long: `构建功能数据`,
|
||||||
|
Run: singleSet.Run,
|
||||||
|
}
|
||||||
|
|
||||||
|
logsCmd.PersistentFlags().BoolVar(&singleSet.debug, "debug", false, "是否启动调试模式")
|
||||||
|
logsCmd.PersistentFlags().StringVar(&singleSet.Path, "path", globalCacheFileName, "缓存数据存放地址(相对于根目录)")
|
||||||
|
|
||||||
|
rootCmd.AddCommand(logsCmd)
|
||||||
|
}
|
||||||
+79
-18
@@ -1,11 +1,12 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"complie-erlang/cache"
|
||||||
|
"complie-erlang/parser"
|
||||||
"complie-erlang/parser/zm_lib"
|
"complie-erlang/parser/zm_lib"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -18,21 +19,71 @@ type ErrCode struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *ErrCode) run(_ *cobra.Command, arg []string) {
|
func (s *ErrCode) run(_ *cobra.Command, arg []string) {
|
||||||
pluginPathByWd, err := zm_lib.GetPluginPathByWd(s.Plugin)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("[warn] plugin path no find:%s", err.Error())
|
|
||||||
pluginPathByWd = ""
|
|
||||||
}
|
|
||||||
errPath := filepath.Join(pluginPathByWd, s.ErrPath)
|
|
||||||
|
|
||||||
fmt.Printf("errPath:%s %s\n", pluginPathByWd, errPath)
|
if len(arg) == 0 {
|
||||||
errorLanguageBytes, err := os.ReadFile(errPath)
|
arg = append(arg, "show")
|
||||||
if err != nil {
|
|
||||||
log.Printf("[error] read errPath:%s %s\n", errPath, err.Error())
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
switch arg[0] {
|
||||||
|
case "merge":
|
||||||
|
newCache, err := cache.NewCache("errorCode.json")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[error] newCache err:%s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("")
|
||||||
|
newCache.Iteration(func(key string, val any) {
|
||||||
|
fmt.Printf(" key:%s val:%s\n", key, val)
|
||||||
|
})
|
||||||
|
fmt.Println("ok")
|
||||||
|
case "set":
|
||||||
|
newCache, err := cache.NewCache("errorCode.json")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[error] newCache err:%s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(arg) != 3 {
|
||||||
|
log.Printf("[error] len(arg):%d %s", len(arg), arg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = newCache.Set(arg[1], arg[2])
|
||||||
|
fmt.Println("err:", err)
|
||||||
|
case "get":
|
||||||
|
newCache, err := cache.NewCache("errorCode.json")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[error] newCache err:%s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("")
|
||||||
|
newCache.Iteration(func(key string, val any) {
|
||||||
|
fmt.Printf(" key:%s val:%s\n", key, val)
|
||||||
|
})
|
||||||
|
fmt.Println("")
|
||||||
|
default:
|
||||||
|
pluginPathByWd, err := zm_lib.GetPluginPathByWd(s.Plugin)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[warn] plugin path no find:%s", err.Error())
|
||||||
|
pluginPathByWd = ""
|
||||||
|
}
|
||||||
|
errPath := filepath.Join(pluginPathByWd, s.ErrPath)
|
||||||
|
|
||||||
fmt.Printf("errPath:%s %s\n", errorLanguageBytes, errPath)
|
clientCfg, err := parser.NewClientConfigWithFile(errPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[error] load errPath:%s %s\n", errPath, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
errCode := parser.NewErrCode(clientCfg)
|
||||||
|
err = errCode.LoadWd()
|
||||||
|
|
||||||
|
newCache, err := cache.NewCache("errorCode.json")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[error] newCache err:%s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = errCode.PrintErrCode(newCache)
|
||||||
|
fmt.Printf("err:%v \n", err)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,14 +91,24 @@ func init() {
|
|||||||
var singleSet = new(ErrCode)
|
var singleSet = new(ErrCode)
|
||||||
var logsCmd = &cobra.Command{
|
var logsCmd = &cobra.Command{
|
||||||
Use: "err_code",
|
Use: "err_code",
|
||||||
Short: "根据proto 文件构建 功能模版",
|
Short: "检索代码模块生成错误码配置",
|
||||||
Long: `构建功能数据`,
|
Long: `检索代码模块生成错误码配置
|
||||||
Run: singleSet.run,
|
|
||||||
|
更多用法:
|
||||||
|
- 查看缓存区 get
|
||||||
|
- 设置缓存区 set <错误码> <错误码翻译设置>
|
||||||
|
- 提交缓存区 merge <功能名称>
|
||||||
|
`,
|
||||||
|
Run: singleSet.run,
|
||||||
|
PostRun: func(cmd *cobra.Command, args []string) {
|
||||||
|
fmt.Println("\n-h 可解锁更多用法")
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
logsCmd.PersistentFlags().BoolVar(&singleSet.debug, "debug", false, "是否启动调试模式")
|
logsCmd.PersistentFlags().BoolVar(&singleSet.debug, "debug", false, "是否启动调试模式")
|
||||||
logsCmd.PersistentFlags().StringVar(&singleSet.ErrPath, "path", ".cfg/ErrorLanguage.txt", "错误码地址(相对于根目录)")
|
|
||||||
logsCmd.PersistentFlags().StringVar(&singleSet.Plugin, "plugin", "plugin", "代码根目录")
|
_ = zm_lib.PersistentFlagsStringVar(logsCmd, &singleSet.ErrPath, globalCache, "path", "cfg/ErrorLanguagePackage.txt", "错误码地址(相对于根目录)")
|
||||||
|
_ = zm_lib.PersistentFlagsStringVar(logsCmd, &singleSet.Plugin, globalCache, "plugin", "plugin", "代码根目录")
|
||||||
|
|
||||||
rootCmd.AddCommand(logsCmd)
|
rootCmd.AddCommand(logsCmd)
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-9
@@ -9,7 +9,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Pb2Port struct {
|
type Pb2Port struct {
|
||||||
@@ -113,20 +112,25 @@ func init() {
|
|||||||
|
|
||||||
// 写入默认数据
|
// 写入默认数据
|
||||||
if currentDir, err := os.Getwd(); err == nil {
|
if currentDir, err := os.Getwd(); err == nil {
|
||||||
out = fmt.Sprintf("%s_port.erl", filepath.Base(currentDir))
|
outPut, _ := globalCache.GetDefault(fmt.Sprintf("%s.out", logsCmd.Use), "%s_port.erl")
|
||||||
pluginSpilt := strings.Split(currentDir, "plugin")
|
out = fmt.Sprintf(outPut.(string), filepath.Base(currentDir))
|
||||||
if len(pluginSpilt) > 0 {
|
|
||||||
pluginSpilt = pluginSpilt[:len(pluginSpilt)-1]
|
plugin, _ := globalCache.GetDefault(fmt.Sprintf("%s.Plugin", logsCmd.Use), "plugin")
|
||||||
protoPath = filepath.Join(strings.Join(pluginSpilt, "plugin"), fmt.Sprintf("\\gpb\\game\\pro_%s.proto", filepath.Base(currentDir)))
|
pluginPathByWd, err := zm_lib.GetPluginPathByWd(plugin.(string))
|
||||||
|
if err == nil {
|
||||||
|
defaultProtoPath, _ := globalCache.GetDefault(fmt.Sprintf("%s.Proto", logsCmd.Use), "\\gpb\\game\\pro_%s.proto")
|
||||||
|
protoPath = filepath.Join(pluginPathByWd, fmt.Sprintf(defaultProtoPath.(string), filepath.Base(currentDir)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logsCmd.PersistentFlags().BoolVar(&singleSet.debug, "debug", false, "是否启动调试模式")
|
logsCmd.PersistentFlags().BoolVar(&singleSet.debug, "debug", false, "是否启动调试模式")
|
||||||
logsCmd.PersistentFlags().StringVar(&singleSet.protoPath, "proto", protoPath, "读取文件")
|
logsCmd.PersistentFlags().StringVar(&singleSet.protoPath, "proto", protoPath, "读取文件")
|
||||||
logsCmd.PersistentFlags().StringVar(&singleSet.out, "out", out, "输出文件")
|
logsCmd.PersistentFlags().StringVar(&singleSet.out, "out", out, "输出文件")
|
||||||
logsCmd.PersistentFlags().StringVar(&singleSet.author, "author", "st,sutong@youkia.net", "作者")
|
_ = zm_lib.PersistentFlagsStringVar(logsCmd, &singleSet.author, globalCache, "author", "st,sutong@youkia.net", "作者")
|
||||||
logsCmd.PersistentFlags().StringVar(&singleSet.mainTemplate, "main_tpl", "ErlangPort", "主模版")
|
_ = zm_lib.PersistentFlagsStringVar(logsCmd, &singleSet.mainTemplate, globalCache, "main_tpl", "ErlangPort", "主模版")
|
||||||
logsCmd.PersistentFlags().StringVar(&singleSet.tplDir, "tpl", "./templates/*.tpl", "模版地址")
|
_ = zm_lib.PersistentFlagsStringVar(logsCmd, &singleSet.tplDir, globalCache, "tpl", "./templates/*.tpl", "模版地址")
|
||||||
|
//logsCmd.PersistentFlags().StringVar(&singleSet.mainTemplate, "main_tpl", "ErlangPort", "主模版")
|
||||||
|
//logsCmd.PersistentFlags().StringVar(&singleSet.tplDir, "tpl", "./templates/*.tpl", "模版地址")
|
||||||
|
|
||||||
rootCmd.AddCommand(logsCmd)
|
rootCmd.AddCommand(logsCmd)
|
||||||
}
|
}
|
||||||
|
|||||||
+19
@@ -1,11 +1,30 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"complie-erlang/cache"
|
||||||
|
"complie-erlang/parser/zm_lib"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 全局缓存
|
||||||
|
var globalCache = InitGlobalCache()
|
||||||
|
|
||||||
|
const globalCacheFileName = "global.json"
|
||||||
|
|
||||||
|
func InitGlobalCache() cache.Cache {
|
||||||
|
pathByExecutable, err := zm_lib.FindPathByExecutable(globalCacheFileName)
|
||||||
|
if err != nil {
|
||||||
|
panic("未查找到根目录 Err:" + err.Error())
|
||||||
|
}
|
||||||
|
newCache, err := cache.NewCache(pathByExecutable)
|
||||||
|
if err != nil {
|
||||||
|
panic("创建缓存失败 Err:" + err.Error())
|
||||||
|
}
|
||||||
|
return newCache
|
||||||
|
}
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Use: "",
|
Use: "",
|
||||||
Short: "erlang注解生成配置模版工具",
|
Short: "erlang注解生成配置模版工具",
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"complie-erlang/parser/zm_proto"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PluginConfig struct {
|
||||||
|
Name string
|
||||||
|
Desc string
|
||||||
|
CreatAt time.Time
|
||||||
|
Type PluginType // 项目类型
|
||||||
|
// 差异数据
|
||||||
|
ProtoDir string // 接口proto 地址
|
||||||
|
CfgDir string // 配置地址
|
||||||
|
FunOpenId int
|
||||||
|
Port []zm_proto.Port
|
||||||
|
ErrorCodes map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Plugin interface {
|
||||||
|
Init(args []string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type PluginType string
|
||||||
|
|
||||||
|
var (
|
||||||
|
PluginTypeGame PluginType = "Game"
|
||||||
|
PluginTypeGm = "Gm"
|
||||||
|
PluginTypeGmActivity = "GmActivity"
|
||||||
|
)
|
||||||
|
|
||||||
|
const pluginPath = "./plugin.json"
|
||||||
|
|
||||||
|
func (p *PluginConfig) Init(args []string) error {
|
||||||
|
// 创建配置文件
|
||||||
|
|
||||||
|
// 根据类型创建各种 初始化文件
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
package parser
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ClientConfig struct {
|
||||||
|
Types map[int]ClientValue
|
||||||
|
TypeName2Index map[string]int
|
||||||
|
Data map[string]map[int]string
|
||||||
|
mu sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClientValue struct {
|
||||||
|
Desc string
|
||||||
|
Type string
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClientConfig() *ClientConfig {
|
||||||
|
return &ClientConfig{
|
||||||
|
Types: make(map[int]ClientValue),
|
||||||
|
Data: make(map[string]map[int]string),
|
||||||
|
TypeName2Index: make(map[string]int),
|
||||||
|
mu: sync.RWMutex{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClientConfigWithFile(filename string) (*ClientConfig, error) {
|
||||||
|
c := NewClientConfig()
|
||||||
|
return c, c.LoadFile(filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ClientConfig) LoadFile(filename string) error {
|
||||||
|
file, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
c.mu.Lock()
|
||||||
|
defer c.mu.Unlock()
|
||||||
|
return c.loadByReader(bufio.NewReader(file))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ClientConfig) LoadByReader(reader io.Reader) error {
|
||||||
|
c.mu.Lock()
|
||||||
|
defer c.mu.Unlock()
|
||||||
|
return c.loadByReader(reader)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ClientConfig) loadByReader(reader io.Reader) error {
|
||||||
|
// 创建缓存读取 分隔符设置成 回车
|
||||||
|
scan := bufio.NewScanner(reader)
|
||||||
|
scan.Split(bufio.ScanLines)
|
||||||
|
|
||||||
|
var line int
|
||||||
|
var types []string
|
||||||
|
var desc []string
|
||||||
|
|
||||||
|
for scan.Scan() {
|
||||||
|
line++
|
||||||
|
|
||||||
|
lineContent := strings.TrimSpace(scan.Text())
|
||||||
|
if len(lineContent) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去除注释
|
||||||
|
split := strings.Split(lineContent, "//")
|
||||||
|
if len(split) > 1 {
|
||||||
|
lineContent = split[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 类型
|
||||||
|
if line == 1 {
|
||||||
|
types = strings.Split(lineContent, "\t")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 备注
|
||||||
|
if line == 2 {
|
||||||
|
desc = strings.Split(lineContent, "\t")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// key
|
||||||
|
if line == 3 {
|
||||||
|
for i, t := range strings.Split(lineContent, "\t") {
|
||||||
|
if len(types) < i {
|
||||||
|
return fmt.Errorf("line %d: invalid type", line)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(desc) < i {
|
||||||
|
return fmt.Errorf("line %d: invalid desc", line)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Types[i] = ClientValue{
|
||||||
|
Desc: desc[i],
|
||||||
|
Type: types[i],
|
||||||
|
Name: t,
|
||||||
|
}
|
||||||
|
c.TypeName2Index[t] = i
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var lineData = make(map[int]string)
|
||||||
|
var lineKey string
|
||||||
|
for i1, v1 := range strings.Split(lineContent, "\t") {
|
||||||
|
if i1 == 0 {
|
||||||
|
lineKey = strings.TrimSpace(v1)
|
||||||
|
}
|
||||||
|
lineData[i1] = strings.TrimSpace(v1)
|
||||||
|
}
|
||||||
|
if len(lineData) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
c.Data[lineKey] = lineData
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value 读取单个
|
||||||
|
func (c *ClientConfig) Value(key string, objKey string) (ClientValue, string, error) {
|
||||||
|
c.mu.RLock()
|
||||||
|
defer c.mu.RUnlock()
|
||||||
|
|
||||||
|
l, is := c.Data[key]
|
||||||
|
if !is {
|
||||||
|
return ClientValue{}, "", fmt.Errorf("key %s not found", key)
|
||||||
|
}
|
||||||
|
index, is2 := c.TypeName2Index[objKey]
|
||||||
|
if !is2 {
|
||||||
|
return ClientValue{}, "", fmt.Errorf("objKey %s not found", objKey)
|
||||||
|
}
|
||||||
|
return c.Types[index], l[index], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValueByLine 读取
|
||||||
|
func (c *ClientConfig) ValueByLine(line map[int]string, key string) (ClientValue, string, error) {
|
||||||
|
c.mu.RLock()
|
||||||
|
defer c.mu.RUnlock()
|
||||||
|
|
||||||
|
index, is2 := c.TypeName2Index[key]
|
||||||
|
if !is2 {
|
||||||
|
return ClientValue{}, "", fmt.Errorf("objKey %s not found", key)
|
||||||
|
}
|
||||||
|
return c.Types[index], line[index], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LineByKey 通过Key获取一行
|
||||||
|
func (c *ClientConfig) LineByKey(key string) map[int]string {
|
||||||
|
c.mu.RLock()
|
||||||
|
defer c.mu.RUnlock()
|
||||||
|
|
||||||
|
return c.Data[key]
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
package parser
|
||||||
|
|
||||||
|
import (
|
||||||
|
"complie-erlang/cache"
|
||||||
|
"complie-erlang/parser/zm_lib"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ErrCode struct {
|
||||||
|
codeMap map[string]bool
|
||||||
|
ClientConfig *ClientConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewErrCode(c *ClientConfig) *ErrCode {
|
||||||
|
return &ErrCode{
|
||||||
|
codeMap: make(map[string]bool),
|
||||||
|
ClientConfig: c,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrCode) LoadWd() error {
|
||||||
|
wdDir, err := zm_lib.FindPathByWd(".")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return e.iterationDir(wdDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrCode) iterationDir(baseDir string) error {
|
||||||
|
|
||||||
|
dir, err := os.ReadDir(baseDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, d := range dir {
|
||||||
|
if d.IsDir() {
|
||||||
|
err = e.iterationDir(filepath.Join(filepath.Join(baseDir, d.Name())))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
path := filepath.Join(baseDir, d.Name())
|
||||||
|
|
||||||
|
if err = e.loadFile(path); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrCode) loadFile(filename string) error {
|
||||||
|
bytes, err := os.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义正则表达式
|
||||||
|
// 注意:由于\?在Go的字符串中是一个特殊字符,我们使用\\?来表示一个问号。
|
||||||
|
// 同时,由于双引号在正则表达式中有特殊含义,我们需要使用\\"来表示一个普通双引号。
|
||||||
|
// 我们使用非贪婪匹配来确保只匹配到第一个双引号后的内容。
|
||||||
|
re := regexp.MustCompile(`(?:\\?\?ThrowErr|throw)\("([^"]+)"\)`)
|
||||||
|
|
||||||
|
// 查找所有匹配项
|
||||||
|
matches := re.FindAllStringSubmatch(string(bytes), -1)
|
||||||
|
|
||||||
|
// 提取并打印双引号内的内容
|
||||||
|
for _, match := range matches {
|
||||||
|
// match[0] 是整个匹配的字符串,match[1] 是第一个括号内的匹配(即双引号内的内容)
|
||||||
|
if e.codeMap[match[1]] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
e.codeMap[match[1]] = true
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrCode) PrintErrCode(c cache.Cache) error {
|
||||||
|
fmt.Println(">")
|
||||||
|
|
||||||
|
for key := range e.codeMap {
|
||||||
|
line := e.ClientConfig.LineByKey(key)
|
||||||
|
if line == nil {
|
||||||
|
val, is := c.Get(key)
|
||||||
|
if is {
|
||||||
|
fmt.Printf(" %s: %v[cache] \n", key, val)
|
||||||
|
} else {
|
||||||
|
fmt.Printf(" %s: %v \n", key, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_, s, err := e.ClientConfig.ValueByLine(line, "UserCN")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf(" %s: %s \n", key, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package zm_lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"complie-erlang/cache"
|
||||||
|
"fmt"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PersistentFlagsStringVar(cmd *cobra.Command, varK *string, cache cache.Cache, globalKey string, defaultValue string, desc string) error {
|
||||||
|
pluginKey := fmt.Sprintf("%s.%s", cmd.Use, globalKey)
|
||||||
|
plugin, err := cache.GetDefault(pluginKey, defaultValue)
|
||||||
|
cmd.PersistentFlags().StringVar(varK, globalKey, plugin.(string), fmt.Sprintf("%s (global.key:\"%s\")", desc, pluginKey))
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -67,6 +67,16 @@ func FindPathByBasePath(basefun func() (basePath string, err error), path string
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
path = filepath.Join(filepath.Dir(basePath), path)
|
|
||||||
|
info, err := os.Stat(basePath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if !info.IsDir() {
|
||||||
|
path = filepath.Join(filepath.Dir(basePath), path)
|
||||||
|
} else {
|
||||||
|
path = filepath.Join(basePath, path)
|
||||||
|
}
|
||||||
|
|
||||||
return path, nil
|
return path, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user