Golang - 如何从代码内部显示模块版本

Séb*_*ien 10 go go-modules

我正在编写两个二进制文件,它们都使用两个库(我们可以称它们为 libA 和 libB)。

每个库都位于专用的 git 存储库中,并使用 git 标签来声明版本。例如,libA 的版本为 v1.0.9,libB 的版本为 v0.0.12。

两个二进制文件都有 CLI 标志,我想添加一个调试标志来显示 lib 版本,如下所示:

> ./prog -d
Used libraries:
- libA, v1.0.9
- libB, v0.0.12
Run Code Online (Sandbox Code Playgroud)

我不知道该怎么做。

我看到从“外部”设置变量的唯一方法是使用 ldflags (go build -ldflags="-X 'main.Version=v1.0.0'"例如)。但这种方式似乎不可扩展,如何添加libC?它还意味着管理标签两次,一次在 git 中,一次在 goreleaser.yml 或 makefile 中。

你能帮我找到解决方案吗?

icz*_*cza 14

Go 工具在可执行二进制文件中包含模块和依赖项信息。您可以使用runtime/debug.ReadBuildInfo()它来获取它。它会返回依赖项列表,包括模块路径和版本。debug.Module每个模块/依赖项都由包含以下信息的类型值描述:

type Module struct {
    Path    string  // module path
    Version string  // module version
    Sum     string  // checksum
    Replace *Module // replaced by this module
}
Run Code Online (Sandbox Code Playgroud)

例如:

package main

import (
    "fmt"
    "log"
    "runtime/debug"

    "github.com/icza/bitio"
)

func main() {
    _ = bitio.NewReader
    bi, ok := debug.ReadBuildInfo()
    if !ok {
        log.Printf("Failed to read build info")
        return
    }

    for _, dep := range bi.Deps {
        fmt.Printf("Dep: %+v\n", dep)
    }
}
Run Code Online (Sandbox Code Playgroud)

输出(在Go Playground上尝试):

Dep: &{Path:github.com/icza/bitio Version:v1.0.0 Sum:h1:squ/m1SHyFeCA6+6Gyol1AxV9nmPPlJFT8c2vKdj3U8= Replace:<nil>}
Run Code Online (Sandbox Code Playgroud)

另请参阅相关问题:如何获取 Go 详细的构建日志,以及 GOPATH 和“go module”模式下所有使用的包?