#!/usr/bin/env bash # Build and validate the EurKEY-macOS keyboard layout bundle. # # Regenerates Info.plist with correct KLInfo entries for all layout versions, # sets the bundle version, and validates the bundle structure. # # Usage: bash scripts/build-bundle.sh [--version YYYY.MM.DD] set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" BUNDLE_DIR="${PROJECT_DIR}/EurKey-macOS.bundle" CONTENTS_DIR="${BUNDLE_DIR}/Contents" RESOURCES_DIR="${CONTENTS_DIR}/Resources" # parse arguments VERSION="${1:-$(date +%Y.%m.%d)}" if [[ "${1:-}" == "--version" ]]; then VERSION="${2:?missing version argument}" fi BUNDLE_ID="de.felixfoertsch.keyboardlayout.EurKEY-macOS" BUNDLE_NAME="EurKEY-macOS" # layout versions to include VERSIONS=("v1.2" "v1.3" "v1.4" "v2.0") echo "Building ${BUNDLE_NAME} ${VERSION}" echo "Bundle: ${BUNDLE_DIR}" echo # --- validate that all required files exist --- errors=0 for ver in "${VERSIONS[@]}"; do keylayout="${RESOURCES_DIR}/EurKEY ${ver}.keylayout" icns="${RESOURCES_DIR}/EurKEY ${ver}.icns" if [[ ! -f "${keylayout}" ]]; then echo "ERROR: missing ${keylayout}" errors=$((errors + 1)) fi if [[ ! -f "${icns}" ]]; then echo "ERROR: missing ${icns}" errors=$((errors + 1)) fi done for lang in en de es; do strings="${RESOURCES_DIR}/${lang}.lproj/InfoPlist.strings" if [[ ! -f "${strings}" ]]; then echo "ERROR: missing ${strings}" errors=$((errors + 1)) fi done if [[ $errors -gt 0 ]]; then echo "FAILED: ${errors} missing file(s)" exit 1 fi # --- generate Info.plist --- cat > "${CONTENTS_DIR}/Info.plist" << 'PLIST_HEADER' CFBundleIdentifier PLIST_HEADER echo " ${BUNDLE_ID}" >> "${CONTENTS_DIR}/Info.plist" cat >> "${CONTENTS_DIR}/Info.plist" << 'PLIST_NAME' CFBundleName PLIST_NAME echo " ${BUNDLE_NAME}" >> "${CONTENTS_DIR}/Info.plist" cat >> "${CONTENTS_DIR}/Info.plist" << 'PLIST_VERSION' CFBundleVersion PLIST_VERSION echo " ${VERSION}" >> "${CONTENTS_DIR}/Info.plist" # add KLInfo for each version for ver in "${VERSIONS[@]}"; do layout_name="EurKEY ${ver}" # generate input source ID: bundle id + layout name with spaces removed, lowercased source_id_suffix=$(echo "eurkey${ver}" | tr '[:upper:]' '[:lower:]' | tr -d ' ') source_id="${BUNDLE_ID}.${source_id_suffix}" cat >> "${CONTENTS_DIR}/Info.plist" << KLINFO_ENTRY KLInfo_${layout_name} TICapsLockLanguageSwitchCapable TISIconIsTemplate TISInputSourceID ${source_id} TISIntendedLanguage en KLINFO_ENTRY done cat >> "${CONTENTS_DIR}/Info.plist" << 'PLIST_FOOTER' PLIST_FOOTER echo "Generated Info.plist with ${#VERSIONS[@]} layout entries" # --- generate version.plist --- cat > "${CONTENTS_DIR}/version.plist" << VPLIST BuildVersion ${VERSION} ProjectName ${BUNDLE_NAME} SourceVersion ${VERSION} VPLIST echo "Generated version.plist (${VERSION})" # --- validate with plutil --- if command -v plutil &> /dev/null; then plutil -lint "${CONTENTS_DIR}/Info.plist" || exit 1 plutil -lint "${CONTENTS_DIR}/version.plist" || exit 1 echo "plist validation passed" fi # --- run layout validation --- if [[ -f "${SCRIPT_DIR}/validate_layouts.py" ]]; then echo python3 "${SCRIPT_DIR}/validate_layouts.py" || exit 1 fi echo echo "Bundle build complete: ${BUNDLE_DIR}" echo "Version: ${VERSION}"