|
2 | 2 | # |
3 | 3 | # SPDX-License-Identifier: Apache-2.0 |
4 | 4 | # |
| 5 | +# |
5 | 6 |
|
6 | 7 | PROJECT_NAME := metricfunc |
7 | | -DOCKER_VERSION ?= $(shell cat ./VERSION) |
| 8 | +VERSION ?= $(shell cat ./VERSION 2>/dev/null || echo "dev") |
| 9 | + |
| 10 | +# Extract minimum Go version from go.mod file |
| 11 | +GOLANG_MINIMUM_VERSION ?= $(shell awk '/^go / {print $$2}' go.mod 2>/dev/null || echo "1.25") |
| 12 | + |
| 13 | +# Number of processors for parallel builds (Linux only) |
| 14 | +NPROCS := $(shell nproc) |
8 | 15 |
|
9 | | -## Docker related |
| 16 | +## Docker configuration |
10 | 17 | DOCKER_REGISTRY ?= |
11 | 18 | DOCKER_REPOSITORY ?= |
12 | | -DOCKER_TAG ?= ${DOCKER_VERSION} |
13 | | -DOCKER_IMAGENAME := ${DOCKER_REGISTRY}${DOCKER_REPOSITORY}${PROJECT_NAME}:${DOCKER_TAG} |
| 19 | +DOCKER_TAG ?= $(VERSION) |
| 20 | +DOCKER_IMAGE_PREFIX ?= 5gc- |
| 21 | +DOCKER_IMAGENAME := $(DOCKER_REGISTRY)$(DOCKER_REPOSITORY)$(DOCKER_IMAGE_PREFIX)$(PROJECT_NAME):$(DOCKER_TAG) |
14 | 22 | DOCKER_BUILDKIT ?= 1 |
15 | | -DOCKER_BUILD_ARGS ?= |
16 | | - |
17 | | -## Docker labels. Only set ref and commit date if committed |
18 | | -DOCKER_LABEL_VCS_URL ?= $(shell git remote get-url $(shell git remote)) |
19 | | -DOCKER_LABEL_VCS_REF ?= $(shell git diff-index --quiet HEAD -- && git rev-parse HEAD || echo "unknown") |
20 | | -DOCKER_LABEL_COMMIT_DATE ?= $(shell git diff-index --quiet HEAD -- && git show -s --format=%cd --date=iso-strict HEAD || echo "unknown" ) |
| 23 | +DOCKER_BUILD_ARGS ?= --build-arg MAKEFLAGS=-j$(NPROCS) |
| 24 | +DOCKER_PULL ?= --pull |
| 25 | + |
| 26 | +## Docker labels with better error handling |
| 27 | +DOCKER_LABEL_VCS_URL ?= $(shell git remote get-url origin 2>/dev/null || echo "unknown") |
| 28 | +DOCKER_LABEL_VCS_REF ?= $(shell \ |
| 29 | + echo "$${GIT_COMMIT:-$${GITHUB_SHA:-$${CI_COMMIT_SHA:-$(shell \ |
| 30 | + if git rev-parse --git-dir > /dev/null 2>&1; then \ |
| 31 | + git rev-parse HEAD 2>/dev/null; \ |
| 32 | + else \ |
| 33 | + echo "unknown"; \ |
| 34 | + fi \ |
| 35 | + )}}}") |
21 | 36 | DOCKER_LABEL_BUILD_DATE ?= $(shell date -u "+%Y-%m-%dT%H:%M:%SZ") |
22 | 37 |
|
23 | | -DOCKER_TARGETS ?= metricfunc |
24 | | - |
25 | | -GO_BIN_PATH = bin |
26 | | -GO_SRC_PATH = ./ |
27 | | -C_BUILD_PATH = build |
28 | | -ROOT_PATH = $(shell pwd) |
| 38 | +## Build configuration |
| 39 | +BINARY_NAME := $(PROJECT_NAME) |
| 40 | +GO_PACKAGES ?= ./... |
29 | 41 |
|
30 | | -NF = $(GO_NF) |
31 | | -GO_NF = metricfunc |
| 42 | +## Directory configuration |
| 43 | +BIN_DIR := bin |
| 44 | +COVERAGE_DIR := .coverage |
32 | 45 |
|
33 | | -NF_GO_FILES = $(shell find $(GO_SRC_PATH)/$(%) -name "*.go" ! -name "*_test.go") |
| 46 | +## Go build configuration |
| 47 | +GO_FILES := $(shell find . -name "*.go" ! -name "*_test.go" 2>/dev/null) |
| 48 | +GO_FILES_ALL := $(shell find . -name "*.go" 2>/dev/null) |
34 | 49 |
|
35 | | -VERSION = $(shell git describe --tags) |
36 | | -BUILD_TIME = $(shell date -u +"%Y-%m-%dT%H:%M:%SZ") |
37 | | -COMMIT_HASH = $(shell git submodule status | grep $(GO_SRC_PATH)/$(@F) | awk '{print $$(1)}' | cut -c1-8) |
38 | | -COMMIT_TIME = $(shell cd $(GO_SRC_PATH) && git log --pretty="%ai" -1 | awk '{time=$$(1)"T"$$(2)"Z"; print time}') |
| 50 | +## Tool versions (for reproducible builds) |
| 51 | +GOLANGCI_LINT_VERSION ?= latest |
39 | 52 |
|
40 | | -.PHONY: $(NF) clean docker-build docker-push |
| 53 | +# Default target |
| 54 | +.DEFAULT_GOAL := help |
41 | 55 |
|
42 | | -.DEFAULT_GOAL: nfs |
| 56 | +## Help target |
| 57 | +help: ## Show this help message |
| 58 | + @echo "Available targets:" |
| 59 | + @awk 'BEGIN {FS = ":.*##"} /^[a-zA-Z_-]+:.*##/ { printf " %-20s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) | sort |
43 | 60 |
|
44 | | -nfs: $(NF) |
| 61 | +## Build targets |
| 62 | +build: $(BIN_DIR)/$(BINARY_NAME) ## Build binary |
45 | 63 |
|
46 | | -all: $(NF) |
| 64 | +all: build ## Build binary (alias for compatibility) |
47 | 65 |
|
48 | | -$(GO_NF): % : $(GO_BIN_PATH)/% |
| 66 | +$(BIN_DIR)/$(BINARY_NAME): $(GO_FILES) | bin-dir |
| 67 | + @echo "Building $(BINARY_NAME)..." |
| 68 | + @CGO_ENABLED=0 go build -o $@ . |
49 | 69 |
|
50 | | -$(GO_BIN_PATH)/%: %.go $(NF_GO_FILES) |
51 | | -# $(@F): The file-within-directory part of the file name of the target. |
52 | | - @echo "Start building $(@F)...." |
53 | | - cd $(GO_SRC_PATH)/ && \ |
54 | | - CGO_ENABLED=0 go build -o $(ROOT_PATH)/$@ $(@F).go |
| 70 | +bin-dir: ## Create binary directory |
| 71 | + @mkdir -p $(BIN_DIR) |
55 | 72 |
|
56 | | -vpath %.go $(addprefix $(GO_SRC_PATH)/, $(GO_NF)) |
57 | | - |
58 | | -clean: |
59 | | - rm -rf $(addprefix $(GO_BIN_PATH)/, $(GO_NF)) |
60 | | - rm -rf $(addprefix $(GO_SRC_PATH)/, $(addsuffix /$(C_BUILD_PATH), $(C_NF))) |
61 | | - |
62 | | -docker-build: |
| 73 | +## Docker targets |
| 74 | +docker-build: ## Build Docker image |
| 75 | + @echo "Building Docker image: $(DOCKER_IMAGENAME)" |
63 | 76 | @go mod vendor |
64 | | - for target in $(DOCKER_TARGETS); do \ |
65 | | - DOCKER_BUILDKIT=$(DOCKER_BUILDKIT) docker build $(DOCKER_BUILD_ARGS) \ |
66 | | - --target $$target \ |
67 | | - --tag ${DOCKER_REGISTRY}${DOCKER_REPOSITORY}$$target:${DOCKER_TAG} \ |
68 | | - --build-arg org_label_schema_version="${DOCKER_VERSION}" \ |
69 | | - --build-arg org_label_schema_vcs_url="${DOCKER_LABEL_VCS_URL}" \ |
70 | | - --build-arg org_label_schema_vcs_ref="${DOCKER_LABEL_VCS_REF}" \ |
71 | | - --build-arg org_label_schema_build_date="${DOCKER_LABEL_BUILD_DATE}" \ |
72 | | - --build-arg org_opencord_vcs_commit_date="${DOCKER_LABEL_COMMIT_DATE}" \ |
73 | | - . \ |
74 | | - || exit 1; \ |
75 | | - done |
76 | | - rm -rf vendor |
77 | | - |
78 | | -docker-push: |
79 | | - for target in $(DOCKER_TARGETS); do \ |
80 | | - docker push ${DOCKER_REGISTRY}${DOCKER_REPOSITORY}$$target:${DOCKER_TAG}; \ |
81 | | - done |
82 | | - |
83 | | -.coverage: |
84 | | - rm -rf $(CURDIR)/.coverage |
85 | | - mkdir -p $(CURDIR)/.coverage |
86 | | - |
87 | | -test: .coverage |
88 | | - docker run --rm -v $(CURDIR):/metricfunc -w /metricfunc golang:latest \ |
| 77 | + @DOCKER_BUILDKIT=$(DOCKER_BUILDKIT) docker build $(DOCKER_PULL) $(DOCKER_BUILD_ARGS) \ |
| 78 | + --build-arg VERSION="$(VERSION)" \ |
| 79 | + --build-arg VCS_URL="$(DOCKER_LABEL_VCS_URL)" \ |
| 80 | + --build-arg VCS_REF="$(DOCKER_LABEL_VCS_REF)" \ |
| 81 | + --build-arg BUILD_DATE="$(DOCKER_LABEL_BUILD_DATE)" \ |
| 82 | + --tag $(DOCKER_IMAGENAME) \ |
| 83 | + . \ |
| 84 | + || exit 1 |
| 85 | + @rm -rf vendor |
| 86 | + |
| 87 | +docker-push: ## Push Docker image to registry |
| 88 | + @echo "Pushing Docker image: $(DOCKER_IMAGENAME)" |
| 89 | + @docker push $(DOCKER_IMAGENAME) |
| 90 | + |
| 91 | +docker-clean: ## Remove local Docker image |
| 92 | + @echo "Cleaning local Docker image..." |
| 93 | + @docker rmi $(DOCKER_IMAGENAME) 2>/dev/null || true |
| 94 | + |
| 95 | +## Testing targets |
| 96 | +$(COVERAGE_DIR): ## Create coverage directory |
| 97 | + @mkdir -p $(COVERAGE_DIR) |
| 98 | + |
| 99 | +test: $(COVERAGE_DIR) ## Run unit tests with coverage |
| 100 | + @echo "Running unit tests..." |
| 101 | + @docker run --rm \ |
| 102 | + -v $(CURDIR):/$(PROJECT_NAME) \ |
| 103 | + -w /$(PROJECT_NAME) \ |
| 104 | + golang:$(GOLANG_MINIMUM_VERSION) \ |
89 | 105 | go test \ |
90 | 106 | -race \ |
91 | 107 | -failfast \ |
92 | | - -coverprofile=.coverage/coverage-unit.txt \ |
| 108 | + -coverprofile=$(COVERAGE_DIR)/coverage-unit.txt \ |
93 | 109 | -covermode=atomic \ |
94 | 110 | -v \ |
95 | | - ./ ./... |
96 | | - |
97 | | -fmt: |
| 111 | + $(GO_PACKAGES) |
| 112 | + |
| 113 | +test-local: $(COVERAGE_DIR) ## Run unit tests locally (without Docker) |
| 114 | + @echo "Running unit tests locally..." |
| 115 | + @go test \ |
| 116 | + -race \ |
| 117 | + -failfast \ |
| 118 | + -coverprofile=$(COVERAGE_DIR)/coverage-unit.txt \ |
| 119 | + -covermode=atomic \ |
| 120 | + -v \ |
| 121 | + $(GO_PACKAGES) |
| 122 | + |
| 123 | +## Code quality targets |
| 124 | +fmt: ## Format Go code |
| 125 | + @echo "Formatting Go code..." |
98 | 126 | @go fmt ./... |
99 | 127 |
|
100 | | -golint: |
101 | | - @docker run --rm -v $(CURDIR):/app -w /app golangci/golangci-lint:latest golangci-lint run -v --config /app/.golangci.yml |
102 | | - |
103 | | -check-reuse: |
104 | | - @docker run --rm -v $(CURDIR):/metricfunc -w /metricfunc omecproject/reuse-verify:latest reuse lint |
| 128 | +lint: ## Run linter |
| 129 | + @echo "Running linter..." |
| 130 | + @docker run --rm \ |
| 131 | + -v $(CURDIR):/app \ |
| 132 | + -w /app \ |
| 133 | + golangci/golangci-lint:$(GOLANGCI_LINT_VERSION) \ |
| 134 | + golangci-lint run -v --config /app/.golangci.yml |
| 135 | + |
| 136 | +lint-local: ## Run linter locally (without Docker) |
| 137 | + @echo "Running linter locally..." |
| 138 | + @golangci-lint run -v --config .golangci.yml |
| 139 | + |
| 140 | +check-reuse: ## Check REUSE compliance |
| 141 | + @echo "Checking REUSE compliance..." |
| 142 | + @docker run --rm \ |
| 143 | + -v $(CURDIR):/$(PROJECT_NAME) \ |
| 144 | + -w /$(PROJECT_NAME) \ |
| 145 | + omecproject/reuse-verify:latest \ |
| 146 | + reuse lint |
| 147 | + |
| 148 | +check: fmt lint check-reuse ## Run all code quality checks |
| 149 | + |
| 150 | +## Utility targets |
| 151 | +clean: ## Clean build artifacts |
| 152 | + @echo "Cleaning build artifacts..." |
| 153 | + @rm -rf $(BIN_DIR) |
| 154 | + @rm -rf $(COVERAGE_DIR) |
| 155 | + @rm -rf vendor |
| 156 | + @docker system prune -f --filter label=org.opencontainers.image.source="https://github.com/omec-project/$(PROJECT_NAME)" 2>/dev/null || true |
| 157 | + |
| 158 | +print-version: ## Print current version |
| 159 | + @echo $(VERSION) |
| 160 | + |
| 161 | +env: ## Print environment variables |
| 162 | + @echo "PROJECT_NAME=$(PROJECT_NAME)" |
| 163 | + @echo "VERSION=$(VERSION)" |
| 164 | + @echo "GOLANG_MINIMUM_VERSION=$(GOLANG_MINIMUM_VERSION)" |
| 165 | + @echo "BINARY_NAME=$(BINARY_NAME)" |
| 166 | + @echo "DOCKER_REGISTRY=$(DOCKER_REGISTRY)" |
| 167 | + @echo "DOCKER_REPOSITORY=$(DOCKER_REPOSITORY)" |
| 168 | + @echo "DOCKER_IMAGE_PREFIX=$(DOCKER_IMAGE_PREFIX)" |
| 169 | + @echo "DOCKER_TAG=$(DOCKER_TAG)" |
| 170 | + @echo "DOCKER_IMAGENAME=$(DOCKER_IMAGENAME)" |
| 171 | + @echo "DOCKER_LABEL_VCS_URL=$(DOCKER_LABEL_VCS_URL)" |
| 172 | + @echo "DOCKER_LABEL_VCS_REF=$(DOCKER_LABEL_VCS_REF)" |
| 173 | + @echo "NPROCS=$(NPROCS)" |
| 174 | + |
| 175 | +## Phony targets |
| 176 | +.PHONY: all \ |
| 177 | + bin-dir \ |
| 178 | + build \ |
| 179 | + check \ |
| 180 | + check-reuse \ |
| 181 | + clean \ |
| 182 | + docker-build \ |
| 183 | + docker-clean \ |
| 184 | + docker-push \ |
| 185 | + env \ |
| 186 | + fmt \ |
| 187 | + help \ |
| 188 | + lint \ |
| 189 | + lint-local \ |
| 190 | + print-version \ |
| 191 | + test \ |
| 192 | + test-local |
0 commit comments