When golang compiles, it assigns values to variables in the package to print version number and commit

Posted by MitchEvans on Fri, 29 Nov 2019 17:15:07 +0100

Many command-line programs can output version information, commit, operating system and other information through the version parameter. Here is a method to print the version number of the command line program compiled by golang.

Version information printed by docker:

$ ~ docker version
Client: Docker Engine - Community
 Version:           18.09.2
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        6247962
 Built:             Sun Feb 10 04:12:39 2019
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.2
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.6
  Git commit:       6247962
  Built:            Sun Feb 10 04:13:06 2019
  OS/Arch:          linux/amd64
  Experimental:     false

The implementation method is to use ldflags, a parameter of go build. Enter go help build to see a configuration item:

-ldflags 'flag list' arguments to pass on each go tool link invocation.

This parameter is used to set some parameters of go link (static link). The specific parameters can be viewed through go tool link --help.

The - X parameter can be used to assign values to variables in the package at compile time. Then we can use the flag package to set the version parameter to print the version number.

main.go:

package main

import (
    "flag"
    "log"
    "os"
)

var (
    Version   string
    Branch    string
    Commit    string
    BuildTime string
    lowercase string // Lower case is OK
)

func main() {
    versionFlag := flag.Bool("version", false, "print the version")
    flag.Parse()

    if *versionFlag {
        log.Printf("Version: %s\n", Version)
        log.Printf("Branch: %s\n", Branch)
        log.Printf("Commit: %s\n", Commit)
        log.Printf("BuildTime: %s\n", BuildTime)
        log.Printf("lowercase: %s\n", lowercase)
        os.Exit(0)
    }

    log.Println("run main.go")
}

Package script:

#!/usr/bin/env bash

prog=xxx
version=1.1.0
lowercase=ok

# Cross compilation
# CGO_ENABLED=0 GOOS=linux GOARCH=amd64
go build -ldflags "\
-X main.Version=$version \
-X main.Branch=`git rev-parse --abbrev-ref HEAD` \
-X main.Commit=`git rev-parse HEAD` \
-X main.BuildTime=`date -u '+%Y-%m-%d_%H:%M:%S'` \
-X main.lowercase=$lowercase \
" -v -o $prog main.go

Final effect:

$ ./xxx -version
2019/04/11 00:59:08 Version: 1.1.0
2019/04/11 00:59:08 Branch: master
2019/04/11 00:59:08 Commit: 29921d9df18543693321e2109ea36462dbb346d3
2019/04/11 00:59:08 BuildTime: 2019-04-10_16:59:07
2019/04/11 00:59:08 lowercase: ok

Topics: Go Docker git Linux