1#!/bin/sh
2set -e
3cd "$(dirname "$0")"
4
5CONFIG=release
6APP=Pitch.app
7BIN=Pitch
8
9# Signing identity. Override with: SIGN_ID="Some Identity" ./build.sh
10SIGN_ID="${SIGN_ID:-Pitch Dev}"
11LOGIN_KEYCHAIN="$HOME/Library/Keychains/login.keychain-db"
12
13# Create a self-signed code-signing identity named "$SIGN_ID" in the login
14# keychain, so codesign works on a machine that has no dev certificate.
15create_cert() {
16 name="$SIGN_ID"
17 echo "Creating self-signed code-signing identity \"$name\"…"
18 tmp=$(mktemp -d)
19 openssl req -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes \
20 -keyout "$tmp/key.pem" -out "$tmp/cert.pem" \
21 -subj "/CN=$name" \
22 -addext "basicConstraints=critical,CA:false" \
23 -addext "keyUsage=critical,digitalSignature" \
24 -addext "extendedKeyUsage=critical,codeSigning" >/dev/null 2>&1
25 openssl pkcs12 -export -legacy -out "$tmp/id.p12" \
26 -inkey "$tmp/key.pem" -in "$tmp/cert.pem" -passout pass: >/dev/null 2>&1 \
27 || openssl pkcs12 -export -out "$tmp/id.p12" \
28 -inkey "$tmp/key.pem" -in "$tmp/cert.pem" -passout pass: >/dev/null 2>&1
29 security import "$tmp/id.p12" -k "$LOGIN_KEYCHAIN" -P "" \
30 -T /usr/bin/codesign -T /usr/bin/security
31 security add-trusted-cert -r trustRoot -p codeSign -k "$LOGIN_KEYCHAIN" \
32 "$tmp/cert.pem" >/dev/null 2>&1 || true
33 security set-key-partition-list -S apple-tool:,apple:,codesign: -s \
34 -k "" "$LOGIN_KEYCHAIN" >/dev/null 2>&1 || true
35 rm -rf "$tmp"
36}
37
38pick_identity() {
39 if security find-identity -v -p codesigning 2>/dev/null | grep -qF "\"$SIGN_ID\""; then
40 printf '%s' "$SIGN_ID"; return
41 fi
42 first=$(security find-identity -v -p codesigning 2>/dev/null \
43 | sed -n 's/^[[:space:]]*[0-9][0-9]*)[[:space:]]*[0-9A-Fa-f]*[[:space:]]*"\(.*\)"$/\1/p' \
44 | head -n1)
45 if [ -n "$first" ]; then
46 echo "Identity \"$SIGN_ID\" not found; using \"$first\"." >&2
47 printf '%s' "$first"; return
48 fi
49 echo "No code-signing identity found — using ad-hoc signing (-)." >&2
50 echo " Run './build.sh --create-cert' to make a reusable self-signed \"$SIGN_ID\"." >&2
51 printf '%s' "-"
52}
53
54if [ "$1" = "--create-cert" ]; then
55 create_cert
56 shift
57fi
58
59swift build -c "$CONFIG"
60
61rm -rf "$APP"
62mkdir -p "$APP/Contents/MacOS" "$APP/Contents/Resources"
63
64cp ".build/$CONFIG/$BIN" "$APP/Contents/MacOS/$BIN"
65
66cat > "$APP/Contents/Info.plist" <<'PLIST'
67<?xml version="1.0" encoding="UTF-8"?>
68<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
69<plist version="1.0">
70<dict>
71 <key>CFBundleName</key>
72 <string>Clover Pitch</string>
73 <key>CFBundleDisplayName</key>
74 <string>Clover Pitch</string>
75 <key>CFBundleExecutable</key>
76 <string>Pitch</string>
77 <key>CFBundleIdentifier</key>
78 <string>com.clover.Pitch</string>
79 <key>CFBundlePackageType</key>
80 <string>APPL</string>
81 <key>CFBundleShortVersionString</key>
82 <string>1.0</string>
83 <key>CFBundleVersion</key>
84 <string>1</string>
85 <key>LSMinimumSystemVersion</key>
86 <string>14.0</string>
87 <key>NSHighResolutionCapable</key>
88 <true/>
89 <key>NSPrincipalClass</key>
90 <string>NSApplication</string>
91 <key>NSMicrophoneUsageDescription</key>
92 <string>Pitch listens to your microphone to detect and visualise the pitch you sing or play. Audio is processed live and never recorded or sent anywhere.</string>
93</dict>
94</plist>
95PLIST
96
97printf 'APPL????' > "$APP/Contents/PkgInfo"
98
99IDENTITY=$(pick_identity)
100echo "Signing with: $IDENTITY"
101codesign --force --deep --sign "$IDENTITY" "$APP"
102
103echo "Built $APP"