如何获取Go程序所有依赖包的校验和,含同一模块内的子包?
Go的校验和本身是模块维度设计的,官方没有提供包级别的校验和能力,你遇到的pkgA没有出现在debug.ReadBuildInfo()输出里,确实是因为它和pkgB属于同一个模块,该接口仅会返回依赖的外部模块的整体校验和,不会输出同模块内的子包信息。
如果确实有获取子包校验和的需求,可参考以下两种实现方案:
方案1:构建阶段嵌入子包哈希
你可以在构建二进制时,先通过go list -deps命令拿到程序依赖的所有包路径,逐包计算源码哈希后,通过ldflags参数把哈希值嵌入到二进制变量中,运行时直接读取变量即可。
示例构建流程:# 导出所有依赖包路径到文件 go list -deps ./main.go > all_pkgs.txt # 遍历计算每个包的源码哈希,通过ldflags注入到代码变量中 go build -ldflags "-X main.pkgHashes=$(cat all_pkgs.txt | xargs sha256sum | tr '\n' ';')"代码中提前声明对应变量接收注入值即可:
package main // 该变量值会在构建时自动注入 var pkgHashes string方案2:基于模块校验和关联子包
同一模块下的所有子包内容和模块本身的校验和是绑定的,只要模块校验和没有变化,模块下所有子包的内容就和go.sum中记录的版本完全一致。你可以先通过debug.ReadBuildInfo()拿到模块的校验和,再通过模块路径匹配对应子包的归属即可。示例:如果模块路径为
example,那么example/pkgA、example/pkgB都属于该模块,只要模块校验和为v0.0.0-20210225235400-92e28d816f64,就代表这两个子包的内容和对应版本的模块内容完全一致。
需要注意,Go官方的校验和数据库sum.golang.org也仅存储模块级别的校验和,没有子包维度的官方校验和记录。
内容的提问来源于stack exchange,提问作者Aristos Athens
相关产品推荐
相关产品推荐

