update makefile

Signed-off-by: Jess Frazelle <acidburn@microsoft.com>
diff --git a/.gitignore b/.gitignore
index 7c73e39..518f3e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,3 +48,5 @@
 # Go coverage results
 coverage.txt
 profile.out
+
+!go.mod
diff --git a/.goosarch b/.goosarch
new file mode 100644
index 0000000..1a61703
--- /dev/null
+++ b/.goosarch
@@ -0,0 +1,11 @@
+darwin/amd64
+darwin/386
+freebsd/amd64
+freebsd/386
+linux/arm
+linux/arm64
+linux/amd64
+linux/386
+solaris/amd64
+windows/amd64
+windows/386
diff --git a/.travis.yml b/.travis.yml
index bb43bd6..2995d2c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,3 +11,48 @@
     - stage: Run Test Coverage
       script: make cover
       after_success: bash <(curl -s https://codecov.io/bash)
+    - stage: Build Release
+      script:
+        - make release
+        - echo "Deploying to GitHub releases ..."
+      deploy:
+        provider: releases
+        file:
+          - cross/pkg-darwin-amd64
+          - cross/pkg-darwin-amd64.md5
+          - cross/pkg-darwin-amd64.sha256
+          - cross/pkg-darwin-386
+          - cross/pkg-darwin-386.md5
+          - cross/pkg-darwin-386.sha256
+          - cross/pkg-freebsd-amd64
+          - cross/pkg-freebsd-amd64.md5
+          - cross/pkg-freebsd-amd64.sha256
+          - cross/pkg-freebsd-386
+          - cross/pkg-freebsd-386.md5
+          - cross/pkg-freebsd-386.sha256
+          - cross/pkg-linux-arm
+          - cross/pkg-linux-arm.md5
+          - cross/pkg-linux-arm.sha256
+          - cross/pkg-linux-arm64
+          - cross/pkg-linux-arm64.md5
+          - cross/pkg-linux-arm64.sha256
+          - cross/pkg-linux-amd64
+          - cross/pkg-linux-amd64.md5
+          - cross/pkg-linux-amd64.sha256
+          - cross/pkg-linux-386
+          - cross/pkg-linux-386.md5
+          - cross/pkg-linux-386.sha256
+          - cross/pkg-solaris-amd64
+          - cross/pkg-solaris-amd64.md5
+          - cross/pkg-solaris-amd64.sha256
+          - cross/pkg-windows-amd64
+          - cross/pkg-windows-amd64.md5
+          - cross/pkg-windows-amd64.sha256
+          - cross/pkg-windows-386
+          - cross/pkg-windows-386.md5
+          - cross/pkg-windows-386.sha256
+        skip_cleanup: true
+        on:
+          tags: true
+        api_key:
+          secure: "BNAyNmcLUFQg/ua24FDrBna8MyKHAzUEwHQuglxp4rlp+4CDuFyRWI03N9XnzdOXvl0NnFLwpp154xPhw3O1oqHvEbBnAKZ5yEXtzmXMFlUxBlQa7QJcgFapkyUeNM7FrSr9Pz8TDWGQ8ajRZUSuKJq/NK9geqS55BpxfnvQWfl5BpGsV4D0XM+QDyTbOfdnsCjxsP2T6b7h5v5Yd3xbR5CDlj8kIUxB+ccPQiRz7knnH7v7JLeE4yiee79bwuiOHFJ7RHu8YOZM6f4JDhNwqr4N/qA2m1wyBR+mIt23LxtSpgTx5IAcTdlMvU3Ny7zV1j3R5JmWClxa+tgUZ4FaEfURa8LJ9adWwV9X3HItFaLe5ABpZUSQSDvqz1A6H4qD3SVZMOIrK1y38sYzeuU6BAlTZYtn3Btu1BCTSI8yymqbVBn9siW+Y+JKHsBQs9/7yyI2CC8v4jU54lHnz6NHE58Pc4PgOX8rZTmgn6gLLBLtmJeirjejnPoMTfK/DdX2w5vGTzHxrmuy+0NpHcbsSARvOAnI8Q9fUce3yOI+lVRWFq3v5rK+UTkXzhC7mQcv5yVsHI1CXQf900PX63T4TwHarUQun1+D527RslOSmcCedHXFpuSO4P1cxX2ffj7B4WpaY2hRoJcQAHT6JDdl34oaWt90NLdxh6ZFmQLEWY8="
diff --git a/Makefile b/Makefile
index 83ad90c..abc3f18 100644
--- a/Makefile
+++ b/Makefile
@@ -1,150 +1,16 @@
-# Set an output prefix, which is the local directory if not specified
-PREFIX?=$(shell pwd)
-
 # Setup name variables for the package/tool
 NAME := pkg
 PKG := github.com/genuinetools/$(NAME)
 
-# Set any default go build tags
+CGO_ENABLED := 0
+
+# Set any default go build tags.
 BUILDTAGS :=
 
-# Set the build dir, where built cross-compiled binaries will be output
-BUILDDIR := ${PREFIX}/cross
+# Set our directory to build.
+GO_CMD := ./...
 
-# Populate version variables
-# Add to compile time flags
-VERSION := $(shell cat VERSION.txt)
-GITCOMMIT := $(shell git rev-parse --short HEAD)
-GITUNTRACKEDCHANGES := $(shell git status --porcelain --untracked-files=no)
-ifneq ($(GITUNTRACKEDCHANGES),)
-	GITCOMMIT := $(GITCOMMIT)-dirty
-endif
-CTIMEVAR=-X $(PKG)/version.GITCOMMIT=$(GITCOMMIT) -X $(PKG)/version.VERSION=$(VERSION)
-GO_LDFLAGS=-ldflags "-w $(CTIMEVAR)"
-GO_LDFLAGS_STATIC=-ldflags "-w $(CTIMEVAR) -extldflags -static"
+include basic.mk
 
-# Set our default go compiler
-GO := go
-
-# List the GOOS and GOARCH to build
-GOOSARCHES = darwin/amd64 darwin/386 freebsd/amd64 freebsd/386 linux/arm linux/arm64 linux/amd64 linux/386 solaris/amd64 windows/amd64 windows/386
-
-.PHONY: build
-build: $(NAME) ## Builds a dynamic executable or package
-
-$(NAME): $(wildcard *.go) $(wildcard */*.go) VERSION.txt
-	@echo "+ $@"
-	$(GO) build -tags "$(BUILDTAGS)" ${GO_LDFLAGS} ./...
-
-.PHONY: static
-static: ## Builds a static executable
-	@echo "+ $@"
-	CGO_ENABLED=0 $(GO) build \
-				-tags "$(BUILDTAGS) static_build" \
-				${GO_LDFLAGS_STATIC} ./...
-
-all: clean build fmt lint test staticcheck vet install ## Runs a clean, build, fmt, lint, test, staticcheck, vet and install
-
-.PHONY: fmt
-fmt: ## Verifies all files have been `gofmt`ed
-	@echo "+ $@"
-	@gofmt -s -l . | grep -v '.pb.go:' | grep -v vendor | tee /dev/stderr
-
-.PHONY: lint
-lint: ## Verifies `golint` passes
-	@echo "+ $@"
-	@golint ./... | grep -v '.pb.go:' | grep -v vendor | tee /dev/stderr
-
-.PHONY: test
-test: ## Runs the go tests
-	@echo "+ $@"
-	@$(GO) test -tags "$(BUILDTAGS) cgo" $(shell $(GO) list ./... | grep -v vendor)
-
-.PHONY: vet
-vet: ## Verifies `go vet` passes
-	@echo "+ $@"
-	@$(GO) vet $(shell $(GO) list ./... | grep -v vendor) | grep -v '.pb.go:' | tee /dev/stderr
-
-.PHONY: staticcheck
-staticcheck: ## Verifies `staticcheck` passes
-	@echo "+ $@"
-	@staticcheck $(shell $(GO) list ./... | grep -v vendor) | grep -v '.pb.go:' | tee /dev/stderr
-
-.PHONY: cover
-cover: ## Runs go test with coverage
-	@echo "" > coverage.txt
-	@for d in $(shell $(GO) list ./... | grep -v vendor); do \
-		$(GO) test -race -coverprofile=profile.out -covermode=atomic "$$d"; \
-		if [ -f profile.out ]; then \
-			cat profile.out >> coverage.txt; \
-			rm profile.out; \
-		fi; \
-	done;
-
-.PHONY: install
-install: ## Installs the executable or package
-	@echo "+ $@"
-	$(GO) install -a -tags "$(BUILDTAGS)" ${GO_LDFLAGS} ./...
-
-define buildpretty
-mkdir -p $(BUILDDIR)/$(1)/$(2);
-GOOS=$(1) GOARCH=$(2) CGO_ENABLED=0 $(GO) build \
-	 -o $(BUILDDIR)/$(1)/$(2)/$(NAME) \
-	 -a -tags "$(BUILDTAGS) static_build netgo" \
-	 -installsuffix netgo ${GO_LDFLAGS_STATIC} .;
-md5sum $(BUILDDIR)/$(1)/$(2)/$(NAME) > $(BUILDDIR)/$(1)/$(2)/$(NAME).md5;
-sha256sum $(BUILDDIR)/$(1)/$(2)/$(NAME) > $(BUILDDIR)/$(1)/$(2)/$(NAME).sha256;
-endef
-
-.PHONY: cross
-cross: *.go VERSION.txt ## Builds the cross-compiled binaries, creating a clean directory structure (eg. GOOS/GOARCH/binary)
-	@echo "+ $@"
-	$(foreach GOOSARCH,$(GOOSARCHES), $(call buildpretty,$(subst /,,$(dir $(GOOSARCH))),$(notdir $(GOOSARCH))))
-
-define buildrelease
-GOOS=$(1) GOARCH=$(2) CGO_ENABLED=0 $(GO) build \
-	 -o $(BUILDDIR)/$(NAME)-$(1)-$(2) \
-	 -a -tags "$(BUILDTAGS) static_build netgo" \
-	 -installsuffix netgo ${GO_LDFLAGS_STATIC} .;
-md5sum $(BUILDDIR)/$(NAME)-$(1)-$(2) > $(BUILDDIR)/$(NAME)-$(1)-$(2).md5;
-sha256sum $(BUILDDIR)/$(NAME)-$(1)-$(2) > $(BUILDDIR)/$(NAME)-$(1)-$(2).sha256;
-endef
-
-.PHONY: release
-release: *.go VERSION.txt ## Builds the cross-compiled binaries, naming them in such a way for release (eg. binary-GOOS-GOARCH)
-	@echo "+ $@"
-	$(foreach GOOSARCH,$(GOOSARCHES), $(call buildrelease,$(subst /,,$(dir $(GOOSARCH))),$(notdir $(GOOSARCH))))
-
-.PHONY: bump-version
-BUMP := patch
-bump-version: ## Bump the version in the version file. Set BUMP to [ patch | major | minor ]
-	@$(GO) get -u github.com/jessfraz/junk/sembump # update sembump tool
-	$(eval NEW_VERSION = $(shell sembump --kind $(BUMP) $(VERSION)))
-	@echo "Bumping VERSION.txt from $(VERSION) to $(NEW_VERSION)"
-	echo $(NEW_VERSION) > VERSION.txt
-	@echo "Updating links to download binaries in README.md"
-	sed -i s/$(VERSION)/$(NEW_VERSION)/g README.md
-	git add VERSION.txt README.md
-	git commit -vsam "Bump version to $(NEW_VERSION)"
-	@echo "Run make tag to create and push the tag for new version $(NEW_VERSION)"
-
-.PHONY: tag
-tag: ## Create a new git tag to prepare to build a release
-	git tag -sa $(VERSION) -m "$(VERSION)"
-	@echo "Run git push origin $(VERSION) to push your new tag to GitHub and trigger a travis build."
-
-.PHONY: AUTHORS
-AUTHORS:
-	@$(file >$@,# This file lists all individuals having contributed content to the repository.)
-	@$(file >>$@,# For how it is generated, see `make AUTHORS`.)
-	@echo "$(shell git log --format='\n%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf)" >> $@
-
-.PHONY: clean
-clean: ## Cleanup any build binaries or packages
-	@echo "+ $@"
-	$(RM) $(NAME)
-	$(RM) -r $(BUILDDIR)
-
-.PHONY: help
-help:
-	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
+.PHONY: prebuild
+prebuild:
diff --git a/basic.mk b/basic.mk
new file mode 100644
index 0000000..cdde324
--- /dev/null
+++ b/basic.mk
@@ -0,0 +1,185 @@
+# Set an output prefix, which is the local directory if not specified
+PREFIX?=$(shell pwd)
+
+# Set the build dir, where built cross-compiled binaries will be output
+BUILDDIR := ${PREFIX}/cross
+
+# Populate version variables
+# Add to compile time flags
+VERSION := $(shell cat VERSION.txt)
+GITCOMMIT := $(shell git rev-parse --short HEAD)
+GITUNTRACKEDCHANGES := $(shell git status --porcelain --untracked-files=no)
+ifneq ($(GITUNTRACKEDCHANGES),)
+	GITCOMMIT := $(GITCOMMIT)-dirty
+endif
+ifeq ($(GITCOMMIT),)
+    GITCOMMIT := ${GITHUB_SHA}
+endif
+CTIMEVAR=-X $(PKG)/version.GITCOMMIT=$(GITCOMMIT) -X $(PKG)/version.VERSION=$(VERSION)
+GO_LDFLAGS=-ldflags "-w $(CTIMEVAR)"
+GO_LDFLAGS_STATIC=-ldflags "-w $(CTIMEVAR) -extldflags -static"
+
+# Set our default go compiler
+GO := go
+
+# List the GOOS and GOARCH to build
+GOOSARCHES = $(shell cat .goosarch)
+
+# Set the graph driver as the current graphdriver if not set.
+DOCKER_GRAPHDRIVER := $(if $(DOCKER_GRAPHDRIVER),$(DOCKER_GRAPHDRIVER),$(shell docker info 2>&1 | grep "Storage Driver" | sed 's/.*: //'))
+export DOCKER_GRAPHDRIVER
+
+# If this session isn't interactive, then we don't want to allocate a
+# TTY, which would fail, but if it is interactive, we do want to attach
+# so that the user can send e.g. ^C through.
+INTERACTIVE := $(shell [ -t 0 ] && echo 1 || echo 0)
+ifeq ($(INTERACTIVE), 1)
+	DOCKER_FLAGS += -t
+endif
+
+.PHONY: build
+build: prebuild $(NAME) ## Builds a dynamic executable or package.
+
+$(NAME): $(wildcard *.go) $(wildcard */*.go) VERSION.txt
+	@echo "+ $@"
+	$(GO) build -tags "$(BUILDTAGS)" ${GO_LDFLAGS} $(GO_CMD)
+
+.PHONY: static
+static: prebuild ## Builds a static executable.
+	@echo "+ $@"
+	CGO_ENABLED=$(CGO_ENABLED) $(GO) build \
+				-tags "$(BUILDTAGS) static_build" \
+				${GO_LDFLAGS_STATIC} -o $(NAME) .
+
+all: clean build fmt lint test staticcheck vet install ## Runs a clean, build, fmt, lint, test, staticcheck, vet and install.
+
+.PHONY: fmt
+fmt: ## Verifies all files have been `gofmt`ed.
+	@echo "+ $@"
+	@gofmt -s -l . | grep -v '.pb.go:' | grep -v vendor | tee /dev/stderr
+
+.PHONY: lint
+lint: ## Verifies `golint` passes.
+	@echo "+ $@"
+	@golint ./... | grep -v '.pb.go:' | grep -v vendor | tee /dev/stderr
+
+.PHONY: test
+test: prebuild ## Runs the go tests.
+	@echo "+ $@"
+	@$(GO) test -v -tags "$(BUILDTAGS) cgo" $(shell $(GO) list ./... | grep -v vendor)
+
+.PHONY: vet
+vet: ## Verifies `go vet` passes.
+	@echo "+ $@"
+	@$(GO) vet $(shell $(GO) list ./... | grep -v vendor) | grep -v '.pb.go:' | tee /dev/stderr
+
+.PHONY: staticcheck
+staticcheck: ## Verifies `staticcheck` passes.
+	@echo "+ $@"
+	@staticcheck $(shell $(GO) list ./... | grep -v vendor) | grep -v '.pb.go:' | tee /dev/stderr
+
+.PHONY: cover
+cover: prebuild ## Runs go test with coverage.
+	@echo "" > coverage.txt
+	@for d in $(shell $(GO) list ./... | grep -v vendor); do \
+		$(GO) test -race -coverprofile=profile.out -covermode=atomic "$$d"; \
+		if [ -f profile.out ]; then \
+			cat profile.out >> coverage.txt; \
+			rm profile.out; \
+		fi; \
+	done;
+
+.PHONY: install
+install: prebuild ## Installs the executable or package.
+	@echo "+ $@"
+	$(GO) install -a -tags "$(BUILDTAGS)" ${GO_LDFLAGS} $(GO_CMD)
+
+define buildpretty
+mkdir -p $(BUILDDIR)/$(1)/$(2);
+GOOS=$(1) GOARCH=$(2) CGO_ENABLED=$(CGO_ENABLED) $(GO) build \
+	 -o $(BUILDDIR)/$(1)/$(2)/$(NAME) \
+	 -a -tags "$(BUILDTAGS) static_build netgo" \
+	 -installsuffix netgo ${GO_LDFLAGS_STATIC} $(GO_CMD);
+md5sum $(BUILDDIR)/$(1)/$(2)/$(NAME) > $(BUILDDIR)/$(1)/$(2)/$(NAME).md5;
+sha256sum $(BUILDDIR)/$(1)/$(2)/$(NAME) > $(BUILDDIR)/$(1)/$(2)/$(NAME).sha256;
+endef
+
+.PHONY: cross
+cross: *.go VERSION.txt prebuild ## Builds the cross-compiled binaries, creating a clean directory structure (eg. GOOS/GOARCH/binary).
+	@echo "+ $@"
+	$(foreach GOOSARCH,$(GOOSARCHES), $(call buildpretty,$(subst /,,$(dir $(GOOSARCH))),$(notdir $(GOOSARCH))))
+
+define buildrelease
+GOOS=$(1) GOARCH=$(2) CGO_ENABLED=$(CGO_ENABLED) $(GO) build \
+	 -o $(BUILDDIR)/$(NAME)-$(1)-$(2) \
+	 -a -tags "$(BUILDTAGS) static_build netgo" \
+	 -installsuffix netgo ${GO_LDFLAGS_STATIC} $(GO_CMD);
+md5sum $(BUILDDIR)/$(NAME)-$(1)-$(2) > $(BUILDDIR)/$(NAME)-$(1)-$(2).md5;
+sha256sum $(BUILDDIR)/$(NAME)-$(1)-$(2) > $(BUILDDIR)/$(NAME)-$(1)-$(2).sha256;
+endef
+
+.PHONY: release
+release: *.go VERSION.txt prebuild ## Builds the cross-compiled binaries, naming them in such a way for release (eg. binary-GOOS-GOARCH).
+	@echo "+ $@"
+	$(foreach GOOSARCH,$(GOOSARCHES), $(call buildrelease,$(subst /,,$(dir $(GOOSARCH))),$(notdir $(GOOSARCH))))
+
+.PHONY: bump-version
+BUMP := patch
+bump-version: ## Bump the version in the version file. Set BUMP to [ patch | major | minor ].
+	@$(GO) get -u github.com/jessfraz/junk/sembump # update sembump tool
+	$(eval NEW_VERSION = $(shell sembump --kind $(BUMP) $(VERSION)))
+	@echo "Bumping VERSION.txt from $(VERSION) to $(NEW_VERSION)"
+	echo $(NEW_VERSION) > VERSION.txt
+	@echo "Updating links to download binaries in README.md"
+	sed -i s/$(VERSION)/$(NEW_VERSION)/g README.md
+	git add VERSION.txt README.md
+	git commit -vsam "Bump version to $(NEW_VERSION)"
+	@echo "Run make tag to create and push the tag for new version $(NEW_VERSION)"
+
+.PHONY: tag
+tag: ## Create a new git tag to prepare to build a release.
+	git tag -sa $(VERSION) -m "$(VERSION)"
+	@echo "Run git push origin $(VERSION) to push your new tag to GitHub and trigger a travis build."
+
+REGISTRY := r.j3ss.co
+.PHONY: image
+image: ## Create the docker image from the Dockerfile.
+	@docker build --rm --force-rm -t $(REGISTRY)/$(NAME) .
+
+.PHONY: image-dev
+image-dev:
+	@docker build --rm --force-rm -f Dockerfile.dev -t $(REGISTRY)/$(NAME):dev .
+
+.PHONY: AUTHORS
+AUTHORS:
+	@$(file >$@,# This file lists all individuals having contributed content to the repository.)
+	@$(file >>$@,# For how it is generated, see `make AUTHORS`.)
+	@echo "$(shell git log --format='\n%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf)" >> $@
+
+.PHONY: vendor
+vendor: ## Updates the vendoring directory.
+	@$(RM) go.sum
+	@$(RM) -r vendor
+	GO111MODULE=on $(GO) mod init || true
+	GO111MODULE=on $(GO) mod tidy
+	GO111MODULE=on $(GO) mod vendor
+	@$(RM) Gopkg.toml Gopkg.lock
+
+.PHONY: clean
+clean: ## Cleanup any build binaries or packages.
+	@echo "+ $@"
+	$(RM) $(NAME)
+	$(RM) -r $(BUILDDIR)
+
+.PHONY: help
+help:
+	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | sed 's/^[^:]*://g' | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
+
+check_defined = \
+    $(strip $(foreach 1,$1, \
+	$(call __check_defined,$1,$(strip $(value 2)))))
+
+__check_defined = \
+    $(if $(value $1),, \
+    $(error Undefined $1$(if $2, ($2))$(if $(value @), \
+    required by target `$@')))