在Golang monorepo找到死代码

s4n0splo  于 2023-08-01  发布在  Go
关注(0)|答案(6)|浏览(77)

我的团队把我们所有的Golang代码都存储在一个单核存储器里。

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

我们已经有一段时间了,正在做一些清理工作。是否有任何工具或技术可以找到cmd下的二进制文件未使用的函数?
我知道go vet可以找到包中未使用的私有函数。然而,我怀疑我们也有导出的库函数没有使用。

w8biq8rn

w8biq8rn1#

UPD 2020:unused工具已并入staticcheck。不幸的是,v0.0.1-2020.1.4可能是最后一个支持此功能的。Dominik explains说,这是因为检查消耗了大量资源,很难得到正确的。

获取该版本:

env GO111MODULE=on go get honnef.co/go/tools/cmd/staticcheck@v0.0.1-2020.1.4

字符串
使用它:

$ staticcheck --unused.whole-program=true -- ./...
./internal/pkg/a.go:5:6: type A is unused (U1001)


下面是原始答案。
Dominik Honnef的unused工具可能是您正在寻找的:
通过-exported标志,unused可以将所有参数作为单个程序进行分析,并报告未使用的导出标识符。这对于检查“内部”包或大型软件项目很有用,这些项目不向公众导出API,但在组件之间使用导出的方法。

blmhpbnm

blmhpbnm2#

尝试运行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{}类型的参数)是活动的,第三行声明对fmt.Println的调用是活动的。请注意,它 * 没有 * 说fmt.Println(false)调用是活的,所以我们可以推断它一定是死的。
我知道这不是一个完美的答案,但我希望它能有所帮助。

ilmyapht

ilmyapht3#

这是一个有点脏,但它为我工作。我有很多结构体,我不想手动测试,所以我写了一个脚本,重命名结构体,然后运行所有的测试(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

字符串

bqucvtff

bqucvtff4#

这不是一个开源的解决方案,但它工作。
如果你正在使用Goland,你应该考虑使用它的code-inspections功能,包括有用的功能:

  • 报告未使用的常量
  • 报告未使用的导出函数
  • 报告主包和测试中未使用的导出类型
  • 报告未使用的未导出函数
  • 报告已定义但从未在代码中使用的全局变量
  • 报告未使用的函数参数
  • 报告未使用的类型

(It看起来这个功能的实现是黑盒的,jetbrains没有开源这个功能)
与Go相关的检测工具似乎更强调准确性,他们希望尽最大努力减少错误报告。而使用Golandcode-inspections功能可能需要更多的自我判断。:)
兴趣:仅限付费用户,不为Jetbrains工作,只是认为此功能效果良好。

x6yk4ghg

x6yk4ghg5#

因此,staticcheck不再运行完整的程序分析,不幸的是,这是迄今为止最好的解决方案。
还有https://github.com/bep/punused,它可以工作,但会产生很多误报,例如使用反射和接口的所有内容。但它是目前我所知道的唯一一个仍能运行完整程序分析的工具

pdsfdshx

pdsfdshx6#

我使用过的一种可靠但不优雅的方法是重命名或注解掉您怀疑可能不会使用的函数,然后重新编译所有内容--没有错误意味着您不需要它们。
如果需要它们,它会显示调用这些函数的位置,因此有助于熟悉代码库并了解它们是如何连接的。

相关问题