Skip to content

Commit 4f25a12

Browse files
committed
Add: majos new awsome makefile for go projects
1 parent 56ee402 commit 4f25a12

File tree

2 files changed

+192
-87
lines changed

2 files changed

+192
-87
lines changed

.env.project

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
PROJECT_DISPLAY_NAME=Vault

Makefile

Lines changed: 191 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,227 @@
1-
DISPLAY_NAME := Vault
2-
SHORT_NAME := vault
3-
VERSION := 1.4.3
4-
5-
COMMIT := $(shell git rev-parse --short HEAD)
6-
BUILD_ARGS := "-X main.Version=$(VERSION) -X main.Commit=$(COMMIT) -X main.DisplayName=$(DISPLAY_NAME) -X main.ShortName=$(SHORT_NAME)"
7-
PORT ?= 8080
8-
1+
# import and use env vars if exist
2+
-include .env.project
93
-include .env
104
export
115

12-
## info: prints a project info message
13-
.PHONY: info
14-
info:
15-
@echo "$(DISPLAY_NAME) version $(VERSION), build $(COMMIT)"
6+
# prepare env file and tmp dir
7+
$(shell mkdir -p ./.tmp && touch .env)
168

17-
## run: uses go to start the main.go
18-
.PHONY: run
19-
run:
20-
@go run main.go
9+
# check required project vars
10+
ifndef PROJECT_DISPLAY_NAME
11+
$(error PROJECT_DISPLAY_NAME is not set)
12+
endif
2113

22-
## build: uses go to build the app with build args
23-
.PHONY: build
24-
build:
25-
@touch .env
26-
go build \
27-
-ldflags=$(BUILD_ARGS) \
28-
-o bin
29-
chmod +x bin
14+
# project default vars
15+
ifdef PROJECT_EXTRA_BUILD_ARGS
16+
PROJECT_EXTRA_BUILD_ARGS +=
17+
endif
18+
19+
PROJECT_VERSION ?= 0.0.1
20+
PROJECT_SHORT_NAME ?= $(PROJECT_DISPLAY_NAME)
21+
PROJECT_SHORT_NAME := $(shell echo $(PROJECT_SHORT_NAME) | sed 's/ //g' | sed 's/-/ /g' | tr '[:upper:]' '[:lower:]')
22+
PROJECT_COMMIT_SHORT ?= $(shell echo "$$(git rev-parse --short HEAD)$$([ -n "$$(git status -s)" ] && echo -n "-modified")")
23+
PROJECT_BUILD_ARGS ?= "$(PROJECT_EXTRA_BUILD_ARGS)-X main.Version=$(PROJECT_VERSION) -X main.Commit=$(PROJECT_COMMIT_SHORT) -X \"main.DisplayName=$(PROJECT_DISPLAY_NAME)\" -X main.ShortName=$(PROJECT_SHORT_NAME)"
3024

31-
## install: installs the build binary globally
32-
.PHONY: install
33-
install:
34-
@cp ./bin /usr/local/bin/$(SHORT_NAME)
25+
# general default vars
26+
PORT ?= 8080
27+
HOST ?= 0.0.0.0
28+
GOOS ?= $(shell go env GOOS)
29+
GOARCH ?= $(shell go env GOARCH)
30+
GOCACHE ?= $(shell if [ -d "~/.cache/go-build" ]; then realpath "~/.cache/go-build"; else mkdir -p .tmp/.cache/go-build && realpath ".tmp/.cache/go-build"; fi)
31+
32+
33+
##@ These environment variables control various project configurations, including build, run, and deployment settings.
34+
##@ They are loaded from the `.env.projects` file, which is overwritten the `.env` file variables.
35+
##@
36+
##@ Makefile vars
37+
##@
38+
##@ PROJECT_DISPLAY_NAME: projects full name, required
39+
##@ PROJECT_VERSION: semver like project version,
40+
##@: default is 0.0.1
41+
##@ PROJECT_SHORT_NAME: short spaceless lowercase name,
42+
##@: default is $PROJECT_DISPLAY_NAME
43+
##@ PROJECT_COMMIT_SHORT: commit short hash,
44+
##@: default is loaded via git
45+
##@ PROJECT_BUILD_ARGS: build args,
46+
##@: default is project base vars + $PROJECT_EXTRA_BUILD_ARGS
47+
##@ PROJECT_EXTRA_BUILD_ARGS: additional build args,
48+
##@: default is empty
49+
##@
50+
##@ Docker vars
51+
##@
52+
##@ DOCKER_PORT: container bind port or range (80-84),
53+
##@: default is $PORT else 8080
54+
##@ DOCKER_HOST: container bind host,
55+
##@: default is $HOST else 0.0.0.0
56+
##@ DOCKER_ARGS: container arguments for app executions,
57+
##@: default is $ARGS
58+
##@
59+
##@ General vars
60+
##@
61+
##@ PORT: main app bind port if needed,
62+
##@: default is empty
63+
##@ HOST: main app bind host if needed,
64+
##@: default is empty
65+
##@ ARGS: arguments for app executions,
66+
##@: default is $ARGS
67+
##@ GOOS: target build operating system,
68+
##@: default build system os
69+
##@ GOARCH: target build architecture,
70+
##@: default build system arch
71+
##@ GOCACHE: container go cache dir,
72+
##@: default global go cache if is dir
73+
##@: else creates ./.tmp/.cache/go-build
74+
75+
##@
76+
##@ Misc commands
77+
##@
78+
79+
.PHONY: help
80+
help: ##@ prints a command help message
81+
@make -s info
82+
@grep -F -h "##@" $(MAKEFILE_LIST) | grep -F -v grep -F | sed -e 's/\\$$//' | awk 'BEGIN {FS = ":*[[:space:]]*##@[[:space:]]*"}; \
83+
{ \
84+
if($$2 == "") \
85+
printf "\n"; \
86+
else if($$0 ~ /^#/) { \
87+
split($$2, arr, ": "); \
88+
if (length(arr) > 1) \
89+
printf " \033[34m%s\033[0m %s\n", arr[1], arr[2]; \
90+
else \
91+
printf "%s\n", $$2; \
92+
} \
93+
else if($$1 == "") \
94+
printf "%-15s^- %s\n", "", $$2; \
95+
else \
96+
printf " \033[34m%-16s\033[0m %s\n", $$1, $$2; \
97+
}'
98+
@printf "\nUsage: make <command>\n"
3599

36-
## uninstall: uninstalls the build binary globally
37-
.PHONY: uninstall
38-
uninstall:
39-
@rm -f /usr/local/bin/$(SHORT_NAME)
100+
.PHONY: info
101+
info: ##@ prints a project info message
102+
@echo "$(PROJECT_DISPLAY_NAME) version $(PROJECT_VERSION), build $(PROJECT_COMMIT_SHORT)"
103+
104+
.PHONY: vars
105+
vars: ##@ prints some vars for debugging
106+
@echo "\nProject\n"
107+
@env |grep "^PROJECT_" || true
108+
@echo "\nDocker\n"
109+
@env |grep "^DOCKER_" || true
110+
@echo "\nGo\n"
111+
@env |grep "^GO" || true
112+
@echo "\nGeneral\n"
113+
@echo "ARGS: '$(ARGS)'"
114+
@echo "PORT: '$(PORT)'"
115+
@echo "HOST: '$(HOST)'"
116+
117+
.PHONY: env
118+
env: ##@ prints env vars for debugging
119+
@env
40120

41-
## clean: cleans up the tmp, build and docker cache
42121
.PHONY: clean
43-
clean:
44-
@rm -f bin
45-
@rm -fr ./tmp
122+
clean: ##@ cleans up generated files and docker cache
123+
@rm -fr ./.tmp ./out ./bin
46124
@if command -v go 2>&1 >/dev/null; then \
47125
echo "cleanup go..."; \
48126
go clean; \
49127
go clean -cache -fuzzcache; \
50128
fi
51129
@if command -v docker 2>&1 >/dev/null; then \
52-
echo "cleanup docker..."; \
53-
CACHE_DIR="" PORT="" docker compose down --remove-orphans --rmi all; \
130+
echo "cleanup docker containers and images..."; \
131+
docker rm -f dev-local-$(PROJECT_SHORT_NAME)-bash > /dev/null 2>&1 \
132+
docker rm -f dev-local-$(PROJECT_SHORT_NAME) > /dev/null 2>&1 \
54133
docker image prune -f; \
55134
fi
56135
@echo "cleanup done!"
57-
@echo "WARNING: the .env file still exists!"
58-
@echo "If installed also execute 'make uninstall' to uninstall the binary."
136+
137+
##@
138+
##@ Go commands
139+
##@
140+
141+
.PHONY: run
142+
run: ##@ runs the main.go file using go run
143+
@go run main.go $(ARGS)
59144

60-
## update: updates dependencies
61-
.PHONY: update
62-
update:
145+
.PHONY: build
146+
build: ##@ uses go to build the app with build args
147+
@touch .env
148+
go build \
149+
-ldflags=$(PROJECT_BUILD_ARGS) \
150+
-o bin
151+
@chmod +x bin
152+
153+
.PHONY: buildall
154+
buildall: ##@ cross-compilation for all GOOS/GOARCH combinations
155+
@echo "Run test build-system build..."
156+
@make -s build || { echo "Test system-build build failed!"; exit 1; }
157+
@echo "Prepare out dir..."
158+
@mkdir -p out .tmp/out-bak
159+
@mv out/* .tmp/out-bak || true
160+
@echo "Start build processes..."
161+
@go tool dist list | while IFS=/ read -r GOOS GOARCH; do \
162+
( \
163+
go build \
164+
-ldflags=$(PROJECT_BUILD_ARGS) \
165+
-o out/$(PROJECT_SHORT_NAME)-$$GOOS-$$GOARCH && \
166+
chmod +x out/$(PROJECT_SHORT_NAME)-$$GOOS-$$GOARCH \
167+
) || { echo "Build failed for '$$GOOS'/'$$GOARCH'!"; exit 1; } \
168+
done && \
169+
wait
170+
@echo "All build processes finished."
171+
172+
.PHONY: gi
173+
gi: ##@ installs the build binary globally
174+
@sudo cp ./bin /usr/local/bin/$(PROJECT_SHORT_NAME)
175+
176+
.PHONY: gu
177+
gu: ##@ uninstalls the build binary globally
178+
@sudo rm -f /usr/local/bin/$(PROJECT_SHORT_NAME)
179+
180+
.PHONY: up
181+
up: ##@ updates dependencies recursively using go get
182+
@echo "Update go deps recursively..."
63183
go get -t -u ./...
64184

65-
## test: runs all tests without coverage
185+
.PHONY: i
186+
i: ##@ makes the go.mod matches the source code in the module
187+
@echo "Install go deps recursively..."
188+
go mod tidy
189+
66190
.PHONY: test
67-
test:
191+
test: ##@ runs all GO tests recursively without coverage
192+
@echo "Run go tests recursively..."
68193
go test ./...
69194

70-
## init: prepares ands builds
195+
.PHONY: cover
196+
cover: ##@ generates a cover.html test coverage report
197+
@echo "Run go tests recursively..."
198+
go test -coverprofile .tmp/cover.out ./...
199+
go tool cover -html=.tmp/cover.out -o .tmp/cover.html
200+
71201
.PHONY: init
72-
init:
73-
@touch .env
74-
@echo "update deps..."
75-
@go mod tidy
76-
@echo "testing..."
202+
init: ##@ infos, deps install, test and build
203+
@make -s info
204+
@make -s i
77205
@make -s test
78-
@echo "building..."
79206
@make -s build
80207

81-
## air: starts the go bin in air watch mode
82208
.PHONY: air
83-
air:
209+
air: ##@ air watch mode and also installs air
84210
@go install github.com/air-verse/air@v1
85211
@air
86212

87-
## dev: starts a dev docker container
88-
.PHONY: dev
89-
dev:
90-
@touch .env
91-
$(eval CACHE_DIR = .tmp/.cache/go-build)
92-
@if [ -d ~/.cache/go-build ]; then \
93-
$(eval CACHE_DIR = ~/.cache/go-build) \
94-
echo "Use users go-build cache dir."; \
95-
else \
96-
mkdir -p $(CACHE_DIR); \
97-
echo "Use local go-build cache dir."; \
98-
fi
99-
100-
@docker rm -f $(SHORT_NAME)-local-dev > /dev/null 2>&1
213+
##@
214+
##@ Docker envs
215+
##@
101216

102-
PORT=${PORT} \
103-
CACHE_DIR=${CACHE_DIR} \
104-
docker compose run --build --rm -it --name $(SHORT_NAME)-local-dev -P local
217+
.PHONY: dev
218+
dev: ##@ starts a air dev docker container
219+
@docker rm -f dev-local-$(PROJECT_SHORT_NAME) > /dev/null 2>&1
105220

106-
## exec: starts a bash in a dev container
107-
.PHONY: exec
108-
exec:
109-
@touch .env
110-
$(eval CACHE_DIR = .tmp/.cache/go-build)
111-
@if [ -d ~/.cache/go-build ]; then \
112-
$(eval CACHE_DIR = ~/.cache/go-build) \
113-
echo "Use users go-build cache dir."; \
114-
else \
115-
mkdir -p $(CACHE_DIR); \
116-
echo "Use local go-build cache dir."; \
117-
fi
221+
docker compose run --build --rm -it --name dev-local-$(PROJECT_SHORT_NAME) -P local
118222

119-
@docker rm -f $(SHORT_NAME)-local-bash > /dev/null 2>&1
223+
.PHONY: bash
224+
bash: ##@ runs a bash shell in the dev container
225+
@docker rm -f dev-local-$(PROJECT_SHORT_NAME)-bash > /dev/null 2>&1
120226

121-
PORT=${PORT} \
122-
CACHE_DIR=${CACHE_DIR} \
123-
docker compose run --build --rm -it --name $(SHORT_NAME)-local-bash --entrypoint bash -P local
227+
docker compose run --build --rm -it --name dev-local-$(PROJECT_SHORT_NAME)-bash --entrypoint bash -P local

0 commit comments

Comments
 (0)