-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMakefile
More file actions
335 lines (280 loc) · 10.7 KB
/
Makefile
File metadata and controls
335 lines (280 loc) · 10.7 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
LOCAL_BIN:=$(CURDIR)/bin
NODE_BIN:=$(CURDIR)/bin/node_bin/bin
PATH:=$(LOCAL_BIN):$(NODE_BIN):$(PATH)
GOPROXY:=https://goproxy.io,direct
BUILD_TARGET_DIR=$(CURDIR)/build
PROTO_BUILD_TARGET_DIR=$(CURDIR)/proto/build
VERSION=$(shell git describe --tags --always 2>/dev/null || echo "0.0.0")
UNAME_S := $(shell uname -s)
UNAME_M := $(shell uname -m)
# Detect system info
ifeq ($(UNAME_S),Darwin)
OS := osx
else ifeq ($(UNAME_S),Linux)
OS := linux
else
$(error Unsupported OS: $(UNAME_S))
endif
ifeq ($(UNAME_M),x86_64)
ARCH := x86_64
else ifeq ($(UNAME_M),arm64)
ARCH := aarch_64
else
$(error Unsupported architecture: $(UNAME_M))
endif
# Set GOOS only if not already set
ifndef GOOS
ifeq ($(OS),osx)
GOOS := darwin
else ifeq ($(OS),linux)
GOOS := linux
else
$(error Unsupported OS for Go: $(OS))
endif
endif
# Set GOARCH only if not already set
ifndef GOARCH
ifeq ($(ARCH),aarch_64)
GOARCH := arm64
else ifeq ($(ARCH),x86_64)
GOARCH := amd64
else
$(error Unsupported architecture for Go: $(ARCH))
endif
endif
default: help
.PHONY: help
help: # Show help in Makefile
@grep -E '^[a-zA-Z0-9 _-]+:.*#' Makefile | sort | while read -r l; do printf "\033[1;32m$$(echo $$l | cut -f 1 -d':')\033[00m:$$(echo $$l | cut -f 2- -d'#')\n"; done
# List of required binaries (default checks PATH)
# Optional: Specify custom paths for binaries not in PATH
# Format: binary_name=/path/to/binary
REQUIRED_BINS = git node npm go curl unzip \
protoc=$(LOCAL_BIN)/protoc \
easyp=$(LOCAL_BIN)/easyp \
protoc-gen-ts=$(NODE_BIN)/protoc-gen-ts \
protoc-gen-go=$(LOCAL_BIN)/protoc-gen-go \
protoc-gen-go-grpc=$(LOCAL_BIN)/protoc-gen-go-grpc \
protoc-gen-validate=$(LOCAL_BIN)/protoc-gen-validate \
protoc-gen-doc=$(LOCAL_BIN)/protoc-gen-doc \
xk6=$(LOCAL_BIN)/xk6
.PHONY: .check-bins
.check-bins: # Check for required binaries if build locally
@echo "Checking for required binaries..."
@missing=0; \
for bin_spec in $(REQUIRED_BINS); do \
case "$$bin_spec" in \
*=*) \
bin=$${bin_spec%%=*}; \
custom_path=$${bin_spec#*=}; \
if [ -x "$$custom_path" ]; then \
echo "✓ $$bin is installed at $$custom_path"; \
continue; \
else \
echo "✗ $$bin expected at $$custom_path but not found"; \
missing=1; \
continue; \
fi \
;; \
*) \
bin=$$bin_spec; \
;; \
esac; \
if command -v "$$bin" >/dev/null 2>&1; then \
echo "✓ $$bin is installed in PATH"; \
else \
echo "✗ $$bin is NOT found"; \
missing=1; \
fi; \
done; \
if [ $$missing -eq 1 ]; then \
echo "Error: Some required binaries are missing"; \
exit 1; \
else \
echo "All required binaries are available"; \
fi
PROTOC_VERSION ?= 32.1
PROTOC_BIN := $(LOCAL_BIN)/protoc
PROTOC_URL := https://github.com/protocolbuffers/protobuf/releases/download/v$(PROTOC_VERSION)/protoc-$(PROTOC_VERSION)-$(OS)-$(ARCH).zip
PROTOC_ZIP := /tmp/protoc-$(PROTOC_VERSION)-$(OS)-$(ARCH).zip
PROTOC_TMP := /tmp/protoc-$(PROTOC_VERSION)-$(OS)-$(ARCH)
.PHONY: .install-protoc
.install-protoc:
@echo ">>> Installing protoc v$(PROTOC_VERSION) to $(PROTOC_BIN)"
@mkdir -p $(LOCAL_BIN)
@rm -rf $(PROTOC_TMP) && rm -rf $(PROTOC_ZIP) && rm -rf $(LOCAL_BIN)/include && rm -rf $(LOCAL_BIN)/protoc
@echo ">>> Downloading $(PROTOC_URL)"
@curl -SL -o $(PROTOC_ZIP) $(PROTOC_URL)
@unzip -o -q $(PROTOC_ZIP) -d $(PROTOC_TMP)
@mkdir -p $(LOCAL_BIN)/include
@cp $(PROTOC_TMP)/bin/protoc $(PROTOC_BIN)
@cp -r $(PROTOC_TMP)/include/* $(LOCAL_BIN)/include/
@chmod +x $(PROTOC_BIN)
@rm $(PROTOC_ZIP) && rm -rf $(PROTOC_TMP)
.PHONY: .install-easyp
.install-easyp:
mkdir -p $(LOCAL_BIN)
GOBIN=$(LOCAL_BIN) GOPROXY=$(GOPROXY) go install github.com/easyp-tech/easyp/cmd/easyp@v0.7.15
.PHONY: .install-go-proto-deps
.install-go-proto-deps:
mkdir -p $(LOCAL_BIN)
GOBIN=$(LOCAL_BIN) GOPROXY=$(GOPROXY) go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.36.9
GOBIN=$(LOCAL_BIN) GOPROXY=$(GOPROXY) go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.5.1
GOBIN=$(LOCAL_BIN) GOPROXY=$(GOPROXY) go install github.com/envoyproxy/protoc-gen-validate@v1.2.1
GOBIN=$(LOCAL_BIN) GOPROXY=$(GOPROXY) go install connectrpc.com/connect/cmd/protoc-gen-connect-go@v1.19.1
GOBIN=$(LOCAL_BIN) GOPROXY=$(GOPROXY) go install github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc@v1.5.1
.PHONY: .install-node-proto-deps
.install-node-proto-deps:
mkdir -p $(LOCAL_BIN)
npm install --global --prefix $(LOCAL_BIN)/node_bin @protobuf-ts/plugin@2.11.1
TS_TARGET_DIR=$(PROTO_BUILD_TARGET_DIR)/ts
TS_BUNDLE_DIR=$(CURDIR)/proto/ts_bundle
TMP_BUNDLE_DIR=$(TS_BUNDLE_DIR)/tmp
.PHONY: .build-proto-ts-sdk
.build-proto-ts-sdk: # Build ts sdk with single js file for proto files
rm -rf $(TMP_BUNDLE_DIR)
mkdir -p $(TS_TARGET_DIR)
mkdir -p $(TMP_BUNDLE_DIR)
# Copy the entire directory structure to preserve relative imports
cp -r $(TS_TARGET_DIR) $(TMP_BUNDLE_DIR)/ts_source
# Copy analyze_ddl source before building
cp $(CURDIR)/internal/static/parse_sql.ts $(TMP_BUNDLE_DIR)/parse_sql.ts
cp $(TS_BUNDLE_DIR)/build.js $(TMP_BUNDLE_DIR)/
cp $(TS_BUNDLE_DIR)/package.json $(TMP_BUNDLE_DIR)/
cd $(TMP_BUNDLE_DIR) && npm install
cd $(TMP_BUNDLE_DIR) && node build.js
cp $(TMP_BUNDLE_DIR)/stroppy.pb.ts $(TS_TARGET_DIR)/stroppy.pb.ts
cp $(TMP_BUNDLE_DIR)/dist/bundle.js $(TS_TARGET_DIR)/stroppy.pb.js
# Bundle parse_sql with node-sql-parser (handled by build.js)
# TODO: make single bundle aka stroppy.js or automatically copy all from dist
cp $(TMP_BUNDLE_DIR)/dist/parse_sql.js $(TS_TARGET_DIR)/parse_sql.js
rm -rf $(TMP_BUNDLE_DIR)
.PHONY: .easyp-gen
.easyp-gen:
$(LOCAL_BIN)/easyp generate
.PHONY: install-linter
install-linter: # Install golangci-lint
$(info Installing golangci-lint...)
mkdir -p $(LOCAL_BIN)
GOBIN=$(LOCAL_BIN) go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.10.1
.PHONY: install-xk6
install-xk6:
$(info Installing xk6...)
mkdir -p $(LOCAL_BIN)
GOBIN=$(LOCAL_BIN) go install go.k6.io/xk6@v1.1.5
.PHONY: .install-proto-deps
.install-proto-deps: .install-protoc .install-easyp .install-go-proto-deps .install-node-proto-deps
.PHONY: install-bin-deps
install-bin-deps: install-linter install-xk6 .install-proto-deps # Install binary dependencies in ./bin
$(info Installing binary dependencies...)
.PHONY: app-deps
app-deps: # Install application dependencies in ./bin
GOPROXY=$(GOPROXY) go mod tidy
GOPROXY=$(GOPROXY) cd cmd/xk6air/ && go mod tidy
.PHONY: proto
proto: .check-bins
rm -rf $(CURDIR)/pkg/common/proto/*
rm -rf $(PROTO_BUILD_TARGET_DIR)/ts
mkdir -p $(PROTO_BUILD_TARGET_DIR)/ts/stroppy
mkdir -p $(PROTO_BUILD_TARGET_DIR)/docs
mkdir -p $(PROTO_BUILD_TARGET_DIR)/go
$(MAKE) .easyp-gen && $(MAKE) .build-proto-ts-sdk
# NOTE: easyp generates the code into the right place 'proto/stroppy' by itself
printf '// Code generated by stroppy. DO NOT EDIT.\npackage stroppy\n\nconst Version = "%s"\n' "$(VERSION)" > ./pkg/common/proto/stroppy/version.stroppy.pb.go
cp $(PROTO_BUILD_TARGET_DIR)/ts/stroppy.pb.ts $(CURDIR)/internal/static/
cp $(PROTO_BUILD_TARGET_DIR)/ts/stroppy.pb.js $(CURDIR)/internal/static/
cp $(PROTO_BUILD_TARGET_DIR)/ts/parse_sql.js $(CURDIR)/internal/static/
cp $(PROTO_BUILD_TARGET_DIR)/docs/proto.md $(CURDIR)/docs
.PHONY: linter linter_fix tests
linter: # Start linter
$(LOCAL_BIN)/golangci-lint cache clean
$(LOCAL_BIN)/golangci-lint --config $(CURDIR)/.golangci.yml run
linter_fix: # Start linter with possible fixes
$(LOCAL_BIN)/golangci-lint cache clean
$(LOCAL_BIN)/golangci-lint --config $(CURDIR)/.golangci.yml run --fix
tests: # Run tests with coverage
go test -race ./... -coverprofile=coverage.out
# K6/Stroppy build section
.PHONY: build-k6 build-k6-debug build-debug build build-all
STROPPY_BIN_NAME=stroppy
STROPPY_OUT_FILE=$(CURDIR)/build/$(STROPPY_BIN_NAME)
K6_OUT_FILE=$(CURDIR)/build/k6
K6_COMMON_FLAGS := --verbose \
--k6-version v1.7.0 \
--with github.com/stroppy-io/stroppy/cmd/xk6air=./cmd/xk6air/ \
--replace github.com/stroppy-io/stroppy=./ \
--with github.com/oleiade/xk6-encoding@v0.0.0-20251120082946-fbe7a8cbb88e \
--with github.com/grafana/xk6-dashboard@v0.8.1 \
--output $(K6_OUT_FILE)
build-k6: # Build k6 module
@mkdir -p $(CURDIR)/build
CGO_ENABLED=0 XK6_RACE_DETECTOR=0 \
xk6 build $(K6_COMMON_FLAGS) \
--build-flags -trimpath \
--build-flags "-ldflags=-s -w -X 'github.com/stroppy-io/stroppy/internal/version.Version=$(VERSION)'"
build-k6-debug: # Build k6 module
@mkdir -p $(CURDIR)/build
xk6 build $(K6_COMMON_FLAGS) \
--build-flags "-ldflags=-X 'github.com/stroppy-io/stroppy/internal/version.Version=$(VERSION)'"
build-debug: build-k6-debug # Build binary stroppy
echo $(VERSION)
cp $(K6_OUT_FILE) $(STROPPY_OUT_FILE)
build: build-k6 # Build binary stroppy
echo $(VERSION)
cp $(K6_OUT_FILE) $(STROPPY_OUT_FILE)
build-all: build
branch=main
.PHONY: revision
revision: # Recreate git tag with version tag=<semver>
@if [ -z "$(tag)" ]; then \
echo "error: Specify version 'tag='"; \
exit 1; \
fi
git tag -d v${tag} || true
git push --delete origin v${tag} || true
git tag v$(tag)
git push origin v$(tag)
##
## Local K6 fast tests
##
.PHONY: run-simple-test run-tpcb-test run-tpcc-test run-tpcc-pick-test run-tpcc-mysql-test run-tpcds-test run-k6-tests
WORKDIR=dev
run-simple-test:
rm -rf $(WORKDIR)
./build/stroppy gen --workdir $(WORKDIR) --preset=simple
cd $(WORKDIR) && ./stroppy run simple.ts
run-tpcb-test:
LOG_LEVEL=DEBUG STROPPY_ERROR_MODE=throw \
./build/stroppy run tpcb
run-tpcc-test:
DURATION="1s" SCALE_FACTOR=1 ./build/stroppy run tpcc.ts tpcc.sql
run-tpcc-mysql-test:
LOG_LEVEL=DEBUG STROPPY_ERROR_MODE=throw \
DURATION="1s" SCALE_FACTOR=1 ./build/stroppy run tpcc/pick-mysql mysql -- -q
run-tpcc-pick-test:
SCALE_FACTOR=1 ./build/stroppy run tpcc/pick.ts tpcc -- --duration "1s"
run-tpcds-test:
./build/stroppy run tpcds tpcds-scale-1.sql
run-k6-tests: # Run SQL API integration tests
# rc - return code
# This allows to run all the test and to exit with the nonzero code if any failed
@rc=0; \
./build/stroppy run tests/sqlapi_test -- -q || rc=1; \
./build/stroppy run tests/multi_drivers_test -- -q || rc=1; \
./build/stroppy run tests/transaction_test -- -q || rc=1; \
exit $$rc
##
## TypeScript Development
##
.PHONY: ts-setup ts-test ts-watch ts-typecheck
ts-setup: # Setup TypeScript testing environment
@echo "Setting up TypeScript testing environment..."
cd internal/static && npm install
@echo "✓ TypeScript testing environment ready!"
@echo "Run 'make ts-test' to run tests or 'make ts-watch' for watch mode"
ts-typecheck: # Typecheck TypeScript framework code (helpers.ts, parse_sql.ts, stroppy.d.ts)
cd internal/static && npx tsc --noEmit
ts-test: # Run TypeScript unit tests
cd internal/static && npm test
ts-watch: # Watch TypeScript files and run tests automatically
cd internal/static && npm run test:watch