|
1 | | -# import config. |
2 | | -# You can change the default config with `make cnf="config_special.env" build` |
3 | | -cnf ?= config.env |
4 | | -include $(cnf) |
5 | | -export $(shell sed 's/=.*//' $(cnf)) |
6 | | - |
7 | | -ifndef NAME |
8 | | -$(error NAME is not set. Please review and copy config.env.default to config.env and try again) |
| 1 | +# |
| 2 | +# COMMAND CONFIGURATION |
| 3 | +# |
| 4 | + |
| 5 | +# Paths to commands |
| 6 | +GO ?= $(shell command -v go 2>/dev/null) |
| 7 | +GIT ?= $(shell command -v git 2>/dev/null) |
| 8 | +# Use HOSTCMD to not conflict with Make's $(HOSTNAME) |
| 9 | +HOSTCMD ?= $(shell command -v hostname 2>/dev/null) |
| 10 | +INSTALL ?= $(shell command -v install 2>/dev/null) |
| 11 | +SCDOC ?= $(shell command -v scdoc 2>/dev/null) |
| 12 | +CONTAINER ?= $(shell command -v docker 2>/dev/null) |
| 13 | +CONTAINER_ARGS ?= '' |
| 14 | +SHELL ?= /bin/sh |
| 15 | + |
| 16 | +# `install` command invocations |
| 17 | +INSTALL_PROGRAM ?= $(INSTALL) -Dm755 |
| 18 | +INSTALL_DATA ?= $(INSTALL) -Dm644 |
| 19 | + |
| 20 | +# Check that commands are present |
| 21 | +ifeq ($(GIT),) |
| 22 | +$(error git command not found.) |
9 | 23 | endif |
10 | | - |
11 | | -ifndef VERSION |
12 | | -$(error VERSION is not set. Please review and copy config.env.default to config.env and try again) |
| 24 | +ifeq ($(HOSTCMD),) |
| 25 | +$(error hostname command not found.) |
13 | 26 | endif |
14 | | - |
15 | | -ifndef BUILD |
16 | | -$(error BUILD is not set. Please review and copy config.env.default to config.env and try again) |
| 27 | +ifeq ($(SHELL),) |
| 28 | +$(error '$(SHELL)' undefined.) |
17 | 29 | endif |
18 | 30 |
|
19 | | -LDFLAGS="-s -X=$(GIT)main.commit=$(BUILD) -X=$(GIT)main.version=$(VERSION) -X=$(GIT)main.date=$(shell date +%Y-%m-%d:%H:%M:%S)" |
| 31 | +# |
| 32 | +# FUNCTIONS |
| 33 | +# |
20 | 34 |
|
21 | | -SHELL := /bin/bash |
22 | | -GOPATH ?= $(shell echo $${GOPATH:-~/go}) |
| 35 | +# Recursive wildcard function, obtained from https://stackoverflow.com/a/18258352 |
| 36 | +# |
| 37 | +# Arg 1: Space-separated list of directories to recurse into |
| 38 | +# Arg 2: Space-separated list of patterns to match |
| 39 | +rwildcard = $(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d)) |
23 | 40 |
|
24 | | -.DEFAULT_GOAL := all |
| 41 | +# Print currently running target |
| 42 | +define print-target |
| 43 | + @printf "Executing target: \033[36m$@\033[0m\n" |
| 44 | +endef |
| 45 | + |
| 46 | +# |
| 47 | +# BUILD CONFIGURATION |
| 48 | +# |
| 49 | + |
| 50 | +NAME ?= magellan |
| 51 | +VERSION ?= $(shell git describe --tags --always --dirty --broken --abbrev=0) |
| 52 | +BUILD ?= $(shell git rev-parse --short HEAD) |
| 53 | +GOPATH ?= $(shell echo $${GOPATH:-~/go}) |
| 54 | +IMPORT := github.com/OpenCHAMI/magellan/ |
| 55 | +LDFLAGS := -s \ |
| 56 | + -X='$(IMPORT)main.commit=$(BUILD)' \ |
| 57 | + -X='$(IMPORT)main.version=$(VERSION)' \ |
| 58 | + -X='$(IMPORT)main.date=$(shell date -Iseconds)' |
| 59 | +INTERNAL := $(call rwildcard,internal,*.go) |
| 60 | +PKG := $(call rwildcard,pkg,*.go) |
| 61 | +MANSRC := $(wildcard man/*.sc) |
| 62 | +MANBIN := $(subst .sc,,$(MANSRC)) |
| 63 | +MAN1BIN := $(filter %.1,$(MANBIN)) |
| 64 | + |
| 65 | +# Installation paths |
| 66 | +prefix ?= /usr/local |
| 67 | +exec_prefix ?= $(prefix) |
| 68 | +bindir ?= $(exec_prefix)/bin |
| 69 | +mandir ?= $(exec_prefix)/man |
| 70 | + |
| 71 | +# |
| 72 | +# TARGETS |
| 73 | +# |
| 74 | + |
| 75 | +# Default target |
25 | 76 | .PHONY: all |
26 | | -all: ## build pipeline |
27 | | -all: mod inst build lint test |
| 77 | +all: binaries |
| 78 | + |
| 79 | +# Build all program binaries |
| 80 | +.PHONY: binaries |
| 81 | +binaries: $(NAME) |
28 | 82 |
|
| 83 | +# CI build pipeline |
29 | 84 | .PHONY: ci |
30 | | -ci: ## CI build pipeline |
31 | 85 | ci: all diff |
32 | 86 |
|
33 | | -.PHONY: help |
34 | | -help: |
35 | | - @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' |
36 | | - |
| 87 | +# Remove files created during build pipeline |
37 | 88 | .PHONY: clean |
38 | | -clean: ## remove files created during build pipeline |
| 89 | +clean: |
39 | 90 | $(call print-target) |
| 91 | +ifeq ($(GO),) |
| 92 | + $(error go command not found.) |
| 93 | +endif |
40 | 94 | rm -rf dist |
41 | 95 | rm -f coverage.* |
42 | 96 | rm -f '"$(shell go env GOCACHE)/../golangci-lint"' |
43 | | - go clean -i -cache -testcache -modcache -fuzzcache -x |
| 97 | + $(GO) clean -i -x |
| 98 | + |
| 99 | +# Separate clean target for go modules, cache, etc. |
| 100 | +# |
| 101 | +# The user may not want their Go module cache cleaned by default, so a separate |
| 102 | +# target is provided to do so. |
| 103 | +.PHONY: clean-go |
| 104 | +clean-go: |
| 105 | + $(call print-target) |
| 106 | +ifeq ($(GO),) |
| 107 | + $(error go command not found.) |
| 108 | +endif |
| 109 | + $(GO) clean -i -cache -testcache -modcache -fuzzcache -x |
44 | 110 |
|
45 | | -.PHONY: mod |
46 | | -mod: ## go mod tidy |
| 111 | +.PHONY: clean-man |
| 112 | +clean-man: |
47 | 113 | $(call print-target) |
48 | | - go mod tidy |
| 114 | + rm -f $(MANBIN) |
49 | 115 |
|
50 | | -.PHONY: inst |
51 | | -inst: ## go install tools |
| 116 | +# Build container |
| 117 | +.PHONY: container |
| 118 | +container: |
52 | 119 | $(call print-target) |
53 | | - go install github.com/client9/misspell/cmd/misspell@v0.3.4 |
54 | | - go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.0.1 |
55 | | - go install github.com/goreleaser/goreleaser/v2@v2.3.2 |
56 | | - go install github.com/cpuguy83/go-md2man/v2@latest |
| 120 | + $(CONTAINER) build . --build-arg REGISTRY_HOST=${REGISTRY_HOST} --no-cache --pull --tag '${NAME}:${VERSION}' |
57 | 121 |
|
58 | | -.PHONY: release |
59 | | -release: ## goreleaser build |
| 122 | +.PHONY: diff |
| 123 | +diff: |
| 124 | + $(call print-target) |
| 125 | +ifeq ($(GIT),) |
| 126 | + $(error git command not found.) |
| 127 | +endif |
| 128 | + $(GIT) diff --exit-code |
| 129 | + RES=$$($(GIT) status --porcelain) ; if [ -n "$$RES" ]; then echo $$RES && exit 1 ; fi |
| 130 | + |
| 131 | +.PHONY: distclean |
| 132 | +distclean: clean clean-man |
| 133 | + |
| 134 | +# Generate docs from Go comments |
| 135 | +.PHONY: docs |
| 136 | +docs: |
| 137 | + $(call print-target) |
| 138 | +ifeq ($(GO),) |
| 139 | + $(error go command not found.) |
| 140 | +endif |
| 141 | + $(GO) doc github.com/OpenCHAMI/magellan/cmd |
| 142 | + $(GO) doc github.com/OpenCHAMI/magellan/internal |
| 143 | + $(GO) doc github.com/OpenCHAMI/magellan/pkg/crawler |
| 144 | + |
| 145 | +# Run Redfish emulator |
| 146 | +.PHONY: emulator |
| 147 | +emulator: |
| 148 | + $(call print-target) |
| 149 | + ./emulator/setup.sh |
| 150 | + |
| 151 | +# Build using Goreleaser |
| 152 | +.PHONY: goreleaser |
| 153 | +goreleaser: |
60 | 154 | $(call print-target) |
61 | 155 | $(GOPATH)/bin/goreleaser build --clean --single-target --snapshot |
62 | 156 |
|
63 | | -.PHONY: binaries |
64 | | -binaries: build |
| 157 | +.PHONY: help |
| 158 | +help: |
| 159 | + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' |
65 | 160 |
|
66 | | -.PHONY: build |
67 | | -build: ## go build |
68 | | - go build -v --tags=all -ldflags=$(LDFLAGS) -o $(NAME) main.go |
| 161 | +.PHONY: install |
| 162 | +install: install-prog install-man |
69 | 163 |
|
70 | | -.PHONY: docker |
71 | | -container: ## docker build |
72 | | -container: |
| 164 | +.PHONY: install-prog |
| 165 | +install-prog: $(NAME) |
73 | 166 | $(call print-target) |
74 | | - docker build . --build-arg REGISTRY_HOST=${REGISTRY_HOST} --no-cache --pull --tag '${NAME}:${VERSION}' |
| 167 | +ifeq ($(INSTALL),) |
| 168 | + $(error install command not found.) |
| 169 | +endif |
| 170 | + $(INSTALL_PROGRAM) $(NAME) $(DESTDIR)$(bindir)/$(NAME) |
75 | 171 |
|
76 | | -.PHONY: spell |
77 | | -spell: ## misspell |
| 172 | +.PHONY: install-man |
| 173 | +install-man: $(MANBIN) |
78 | 174 | $(call print-target) |
79 | | - $(GOPATH)/bin/misspell -error -locale=US -w **.md |
| 175 | +ifeq ($(INSTALL),) |
| 176 | + $(error install command not found.) |
| 177 | +endif |
| 178 | + mkdir -p $(DESTDIR)$(mandir)/man1 |
| 179 | + $(INSTALL_DATA) $(MAN1BIN) $(DESTDIR)$(mandir)/man1/ |
80 | 180 |
|
| 181 | +# Run golangci-lint to lint Go code |
81 | 182 | .PHONY: lint |
82 | | -lint: ## golangci-lint |
| 183 | +lint: |
83 | 184 | $(call print-target) |
84 | 185 | $(GOPATH)/bin/golangci-lint run --fix |
85 | 186 |
|
86 | | -.PHONY: test |
87 | | -test: ## go test |
| 187 | +.PHONY: man |
| 188 | +man: $(MANBIN) |
| 189 | + |
| 190 | +man/%: man/%.sc |
| 191 | +ifeq ($(SCDOC),) |
| 192 | + $(error scdoc command not found.) |
| 193 | +endif |
| 194 | + $(SCDOC) < $< > $@ |
| 195 | + |
| 196 | +# Download/Prune Go modules |
| 197 | +.PHONY: mod |
| 198 | +mod: |
88 | 199 | $(call print-target) |
89 | | - ./emulator/setup.sh & |
90 | | - sleep 10 |
91 | | - go test -race -covermode=atomic -coverprofile=coverage.out -coverpkg=./... tests/api_test.go tests/compatibility_test.go |
92 | | - go tool cover -html=coverage.out -o coverage.html |
| 200 | + go mod tidy |
93 | 201 |
|
94 | | -.PHONY: diff |
95 | | -diff: ## git diff |
| 202 | +# Prepare by installing necessary Go tools |
| 203 | +.PHONY: prepare |
| 204 | +prepare: |
96 | 205 | $(call print-target) |
97 | | - git diff --exit-code |
98 | | - RES=$$(git status --porcelain) ; if [ -n "$$RES" ]; then echo $$RES && exit 1 ; fi |
| 206 | +ifeq ($(GO),) |
| 207 | + $(error go command not found.) |
| 208 | +endif |
| 209 | + $(GO) install github.com/client9/misspell/cmd/misspell@v0.3.4 |
| 210 | + $(GO) install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.0.1 |
| 211 | + $(GO) install github.com/goreleaser/goreleaser/v2@v2.3.2 |
99 | 212 |
|
100 | | -.PHONY: docs |
101 | | -docs: ## go docs |
| 213 | +# Spellchecking |
| 214 | +.PHONY: spell |
| 215 | +spell: |
102 | 216 | $(call print-target) |
103 | | - go doc github.com/OpenCHAMI/magellan/cmd |
104 | | - go doc github.com/OpenCHAMI/magellan/internal |
105 | | - go doc github.com/OpenCHAMI/magellan/pkg/crawler |
| 217 | + $(GOPATH)/bin/misspell -error -locale=US -w **.md |
106 | 218 |
|
107 | | -.PHONY: emulator |
108 | | -emulator: |
| 219 | +# Run Go tests |
| 220 | +.PHONY: test |
| 221 | +test: |
109 | 222 | $(call print-target) |
110 | | - ./emulator/setup.sh |
| 223 | +ifeq ($(GO),) |
| 224 | + $(error go command not found.) |
| 225 | +endif |
| 226 | + ./emulator/setup.sh & |
| 227 | + sleep 10 |
| 228 | + $(GO) test -race -covermode=atomic -coverprofile=coverage.out -coverpkg=./... tests/api_test.go tests/compatibility_test.go |
| 229 | + $(GO) tool cover -html=coverage.out -o coverage.html |
111 | 230 |
|
112 | | -magellan.1: README.md inst |
113 | | - $(GOPATH)/bin/go-md2man -in $< -out $@ |
| 231 | +.PHONY: uninstall |
| 232 | +uninstall: uninstall-prog uninstall-man |
114 | 233 |
|
115 | | -.PHONY: man |
116 | | -man: |
| 234 | +.PHONY: uninstall-prog |
| 235 | +uninstall-prog: |
117 | 236 | $(call print-target) |
118 | | - $(MAKE) -f $(firstword $(MAKEFILE_LIST)) magellan.1 |
| 237 | + rm -f $(DESTDIR)$(bindir)/$(NAME) |
119 | 238 |
|
120 | | -define print-target |
121 | | - @printf "Executing target: \033[36m$@\033[0m\n" |
122 | | -endef |
| 239 | +.PHONY: uninstall-man |
| 240 | +uninstall-man: |
| 241 | + $(call print-target) |
| 242 | + rm -f $(foreach man1page,$(subst man/,,$(MAN1BIN)),$(DESTDIR)$(mandir)/man1/$(man1page)) |
| 243 | + |
| 244 | +$(NAME): *.go cmd/*.go $(INTERNAL) $(PKG) |
| 245 | +ifeq ($(GO),) |
| 246 | + $(error go command not found.) |
| 247 | +endif |
| 248 | + $(GO) build -v -ldflags="$(LDFLAGS)" |
0 commit comments