| | |
| | | -framework AppKit \ |
| | | -framework SwiftUI \ |
| | | -framework Carbon \ |
| | | -framework CoreServices \ |
| | | -lcompression \ |
| | | -sdk "$SDK_PATH" \ |
| | | -target "$TARGET" \ |
| | | -Osize \ |
| | |
| | | /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $APP_BUILD" "$APP_INFO_PLIST" |
| | | |
| | | echo "==> Copying AppIcon.icns..." |
| | | if [ -f "$PROJECT_DIR/icon-icns.icns" ]; then |
| | | APPICON_SOURCE_DIR="$SWIFT_DIR/Assets.xcassets/AppIcon.appiconset" |
| | | if [ -d "$APPICON_SOURCE_DIR" ]; then |
| | | TMP_ICONSET_PARENT="$(mktemp -d -t taglauncher-appicon.XXXXXX)" |
| | | TMP_ICONSET="$TMP_ICONSET_PARENT/AppIcon.iconset" |
| | | mkdir -p "$TMP_ICONSET" |
| | | ICON_NAMES=( |
| | | icon_16x16.png |
| | | icon_16x16@2x.png |
| | | icon_32x32.png |
| | | icon_32x32@2x.png |
| | | icon_128x128.png |
| | | icon_128x128@2x.png |
| | | icon_256x256.png |
| | | icon_256x256@2x.png |
| | | icon_512x512.png |
| | | icon_512x512@2x.png |
| | | ) |
| | | for icon_name in "${ICON_NAMES[@]}"; do |
| | | if [ ! -f "$APPICON_SOURCE_DIR/$icon_name" ]; then |
| | | echo "❌ Missing AppIcon asset: $APPICON_SOURCE_DIR/$icon_name" |
| | | exit 1 |
| | | fi |
| | | cp "$APPICON_SOURCE_DIR/$icon_name" "$TMP_ICONSET/$icon_name" |
| | | done |
| | | iconutil -c icns "$TMP_ICONSET" -o "$RESOURCES_DIR/AppIcon.icns" |
| | | rm -rf "$TMP_ICONSET_PARENT" |
| | | elif [ -f "$PROJECT_DIR/icon-icns.icns" ]; then |
| | | cp "$PROJECT_DIR/icon-icns.icns" "$RESOURCES_DIR/AppIcon.icns" |
| | | elif [ -f "$SWIFT_DIR/AppIcon.iconset/icon_512x512@2x.png" ]; then |
| | | iconutil -c icns "$SWIFT_DIR/AppIcon.iconset" -o "$RESOURCES_DIR/AppIcon.icns" 2>/dev/null |
| | | else |
| | | echo "❌ Missing AppIcon source" |
| | | exit 1 |
| | | fi |
| | | |
| | | echo "==> Copying menu bar icon..." |
| | |
| | | echo "==> Copying Localization files..." |
| | | cp -r "$SWIFT_DIR/Localization" "$RESOURCES_DIR/Localization" |
| | | |
| | | echo "==> Copying Apple default app catalog..." |
| | | APPLE_DEFAULT_SOURCE_DIR="$PROJECT_DIR/Research/AppleDefaultApps" |
| | | for required in \ |
| | | "AppleDefaultApps.base.json" \ |
| | | "AppleDefaultApps.manifest.json" \ |
| | | "AppleDefaultApps.localizations.en.json" \ |
| | | "AppleDefaultApps.localizations.zh-Hans.json"; do |
| | | if [ ! -f "$APPLE_DEFAULT_SOURCE_DIR/$required" ]; then |
| | | echo "❌ Missing Apple default app resource: $required" |
| | | exit 1 |
| | | fi |
| | | done |
| | | python3 - "$APPLE_DEFAULT_SOURCE_DIR/AppleDefaultApps.base.json" "$RESOURCES_DIR/AppleDefaultApps.base.json" <<'PY' |
| | | import json |
| | | import sys |
| | | source, destination = sys.argv[1], sys.argv[2] |
| | | with open(source, "r", encoding="utf-8") as f: |
| | | data = json.load(f) |
| | | with open(destination, "w", encoding="utf-8") as f: |
| | | json.dump(data, f, ensure_ascii=False, separators=(",", ":")) |
| | | PY |
| | | python3 - "$APPLE_DEFAULT_SOURCE_DIR/AppleDefaultApps.manifest.json" "$RESOURCES_DIR/AppleDefaultApps.manifest.json" <<'PY' |
| | | import json |
| | | import sys |
| | | source, destination = sys.argv[1], sys.argv[2] |
| | | with open(source, "r", encoding="utf-8") as f: |
| | | data = json.load(f) |
| | | with open(destination, "w", encoding="utf-8") as f: |
| | | json.dump(data, f, ensure_ascii=False, separators=(",", ":")) |
| | | PY |
| | | for localization_file in "$APPLE_DEFAULT_SOURCE_DIR"/AppleDefaultApps.localizations.*.json; do |
| | | [ -e "$localization_file" ] || continue |
| | | output_name="$(basename "$localization_file").deflate" |
| | | python3 - "$localization_file" "$RESOURCES_DIR/$output_name" <<'PY' |
| | | import json |
| | | import sys |
| | | import zlib |
| | | source, destination = sys.argv[1], sys.argv[2] |
| | | with open(source, "r", encoding="utf-8") as f: |
| | | data = json.load(f) |
| | | payload = json.dumps(data, ensure_ascii=False, separators=(",", ":")).encode("utf-8") |
| | | compressor = zlib.compressobj(level=9, wbits=-15) |
| | | compressed = compressor.compress(payload) + compressor.flush() |
| | | with open(destination, "wb") as f: |
| | | f.write(compressed) |
| | | PY |
| | | done |
| | | |
| | | echo "==> Copying Smart Start catalog..." |
| | | if [ -f "$PROJECT_DIR/Research/SmartStart/UltimateDefaultCatalog/SmartStart_UltimateDefaultCatalog.json" ]; then |
| | | cp "$PROJECT_DIR/Research/SmartStart/UltimateDefaultCatalog/SmartStart_UltimateDefaultCatalog.json" "$RESOURCES_DIR/SmartStartUltimateDefaultCatalog.json" |
| | | fi |
| | | if [ -f "$PROJECT_DIR/Research/SmartStart/UltimateDefaultCatalog/SmartStart_UltimateDefaultCatalog.csv" ]; then |
| | | cp "$PROJECT_DIR/Research/SmartStart/UltimateDefaultCatalog/SmartStart_UltimateDefaultCatalog.csv" "$RESOURCES_DIR/SmartStartUltimateDefaultCatalog.csv" |
| | | fi |
| | | if [ -f "$PROJECT_DIR/Research/SmartStart/AppDefaultTags_Review.csv" ]; then |
| | | cp "$PROJECT_DIR/Research/SmartStart/AppDefaultTags_Review.csv" "$RESOURCES_DIR/SmartStartAppDefaultTags.csv" |
| | | SMARTSTART_SOURCE_DIR="$PROJECT_DIR/Research/SmartStart/UltimateDefaultCatalog" |
| | | for required in \ |
| | | "SmartStart_UltimateDefaultCatalog.base.json" \ |
| | | "SmartStart_UltimateDefaultCatalog.manifest.json" \ |
| | | "SmartStart_UltimateDefaultCatalog.notes.en.json" \ |
| | | "SmartStart_UltimateDefaultCatalog.notes.zh-Hans.json"; do |
| | | if [ ! -f "$SMARTSTART_SOURCE_DIR/$required" ]; then |
| | | echo "❌ Missing Smart Start split resource: $required" |
| | | echo " Run: node Research/SmartStart/Scripts/build-ultimate-default-catalog.mjs" |
| | | exit 1 |
| | | fi |
| | | done |
| | | python3 - "$SMARTSTART_SOURCE_DIR/SmartStart_UltimateDefaultCatalog.base.json" "$RESOURCES_DIR/SmartStartUltimateDefaultCatalog.base.json" <<'PY' |
| | | import json |
| | | import sys |
| | | source, destination = sys.argv[1], sys.argv[2] |
| | | with open(source, "r", encoding="utf-8") as f: |
| | | data = json.load(f) |
| | | with open(destination, "w", encoding="utf-8") as f: |
| | | json.dump(data, f, ensure_ascii=False, separators=(",", ":")) |
| | | PY |
| | | python3 - "$SMARTSTART_SOURCE_DIR/SmartStart_UltimateDefaultCatalog.manifest.json" "$RESOURCES_DIR/SmartStartUltimateDefaultCatalog.manifest.json" <<'PY' |
| | | import json |
| | | import sys |
| | | source, destination = sys.argv[1], sys.argv[2] |
| | | with open(source, "r", encoding="utf-8") as f: |
| | | data = json.load(f) |
| | | with open(destination, "w", encoding="utf-8") as f: |
| | | json.dump(data, f, ensure_ascii=False, separators=(",", ":")) |
| | | PY |
| | | for notes_file in "$SMARTSTART_SOURCE_DIR"/SmartStart_UltimateDefaultCatalog.notes.*.json; do |
| | | [ -e "$notes_file" ] || continue |
| | | output_name="$(basename "$notes_file" | sed 's/SmartStart_UltimateDefaultCatalog/SmartStartUltimateDefaultCatalog/').deflate" |
| | | python3 - "$notes_file" "$RESOURCES_DIR/$output_name" <<'PY' |
| | | import json |
| | | import sys |
| | | import zlib |
| | | source, destination = sys.argv[1], sys.argv[2] |
| | | with open(source, "r", encoding="utf-8") as f: |
| | | data = json.load(f) |
| | | payload = json.dumps(data, ensure_ascii=False, separators=(",", ":")).encode("utf-8") |
| | | compressor = zlib.compressobj(level=9, wbits=-15) |
| | | compressed = compressor.compress(payload) + compressor.flush() |
| | | with open(destination, "wb") as f: |
| | | f.write(compressed) |
| | | PY |
| | | done |
| | | |
| | | if find "$RESOURCES_DIR" -maxdepth 1 -type f \( \ |
| | | -name '*TranslationCache*' -o \ |
| | | -name '*invalid*' -o \ |
| | | -name 'AppleDefaultApps.localizations.*.json' -o \ |
| | | -name 'SmartStartUltimateDefaultCatalog.json' -o \ |
| | | -name 'SmartStartUltimateDefaultCatalog.csv' -o \ |
| | | -name 'SmartStartUltimateDefaultCatalog.notes.*.json' \ |
| | | \) | grep -q .; then |
| | | echo "❌ Forbidden Smart Start artifact copied into app bundle" |
| | | find "$RESOURCES_DIR" -maxdepth 1 -type f \( \ |
| | | -name '*TranslationCache*' -o \ |
| | | -name '*invalid*' -o \ |
| | | -name 'AppleDefaultApps.localizations.*.json' -o \ |
| | | -name 'SmartStartUltimateDefaultCatalog.json' -o \ |
| | | -name 'SmartStartUltimateDefaultCatalog.csv' -o \ |
| | | -name 'SmartStartUltimateDefaultCatalog.notes.*.json' \ |
| | | \) -print |
| | | exit 1 |
| | | fi |
| | | |
| | | echo "==> Embedding PkgInfo..." |