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

-ldflagsplay

-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!