Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
122 lines (105 loc) · 5.74 KB
/
Copy pathMakefile
File metadata and controls
122 lines (105 loc) · 5.74 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
# Crisp — convenience wrappers around the existing build scripts.
#
# Fast dev loop (Command Line Tools only, no Xcode):
# make dev compile, swap the binary into /Applications/Crisp.app, relaunch
# make compile compile the binary only (./Crisp-bin), no swap — quick build check
# make test generate the Xcode project and run unit tests
# make check lint + tests + x86_64 typecheck + localization keys, everything CI enforces: run before pushing
# (auto-run on every push after: git config core.hooksPath .githooks)
#
# Distributable DMG:
# make build signed universal (arm64 + x86_64) DMG via scripts/release.sh (dry run)
# make dmg DMG via Xcode (scripts/build-dmg.sh; needs full Xcode + xcodegen)
# make release ARGS="vX.Y.Z notes.md --publish" full release (see scripts/release.sh)
#
# make clean remove build artifacts
# make help list targets (default)
#
# The dev target honours dev.sh's CRISP_APP override, e.g.:
# make dev CRISP_APP=/path/to/Crisp.app
# Single source of truth for the version: project.yml (used to tag the dry-run DMG).
VERSION := $(shell grep -E '^[[:space:]]*MARKETING_VERSION:' project.yml | head -1 | sed -E 's/.*"([^"]+)".*/\1/')
# Use Xcode.app's toolchain when installed, even if xcode-select still points at
# the Command Line Tools: xcodebuild (test) and SwiftLint's SourceKit need it.
ifneq (,$(wildcard /Applications/Xcode.app))
export DEVELOPER_DIR ?= /Applications/Xcode.app/Contents/Developer
# git hooks inherit SDKROOT for the Command Line Tools SDK from the git shim; with
# Xcode's swiftc that pairs a compiler and an SDK of different Swift versions.
unexport SDKROOT
endif
# swiftc invocation kept in sync with dev.sh's compile step.
SWIFT_SOURCES := Crisp/App/*.swift Crisp/Models/*.swift Crisp/Services/*.swift \
Crisp/Views/*.swift Crisp/Utilities/*.swift
SWIFTC_FLAGS := -O -swift-version 6 -parse-as-library \
-import-objc-header Crisp/Crisp-Bridging-Header.h \
-framework AppKit -framework SwiftUI -framework IOKit -framework CoreAudio \
-F vendor/Sparkle -framework Sparkle \
-Xlinker -rpath -Xlinker @executable_path/../Frameworks \
-Xlinker -undefined -Xlinker dynamic_lookup
.DEFAULT_GOAL := help
.PHONY: help dev compile test lint loc-check typecheck-x86 check build dmg release clean vendor
# Sparkle framework, pinned + cached in vendor/ (needed to compile and to
# generate the Xcode project's framework reference).
vendor:
@./scripts/fetch-sparkle.sh
help:
@echo "Crisp — make targets:"
@echo " make dev compile + swap into /Applications/Crisp.app + relaunch (dev.sh)"
@echo " make compile compile ./Crisp-bin only, no swap (quick build check)"
@echo " make test generate the Xcode project and run unit tests"
@echo " make check lint + tests + x86_64 typecheck + localization keys, everything CI enforces"
@echo " make build signed universal DMG, needs Xcode (scripts/release.sh v$(VERSION))"
@echo " make dmg DMG via Xcode (scripts/build-dmg.sh)"
@echo " make release ARGS=\"vX.Y.Z notes.md --publish\" full release (scripts/release.sh)"
@echo " make clean remove build artifacts (Crisp-bin, build/, Crisp.dmg)"
dev:
./dev.sh
compile: vendor
@echo "==> Compiling Crisp $(VERSION) -> ./Crisp-bin"
swiftc $(SWIFTC_FLAGS) $(SWIFT_SOURCES) -o Crisp-bin
@echo "Done. ./Crisp-bin built (not swapped into the app; use 'make dev' for that)."
# Warnings are errors here (the baseline is zero, issue #47), so a PR that
# introduces one fails make check and CI. `make compile` stays permissive for
# mid-iteration builds.
test: vendor
xcodegen generate
xcodebuild -quiet test -project Crisp.xcodeproj -scheme Crisp \
-destination 'platform=macOS' CODE_SIGNING_ALLOWED=NO \
SWIFT_TREAT_WARNINGS_AS_ERRORS=YES
lint:
@command -v swiftlint >/dev/null || { echo "SwiftLint not installed: brew install swiftlint"; exit 1; }
swiftlint lint --strict --quiet
# Same check as CI's "Check localization keys" step: every key the code uses
# must exist in the String Catalog (missing keys silently fall back to English).
# The export writes every key it extracts into the catalog, so the check would pass
# for a key the committed catalog lacks. Put the file back before checking it.
loc-check: vendor
xcodegen generate
mkdir -p build && cp Crisp/Resources/Localizable.xcstrings build/Localizable.xcstrings.orig
xcodebuild -quiet -exportLocalizations -project Crisp.xcodeproj \
-localizationPath build/loc CODE_SIGNING_ALLOWED=NO \
SWIFT_EMIT_LOC_STRINGS=YES; status=$$?; \
cp build/Localizable.xcstrings.orig Crisp/Resources/Localizable.xcstrings; exit $$status
python3 scripts/check-localization-keys.py build/loc/en.xcloc \
Crisp/Resources/Localizable.xcstrings scripts/i18n-missing-allowlist.txt
# The release binary is universal, and code that only compiles on arm64 (an
# `#if arch(arm64)` block that a caller outside it depends on, which is how #110
# first failed the hook) breaks the x86_64 slice. Typechecking that slice takes
# seconds where the universal build takes minutes, so it runs on every check.
typecheck-x86: vendor
swiftc -typecheck -target x86_64-apple-macos14.0 -swift-version 6 \
-parse-as-library -import-objc-header Crisp/Crisp-Bridging-Header.h \
-F vendor/Sparkle $(SWIFT_SOURCES)
# Everything CI enforces (lint + build + tests + x86_64 slice + localization keys), locally.
check: lint test typecheck-x86 loc-check
@echo "check passed: lint clean, tests green, x86_64 slice typechecks, localization keys complete"
build:
./scripts/release.sh v$(VERSION)
dmg:
./scripts/build-dmg.sh
release:
./scripts/release.sh $(ARGS)
clean:
rm -f Crisp-bin Crisp.dmg
rm -rf build
@echo "Cleaned: Crisp-bin, Crisp.dmg, build/"