PREFIX  = /usr/local
BIN_DIR = $(PREFIX)/bin
MANDIR  = $(PREFIX)/share/man
MAN8DIR = $(MANDIR)/man8

APP_NAME = $(notdir $(CURDIR))

MANPAGE = $(APP_NAME).8

GO      = go
RM      = rm --recursive --force
MOD     = go.mod
SUM     = go.sum
INSTALL = install
TOUCH   = touch
MKDIR   = mkdir --parents

GO_FILES  != find . -name '*.go'
BUILD_MOD  = build.mod
COVER_FILE = coverage.out
TEST_LOG   = test.log

VERSION        = $(shell ./$(APP_NAME) -v)
RELEASE        = $(APP_NAME)-$(VERSION)
ARCHIVE_FORMAT = tar.gz

# Keep offline package builds independent of test dependencies and go mod tidy.
$(APP_NAME): $(GO_FILES) $(MOD) $(BUILD_MOD)
	$(GO) build -modfile=$(BUILD_MOD) -mod=readonly -o $(APP_NAME) cmd/main.go

all: $(APP_NAME) doc

$(MOD):
	$(GO) mod init gitlab.com/M0M097/$(APP_NAME)

$(SUM): $(GO_FILES) $(MOD)
	$(GO) mod tidy
	$(TOUCH) $@

clean:
	$(RM) $(APP_NAME) $(COVER_FILE) $(TEST_LOG) *$(ARCHIVE_FORMAT)

run: $(APP_NAME)
	./$<

# Requires go from the `google-go-lang` package
$(COVER_FILE): $(GO_FILES) $(SUM) $(MOD)
	$(GO) test -coverprofile=$@ ./...

# Requires go from the `google-go-lang` package
cover: $(COVER_FILE)
	$(GO) tool cover -html=$<

# Requires go from the `google-go-lang` package
vet: $(GO_FILES) $(SUM) $(MOD)
	$(GO) vet ./...

test: $(TEST_LOG)
	cat $<
	@! grep -q -E 'FAIL|panic|fatal' $<

$(TEST_LOG): $(GO_FILES) $(MOD) $(SUM)
	$(GO) test -vet=off ./... > $@ || true

fmt:
	$(GO) fmt ./...

install: $(APP_NAME) $(BIN_DIR)/ $(MAN8DIR)/
	$(INSTALL) --mode=0755 --strip $< $(BIN_DIR)
	$(INSTALL) --mode=0644 $(MANPAGE) $(MAN8DIR)
	gzip -f $(MAN8DIR)/$(MANPAGE)

archive: $(APP_NAME)
	git archive HEAD \
		--format=$(ARCHIVE_FORMAT) \
		--prefix=$(RELEASE)/ \
		--output=$(RELEASE).$(ARCHIVE_FORMAT)

%/:
	$(MKDIR) $@

# If doc.mk exists, include it for documentation generation
doc: $(APP_NAME) test.log
	$(addprefix $(MAKE) APP_NAME=$< --makefile=, $(wildcard doc.mk))

.PHONY: all clean cover run test fmt install doc vet archive
