ma6174 / blog

博客
https://ma6174.github.io/blog/
138 stars 18 forks source link

使用 go_dep_search 分析项目里面的包依赖 #23

Open ma6174 opened 5 years ago

ma6174 commented 5 years ago

开发过程中经常会遇到这样的问题:我改了一个包,哪些服务受影响?我们期望是把所有相关的服务都升级,避免出现遗漏。

对于业务不复杂或者比较偏上层的包,大部分直接在代码库里面grep一下就知道了。如果的偏底层的包,业务不一定会直接引用,这种直接分析的话就比较复杂了。

之前有种比较麻烦但是也相对有效的方法。我们知道Go的编译是有缓存的,如果代码有变更的话就会触发包重新编译,通过 go build -v可以把重新编译的包的名字输出出来,当然也包含最终的服务程序。实际操作的时候需要避免ide编译影响。

后来研究了一下,实际有更好的办法来实现。go list命令有个-json的参数,会自动分析各个包的依赖关系,以json的格式输出出来,我们以官方库里面的encoding/base64包为例:

点击展开查看...

```bash # go list -json encoding/base64 { "Dir": "/usr/local/go/src/encoding/base64", "ImportPath": "encoding/base64", "Name": "base64", "Doc": "Package base64 implements base64 encoding as specified by RFC 4648.", "Target": "/usr/local/go/pkg/linux_amd64/encoding/base64.a", "Root": "/usr/local/go", "Match": [ "encoding/base64" ], "Goroot": true, "Standard": true, "GoFiles": [ "base64.go" ], "Imports": [ "encoding/binary", "io", "strconv" ], "Deps": [ "encoding/binary", "errors", "internal/bytealg", "internal/cpu", "internal/race", "io", "math", "math/bits", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/math", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "unicode", "unicode/utf8", "unsafe" ], "TestGoFiles": [ "base64_test.go" ], "TestImports": [ "bytes", "errors", "fmt", "io", "io/ioutil", "reflect", "strings", "testing", "time" ], "XTestGoFiles": [ "example_test.go" ], "XTestImports": [ "encoding/base64", "fmt", "os" ] } ```

其中有几个字段需要关注一下:

有了上面的Deps信息之后,开头提到的依赖分析问题就比较简单了。只要在Deps里面有我们修改的包就可以了,如果要找是哪个服务的话,需要看Namemain的包。另外go list -json ./... 就可以分析当前项目里面的所有包。

go list -json ./... 输出的信息还是挺多的,为了方便分析,写了个小工具 go_dep_search (https://github.com/ma6174/go_dep_search)

比如找出官方库里面所有依赖net/http或者encoding/json的可执行程序(ImportPath那一列):

/usr/local/go/src# go list -json ./... | go_dep_search -main net/http encoding/json
Name    ->  ImportPath  ->  dep_package
main    ->  cmd/compile ->  encoding/json
main    ->  cmd/cover   ->  encoding/json
main    ->  cmd/dist    ->  encoding/json
main    ->  cmd/go  ->  net/http
main    ->  cmd/go  ->  encoding/json
main    ->  cmd/link    ->  encoding/json
main    ->  cmd/pprof   ->  net/http
main    ->  cmd/pprof   ->  encoding/json
main    ->  cmd/test2json   ->  encoding/json
main    ->  cmd/trace   ->  net/http
main    ->  cmd/trace   ->  encoding/json
main    ->  cmd/vet ->  encoding/json

希望对大家有帮助。

ma6174 commented 5 years ago

https://github.com/ma6174/go_dep_search

新版的 go_dep_search 支持分析包调用链、支持找出未被使用的包。

ma6174 commented 3 years ago

增加了一个图形化分析包完整调用链的功能,比如分析标准库的 net/httpnet 的调用链,欢迎更新到最新版使用 😄

root@b7e158d83ff2:/go# go list -json all | go_dep_search -graph -o net.jpg net/http net

net.jpg

xhd2015 commented 5 months ago

赞,我之前也有类似的问题,需要找到init依赖的顺序,不知道这两个是否可以整合到一起? https://github.com/xhd2015/go-inspect/tree/master/cmd/depcheck

depcheck -mod=vendor ./

效果相似,但目的不一样。 depcheck主要是找到程序启动的时候,init的顺序;go_dep_search则是找到依赖树。

jamebluntcc commented 5 months ago

我已收到你发的邮件,我将会尽快阅读,谢谢!