verify-macos-document-icon

 1#!/usr/bin/env bash
 2set -euo pipefail
 3
 4usage() {
 5  cat <<'USAGE'
 6Usage:
 7  script/verify-macos-document-icon /path/to/Zed.app
 8
 9Verifies that the given macOS app bundle's Info.plist references a document icon
10named "Document" and that the corresponding icon file exists in the bundle.
11
12Specifically checks:
13  - CFBundleDocumentTypes[*].CFBundleTypeIconFile includes "Document"
14  - Contents/Resources/Document.icns exists
15
16Exit codes:
17  0 - success
18  1 - verification failed
19  2 - invalid usage / missing prerequisites
20USAGE
21}
22
23fail() {
24  echo "error: $*" >&2
25  exit 1
26}
27
28if [[ $# -ne 1 ]]; then
29  usage >&2
30  exit 2
31fi
32
33app_path="$1"
34
35if [[ ! -d "${app_path}" ]]; then
36  fail "app bundle not found: ${app_path}"
37fi
38
39info_plist="${app_path}/Contents/Info.plist"
40if [[ ! -f "${info_plist}" ]]; then
41  fail "missing Info.plist: ${info_plist}"
42fi
43
44if ! command -v plutil >/dev/null 2>&1; then
45  fail "plutil not found (required on macOS to read Info.plist)"
46fi
47
48# Convert to JSON for robust parsing. plutil outputs JSON to stdout in this mode.
49info_json="$(plutil -convert json -o - "${info_plist}")"
50
51# Check that CFBundleDocumentTypes exists and that at least one entry references "Document".
52# We use Python for JSON parsing; macOS ships with Python 3 on many setups, but not all.
53# If python3 isn't available, fall back to a simpler grep-based check.
54has_document_icon_ref="false"
55if command -v python3 >/dev/null 2>&1; then
56  has_document_icon_ref="$(python3 -c "import json,sys; d=json.load(sys.stdin); types=d.get('CFBundleDocumentTypes', []); vals=[t.get('CFBundleTypeIconFile') for t in types if isinstance(t, dict)]; print('true' if 'Document' in vals else 'false')" <<<"${info_json}")"
57else
58  # This is a best-effort fallback. It may produce false negatives if the JSON formatting differs.
59  if echo "${info_json}" | grep -q '"CFBundleTypeIconFile"[[:space:]]*:[[:space:]]*"Document"'; then
60    has_document_icon_ref="true"
61  fi
62fi
63
64if [[ "${has_document_icon_ref}" != "true" ]]; then
65  echo "Verification failed for: ${app_path}" >&2
66  echo "Expected Info.plist to reference CFBundleTypeIconFile \"Document\" in CFBundleDocumentTypes." >&2
67  echo "Tip: This bundle may be missing DocumentTypes.plist extensions or may have different icon naming." >&2
68  exit 1
69fi
70
71document_icon_path="${app_path}/Contents/Resources/Document.icns"
72if [[ ! -f "${document_icon_path}" ]]; then
73  echo "Verification failed for: ${app_path}" >&2
74  echo "Expected document icon to exist: ${document_icon_path}" >&2
75  echo "Tip: The bundle script should copy crates/zed/resources/Document.icns into Contents/Resources/Document.icns." >&2
76  exit 1
77fi
78
79echo "OK: ${app_path}"
80echo " - Info.plist references CFBundleTypeIconFile \"Document\""
81echo " - Found ${document_icon_path}"