起因是這樣的,在編譯發布 golang 工程時,希望版本號中包含有 git revision number。 但是,沒有commit之前,是沒法知道 revision number 的,commit之後,如果要修改代碼中 version 的相關信息,又會導致需要再次的 commit。
針對這種情況,希望能夠在編譯時動態的將當前的 git revision number 加入到 version 中。 這樣,每次編譯的時候獲取當前 revision number,寫入編譯完的 二進制中,可以避免現有的代碼(修改現有代碼會導致又需要 commit)。
注 revision number 就是每個 commit 對應的 唯一字符串。
實現的原理很簡單:在 golang 編譯時,通過 ldflags 給代碼中的變量賦值,達到注入 revision number 的目的。
package main
import "fmt"
import "flag"
var (
version = "v0.0.1"
build = "not set"
)
func main() {
var v = flag.Bool("v", false, "display version")
flag.Parse()
if *v {
fmt.Printf("version: %s\n", version)
fmt.Printf("build : %s\n", build)
} else {
fmt.Println("hello, test version")
}
}
上面的代碼編譯運行,效果如下:
$ go build main.go
$ ./main
hello, test version
$ ./main -v
version: v0.0.1
build : not set
通過 ldflags, 動態修改 build
$ go build -ldflags "-X main.build=`git rev-parse HEAD`" main.go
$ ./main -v
version: v0.0.1
build : 23af559af14a0b83c35a7f8bd0670a9741b1dc7e
動態注入版本號,避免了手動修改版本號而導致的再次 commit,也避免了手動操作的繁瑣和錯誤。 為了方便使用,也可以把上面的編譯命令封裝到 makefile 或者某個編譯腳本中。