From 41549397a3b71d343569ac8a4d77a520a7d23174 Mon Sep 17 00:00:00 2001 From: zhaoyihang Date: Tue, 25 Mar 2025 09:49:21 +0800 Subject: [PATCH 1/2] feat: entrypoint support use relative path --- astdiff/astdiff.go | 4 +++- cmd/version.go | 2 +- parser/project.go | 19 ++++++++++++++++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/astdiff/astdiff.go b/astdiff/astdiff.go index ba953d8..f4b5198 100644 --- a/astdiff/astdiff.go +++ b/astdiff/astdiff.go @@ -586,7 +586,9 @@ func astNodesEqual(a, b ast.Node) bool { } } return true - + case *ast.TypeSwitchStmt: + y := b.(*ast.TypeSwitchStmt) + return astNodesEqual(x.Init, y.Init) && astNodesEqual(x.Assign, y.Assign) && astNodesEqual(x.Body, y.Body) default: panic(fmt.Sprintf("未处理的节点类型: %T, a: %v, b: %v\n", x, a, b)) } diff --git a/cmd/version.go b/cmd/version.go index 0b33cf8..ff9c6c1 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -6,7 +6,7 @@ import ( "github.com/spf13/cobra" ) -const Version = "1.0.1" +const Version = "1.0.2" var versionCmd = &cobra.Command{ Use: "version", diff --git a/parser/project.go b/parser/project.go index 1348fde..2fd4eef 100644 --- a/parser/project.go +++ b/parser/project.go @@ -1,6 +1,8 @@ package parser import ( + "strings" + "github.com/pkg/errors" "github.com/bootun/veronica/config" @@ -40,19 +42,30 @@ func NewProject(root string) (*project, error) { if err != nil { return nil, errors.WithMessage(err, "failed to parse go.mod") } + if module == nil { + return nil, errors.New("invalid go.mod file") + } + moduleName := module.Name + if moduleName == "" { + return nil, errors.New("invalid go.mod file, module name is empty") + } services := make(map[string]Service) // initialize entrypoint ignores := make(map[string][]string) hooks := make(map[string][]string) for _, v := range cfg.Services { - fullRelPath := rootPath.Join(v.Entrypoint) + entrypoint := v.Entrypoint + if !strings.HasPrefix(entrypoint, moduleName) { + entrypoint = moduleName + "/" + entrypoint + } + fullRelPath := rootPath.Join(entrypoint) relPath, err := fullRelPath.Rel(root) if err != nil { return nil, errors.WithMessage(err, "failed to get relative path") } - services[v.Entrypoint] = Service{ + services[entrypoint] = Service{ Name: v.Name, - Entrypoint: v.Entrypoint, + Entrypoint: entrypoint, Ignores: v.Ignores, Hooks: v.Hooks, } From d392389b724158bd53d42947e697ea784704d431 Mon Sep 17 00:00:00 2001 From: zhaoyihang Date: Tue, 25 Mar 2025 10:26:30 +0800 Subject: [PATCH 2/2] chore: add configuration explan in README --- README.md | 65 ++++++++++++++++++++++++++++++++++++++++++- cmd/version.go | 2 +- veronica_example.yaml | 7 +++-- 3 files changed, 69 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 46a2af7..3ee1928 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,66 @@ GRPC_BatchGetPlayletInfo # 如果你的代码让更多的服务受到了影响,veronica会将它输出到这里 ``` +## 配置文件 +veronica在运行时,会在项目跟目录下寻找`veronica.yaml`配置文件, 当前版本的配置文件主要由以下部分组成: + +`version`: 指定veronica配置文件的版本,当前项目还处于早期阶段,变动较大,未来更新可能导致配置文件的语法产生变化,因此使用版本号来进行区分。 + +```yaml +version: 1.0.0 +``` + +`services`: services下可以定义一系列的service item,通常来说,每个service item都是一个服务,比如CronJob进程、消费者进程、对外提供HTTP或RPC的进程。 +> 但services并不局限于服务,它可以是任何你想要让veronica关注的内容(你将会在下面的entrypoint部分来了解它) + +```yaml +services: + # refresh_playlet_info 是一个CronJob进程 + refresh_playlet_info: + entrypoint: ... + # update_playlet 是一个消费者进程 + update_playlet: + entrypoint: ... + # playlet_server是一个对外提供RPC服务的进程 + playlet_server: + entrypoint: ... +``` + +`entrypoint`: 每个service都需要有一个entrypoint,entrypoint一般是该服务的入口,它可能是个函数,可能是个方法,可能是个变量。 +但entrypoint并不局限于此,它甚至可以是常量/类型声明,只要是你想让veronica关注的内容,都可以写进services里: + +```yaml +services: + refresh_playlet_info: + # NewRefreshPlayletInfoCronjob 这个函数是CronJob进程的入口 + entrypoint: 'cmd/cron/refresh_playlet_info.go:NewRefreshPlayletInfoCronjob' + + update_playlet: + # UpdatePlaylet 是个变量(&cobra.Command),是消费者进程的入口,通过cobra.AddCommand绑定到root上进行执行 + entrypoint: 'github.com/bootun/some-project/cmd/consumer/update_playlet.go:UpdatePlaylet' + + # or gRPC interface + # GetPlayletInf是一个gRPC接口实现 + GRPC_GetPlayletInfo: + # GetPlayletInfo 是一个方法,它的签名如下: + # func (svc *PlayletServer) GetPlayletInfo(ctx context.Context, req *pb.GetPlayletInfoReq) (*pb.PlayletBaseInfo, error) + # 如果你也想关注本次改动对RPC的影响,你可以像这样将RPC接口也纳入veronica的管控 + entrypoint: "internal/server/grpc.go:(*PlayletServer).GetPlayletInfo" + + # 除此之外,service还支持类型声明(结构体)、常量等顶级字段的依赖分析 + # ... +``` +entrypoint的值为你想要关注对象的包路径,比如你的Go module name是`github.com/bootun/some-project`, +那么你的entrypoint可以是: `github.com/bootun/some-project/cmd/consumer/update_playlet.go:UpdatePlaylet`。 +你也可以使用简略版的相对包名, 例如`cmd/consumer/update_playlet.go:UpdatePlaylet`来表示,veronica会自动为你添加前缀。 + +如果你关注的对象是个方法(method), 你需要写出他的receiver,就像上面示例中`GRPC_GetPlayletInfo`那样: +```yaml +GRPC_GetPlayletInfo: + # func (svc *PlayletServer) GetPlayletInfo(ctx context.Context, req *pb.GetPlayletInfoReq) (*pb.PlayletBaseInfo, error) + entrypoint: "internal/server/grpc.go:(*PlayletServer).GetPlayletInfo" +``` + ## 可配置项 **输出源代码变更可能会产生的全部影响** @@ -58,7 +118,10 @@ remove (*playletService).setPlayletCacheInfo in github.com/bootun/some-project/i ``` 该命令会详细告诉你对那些内容做了哪些操作(add/modify/remove), 并报告该修改产生的影响。 - +## 未来规划 +1. 当前GRPC这种方式对超多接口的项目来说,需要配置非常多的service,veronica计划改进这一点。 +2. 当前veronica只能分析go文件带来的影响,接下来我计划实现service的`hooks`和`ignores`字段,使任意文件的改动都能与service进行关联。 +3. veronica输出变更产生的影响时,计划增加对Go模版语法的支持。 ## 命名背景 `Veronica`取自钢铁侠的同名外太空支援系统,在你需要升级战甲时,只需要通知维罗妮卡,它就会将战甲的模块从外太空发送给你,重新组合后完成升级。 diff --git a/cmd/version.go b/cmd/version.go index ff9c6c1..2c55c44 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -6,7 +6,7 @@ import ( "github.com/spf13/cobra" ) -const Version = "1.0.2" +const Version = "1.0.3" var versionCmd = &cobra.Command{ Use: "version", diff --git a/veronica_example.yaml b/veronica_example.yaml index c567763..f3a0ee4 100644 --- a/veronica_example.yaml +++ b/veronica_example.yaml @@ -2,7 +2,7 @@ version: 1.0.0-alpha services: # every item is a service refresh_playlet_info: - entrypoint: 'github.com/bootun/some-project/cmd/cron/refresh_playlet_info.go:NewRefreshPlayletInfoCronjob' + entrypoint: 'cmd/cron/refresh_playlet_info.go:NewRefreshPlayletInfoCronjob' # the current version does not currently support it #ignores: @@ -12,13 +12,14 @@ services: # - 'go.mod' update_playlet: + # or use the full package path entrypoint: 'github.com/bootun/some-project/cmd/consumer/update_playlet.go:UpdatePlaylet' # or gRPC interface GRPC_GetPlayletInfo: - entrypoint: "github.com/bootun/some-project/internal/server/grpc.go:(*PlayletServer).GetPlayletInfo" + entrypoint: "internal/server/grpc.go:(*PlayletServer).GetPlayletInfo" GRPC_BatchGetPlayletInfo: - entrypoint: "github.com/bootun/some-project/internal/server/grpc.go:(*PlayletServer).BatchGetPlayletInfo" + entrypoint: "internal/server/grpc.go:(*PlayletServer).BatchGetPlayletInfo" # or variable declare / type declare ... # ... \ No newline at end of file