一、参考资料 Golang中管理程序的版本信息Golang程序版本管理ldflags_使用ldflags设置Go应用程序的版本信息软件项目版本号的命名规则及格式官方文档_ldflags官方文档_link 二、版本信息 2.1 使用目的日期:2022-01-25 11:02:18
作者:JonathanJiang
此文章为个人笔记,有误请指正,推荐读者查看参考资料的原文
追踪、管理软件的变更迭代,能够提高开发效率
2.2GNU
命名方式
主版本号 . 子版本号 [. 修正版本号 [. 编译版本号 ]]
Major_Version_Number.Minor_Version_Number[.Revision_Number[.Build_Number]]
示例 : 1.2.1、 2.0、 5.0.0 build-13124
情景 | 主版本号 | 子版本号 | 修正版本 | 最终版本号 |
---|---|---|---|---|
项目初始版本 | 1 | 0 | 0 | 1.0.0 |
修复bug或局部修改 | 不变 | 不变 | +1 | 1.0.1 |
增加功能、兼容优化、性能优化 | 不变 | +1 | 归零 | 1.1.0 |
重大修改或修改过多,导致项目整体发生变化,无法向前兼容 | +1 | 归零 | 归零 | 2.0.0 |
以docker
举例,查看版本信息有子命令
与参数
两种方式
# 使用参数查看
jonathanjiang@linux:~$ docker -v
Docker version 20.10.12, build e91ed57
# 使用子命令查看
jonathanjiang@linux:~$ docker version
Client: Docker Engine - Community
Version: 20.10.12
API version: 1.41
Go version: go1.16.12
Git commit: e91ed57
Built: Mon Dec 13 11:45:33 2021
OS/Arch: linux/amd64
Context: default
Experimental: true
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/version": dial unix /var/run/docker.sock: connect: permission denied
三、硬编码版本信息(不推荐)后续的代码中模仿docker的形式,提供版本信息
项目simple_app
目录结构
jonathanjiang@linux:simple_app$ tree
.
├── app
├── go.mod
├── main.go
├── simple_app
└── version
└── version.go
1 directory, 5 files
将版本信息单独放入version包中,引用即可
main.go
代码
package main
import (
"flag"
"fmt"
"gitee.com/Jonathan_Jiang/simple_app/version"
)
func main() {
v := flag.Bool("v", false, "Print Version")
flag.Parse()
vi := version.GetVersion()
// 参数获取
if *v {
fmt.Printf("SimpleApp Version %s Built %s \n", vi.Version, vi.Built)
return
}
// 命令方式
args := flag.Args()
if len(args) > 0 && args[0] == "version" {
fmt.Printf("Version: \t %s \n", vi.Version)
fmt.Printf("Built: \t\t %s \n", vi.Built)
fmt.Printf("Platform: \t %s \n", vi.Platform)
fmt.Printf("GoVersion: \t %s \n", vi.GoVersion)
fmt.Printf("GitCommit: \t %s \n", vi.GitCommit)
return
}
// 正常执行
fmt.Println("start app")
}
version/version.go
代码
package version
type VersionInfo struct {
Version string `json:"version"`
Built string `json:"built"`
Platform string `json:"platform"`
GoVersion string `json:"go_version"`
GitCommit string `json:"git_commit"`
}
func GetVersion() VersionInfo {
return VersionInfo{
Version: "1.0.0",
Built: "mock",
Platform: "mock",
GoVersion: "mock",
GitCommit: "mock",
}
}
使用效果
# 编译程序,-o app 命名为app
jonathanjiang@linux:simple_app$ go build
# 参数方式,查询版本信息
jonathanjiang@linux:simple_app$ ./simple_app -v
SimpleApp Version 1.0.0 Built mock
# 命令方式,查询版本信息
jonathanjiang@linux:simple_app$ ./simple_app version
Version: 1.0.0
Built: mock
Platform: mock
GoVersion: mock
GitCommit: mock
# 正常执行
jonathanjiang@linux:simple_app$ ./simple_app
start app
四、link
版本信息(推荐)
优化
版本信息一般是在发布时确定的,所以最好不要写死在代码中。最好是在编译时传入信息,类似C/C++在代码中预置版本宏定义,在编译中从外部传入版本号,虽然golang不支持宏定义,但是提供了link
去处理相似场景
link
基础
go build -ldflags
,编译时将参数传递给go tool link
go tool link -X importpath.name=value
,将importpath.name
的值设置为value
修改version/version.go
代码
package version
import (
"fmt"
"runtime"
)
var (
// 声明包变量,方便link设置值
// 尽量不要作为函数入参使用
version string
built string
git_commit string
)
type VersionInfo struct {
Version string `json:"version"`
Built string `json:"built"`
Platform string `json:"platform"`
GoVersion string `json:"go_version"`
GitCommit string `json:"git_commit"`
}
func GetVersion() VersionInfo {
// 使用runtime读取go信息
return VersionInfo{
Version: version,
Built: built,
Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
GoVersion: runtime.Version(),
GitCommit: git_commit,
}
}
使用
# 编译
jonathanjiang@linux:simple_app$ go build -ldflags="-X 'gitee.com/Jonathan_Jiang/simple_app/version.version=1.0.1' -X 'gitee.com/Jonathan_Jiang/simple_app/version.built=2022-01-26T16:57:31+0800' -X 'gitee.com/Jonathan_Jiang/simple_app/version.git_commit=abcdef'"
# 打印
jonathanjiang@linux:simple_app$ ./simple_app version
Version: 1.0.1
Built: 2022-01-26T16:57:31+0800
Platform: linux/amd64
GoVersion: go1.17.2
GitCommit: abcdef
jonathanjiang@linux:simple_app$ ./simple_app -v
SimpleApp Version 1.0.1 Built 2022-01-26T16:57:31+0800
注意:
importpath是指变量的包路径,比如我在main包中引用version包,其引用路径是gitee.com/Jonathan_Jiang/simple_app/version
,那么你在go build
时就要把包路径带进去,不然link
找不到变量,也就无法赋值
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)