You have developed a CLI for your Go program. You even added the version sub-command following the useful semantic versioning: vMAJOR.MINOR.PATCH

const Major = "1"
const Minor = "2"
const Fix = "1"
const Verbal = "TBB Training Ledger - HTTPS"

var versionCmd = &cobra.Command{
   Use:   "version",
   Short: "Describes version.",
   Run: func(cmd *cobra.Command, args []string) {
      fmt.Println(fmt.Sprintf("Version: %s.%s.%s-alpha %s", Major, Minor, Fix, Verbal))
   },
}

A few days later, you discover an urgent bug.

You quickly fix the code, compile the code, release the new binary and tell your users to download the latest version.

But, some users are complaining the bug prevails. You ask them to run the version sub-command to ensure their binary is up-to-date.

$ tbb version
Version: 1.2.1-alpha TBB Training Ledger - HTTPS

Ooops.

You realize you forgot to change the version. Solution? Automate the build process to inject the latest Git commit into your binary during the compilation time!

Step 1)

Define a new global variable that will be populated during the build using the -ldflags Go feature, and it's going to be part of the version output.

// Configured via -ldflags during build
var GitCommit string

var versionCmd = &cobra.Command{
   Use:   "version",
   Short: "Describes version.",
   Run: func(cmd *cobra.Command, args []string) {
      fmt.Println(fmt.Sprintf("Version: %s.%s.%s-alpha %s %s", Major, Minor, Fix, shortGitCommit(GitCommit), Verbal))
   },
}

// Bonus, shorten the git commit to first 6 chars for readability
func shortGitCommit(fullGitCommit string) string {
   shortCommit := ""
   if len(fullGitCommit) >= 6 {
      shortCommit = fullGitCommit[0:6]
   }

   return shortCommit
}

Step 2)

Add two new variables into your Makefile:

  • GIT_COMMIT populated with latest commit using the git rev-list command, listing commit objects in reverse chronological order
  • LDFLAGS with instructions to pass the GIT_COMMIT into the main.GitCommit var

And pass the GitCommit argument into your program using the ldflags on make build:

GIT_COMMIT:=$(shell git rev-list -1 HEAD)
LDFLAGS:=-X main.GitCommit=${GIT_COMMIT}

install:
   go install -ldflags "$(LDFLAGS)" ./...

Step 3)

Run the make install and enjoy the detailed version output:

$ make install
> go install -ldflags "-X main.GitCommit=ed441aee39e11...160" ./...

$ tbb version
> Version: 1.2.1-alpha ed441a TBB Training Ledger - HTTPS

You can see the full source code with the changes here: https://github.com/web3coach/the-blockchain-bar/commit/fecdd0fe12a6d37bcd520da2202c6093f32a241f

Get Started with Blockchain Development

Hi, I am writing an eBook on how to build a peer-to-peer system in Go from scratch!

Follow how the main protagonist Andrej, a web developer by day and a bartender by night, learns real-world use of blockchain through the growth of his new business venture: "The Blockchain Bar".

Free chapter