-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Expand file tree
/
Copy pathMakefile
More file actions
314 lines (278 loc) · 13.3 KB
/
Copy pathMakefile
File metadata and controls
314 lines (278 loc) · 13.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
.PHONY: build clean host _bundle_mac_app plugins help dev sdk _update_sdk_versions _sync_sdk_versions test test-all test-calculator test-converter test-plugin test-time test-network test-quick test-legacy only_test check_deps release release-continue appimage smoke www
SMOKE_FILTER := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
SQLITE_BUILD_TAGS ?= sqlite_fts5
# GNU Make on Windows may choose Git's sh.exe without exposing Git usr/bin to
# recipes or $(shell ...) calls. The root build relies on sed/rm/uname before
# dependency checks run, so normalize PATH here instead of requiring callers to
# launch from a preconfigured MINGW64 shell.
ifeq ($(OS),Windows_NT)
GIT_USR_BIN := $(patsubst %/bin/sh.exe,%/usr/bin,$(SHELL))
ifneq ($(GIT_USR_BIN),$(SHELL))
export PATH := $(GIT_USR_BIN);$(PATH)
endif
endif
# The previous build always preferred Corepack when the shim existed, but some
# Node/Corepack installs expose the command while `corepack pnpm` still fails at
# runtime. Prefer a working global pnpm first, then fall back to a working
# Corepack shim so dependency checks and nested builds choose an executable CLI.
PNPM ?= $(shell if command -v pnpm >/dev/null 2>&1 && pnpm --version >/dev/null 2>&1; then echo pnpm; elif command -v corepack >/dev/null 2>&1 && corepack pnpm --version >/dev/null 2>&1; then echo "corepack pnpm"; else echo pnpm; fi)
export PNPM
CURRENT_NODEJS_SDK_VERSION := $(shell node -p "require('./wox.plugin.nodejs/package.json').version")
CURRENT_PYTHON_SDK_VERSION := $(shell sed -n 's/^version = "\(.*\)"/\1/p' wox.plugin.python/pyproject.toml)
NEXT_NODEJS_SDK_VERSION := $(shell node -e "const parts='$(CURRENT_NODEJS_SDK_VERSION)'.split('.').map(Number); if (parts.length !== 3 || parts.some(Number.isNaN)) process.exit(1); parts[2] += 1; console.log(parts.join('.'))")
NEXT_PYTHON_SDK_VERSION := $(shell node -e "const parts='$(CURRENT_PYTHON_SDK_VERSION)'.split('.').map(Number); if (parts.length !== 3 || parts.some(Number.isNaN)) process.exit(1); parts[2] += 1; console.log(parts.join('.'))")
SYNC_NODEJS_SDK_VERSION ?= $(NEXT_NODEJS_SDK_VERSION)
SYNC_PYTHON_SDK_VERSION ?= $(NEXT_PYTHON_SDK_VERSION)
# Determine the current platform
ifeq ($(OS),Windows_NT)
PLATFORM := windows
ARCH := amd64
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
PLATFORM := linux
ARCH := amd64
endif
ifeq ($(UNAME_S),Darwin)
PLATFORM := macos
UNAME_M := $(shell uname -m)
ifeq ($(UNAME_M),arm64)
ARCH := arm64
else
ARCH := amd64
endif
endif
endif
RELEASE_DIR := release
APPIMAGE_TOOL ?= appimagetool.AppImage
APPIMAGE_DIR := $(RELEASE_DIR)/wox.AppDir
APPIMAGE_NAME := wox-linux-$(ARCH).AppImage
APPIMAGE_DESKTOP_FILE := io.github.WoxLauncher.Wox.desktop
APPIMAGE_ICON_FILE := io.github.WoxLauncher.Wox.png
ifeq ($(ARCH),amd64)
APPIMAGE_ARCH := x86_64
else
APPIMAGE_ARCH := $(ARCH)
endif
help:
@echo "Usage: make [target]"
@echo ""
@echo "Targets:"
@echo " help Show this help message"
@echo " dev Setup development environment"
@echo " test Run tests"
@echo " build Build all components"
@echo " smoke Run the desktop smoke E2E flow"
@echo " sdk Bump SDK patch versions, publish SDKs, sync hosts, then run dev"
@echo " appimage Build Linux AppImage"
@echo " plugins Update plugin store"
@echo " www Run docs dev server"
@echo " clean Clean release directory"
@echo " host Build plugin hosts"
@echo " release Create a new release (reads version from CHANGELOG.md)"
@echo " release-continue Re-push the existing top CHANGELOG release tag after a failed release run"
_check_deps:
@echo "Checking required dependencies..."
@command -v go >/dev/null 2>&1 || { echo "go is required but not installed. Visit https://golang.org/doc/install" >&2; exit 1; }
@command -v flutter >/dev/null 2>&1 || { echo "flutter is required but not installed. Visit https://flutter.dev/docs/get-started/install" >&2; exit 1; }
@command -v node >/dev/null 2>&1 || { echo "nodejs is required but not installed. Visit https://nodejs.org/" >&2; exit 1; }
@$(PNPM) --version >/dev/null 2>&1 || { echo "pnpm is required but unavailable. Install pnpm globally or enable Corepack for this Node.js installation." >&2; exit 1; }
@command -v uv >/dev/null 2>&1 || { echo "uv is required but not installed. Visit https://github.com/astral-sh/uv" >&2; exit 1; }
ifeq ($(PLATFORM),linux)
@if ! command -v $(APPIMAGE_TOOL) >/dev/null 2>&1 && [ ! -x "$(APPIMAGE_TOOL)" ]; then \
echo "appimagetool is required but not installed. Install from https://github.com/AppImage/AppImageKit/releases or set APPIMAGE_TOOL to its path." >&2; \
exit 1; \
fi
@command -v patchelf >/dev/null 2>&1 || { echo "patchelf is required on Linux to fix bundled shared library rpath." >&2; exit 1; }
endif
ifeq ($(PLATFORM),macos)
@command -v create-dmg >/dev/null 2>&1 || { echo "create-dmg is required but not installed. Visit https://github.com/create-dmg/create-dmg" >&2; exit 1; }
endif
ifeq ($(PLATFORM),windows)
@uname -s | grep -q '^MINGW64_NT' || { \
echo "Please run this command in MINGW64 environment. If you have not installed MINGW64, please install it first. refer to https://www.mingw-w64.org/downloads/ or scoop install mingw" >&2; \
exit 1; \
}
endif
clean:
rm -rf $(RELEASE_DIR)
dev: _check_deps ensure-resources
$(MAKE) -C wox.core woxmr-build
$(MAKE) host
host:
$(MAKE) -C wox.plugin.host.nodejs build
$(MAKE) -C wox.plugin.host.python build
# SDK releases bump both SDK patch versions before publish because both npm and
# PyPI reject already-published versions. The host dependency update still waits
# until both publishes succeed so bundled hosts never point at an SDK release
# that failed partway through the workflow.
sdk: _update_sdk_versions
$(MAKE) -C wox.plugin.nodejs publish
$(MAKE) -C wox.plugin.python publish
$(MAKE) _sync_sdk_versions SYNC_NODEJS_SDK_VERSION=$(NEXT_NODEJS_SDK_VERSION) SYNC_PYTHON_SDK_VERSION=$(NEXT_PYTHON_SDK_VERSION)
_update_sdk_versions:
@echo "Updating Node.js SDK version from $(CURRENT_NODEJS_SDK_VERSION) to $(NEXT_NODEJS_SDK_VERSION)"
# Use direct JSON edits here so the release flow only changes the version field instead of letting a package-manager helper normalize unrelated package.json content.
cd wox.plugin.nodejs && node -e "const fs=require('fs'); const p='package.json'; const data=JSON.parse(fs.readFileSync(p,'utf8')); data.version='$(NEXT_NODEJS_SDK_VERSION)'; fs.writeFileSync(p, JSON.stringify(data, null, 2) + '\n');"
@echo "Updating Python SDK version from $(CURRENT_PYTHON_SDK_VERSION) to $(NEXT_PYTHON_SDK_VERSION)"
cd wox.plugin.python && perl -0pi -e 's/^version = "[^"]+"/version = "$(NEXT_PYTHON_SDK_VERSION)"/m' pyproject.toml
_sync_sdk_versions:
@echo "Hosts use local SDK sources; skip syncing published SDK versions into host dependencies."
# Hosts intentionally depend on the in-repo SDK packages so protocol changes are compiled and bundled with the matching host before any SDK release is published.
# Ensure required resource directories exist with dummy files for go:embed
ensure-resources:
@echo "Ensuring required resource directories exist..."
@mkdir -p wox.core/resource/ui/flutter
@touch wox.core/resource/ui/flutter/placeholder
@mkdir -p wox.core/resource/hosts
@touch wox.core/resource/hosts/placeholder
@mkdir -p wox.core/resource/others
@touch wox.core/resource/others/placeholder
# Bug fix: keep the tracked others placeholder because go:embed rejects an
# empty directory, and deleting it after tests makes the next smoke build fail.
clean-resources:
@rm -f wox.core/resource/ui/flutter/placeholder
@rm -f wox.core/resource/hosts/placeholder
appimage:
ifeq ($(PLATFORM),linux)
@echo "Building AppImage..."
rm -rf $(APPIMAGE_DIR)
mkdir -p $(APPIMAGE_DIR)/usr/bin
mkdir -p $(APPIMAGE_DIR)/usr/share/icons/hicolor/256x256/apps
mkdir -p $(APPIMAGE_DIR)/usr/share/applications
cp $(RELEASE_DIR)/wox-linux-$(ARCH) $(APPIMAGE_DIR)/usr/bin/wox
chmod +x $(APPIMAGE_DIR)/usr/bin/wox
cp assets/linux/wox.desktop $(APPIMAGE_DIR)/$(APPIMAGE_DESKTOP_FILE)
cp assets/linux/wox.desktop $(APPIMAGE_DIR)/usr/share/applications/$(APPIMAGE_DESKTOP_FILE)
cp assets/linux/AppRun $(APPIMAGE_DIR)/AppRun
chmod +x $(APPIMAGE_DIR)/AppRun
cp assets/app.png $(APPIMAGE_DIR)/$(APPIMAGE_ICON_FILE)
cp assets/app.png $(APPIMAGE_DIR)/.DirIcon
cp assets/app.png $(APPIMAGE_DIR)/usr/share/icons/hicolor/256x256/apps/$(APPIMAGE_ICON_FILE)
ARCH=$(APPIMAGE_ARCH) $(APPIMAGE_TOOL) $(APPIMAGE_DIR) $(RELEASE_DIR)/$(APPIMAGE_NAME)
else
@echo "appimage target is only supported on Linux"
endif
# Test without rebuilding dependencies (fast)
test: ensure-resources
@trap '$(MAKE) clean-resources' EXIT; $(MAKE) test-isolated
# Test with custom environment
# Bug fix: let the Go test config choose its per-process sandbox instead of
# forcing one shared /tmp directory. The shared directory lets stateful plugin
# tests leak saved settings, favorites, and histories into later make test
# runs, which makes CI and local reruns fail for reasons unrelated to code.
test-isolated:
cd wox.core && WOX_TEST_CLEANUP=true go test -tags "$(SQLITE_BUILD_TAGS)" ./test -v
# Test without network dependencies
test-offline:
cd wox.core && WOX_TEST_ENABLE_NETWORK=false go test -tags "$(SQLITE_BUILD_TAGS)" ./test -v
test-verbose:
cd wox.core && WOX_TEST_VERBOSE=true go test -tags "$(SQLITE_BUILD_TAGS)" ./test -v
# Test with custom directories and no cleanup (for debugging)
test-debug:
cd wox.core && WOX_TEST_DATA_DIR=/tmp/wox-test-debug WOX_TEST_CLEANUP=false WOX_TEST_VERBOSE=true go test -tags "$(SQLITE_BUILD_TAGS)" ./test -v
smoke: ensure-resources
@trap '$(MAKE) clean-resources' EXIT; $(MAKE) -C wox.test smoke SMOKE_FILTER="$(SMOKE_FILTER)"
%:
@:
build: clean dev
$(MAKE) -C wox.ui.flutter/wox build
$(MAKE) -C wox.core build
ifeq ($(PLATFORM),linux)
$(MAKE) appimage
endif
ifeq ($(PLATFORM),macos)
# to make sure the working directory is the release directory
cd $(RELEASE_DIR) && $(MAKE) -f ../Makefile _bundle_mac_app APP_NAME=wox-mac-$(ARCH)
endif
_bundle_mac_app:
chmod +x $(APP_NAME)
rm -rf $(APP_NAME).app Wox.app
mkdir -p $(APP_NAME).app/Contents/MacOS
mkdir -p $(APP_NAME).app/Contents/Resources
cp $(APP_NAME) $(APP_NAME).app/Contents/MacOS/wox
cp ../assets/mac/Info.plist $(APP_NAME).app/Contents/Info.plist
cp ../assets/mac/app.icns $(APP_NAME).app/Contents/Resources/app.icns
mv $(APP_NAME).app Wox.app
@if [ -n "$(MACOS_KEYCHAINPWD)" ]; then \
security unlock-keychain -p "$(MACOS_KEYCHAINPWD)"; \
fi
@if [ -n "$(MACOS_SIGN_IDENTITY)" ]; then \
codesign --options=runtime --force --deep --sign "$(MACOS_SIGN_IDENTITY)" Wox.app/Contents/MacOS/wox; \
else \
echo "MACOS_SIGN_IDENTITY is empty; skip codesign"; \
fi
@if [ -n "$(MACOS_SIGN_IDENTITY)" ]; then \
create-dmg \
--codesign "$(MACOS_SIGN_IDENTITY)" \
--notarize "wox" \
--volname "Wox Installer" \
--volicon "../assets/mac/app.icns" \
--window-pos 200 120 \
--window-size 800 400 \
--icon-size 100 \
--icon "Wox.app" 200 190 \
--hide-extension "Wox.app" \
--app-drop-link 600 185 \
Wox.dmg Wox.app; \
else \
create-dmg \
--volname "Wox Installer" \
--volicon "../assets/mac/app.icns" \
--window-pos 200 120 \
--window-size 800 400 \
--icon-size 100 \
--icon "Wox.app" 200 190 \
--hide-extension "Wox.app" \
--app-drop-link 600 185 \
Wox.dmg Wox.app; \
fi
mv "Wox.dmg" $(APP_NAME).dmg
release:
cd ci && go run . release
release-continue:
@tag=$$(awk '/^## v[0-9]/{ print $$2; exit }' CHANGELOG.md); \
if [ -z "$$tag" ]; then \
echo "Unable to read release tag from the top CHANGELOG.md version header." >&2; \
exit 1; \
fi; \
if [ -n "$$(git status --porcelain)" ]; then \
echo "Please commit/stash your changes before continuing release $$tag." >&2; \
git status --short; \
exit 1; \
fi; \
if ! git ls-remote --exit-code --tags origin "refs/tags/$$tag" >/dev/null 2>&1; then \
echo "Remote release tag $$tag does not exist. Run make release first." >&2; \
exit 1; \
fi; \
remote_tag=$$(git ls-remote --tags origin "refs/tags/$$tag" | awk '{ print $$1; exit }'); \
current_head=$$(git rev-parse --short HEAD); \
echo ""; \
echo "============================================================"; \
echo "Release Continue Review"; \
echo "============================================================"; \
echo "Tag: $$tag"; \
echo "Current HEAD: $$current_head"; \
echo "Remote tag SHA: $$remote_tag"; \
echo ""; \
echo "This will:"; \
echo " 1. Recreate local annotated tag $$tag at current HEAD"; \
echo " 2. Force-push $$tag to origin"; \
echo " 3. Trigger the GitHub Release workflow again"; \
echo "============================================================"; \
printf "\nProceed with release continue? (yes/no): "; \
read input; \
input=$$(printf "%s" "$$input" | tr '[:upper:]' '[:lower:]'); \
if [ "$$input" != "yes" ] && [ "$$input" != "y" ]; then \
echo "Release continue cancelled."; \
exit 0; \
fi; \
echo "Continuing release $$tag from current HEAD $$current_head"; \
git tag -f -a "$$tag" -m "Release $$tag"; \
git push origin "refs/tags/$$tag" --force; \
echo "Re-pushed $$tag."; \
plugins:
cd ci && go run . plugin
# Keep the docs dev shortcut at the repository root so contributors can discover the website workflow without duplicating the script definition from www/package.json.
www:
cd www && pnpm docs:dev