-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathmenuet.mk
More file actions
151 lines (133 loc) · 5.67 KB
/
Copy pathmenuet.mk
File metadata and controls
151 lines (133 loc) · 5.67 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
# This is a shared Makefile for building menuet apps.
# To use it, create a Makefile in your applications directory, set the name of the app, and include this file.
# For example:
#
# APP=Hello World
# include $(GOPATH)/src/github.com/caseymrm/menuet/menuet.mk
#
# Optional features:
#
# To set your CFBundleIdentifier, set IDENTIFIER:
# IDENTIFIER=whyawake.caseymrm.github.com
#
# To monitor other directories for source changes, set LIBDIRS:
# LIBDIR= ../go-pmset ../go-caffeinate
#
# To sign your app, set IDENTITY:
# IDENTITY=Developer ID Application: Hello World LLC (AP2AFA8XAX)
#
# With a real (non ad-hoc) IDENTITY, `make sign` applies the hardened
# runtime and a secure timestamp, and `make notarize` submits the zip to
# Apple's notary service and staples the ticket — see the notarize target
# below for the one-time credential setup.
#
# To release your app, `make release` builds + zips the bundle and uploads
# it to GitHub via the gh CLI (install with `brew install gh`; authenticate
# once with `gh auth login`). The zip asset is what menuet's AutoUpdate
# auto-updater downloads.
ifndef APP
$(error APP variable must be defined, e.g. APP=Hello World)
endif
space :=
space +=
ESCAPED_APP = $(subst $(space),\$(space),$(APP))
EXECUTABLE := $(shell echo $(subst $(space),,$(APP)) | tr '[:upper:]' '[:lower:]')
BINARY = $(ESCAPED_APP).app/Contents/MacOS/$(EXECUTABLE)
PLIST = $(ESCAPED_APP).app/Contents/Info.plist
run: $(BINARY) $(PLIST)
./$(BINARY)
SOURCEDIRS = $(abspath $(dir $(MAKEFILE_LIST)))
SOURCES := $(shell find $(SOURCEDIRS) $(LIBDIRS) -name '*.go' -o -name '*.m' -o -name '*.h' -o -name '*.c' -o -name '*.mk' -o -name Makefile)
$(BINARY): $(SOURCES)
go build -o $(BINARY)
ZIPFILE = $(ESCAPED_APP).zip
# ditto (not zip -r) preserves symlinks, extended attributes, and the
# stapled notarization ticket — Apple's documented archiver for app zips.
$(ZIPFILE): sign $(BINARY) $(PLIST)
ditto -c -k --keepParent $(ESCAPED_APP).app $(ZIPFILE)
clean:
rm -f $(BINARY) $(PLIST) $(ZIPFILE)
.PHONY: zip
zip: $(ZIPFILE)
.PHONY: releases
releases:
@gh release list
.PHONY: release
release: $(ZIPFILE)
@LATEST=$$(gh release view --json tagName -q .tagName 2>/dev/null || echo "(none)"); \
echo "Latest release: $$LATEST"; \
read -p "New tag (e.g. v1.0.0): " TAG; \
read -p "Release notes (one line, or empty for autogenerated): " NOTES; \
if [ -z "$$NOTES" ]; then \
gh release create "$$TAG" "$(ZIPFILE)" --title "$$TAG" --generate-notes; \
else \
gh release create "$$TAG" "$(ZIPFILE)" --title "$$TAG" --notes "$$NOTES"; \
fi
IDENTIFIER ?= $(EXECUTABLE).menuet.caseymrm.github.qkg1.top
$(PLIST):
echo "Generating plist..."
@echo '<?xml version="1.0" encoding="UTF-8"?>' > $(PLIST)
@echo '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' >> $(PLIST)
@echo '<plist version="1.0">' >> $(PLIST)
@echo '<dict>' >> $(PLIST)
@echo ' <key>CFBundleExecutable</key>' >> $(PLIST)
@echo ' <string>$(EXECUTABLE)</string>' >> $(PLIST)
@echo ' <key>CFBundleIconFile</key>' >> $(PLIST)
@echo ' <string>icon</string>' >> $(PLIST)
@echo ' <key>CFBundleGetInfoString</key>' >> $(PLIST)
@echo ' <string>$(APP)</string>' >> $(PLIST)
@echo ' <key>CFBundleIdentifier</key>' >> $(PLIST)
@echo ' <string>$(IDENTIFIER)</string>' >> $(PLIST)
@echo ' <key>CFBundleName</key>' >> $(PLIST)
@echo ' <string>$(APP)</string>' >> $(PLIST)
@echo ' <key>CFBundleShortVersionString</key>' >> $(PLIST)
@echo ' <string>0.1</string>' >> $(PLIST)
@echo ' <key>CFBundleInfoDictionaryVersion</key>' >> $(PLIST)
@echo ' <string>6.0</string>' >> $(PLIST)
@echo ' <key>CFBundlePackageType</key>' >> $(PLIST)
@echo ' <string>APPL</string>' >> $(PLIST)
@echo ' <key>IFMajorVersion</key>' >> $(PLIST)
@echo ' <integer>0</integer>' >> $(PLIST)
@echo ' <key>IFMinorVersion</key>' >> $(PLIST)
@echo ' <integer>1</integer>' >> $(PLIST)
@echo ' <key>NSHighResolutionCapable</key><true/>' >> $(PLIST)
@echo ' <key>NSSupportsAutomaticGraphicsSwitching</key><true/>' >> $(PLIST)
@echo '</dict>' >> $(PLIST)
@echo '</plist>' >> $(PLIST)
# Hardened runtime + secure timestamp are required for notarization, but
# both need a real signing certificate — ad-hoc signatures ("-", the
# default in some apps) can't produce a timestamp, so only add the flags
# for a real identity.
ifeq ($(IDENTITY),-)
SIGNFLAGS =
else
SIGNFLAGS = --options runtime --timestamp
endif
.PHONY: sign
sign: $(BINARY) $(PLIST)
codesign -f $(SIGNFLAGS) -s "$(IDENTITY)" $(ESCAPED_APP).app --deep
# Notarize the signed zip, staple the ticket to the .app, and re-zip so
# the release artifact carries the ticket (Gatekeeper then clears the app
# even offline). One-time setup for the keychain profile:
# xcrun notarytool store-credentials AC_NOTARY
# (prompts for Apple ID, team ID, and an app-specific password from
# appleid.apple.com). Override the profile name with NOTARY_PROFILE.
NOTARY_PROFILE ?= AC_NOTARY
.PHONY: notarize
notarize: $(ZIPFILE)
xcrun notarytool submit $(ZIPFILE) --keychain-profile $(NOTARY_PROFILE) --wait
xcrun stapler staple $(ESCAPED_APP).app
rm -f $(ZIPFILE)
ditto -c -k --keepParent $(ESCAPED_APP).app $(ZIPFILE)
# `make web-preview` writes menuet-demo.json — a JSON snapshot of the
# current MenuState and resolved menu items — by re-running the binary
# in snapshot mode. The snapshot is safe to commit to your repo;
# menuet.app fetches it to render a faithful HTML mockup of your menu.
#
# Default delay is 2s; override with MENUET_SNAPSHOT_DELAY=5s when your
# app fetches data on startup and you want the menu to reflect real
# values in the demo.
.PHONY: web-preview
web-preview: $(BINARY) $(PLIST)
MENUET_SNAPSHOT_PATH=menuet-demo.json ./$(BINARY)
@echo "Wrote menuet-demo.json"