-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
151 lines (139 loc) · 6.51 KB
/
Copy pathMakefile
File metadata and controls
151 lines (139 loc) · 6.51 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
APP := Chestnut
VERSION := 0.9.0
CONFIG ?= debug
BUILD := .build
BUNDLE := $(BUILD)/$(APP).app
DMG := $(BUILD)/$(APP).dmg
.PHONY: build bundle run check clean dmg icon site site-gen release-check
SITE_GEN := $(BUILD)/generate-web-sprites
# Runtime checks in lieu of a test target (Command Line Tools ship no
# XCTest — see CONTRIBUTING.md). Compiles the check harness against the
# sources it exercises and runs it.
check: site-gen
mkdir -p $(BUILD)
swiftc -parse-as-library -o $(BUILD)/chestnut-check Checks/main.swift \
Sources/$(APP)/Vaults/VaultRegistry.swift \
Sources/$(APP)/Vaults/VaultWatcher.swift \
Sources/$(APP)/Actions/ObsidianBridge.swift \
Sources/$(APP)/Actions/Courier.swift \
Sources/$(APP)/Actions/Capture.swift \
Sources/$(APP)/Support/Journal.swift \
Sources/$(APP)/Support/Config.swift \
Sources/$(APP)/Support/AppState.swift \
Sources/$(APP)/Support/DebugLog.swift \
Sources/$(APP)/Support/ObsidianCLI.swift \
Sources/$(APP)/Support/VaultTrash.swift \
Sources/$(APP)/Support/Hotkeys.swift \
Sources/$(APP)/Pet/PetFrames.swift \
Sources/$(APP)/Pet/PetGeometry.swift \
Sources/$(APP)/Pet/SpriteTheme.swift \
Sources/$(APP)/Plugins/PluginManifest.swift \
Sources/$(APP)/Plugins/PluginSave.swift \
Sources/$(APP)/Plugins/PluginRegistry.swift \
Sources/$(APP)/Plugins/PluginRunner.swift \
Sources/$(APP)/Plugins/PluginRunRegistry.swift \
Sources/$(APP)/Plugins/PluginDispatch.swift \
Sources/$(APP)/Plugins/DropRouter.swift
$(BUILD)/chestnut-check
@$(SITE_GEN) $(BUILD)/sprites-drift.js $(VERSION)
@diff -u docs/sprites.js $(BUILD)/sprites-drift.js \
|| { echo "docs/sprites.js is stale — run 'make site'"; exit 1; }
@diff -u docs/favicon.svg $(BUILD)/favicon.svg \
|| { echo "docs/favicon.svg is stale — run 'make site'"; exit 1; }
@test "$$(plutil -extract CFBundleShortVersionString raw \
Resources/Info.plist)" = "$(VERSION)" \
|| { echo "Resources/Info.plist stamps $$(plutil -extract CFBundleShortVersionString raw Resources/Info.plist), not $(VERSION) — its own comment promises they stay in step"; exit 1; }
@grep -q "in the Makefile ($(VERSION))" CLAUDE.md \
|| { echo "CLAUDE.md's intro names a release other than $(VERSION) — it restates VERSION by hand, so it drifts on every bump unless this catches it"; exit 1; }
@# Both pages print the version in their footer. Nothing generates that
@# line — the site is hand-written — so a bump that misses one page ships
@# a download button next to a stale version number.
@for page in docs/index.html docs/guide.html; do \
grep -q ">$(VERSION)</a>" $$page \
|| { echo "$$page's footer names a release other than $(VERSION) — it states the version by hand"; exit 1; }; \
done
@# CLAUDE.md's tripwire index cites a symbol per entry instead of restating
@# the rationale, which now lives in the doc comment on that symbol. A
@# rename or deletion would leave the pointer dangling and silently cost
@# the account it points at, so every one must still resolve.
@# `exit 1` inside the loop would only leave the pipeline's subshell, so
@# collect the dangling pointers and let the recipe's own shell fail on them.
@dangling=$$(grep -o 'Sources/Chestnut/[A-Za-z/]*\.swift:[A-Za-z_][A-Za-z0-9_]*' CLAUDE.md \
| sort -u \
| while IFS=: read -r file symbol; do \
test -f "$$file" || { echo " $$file:$$symbol (no such file)"; continue; }; \
grep -qw "$$symbol" "$$file" || echo " $$file:$$symbol (symbol gone)"; \
done); \
test -z "$$dangling" || { \
echo "CLAUDE.md's tripwire index has pointers that no longer resolve:"; \
echo "$$dangling"; \
echo "Each stands in for a rationale that lives in that symbol's doc comment — repoint it or restore the symbol."; \
exit 1; }
build:
swift build -c $(CONFIG)
bundle: build
rm -rf $(BUNDLE)
mkdir -p $(BUNDLE)/Contents/MacOS $(BUNDLE)/Contents/Resources
cp $(BUILD)/$(CONFIG)/$(APP) $(BUNDLE)/Contents/MacOS/$(APP)
cp Resources/Info.plist $(BUNDLE)/Contents/Info.plist
plutil -replace CFBundleShortVersionString -string "$(VERSION)" \
$(BUNDLE)/Contents/Info.plist
plutil -replace CFBundleVersion -string "$(shell git rev-list --count HEAD)" \
$(BUNDLE)/Contents/Info.plist
@test -f Resources/AppIcon.icns && \
cp Resources/AppIcon.icns $(BUNDLE)/Contents/Resources/AppIcon.icns || true
codesign --force --sign - $(BUNDLE)
run: bundle
open $(BUNDLE)
# Compile the web-sprite exporter (shared by `site` and the drift check in
# `check`).
site-gen:
mkdir -p $(BUILD)
swiftc -parse-as-library -o $(SITE_GEN) Scripts/generate-web-sprites.swift \
Sources/$(APP)/Pet/PetFrames.swift \
Sources/$(APP)/Pet/SpriteTheme.swift \
Sources/$(APP)/Support/Config.swift
# Regenerate the website's sprite data from the app's frame/theme sources.
site: site-gen
$(SITE_GEN) docs/sprites.js $(VERSION)
icon:
mkdir -p $(BUILD)
swiftc -parse-as-library -o $(BUILD)/generate-icon Scripts/generate-icon.swift \
Sources/$(APP)/Pet/PetFrames.swift \
Sources/$(APP)/Pet/SpriteTheme.swift \
Sources/$(APP)/Support/Config.swift
$(BUILD)/generate-icon
iconutil -c icns -o Resources/AppIcon.icns $(BUILD)/$(APP).iconset
rm -rf $(BUILD)/$(APP).iconset $(BUILD)/generate-icon
dmg: CONFIG := release
dmg: bundle
rm -f $(DMG)
mkdir -p $(BUILD)/dmg-stage
cp -R $(BUNDLE) $(BUILD)/dmg-stage/
ln -sf /Applications $(BUILD)/dmg-stage/Applications
hdiutil create -volname $(APP) -srcfolder $(BUILD)/dmg-stage \
-ov -format UDZO $(DMG)
rm -rf $(BUILD)/dmg-stage
clean:
swift package clean
rm -rf $(BUNDLE) $(DMG)
# Release preflight: everything verifiable before the smoke test and the
# public steps (tag/push/publish — see RELEASING.md). Cheap guards first,
# then checks, then the release DMG. Prints the sha256 the cask needs.
release-check:
@git diff --quiet && git diff --cached --quiet \
|| { echo "FAIL: working tree not clean"; exit 1; }
@test "$$(git branch --show-current)" = "main" \
|| { echo "FAIL: not on main"; exit 1; }
@! git rev-parse -q --verify "v$(VERSION)" >/dev/null \
|| { echo "FAIL: v$(VERSION) already tagged"; exit 1; }
@grep -q "^## \[$(VERSION)\] — 20" CHANGELOG.md \
|| { echo "FAIL: CHANGELOG.md has no dated [$(VERSION)] section"; exit 1; }
$(MAKE) check
$(MAKE) dmg
@test "$$(plutil -extract CFBundleShortVersionString raw \
$(BUNDLE)/Contents/Info.plist)" = "$(VERSION)" \
|| { echo "FAIL: bundle stamps $$(plutil -extract CFBundleShortVersionString raw $(BUNDLE)/Contents/Info.plist), not $(VERSION)"; exit 1; }
@echo "sha256 for the Homebrew cask:"
@shasum -a 256 $(DMG)
@echo "OK — smoke test the app, then RELEASING.md from 'Merge and tag'."