在Golang monorepo中找到死代码

时间:2016-10-07 18:57:59

标签: go refactoring

我的团队将所有Golang代码都放在monorepo中。

  • 包含库代码的各种包子目录。
  • cmd
  • 下的二进制文件/服务/工具

我们已经有一段时间了,正在做一些清理工作。是否有任何工具或技术可以找到cmd下的二进制文件未使用的函数?

我知道go vet可以找到包中未使用的私有函数。但是我怀疑我们还导出了未使用的库函数。

4 个答案:

答案 0 :(得分:10)

Dominik Honnef的unused工具可能是您正在寻找的工具:

  

可选地,通过-exported标志,unused可以将所有参数分析为单个程序并报告未使用的导出标识符。这对于检查"内部"软件包或大型软件项目,不向公众导出API,但在组件之间使用导出的方法。

答案 1 :(得分:0)

尝试运行go build -gcflags -live。这会将-live标志传递给编译器(go tool compile),指示它输出有关活体分析的调试消息。不幸的是,它仅在找到实时代码而不是死代码时打印,但理论上你可以查看不会显示在输出中。

以下是编译存储在dead.go中的以下程序的示例:

package main

import "fmt"

func main() {
    if true {
        fmt.Println(true)
    } else {
        fmt.Println(false)
    }
}

go build -gcflags -live的输出:

# _/tmp/dead
./dead.go:7: live at call to convT2E: autotmp_5
./dead.go:7: live at call to Println: autotmp_5

如果我正确读取此内容,则第二行指出对convT2E的隐式调用(将非接口类型转换为接口类型,因为fmt.Println接受interface{}类型的参数1}})是实时的,第三行表示对fmt.Println的调用是有效的。请注意,没有fmt.Println(false)来电是有效的,所以我们可以推断它必须已经死了。

我知道这不是一个完美的答案,但我希望它有所帮助。

答案 2 :(得分:0)

我使用的一种可靠但微不足道的方法是重命名或注释掉您怀疑可能无法使用的函数,然后重新编译所有内容-没有错误意味着您不需要它们。

如果需要它们,它会向您显示这些函数的调用位置,因此有助于熟悉代码库并了解事物之间的联系。

答案 3 :(得分:-1)

有点脏,但是对我有用。 我有很多不想手动测试的结构,因此我编写了一个脚本,将其重命名,然后运行所有测试(ci / test.sh),如果任何测试失败,则将其重命名:

#!/bin/sh

set -e

git grep 'struct {' | grep type | while read line; do
  file=$(echo $line | awk -F ':' '{print $1}')
  struct=$(echo $line | awk '{print $2}') 

  sed "s/$struct struct/_$struct struct/g" -i $file

  echo "testing for struct $struct changed in file $file"

  if ! ./ci/test.sh; then
    sed "s/_$struct struct/$struct struct/g" -i $file
  fi
done