# paths makefile := $(realpath $(lastword $(MAKEFILE_LIST))) root_dir := $(shell dirname $(makefile)) cmd_dir := $(root_dir)/cmd/cheat dist_dir := $(root_dir)/dist # executables CAT := cat COLUMN := column CTAGS := ctags GO := go GREP := grep LINT := revive MKDIR := mkdir -p RM := rm SCC := scc SED := sed SORT := sort ZIP := zip -m # build flags BUILD_FLAGS := -ldflags="-s -w" -mod vendor GOBIN := # NB: this is a kludge to specify the desired build targets. This information # would "naturally" be best structured as an array of structs, but lacking that # capability, we're condensing that information into strings which we will # later split. # # Format: /// .PHONY: $(RELEASES) RELEASES := \ amd64/darwin/0/cheat-darwin-amd64 \ amd64/linux/0/cheat-linux-amd64 \ amd64/windows/0/cheat-windows-amd64.exe \ arm/linux/5/cheat-linux-arm5 \ arm/linux/6/cheat-linux-arm6 \ arm/linux/7/cheat-linux-arm7 # macros to unpack the above parts = $(subst /, ,$@) arch = $(word 1, $(parts)) os = $(word 2, $(parts)) arm = $(word 3, $(parts)) bin = $(word 4, $(parts)) ## build: builds an executable for your architecture .PHONY: build build: clean generate $(GO) build $(BUILD_FLAGS) -o $(dist_dir)/cheat $(cmd_dir) ## build-release: builds release executables .PHONY: build-release build-release: $(RELEASES) .PHONY: generate generate: $(GO) generate $(cmd_dir) .PHONY: $(RELEASES) $(RELEASES): clean generate check ifeq ($(arch),arm) GOARCH=$(arch) GOOS=$(os) GOARM=$(arm) $(GO) build $(BUILD_FLAGS) -o $(dist_dir)/$(bin) $(cmd_dir) && \ $(ZIP) $(dist_dir)/$(bin).zip $(dist_dir)/$(bin) else GOARCH=$(arch) GOOS=$(os) $(GO) build $(BUILD_FLAGS) -o $(dist_dir)/$(bin) $(cmd_dir) && \ $(ZIP) $(dist_dir)/$(bin).zip $(dist_dir)/$(bin) endif ## install: builds and installs cheat on your PATH .PHONY: install install: $(GO) install $(BUILD_FLAGS) $(GOBIN) $(cmd_dir) $(dist_dir): $(MKDIR) $(dist_dir) ## clean: removes compiled executables .PHONY: clean clean: $(dist_dir) $(RM) -f $(dist_dir)/* ## distclean: removes the tags file .PHONY: distclean distclean: $(RM) $(root_dir)/tags ## setup: installs revive (linter) and scc (sloc tool) .PHONY: setup setup: GO111MODULE=off $(GO) get -u github.com/boyter/scc github.com/mgechev/revive ## sloc: counts "semantic lines of code" .PHONY: sloc sloc: $(SCC) --exclude-dir=vendor ## tags: builds a tags file .PHONY: tags tags: $(CTAGS) -R $(root_dir) --exclude=$(root_dir)/vendor ## vendor: downloads, tidies, and verifies dependencies .PHONY: vendor vendor: lint # kludge: revive appears to complain if the vendor directory disappears while a lint is running $(GO) mod vendor && $(GO) mod tidy && $(GO) mod verify ## fmt: runs go fmt .PHONY: fmt fmt: $(GO) fmt $(root_dir)/... ## lint: lints go source files .PHONY: lint lint: $(LINT) -exclude $(root_dir)/vendor/... $(root_dir)/... && \ $(GO) vet $(root_dir)/... ## test: runs unit-tests .PHONY: test test: $(GO) test $(root_dir)/... ## check: formats, lints, vendors, and run unit-tests .PHONY: check check: fmt lint vendor test ## help: displays this help text .PHONY: help help: @$(CAT) $(makefile) | \ $(SORT) | \ $(GREP) "^##" | \ $(SED) 's/## //g' | \ $(COLUMN) -t -s ':'