Go实现获取编译程序的git编译时间、提交时间等环境变量

在 Go 中借助标准库 runtime.debug 这个包的ReadBuildInfo函数去获取编译程序的各种信息,这个信息结构体如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
type BuildInfo struct {
// GoVersion is the version of the Go toolchain that built the binary
// (for example, "go1.19.2").
GoVersion string

// Path is the package path of the main package for the binary
// (for example, "golang.org/x/tools/cmd/stringer").
Path string

// Main describes the module that contains the main package for the binary.
Main Module

// Deps describes all the dependency modules, both direct and indirect,
// that contributed packages to the build of this binary.
Deps []*Module

// Settings describes the build settings used to build the binary.
Settings []BuildSetting
}

上面的结构体就可以获取到 go 的版本信息、路径等信息,其中Settings字段就包含了 git 相关的编译时间、提交 hash 等数据,BuildSetting 类型结构体如下:

1
2
3
4
5
6
type BuildSetting struct {
// Key and Value describe the build setting.
// Key must not contain an equals sign, space, tab, or newline.
// Value must not contain newlines ('\n').
Key, Value string
}

其中 Key 的的取值如下:

  • -buildmode: the buildmode flag used (typically “exe”)
  • -compiler: the compiler toolchain flag used (typically “gc”)
  • CGO_ENABLED: the effective CGO_ENABLED environment variable
  • CGO_CFLAGS: the effective CGO_CFLAGS environment variable
  • CGO_CPPFLAGS: the effective CGO_CPPFLAGS environment variable
  • CGO_CXXFLAGS: the effective CGO_CXXFLAGS environment variable
  • CGO_LDFLAGS: the effective CGO_LDFLAGS environment variable
  • GOARCH: the architecture target
  • GOAMD64/GOARM/GO386/etc: the architecture feature level for GOARCH
  • GOOS: the operating system target
  • vcs: the version control system for the source tree where the build ran
  • vcs.revision: the revision identifier for the current commit or checkout
  • vcs.time: the modification time associated with vcs.revision, in RFC3339 format
  • vcs.modified: true or false indicating whether the source tree had local modifications

从上述描述信息可以得知,BuildSetting 这个结构体以Key/Value的方式去存储各种编译信息,包含了 CGO,GOOS、GOARCH、VCS等各类信息,下面写一个程序来获取:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// buildInfo 输出编译信息中的修订版本和构建时间。
// 该函数尝试从debug.BuildInfo中提取VCS修订版本和构建时间,并打印出来。
func buildInfo() {
// 尝试读取编译信息,如果成功则继续处理。
if buildInfo, ok := debug.ReadBuildInfo(); ok {
// 在编译信息的设置中查找VCS修订版本。
revision, ok := lo.Find(buildInfo.Settings, func(setting debug.BuildSetting) bool {
return setting.Key == "vcs.revision"
})
if ok {
// 如果找到了修订版本,打印出来。
fmt.Println(revision.Value)
}

// 在编译信息的设置中查找VCS构建时间。
buildTime, ok := lo.Find(buildInfo.Settings, func(setting debug.BuildSetting) bool {
return setting.Key == "vcs.time"
})
if ok {
// 如果找到了构建时间,解析并打印出来。
// 时间格式化为"2006-01-02 15:04:05 -0700 MST"。
parse, _ := time.Parse(time.RFC3339, buildTime.Value)
fmt.Println(parse.Format(time.DateTime))
}
}
}

该 Go 函数 buildInfo()旨在从程序的编译元数据中提取并展示两个关键信息:版本控制系统的最新修订编号(Revision)以及构建发生的具体时间。下面是该函数执行步骤的详细分解:

  1. 读取构建信息:
    首先调用 debug.ReadBuildInfo()尝试获取当前程序的构建元数据。此函数返回一个debug.BuildInfo结构体,其中包含了编译时的各种信息,如依赖关系、编译选项等。

  2. 查找 VCS 修订号:
    使用 lo.Find()函数(假设 lo 包已导入,这是一个辅助库提供列表处理功能),遍历 buildInfo.Settings 切片来查找键为”vcs.revision”的条目。这是为了提取版本控制系统中的最后一次提交的修订标识。
    如果找到匹配的设置项,则通过 revision.Value 打印出该修订号。

  3. 查找并格式化构建时间:
    同样利用 lo.Find()方法,在设置中寻找键为”vcs.time”的条目,该条目通常包含最后一次 VCS 提交的时间戳。
    发现时间戳后,尝试使用 time.Parse()函数按照 RFC3339 格式解析该时间字符串到 time.Time 类型。此步骤假设时间数据是符合 RFC3339 标准的字符串。


Go实现获取编译程序的git编译时间、提交时间等环境变量
https://sunshinechen.cn/2024/06/19/Go实现获取编译程序的git编译时间、提交时间等环境变量/
作者
sunshine
发布于
2024年6月19日
许可协议