Skip to content

Instantly share code, notes, and snippets.

@jaytaylor
Last active March 27, 2020 16:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jaytaylor/a4b335fd93efd4211473 to your computer and use it in GitHub Desktop.
Save jaytaylor/a4b335fd93efd4211473 to your computer and use it in GitHub Desktop.
Golang automatic Makefile.
################################################################################
# Golang automatic Makefile #
################################################################################
##
#
# @author Jay Taylor <jay@gigawatt.io>
#
# @date 2015-05-20
#
# @description Automatically builds go projects, including ones with nested
# packages.
#
##
MAKEFLAGS += --warn-undefined-variables
SHELL := bash
#.SHELLFLAGS := -o errexit -o pipefail -o nounset -o xtrace -c
.SHELLFLAGS := -o errexit -o pipefail -o nounset -c
RM := rm -rf
# Automatically discover all buildable targets.
BUILDABLE_PACKAGES := $(shell \
test -r .Makefile.packages.cache && cat .Makefile.packages.cache \
|| \
find . \
-not \( -path ./Godeps -prune \) \
-type f \
-name "*.go" \
-exec bash -c 'test -n "`tr "\n" " " < "{}" | grep "^package main .* func main() { .* }"`" && echo {}' \; \
| xargs -n1 -IX bash -c '( cd "`dirname "X"`" && go list && cd - 1>/dev/null ) | sed "s|^\([^\/]*\/\)\{0,1\}\(.*\)|`dirname "X"`\/\2:`dirname "X"`|"' \
| tee .Makefile.cache \
)
BUILD_DATE := $(shell date +%Y-%m-%dT%H:%M:%S%z)
BUILD_HASH := $(shell git log -1 | head -n 1 | cut -d ' ' -f 2)
all: generate build
generate:
set -e
go generate ./...
build:
set -e
$(foreach PACKAGE_INFO,$(BUILDABLE_PACKAGES), \
$(eval ARTIFACT = $(word 1,$(subst :, ,$(PACKAGE_INFO)))) \
$(eval PACKAGE_PATH = $(word 2,$(subst :, ,$(PACKAGE_INFO)))) \
godep go build -ldflags "-X main.BuildTimeStr $(BUILD_DATE) -X main.BuildCommitHash $(BUILD_HASH)" -o $(ARTIFACT) $(PACKAGE_PATH) ; \
)
clean:
$(RM) $(foreach PACKAGE_INFO,$(BUILDABLE_PACKAGES), \
$(eval ARTIFACT = $(word 1,$(subst :, ,$(PACKAGE_INFO)))) \
$(ARTIFACT) \
)
package main
import (
"flag"
"fmt"
"io"
"os"
"strings"
"time"
)
const (
VERSION_MAJOR = "0.1"
VERSION_MINOR = "0"
ISO8601 = "2006-01-02T15:04:05-0700" // ISO-8601 date-time formatting string.
)
// Versioning detail information, set during build phase.
var (
BuildTime time.Time
BuildTimeStr string
BuildCommitHash string
)
func init() {
// Parse BuildTimeStr into BuildTime.
if BuildTimeStr != "" {
var err error
if BuildTime, err = time.Parse(ISO8601, BuildTimeStr); err != nil {
panic(fmt.Sprintf(`Parsing BuildTimeStr="%s" failed: %s`, BuildTimeStr, err))
}
}
flag.Usage = func() {
DisplayVersion(os.Stderr, "\n")
fmt.Fprintln(os.Stderr, "usage:")
flag.PrintDefaults()
}
}
func DisplayVersion(writer io.Writer, delimiter string) {
pieces := strings.Split(os.Args[0], "/")
fmt.Fprintf(writer, "%s v%s.%s%s", pieces[len(pieces)-1], VERSION_MAJOR, VERSION_MINOR, delimiter)
fmt.Fprintf(writer, "built on %s%s", BuildTime, delimiter)
fmt.Fprintf(writer, "commit hash %s\n", BuildCommitHash)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment