How to write the version information into the program and the resulting executable binary file, so that the CLI -v or CLI –version can display the version information?
Manually writing or using build scripts is something I’ve always done, but today I’ve found another good way to do it, which is to use -ldFlags to set variable values.
Manual written
This method, which I won’t go into more detail, is to manually write the version number and other information into the configuration file or code before each build release, which is very easy to forget or get wrong!
Using build scripts
If you want to create a Makefile, you need to create a Makefile. If you want to create a Makefile, you need to create a Makefile. If you want to create a Makefile, you need to create a Makefile.
.PHONY build test
build:
go build -o cli main.go
test:
go test .
Copy the code
At this point, I will write the following in the Makefile to set the version information:
VERSION = $(shell git tag --sort=committerdate | tail -n 1)
version:
sed -i "s/version = \".*\"/version = \"$(VERSION)\"/g" pkg/cmd/version.go
Copy the code
PKG/CMD /version.go
const version = "dev"
Copy the code
-ldflags
play
-ldFlags can set the variable value for us, we just need to define the variable in the Go source file.
For example, define three variables related to version information in the main.go file:
package main
var (
version string
commit string
date string
)
func main(a) {
args := os.Args
if len(args) == 2 && (args[1] = ="--version" || args[1] = ="-v") {
fmt.Printf("Release version: %s\n", version)
fmt.Printf("Git commit: %s\n", commit)
fmt.Printf("Build date: %s\n", date)
return}... }Copy the code
Then the Makefile build script reads like this:
NAME := cli
CGO_ENABLED = 0
BUILD_GOOS = $(shell go env GOOS)
GO := go
BUILD_TARGET = build
COMMIT := $(shell git rev-parse --short HEAD)
VERSION := dev-$(shell git describe --tags $(shell git rev-list --tags --max-count=1))
BUILD_FLAGS = -ldflags "-X main.version=$(VERSION) \
-X main.commit=$(COMMIT) \
-X main.date=$(shell date +'%Y-%m-%d')"
MAIN_SRC_FILE = main.go
.PHONY: build
build: pre-build
GO111MODULE=on CGO_ENABLED=$(CGO_ENABLED) GOOS=$(BUILD_GOOS) GOARCH=amd64 $(GO) $(BUILD_TARGET) $(BUILD_FLAGS) -o bin/$(BUILD_GOOS)/$(NAME) $(MAIN_SRC_FILE)
chmod +x bin/$(BUILD_GOOS)/$(NAME)
rm -rf $(NAME) && ln -s bin/$(BUILD_GOOS)/$(NAME) $(NAME)
Copy the code
This allows us to write the version information into the resulting binary without modifying the source code. Nice!