forked from apache/polaris
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
362 lines (320 loc) · 14.3 KB
/
Makefile
File metadata and controls
362 lines (320 loc) · 14.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# Configures the shell for recipes to use bash, enabling bash commands and ensuring
# that recipes exit on any command failure (including within pipes).
SHELL = /usr/bin/env bash -o pipefail
.SHELLFLAGS = -ec
## Variables
BUILD_IMAGE ?= true
DOCKER ?= docker
MINIKUBE_PROFILE ?= minikube
DEPENDENCIES ?= ct helm helm-docs java21 git yamllint
OPTIONAL_DEPENDENCIES := jq kubectl minikube
VENV_DIR := .venv
PYTHON_CLIENT_DIR := client/python
ACTIVATE_AND_CD = source $(VENV_DIR)/bin/activate && cd $(PYTHON_CLIENT_DIR)
## Version information
BUILD_VERSION := $(shell cat version.txt)
GIT_COMMIT := $(shell git rev-parse HEAD)
POETRY_VERSION := $(shell cat client/python/pyproject.toml | grep requires-poetry | sed 's/requires-poetry *= *"\(.*\)"/\1/')
##@ General
.PHONY: help
help: ## Display this help
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9\.-]+:.*?##/ { printf " \033[36m%-40s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
.PHONY: version
version: ## Display version information
@echo "Build version: ${BUILD_VERSION}"
@echo "Git commit: ${GIT_COMMIT}"
@echo "Poetry version: ${POETRY_VERSION}"
##@ Polaris Build
.PHONY: build
build: build-server build-admin ## Build Polaris server, admin, and container images
build-server: DEPENDENCIES := java21 $(DOCKER)
.PHONY: build-server
build-server: check-dependencies ## Build Polaris server and container image
@echo "--- Building Polaris server ---"
@./gradlew \
:polaris-server:assemble \
:polaris-server:quarkusAppPartsBuild --rerun \
-Dquarkus.container-image.build=$(BUILD_IMAGE) \
-Dquarkus.docker.executable-name=$(DOCKER)
@echo "--- Polaris server build complete ---"
build-admin: DEPENDENCIES := java21 $(DOCKER)
.PHONY: build-admin
build-admin: check-dependencies ## Build Polaris admin and container image
@echo "--- Building Polaris admin ---"
@./gradlew \
:polaris-admin:assemble \
:polaris-admin:quarkusAppPartsBuild --rerun \
-Dquarkus.container-image.build=$(BUILD_IMAGE) \
-Dquarkus.docker.executable-name=$(DOCKER)
@echo "--- Polaris admin build complete ---"
build-spark-plugin-3.5-2.12: DEPENDENCIES := java21
.PHONY: build-spark-plugin-3.5-2.12
build-spark-plugin-3.5-2.12: check-dependencies ## Build Spark plugin v3.5 with Scala v2.12
@echo "--- Building Spark plugin v3.5 with Scala v2.12 ---"
@./gradlew \
:polaris-spark-3.5_2.12:assemble
@echo "--- Spark plugin v3.5 with Scala v2.12 build complete ---"
build-spark-plugin-3.5-2.13: DEPENDENCIES := java21
.PHONY: build-spark-plugin-3.5-2.13
build-spark-plugin-3.5-2.13: check-dependencies ## Build Spark plugin v3.5 with Scala v2.13
@echo "--- Building Spark plugin v3.5 with Scala v2.13 ---"
@./gradlew \
:polaris-spark-3.5_2.13:assemble
@echo "--- Spark plugin v3.5 with Scala v2.13 build complete ---"
build-cleanup: DEPENDENCIES := java21
.PHONY: build-cleanup
build-cleanup: check-dependencies ## Clean build artifacts
@echo "--- Cleaning up build artifacts ---"
@./gradlew clean
@echo "--- Build artifacts cleaned ---"
spotless-apply: DEPENDENCIES := java21
.PHONY: spotless-apply
spotless-apply: check-dependencies ## Apply code formatting using Spotless Gradle plugin.
@echo "--- Applying Spotless formatting ---"
@./gradlew spotlessApply
@echo "--- Spotless formatting applied ---"
##@ Polaris Client
# Target to create the virtual environment directory
$(VENV_DIR):
@echo "Setting up Python virtual environment at $(VENV_DIR)..."
@python3 -m venv $(VENV_DIR)
@echo "Virtual environment created."
.PHONY: client-install-dependencies
client-install-dependencies: $(VENV_DIR)
@echo "Installing Poetry and project dependencies into $(VENV_DIR)..."
@$(VENV_DIR)/bin/pip install --upgrade pip
@if [ ! -f "$(VENV_DIR)/bin/poetry" ]; then \
$(VENV_DIR)/bin/pip install --upgrade "poetry$(POETRY_VERSION)"; \
fi
@$(ACTIVATE_AND_CD) && poetry lock && poetry install --all-extras
@echo "Poetry and dependencies installed."
.PHONY: client-setup-env
client-setup-env: $(VENV_DIR) client-install-dependencies
.PHONY: client-lint
client-lint: client-setup-env ## Run linting checks for Polaris client
@echo "--- Running client linting checks ---"
@$(ACTIVATE_AND_CD) && poetry run pre-commit run --files integration_tests/* python/cli/*
@echo "--- Client linting checks complete ---"
.PHONY: client-regenerate
client-regenerate: client-setup-env ## Regenerate the client code
@echo "--- Regenerating client code ---"
@$(ACTIVATE_AND_CD) && python3 -B generate_clients.py
@echo "--- Client code regeneration complete ---"
.PHONY: client-unit-test
client-unit-test: client-setup-env ## Run client unit tests
@echo "--- Running client unit tests ---"
@$(ACTIVATE_AND_CD) && poetry run pytest test/
@echo "--- Client unit tests complete ---"
.PHONY: client-integration-test
client-integration-test: build-server client-setup-env ## Run client integration tests
@echo "--- Starting client integration tests ---"
@echo "Ensuring Docker Compose services are stopped and removed..."
@$(DOCKER) compose -f $(PYTHON_CLIENT_DIR)/docker-compose.yml kill || true # `|| true` prevents make from failing if containers don't exist
@$(DOCKER) compose -f $(PYTHON_CLIENT_DIR)/docker-compose.yml rm -f || true # `|| true` prevents make from failing if containers don't exist
@echo "Bringing up Docker Compose services in detached mode..."
@$(DOCKER) compose -f $(PYTHON_CLIENT_DIR)/docker-compose.yml up -d
@echo "Waiting for Polaris HTTP health check to pass..."
@until curl -s -f http://localhost:8182/q/health > /dev/null; do \
echo "Still waiting for HTTP 200 from /q/health (sleeping 2s)..."; \
sleep 2; \
done
@echo "Polaris is healthy. Starting integration tests..."
@$(ACTIVATE_AND_CD) && poetry run pytest integration_tests/
@echo "--- Client integration tests complete ---"
@echo "Tearing down Docker Compose services..."
@$(DOCKER) compose -f $(PYTHON_CLIENT_DIR)/docker-compose.yml down || true # Ensure teardown even if tests fail
.PHONY: client-license-check
client-license-check: client-setup-env ## Run license compliance check
@echo "--- Starting license compliance check ---"
@$(ACTIVATE_AND_CD) && pip-licenses
@echo "--- License compliance check complete ---"
.PHONY: client-build
client-build: client-setup-env ## Build client distribution. Pass FORMAT=sdist or FORMAT=wheel to build a specific format.
@echo "--- Building client distribution ---"
@if [ -n "$(FORMAT)" ]; then \
if [ "$(FORMAT)" != "sdist" ] && [ "$(FORMAT)" != "wheel" ]; then \
echo "Error: Invalid format '$(FORMAT)'. Supported formats are 'sdist' and 'wheel'." >&2; \
exit 1; \
fi; \
echo "Building with format: $(FORMAT)"; \
$(ACTIVATE_AND_CD) && poetry build --format $(FORMAT); \
else \
echo "Building default distribution (sdist and wheel)"; \
$(ACTIVATE_AND_CD) && poetry build; \
fi
@echo "--- Client distribution build complete ---"
.PHONY: client-cleanup
client-cleanup: ## Cleanup virtual environment and Python cache files
@echo "--- Cleaning up virtual environment and Python cache files ---"
@echo "Attempting to remove virtual environment directory: $(VENV_DIR)..."
@if [ -n "$(VENV_DIR)" ] && [ -d "$(VENV_DIR)" ]; then \
rm -rf "$(VENV_DIR)"; \
echo "Virtual environment removed."; \
else \
echo "Virtual environment directory '$(VENV_DIR)' not found or VENV_DIR is empty. No action taken."; \
fi
@echo "Cleaning up Python cache files..."
@find $(PYTHON_CLIENT_DIR) -type f -name "*.pyc" -delete
@find $(PYTHON_CLIENT_DIR) -type d -name "__pycache__" -delete
@echo "--- Virtual environment and Python cache cleanup complete ---"
##@ Helm
helm-doc-generate: DEPENDENCIES := helm-docs
.PHONY: helm-doc-generate
helm-doc-generate: check-dependencies ## Generate Helm chart documentation
@echo "--- Generating Helm documentation ---"
@helm-docs --chart-search-root=helm
@python3 helm/polaris/tools/prepare_helm_readme.py helm/polaris/README.md site/content/in-dev/unreleased/helm.md
@echo "--- Helm documentation generated and copied ---"
helm-unittest: DEPENDENCIES := helm
.PHONY: helm-unittest
helm-unittest: check-dependencies ## Run Helm chart unittest
@echo "--- Running Helm chart unittest ---"
@helm unittest helm/polaris
@echo "--- Helm chart unittest complete ---"
helm-lint: DEPENDENCIES := ct yamllint
.PHONY: helm-lint
helm-lint: check-dependencies ## Run Helm chart lint check
@echo "--- Running Helm chart linting ---"
@ct lint --charts helm/polaris
@echo "--- Helm chart linting complete ---"
##@ Minikube
minikube-start-cluster: DEPENDENCIES := minikube $(DOCKER)
.PHONY: minikube-start-cluster
minikube-start-cluster: check-dependencies ## Start the Minikube cluster
@echo "--- Checking Minikube cluster status ---"
@if minikube status -p $(MINIKUBE_PROFILE) --format "{{.Host}}" | grep -q "Running"; then \
echo "--- Minikube cluster is already running. Skipping start ---"; \
else \
echo "--- Starting Minikube cluster ---"; \
if [ "$(DOCKER)" = "podman" ]; then \
minikube start -p $(MINIKUBE_PROFILE) --driver=$(DOCKER) --container-runtime=cri-o; \
else \
minikube start -p $(MINIKUBE_PROFILE) --driver=$(DOCKER); \
fi; \
echo "--- Minikube cluster started ---"; \
fi
minikube-stop-cluster: DEPENDENCIES := minikube $(DOCKER)
.PHONY: minikube-stop-cluster
minikube-stop-cluster: check-dependencies ## Stop the Minikube cluster
@echo "--- Checking Minikube cluster status ---"
@if minikube status -p $(MINIKUBE_PROFILE) --format "{{.Host}}" | grep -q "Running"; then \
echo "--- Stopping Minikube cluster ---"; \
minikube stop -p $(MINIKUBE_PROFILE); \
echo "--- Minikube cluster stopped ---"; \
else \
echo "--- Minikube cluster is already stopped or does not exist. Skipping stop ---"; \
fi
minikube-load-images: DEPENDENCIES := minikube $(DOCKER)
.PHONY: minikube-load-images
minikube-load-images: minikube-start-cluster check-dependencies ## Load local Docker images into the Minikube cluster
@echo "--- Loading images into Minikube cluster ---"
@minikube image load -p $(MINIKUBE_PROFILE) docker.io/apache/polaris:latest
@minikube image tag -p $(MINIKUBE_PROFILE) docker.io/apache/polaris:latest docker.io/apache/polaris:$(BUILD_VERSION)
@minikube image load -p $(MINIKUBE_PROFILE) docker.io/apache/polaris-admin-tool:latest
@minikube image tag -p $(MINIKUBE_PROFILE) docker.io/apache/polaris-admin-tool:latest docker.io/apache/polaris-admin-tool:$(BUILD_VERSION)
@echo "--- Images loaded into Minikube cluster ---"
minikube-cleanup: DEPENDENCIES := minikube $(DOCKER)
.PHONY: minikube-cleanup
minikube-cleanup: check-dependencies ## Cleanup the Minikube cluster
@echo "--- Checking Minikube cluster status ---"
@if minikube status -p $(MINIKUBE_PROFILE) >/dev/null 2>&1; then \
echo "--- Cleanup Minikube cluster ---"; \
minikube delete -p $(MINIKUBE_PROFILE); \
echo "--- Minikube cluster removed ---"; \
else \
echo "--- Minikube cluster does not exist. Skipping cleanup ---"; \
fi
##@ Pre-commit
.PHONY: pre-commit
pre-commit: spotless-apply helm-doc-generate client-lint ## Run tasks for pre-commit
##@ Dependencies
.PHONY: check-dependencies
check-dependencies: ## Check if all requested dependencies are present
@echo "--- Checking for requested dependencies ---"
@for dependency in $(DEPENDENCIES); do \
echo "Checking for $$dependency..."; \
if [ "$$dependency" = "java21" ]; then \
if java --version | head -n1 | cut -d' ' -f2 | grep -q '^21\.'; then \
echo "Java 21 is installed."; \
else \
echo "Java 21 is NOT installed."; \
echo "--- ERROR: Dependency 'Java 21' is missing. Please install it to proceed. Exiting. ---"; \
exit 1; \
fi ; \
elif command -v $$dependency >/dev/null 2>&1; then \
echo "$$dependency is installed."; \
else \
echo "$$dependency is NOT installed."; \
echo "--- ERROR: Dependency '$$dependency' is missing. Please install it to proceed. Exiting. ---"; \
exit 1; \
fi; \
done
@echo "--- All checks complete. ---"
.PHONY: check-brew
check-brew:
@echo "--- Checking Homebrew installation ---"
@if command -v brew >/dev/null 2>&1; then \
echo "--- Homebrew is installed ---"; \
else \
echo "--- Homebrew is not installed. Aborting ---"; \
exit 1; \
fi
.PHONY: install-dependencies-brew
install-dependencies-brew: check-brew ## Install dependencies if not present via Brew
@echo "--- Checking and installing dependencies for this target ---"
@for dependency in $(DEPENDENCIES); do \
case $$dependency in \
java21) \
if java -version 2>&1 | grep -q '21'; then \
:; \
else \
echo "Java 21 is not installed. Installing openjdk@21 and jenv..."; \
brew install openjdk@21 jenv; \
$(shell brew --prefix jenv)/bin/jenv add $(shell brew --prefix openjdk@21); \
jenv local 21; \
echo "Java 21 installed."; \
fi ;; \
docker|podman) \
if command -v $$dependency >/dev/null 2>&1; then \
:; \
else \
echo "$$dependency is not installed. Manual installation required"; \
fi ;; \
ct) \
if command -v ct >/dev/null 2>&1; then \
:; \
else \
echo "ct is not installed. Installing with Homebrew..."; \
brew install chart-testing; \
echo "ct installed."; \
fi ;; \
*) \
if command -v $$dependency >/dev/null 2>&1; then \
:; \
else \
echo "$$dependency is not installed. Installing with Homebrew..."; \
brew install $$dependency; \
echo "$$dependency installed."; \
fi ;; \
esac; \
done
@echo "--- All requested dependencies checked/installed ---"
install-optional-dependencies-brew: DEPENDENCIES := $(OPTIONAL_DEPENDENCIES)
.PHONY: install-optional-dependencies-brew
install-optional-dependencies-brew: install-dependencies-brew ## Install optional dependencies if not present via Brew