最近在Golang项目开发过程中,发现一些启动依赖关系搞不清楚的问题。项目中会使用 init() 函数进行初始化,然而一个项目会有多个可执行程序,比如:

  • A 程序仅调用 A 应用应该调用的 init 代码,结果在开发过程中,却使得 A 应用调用了其他应用程序的 init 代码。然而这种问题,在构建阶段是无法发现的。
  • 原本规划好了调用层级,比如大致调用层级关系如: app层 -> internal层 -> pkg层

本文将介绍如何使用 godepgraph 工具解决 Golang 项目开发过程中优化代码结构。

安装

go install github.com/kisielk/godepgraph@latest

基础运行

godepgraph github.com/ismdeep/station/cmd/server

输出如下:

digraph godep {
splines=ortho
nodesep=0.4
ranksep=0.8
node [shape="box",style="rounded,filled"]
edge [arrowsize="0.5"]
"bufio" [label="bufio" color="palegreen" URL="https://godoc.org/bufio" target="_blank"];
"bytes" [label="bytes" color="palegreen" URL="https://godoc.org/bytes" target="_blank"];
"compress/bzip2" [label="compress/bzip2" color="palegreen" URL="https://godoc.org/compress/bzip2" target="_blank"];
"compress/flate" [label="compress/flate" color="palegreen" URL="https://godoc.org/compress/flate" target="_blank"];
"compress/gzip" [label="compress/gzip" color="palegreen" URL="https://godoc.org/compress/gzip" target="_blank"];
"compress/zlib" [label="compress/zlib" color="palegreen" URL="https://godoc.org/compress/zlib" target="_blank"];
"container/list" [label="container/list" color="palegreen" URL="https://godoc.org/container/list" target="_blank"];
"unicode" [label="unicode" color="palegreen" URL="https://godoc.org/unicode" target="_blank"];
"unicode/utf16" [label="unicode/utf16" color="palegreen" URL="https://godoc.org/unicode/utf16" target="_blank"];
"unicode/utf8" [label="unicode/utf8" color="palegreen" URL="https://godoc.org/unicode/utf8" target="_blank"];
"unsafe" [label="unsafe" color="palegreen" URL="https://godoc.org/unsafe" target="_blank"];
}

但是这样的输出显示是有太多是我们不想去关心的。可以通过以下参数进行筛选。

筛选

通过 -onlyprefixes 可以筛选仅以某个包名为前缀的包。

godepgraph -onlyprefixes github.com/ismdeep/station github.com/ismdeep/station/cmd/server

结合 graphviz 可视化依赖树

首先安装 graphviz 包

sudo apt update
sudo apt install -y graphviz

产生依赖关系树并输出svg图片

godepgraph -onlyprefixes github.com/ismdeep/station github.com/ismdeep/station/cmd/server | dot -Tsvg -o server.svg

server

小技巧 sed

从上图来看,包名前缀也是比较多余,可以通过 sed 命令清理掉。

godepgraph -onlyprefixes github.com/ismdeep/station github.com/ismdeep/station/cmd/server | sed 's/github\.com\/ismdeep\/station\///g' | dot -Tsvg -o server.svg

server