#!/usr/bin/env bash # 构建 macOS 版 DCAuth.app,并向 LaunchServices 注册 dcauth:// 协议。 # # 为什么需要 .app:macOS 只把自定义协议的 URL 以 Apple Event 形式投递, # 非 Cocoa 的纯命令行程序拿不到(实测 argv 里没有 URL)。这里用 AppleScript # applet 的 on open location 接住事件,再把 URL 作为 argv 交给 Go 二进制, # 从而让浏览器点一下就能唤起本机确认窗口,不需要手动执行命令。 set -euo pipefail if [[ "$(uname -s)" != "Darwin" ]]; then echo "[build-macos] 只支持在 macOS 上运行" >&2 exit 1 fi ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" APP_PATH="${1:-$HOME/Applications/DCAuth.app}" LSREGISTER="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister" VERSION="$(sed -n 's/^const clientVersion = "\(.*\)"$/\1/p' "$ROOT/main.go")" if [[ -z "$VERSION" ]]; then echo "[build-macos] 无法从 main.go 读取 clientVersion" >&2 exit 1 fi WORK_DIR="$(mktemp -d)" trap 'rm -rf "$WORK_DIR"' EXIT echo "[build-macos] 编译 DCAuth v$VERSION" ( cd "$ROOT" CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -o "$WORK_DIR/dcauth" . ) echo "[build-macos] 生成 AppleScript 壳" cat > "$WORK_DIR/main.applescript" <<'APPLESCRIPT' on run set bundlePath to POSIX path of (path to me) do shell script quoted form of (bundlePath & "Contents/Resources/dcauth") end run on open location theURL set bundlePath to POSIX path of (path to me) do shell script quoted form of (bundlePath & "Contents/Resources/dcauth") & " " & quoted form of theURL end open location APPLESCRIPT rm -rf "$APP_PATH" mkdir -p "$(dirname "$APP_PATH")" osacompile -o "$APP_PATH" "$WORK_DIR/main.applescript" mkdir -p "$APP_PATH/Contents/Resources" install -m 0755 "$WORK_DIR/dcauth" "$APP_PATH/Contents/Resources/dcauth" PLIST="$APP_PATH/Contents/Info.plist" plist_set_string() { local entry="$1" local value="$2" # osacompile 生成的 plist 只有少数键,Set 失败时要带类型 Add。 /usr/libexec/PlistBuddy -c "Set $entry $value" "$PLIST" 2>/dev/null || /usr/libexec/PlistBuddy -c "Add $entry string $value" "$PLIST" } plist_delete() { /usr/libexec/PlistBuddy -c "Delete $1" "$PLIST" 2>/dev/null || true } plist_set_string ':CFBundleIdentifier' 'com.khhao.dcauth' plist_set_string ':CFBundleName' 'DCAuth' plist_set_string ':CFBundleDisplayName' 'DCAuth' plist_set_string ':CFBundleShortVersionString' "$VERSION" plist_set_string ':CFBundleVersion' "$VERSION" plist_delete ':CFBundleURLTypes' /usr/libexec/PlistBuddy -c 'Add :CFBundleURLTypes array' "$PLIST" /usr/libexec/PlistBuddy -c 'Add :CFBundleURLTypes:0 dict' "$PLIST" /usr/libexec/PlistBuddy -c 'Add :CFBundleURLTypes:0:CFBundleURLName string com.khhao.dcauth' "$PLIST" /usr/libexec/PlistBuddy -c 'Add :CFBundleURLTypes:0:CFBundleURLSchemes array' "$PLIST" /usr/libexec/PlistBuddy -c 'Add :CFBundleURLTypes:0:CFBundleURLSchemes:0 string dcauth' "$PLIST" # 后台常驻,不显示 Dock 图标;双击 .app 等同于"启动/查看设备码"。 plist_delete ':LSUIElement' /usr/libexec/PlistBuddy -c 'Add :LSUIElement bool true' "$PLIST" echo "[build-macos] 签名并注册协议" codesign --force --deep --sign - "$APP_PATH" >/dev/null 2>&1 if [[ -x "$LSREGISTER" ]]; then "$LSREGISTER" -f "$APP_PATH" fi echo echo "[build-macos] 完成:$APP_PATH" echo "[build-macos] 浏览器再次点击登录即可直接唤起 DCAuth(无需命令行)。" echo "[build-macos] 查看设备码:open \"$APP_PATH\"" echo "[build-macos] 停止后台进程:\"$APP_PATH/Contents/Resources/dcauth\" --exit"