blog icon indicating copy to clipboard operation
blog copied to clipboard

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

Open ma6174 opened this issue 5 years ago • 4 comments

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

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

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

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

点击展开查看...

# 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"
	]
}

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

  • ImportPath:在执行包引用时的名字 encoding/base64
  • Name:包的名字 base64
  • Imports:这个包直接引用的包:"encoding/binary", "io", "strconv"
  • Deps:这个包所有递归依赖的包

有了上面的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 avatar May 19 '19 12:05 ma6174

https://github.com/ma6174/go_dep_search

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

ma6174 avatar Jun 02 '19 10:06 ma6174

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

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

net.jpg

ma6174 avatar Mar 06 '21 14:03 ma6174