added iOS source code
[wl-app.git] / iOS / Pods / RealmSwift / build.sh
diff --git a/iOS/Pods/RealmSwift/build.sh b/iOS/Pods/RealmSwift/build.sh
new file mode 100755 (executable)
index 0000000..04b73b4
--- /dev/null
@@ -0,0 +1,1516 @@
+#!/bin/bash
+
+##################################################################################
+# Custom build tool for Realm Objective-C binding.
+#
+# (C) Copyright 2011-2015 by realm.io.
+##################################################################################
+
+# Warning: pipefail is not a POSIX compatible option, but on OS X it works just fine.
+#          OS X uses a POSIX complain version of bash as /bin/sh, but apparently it does
+#          not strip away this feature. Also, this will fail if somebody forces the script
+#          to be run with zsh.
+set -o pipefail
+set -e
+
+source_root="$(dirname "$0")"
+
+# You can override the version of the core library
+: ${REALM_CORE_VERSION:=$(sed -n 's/^REALM_CORE_VERSION=\(.*\)$/\1/p' ${source_root}/dependencies.list)} # set to "current" to always use the current build
+
+: ${REALM_SYNC_VERSION:=$(sed -n 's/^REALM_SYNC_VERSION=\(.*\)$/\1/p' ${source_root}/dependencies.list)}
+
+: ${REALM_OBJECT_SERVER_VERSION:=$(sed -n 's/^REALM_OBJECT_SERVER_VERSION=\(.*\)$/\1/p' ${source_root}/dependencies.list)}
+
+# You can override the xcmode used
+: ${XCMODE:=xcodebuild} # must be one of: xcodebuild (default), xcpretty, xctool
+
+# Provide a fallback value for TMPDIR, relevant for Xcode Bots
+: ${TMPDIR:=$(getconf DARWIN_USER_TEMP_DIR)}
+
+PATH=/usr/libexec:$PATH
+
+if ! [ -z "${JENKINS_HOME}" ]; then
+    XCPRETTY_PARAMS="--no-utf --report junit --output build/reports/junit.xml"
+    CODESIGN_PARAMS="CODE_SIGN_IDENTITY= CODE_SIGNING_REQUIRED=NO"
+fi
+
+usage() {
+cat <<EOF
+Usage: sh $0 command [argument]
+
+command:
+  clean:                clean up/remove all generated files
+  download-core:        downloads core library (binary version)
+  download-object-server:  downloads and installs the Realm Object Server
+  download-sync:        downloads sync library (binary version, core+sync)
+  build:                builds all iOS  and OS X frameworks
+  ios-static:           builds fat iOS static framework
+  ios-dynamic:          builds iOS dynamic frameworks
+  ios-swift:            builds RealmSwift frameworks for iOS
+  watchos:              builds watchOS framwork
+  watchos-swift:        builds RealmSwift framework for watchOS
+  tvos:                 builds tvOS framework
+  tvos-swift:           builds RealmSwift framework for tvOS
+  osx:                  builds OS X framework
+  osx-swift:            builds RealmSwift framework for OS X
+  analyze-osx:          analyzes OS X framework
+  test:                 tests all iOS and OS X frameworks
+  test-all:             tests all iOS and OS X frameworks in both Debug and Release configurations
+  test-ios-static:      tests static iOS framework on 32-bit and 64-bit simulators
+  test-ios-dynamic:     tests dynamic iOS framework on 32-bit and 64-bit simulators
+  test-ios-swift:       tests RealmSwift iOS framework on 32-bit and 64-bit simulators
+  test-ios-devices:     tests ObjC & Swift iOS frameworks on all attached iOS devices
+  test-ios-devices-objc:  tests ObjC iOS framework on all attached iOS devices
+  test-ios-devices-swift: tests Swift iOS framework on all attached iOS devices
+  test-tvos:            tests tvOS framework
+  test-tvos-swift:      tests RealmSwift tvOS framework
+  test-tvos-devices:    tests ObjC & Swift tvOS frameworks on all attached tvOS devices
+  test-osx:             tests OS X framework
+  test-osx-swift:       tests RealmSwift OS X framework
+  verify:               verifies docs, osx, osx-swift, ios-static, ios-dynamic, ios-swift, ios-device in both Debug and Release configurations, swiftlint
+  verify-osx-object-server:  downloads the Realm Object Server and runs the Objective-C and Swift integration tests
+  docs:                 builds docs in docs/output
+  examples:             builds all examples
+  examples-ios:         builds all static iOS examples
+  examples-ios-swift:   builds all Swift iOS examples
+  examples-osx:         builds all OS X examples
+  get-version:          get the current version
+  set-version version:  set the version
+  cocoapods-setup:      download realm-core and create a stub RLMPlatform.h file to enable building via CocoaPods
+
+
+argument:
+  version: version in the x.y.z format
+
+environment variables:
+  XCMODE: xcodebuild (default), xcpretty or xctool
+  CONFIGURATION: Debug or Release (default)
+  REALM_CORE_VERSION: version in x.y.z format or "current" to use local build
+  REALM_EXTRA_BUILD_ARGUMENTS: additional arguments to pass to the build tool
+  REALM_XCODE_VERSION: the version number of Xcode to use (e.g.: 8.1)
+EOF
+}
+
+######################################
+# Xcode Helpers
+######################################
+
+xcode_version_major() {
+    echo "${REALM_XCODE_VERSION%%.*}"
+}
+
+xcode() {
+    mkdir -p build/DerivedData
+    CMD="xcodebuild -IDECustomDerivedDataLocation=build/DerivedData $@"
+    echo "Building with command:" $CMD
+    eval "$CMD"
+}
+
+xc() {
+    # Logs xcodebuild output in realtime
+    : ${NSUnbufferedIO:=YES}
+    args="$@ SWIFT_VERSION=$REALM_SWIFT_VERSION $REALM_EXTRA_BUILD_ARGUMENTS"
+    if [[ "$XCMODE" == "xcodebuild" ]]; then
+        xcode "$args"
+    elif [[ "$XCMODE" == "xcpretty" ]]; then
+        mkdir -p build
+        xcode "$args" | tee build/build.log | xcpretty -c ${XCPRETTY_PARAMS} || {
+            echo "The raw xcodebuild output is available in build/build.log"
+            exit 1
+        }
+    elif [[ "$XCMODE" == "xctool" ]]; then
+        xctool "$args"
+    fi
+}
+
+copy_bcsymbolmap() {
+    find "$1" -name '*.bcsymbolmap' -type f -exec cp {} "$2" \;
+}
+
+build_combined() {
+    local scheme="$1"
+    local module_name="$2"
+    local os="$3"
+    local simulator="$4"
+    local scope_suffix="$5"
+    local version_suffix="$6"
+    local config="$CONFIGURATION"
+
+    local destination=""
+    local os_name=""
+    if [[ "$os" == "iphoneos" ]]; then
+        os_name="ios"
+        destination="iPhone 6"
+    elif [[ "$os" == "watchos"  ]]; then
+        os_name="$os"
+        destination="Apple Watch - 42mm"
+    elif [[ "$os" == "appletvos"  ]]; then
+        os_name="tvos"
+        if (( $(xcode_version_major) >= 9 )); then
+            destination="Apple TV"
+        else
+            destination="Apple TV 1080p"
+        fi
+    fi
+
+    # Derive build paths
+    local build_products_path="build/DerivedData/Realm/Build/Products"
+    local product_name="$module_name.framework"
+    local binary_path="$module_name"
+    local os_path="$build_products_path/$config-$os$scope_suffix/$product_name"
+    local simulator_path="$build_products_path/$config-$simulator$scope_suffix/$product_name"
+    local out_path="build/$os_name$scope_suffix$version_suffix"
+
+    # Build for each platform
+    xc "-scheme '$scheme' -configuration $config -sdk $os"
+    xc "-scheme '$scheme' -configuration $config -sdk $simulator -destination 'name=$destination' ONLY_ACTIVE_ARCH=NO"
+
+    # Combine .swiftmodule
+    if [ -d $simulator_path/Modules/$module_name.swiftmodule ]; then
+      cp $simulator_path/Modules/$module_name.swiftmodule/* $os_path/Modules/$module_name.swiftmodule/
+    fi
+
+    # Copy *.bcsymbolmap to .framework for submitting app with bitcode
+    copy_bcsymbolmap "$build_products_path/$config-$os$scope_suffix" "$os_path"
+
+    # Retrieve build products
+    clean_retrieve $os_path $out_path $product_name
+
+    # Combine ar archives
+    LIPO_OUTPUT="$out_path/$product_name/$module_name"
+    xcrun lipo -create "$simulator_path/$binary_path" "$os_path/$binary_path" -output "$LIPO_OUTPUT"
+
+    if [[ "$destination" != "" && "$config" == "Release" ]]; then
+        sh build.sh binary-has-bitcode "$LIPO_OUTPUT"
+    fi
+}
+
+clean_retrieve() {
+  mkdir -p "$2"
+  rm -rf "$2/$3"
+  cp -R "$1" "$2"
+}
+
+move_to_clean_dir() {
+    rm -rf "$2"
+    mkdir -p "$2"
+    mv "$1" "$2"
+}
+
+test_ios_static() {
+    destination="$1"
+    xc "-scheme 'Realm iOS static' -configuration $CONFIGURATION -sdk iphonesimulator -destination '$destination' build"
+    if (( $(xcode_version_major) < 9 )); then
+        xc "-scheme 'Realm iOS static' -configuration $CONFIGURATION -sdk iphonesimulator -destination '$destination' test 'ARCHS=\$(ARCHS_STANDARD_32_BIT)'"
+    fi
+
+    # Xcode's depending tracking is lacking and it doesn't realize that the Realm static framework's static library
+    # needs to be recreated when the active architectures change. Help Xcode out by removing the static library.
+    settings=$(xcode "-scheme 'Realm iOS static' -configuration $CONFIGURATION -sdk iphonesimulator -destination '$destination' -showBuildSettings")
+    path=$(echo "$settings" | awk '/CONFIGURATION_BUILD_DIR/ { cbd = $3; } /EXECUTABLE_PATH/ { ep = $3; } END { printf "%s/%s\n", cbd, ep; }')
+    rm "$path"
+
+    xc "-scheme 'Realm iOS static' -configuration $CONFIGURATION -sdk iphonesimulator -destination '$destination' test"
+}
+
+######################################
+# Device Test Helper
+######################################
+
+test_devices() {
+    local serial_numbers=()
+    local awk_script="
+    /^ +Vendor ID: / { is_apple = 0; }
+    /^ +Vendor ID: 0x05[aA][cC] / { is_apple = 1; }
+    /^ +Serial Number: / {
+        if (is_apple) {
+            match(\$0, /^ +Serial Number: /);
+            print substr(\$0, RLENGTH + 1);
+        }
+    }
+    "
+    local serial_numbers_text=$(/usr/sbin/system_profiler SPUSBDataType | /usr/bin/awk "$awk_script")
+    while read -r number; do
+        if [[ "$number" != "" ]]; then
+            serial_numbers+=("$number")
+        fi
+    done <<< "$serial_numbers_text"
+    if [[ ${#serial_numbers[@]} == 0 ]]; then
+        echo "At least one iOS/tvOS device must be connected to this computer to run device tests"
+        if [ -z "${JENKINS_HOME}" ]; then
+            # Don't fail if running locally and there's no device
+            exit 0
+        fi
+        exit 1
+    fi
+    local sdk="$1"
+    local scheme="$2"
+    local configuration="$3"
+    local failed=0
+    for device in "${serial_numbers[@]}"; do
+        xc "-scheme '$scheme' -configuration $configuration -destination 'id=$device' -sdk $sdk test" || failed=1
+    done
+    return $failed
+}
+
+######################################
+# Docs
+######################################
+
+build_docs() {
+    local language="$1"
+    local version=$(sh build.sh get-version)
+
+    local xcodebuild_arguments="--objc,Realm/Realm.h,--,-x,objective-c,-isysroot,$(xcrun --show-sdk-path),-I,$(pwd)"
+    local module="Realm"
+    local objc="--objc"
+
+    if [[ "$language" == "swift" ]]; then
+        sh build.sh set-swift-version
+        xcodebuild_arguments="-scheme,RealmSwift"
+        module="RealmSwift"
+        objc=""
+    fi
+
+    touch Realm/RLMPlatform.h # jazzy will fail if it can't find all public header files
+    jazzy \
+      ${objc} \
+      --clean \
+      --author Realm \
+      --author_url https://realm.io \
+      --github_url https://github.com/realm/realm-cocoa \
+      --github-file-prefix https://github.com/realm/realm-cocoa/tree/v${version} \
+      --module-version ${version} \
+      --xcodebuild-arguments ${xcodebuild_arguments} \
+      --module ${module} \
+      --root-url https://realm.io/docs/${language}/${version}/api/ \
+      --output docs/${language}_output \
+      --head "$(cat docs/custom_head.html)"
+
+    rm Realm/RLMPlatform.h
+}
+
+######################################
+# Input Validation
+######################################
+
+if [ "$#" -eq 0 -o "$#" -gt 3 ]; then
+    usage
+    exit 1
+fi
+
+######################################
+# Downloading
+######################################
+
+kill_object_server() {
+# Based on build.sh conventions we always run ROS from a path ending in 'ros/bin/ros'.
+    pkill -f ros/bin/ros\ start
+}
+
+download_object_server() {
+    rm -rf ./test-ros-instance
+    mkdir -p ./test-ros-instance/ros
+    chmod 777 ./test-ros-instance
+    /usr/local/bin/node /usr/local/bin/npm install --scripts-prepend-node-path=auto --prefix ./test-ros-instance/ros \
+        -g realm-object-server@${REALM_OBJECT_SERVER_VERSION}
+}
+
+download_common() {
+    local download_type=$1 tries_left=3 version url error temp_dir temp_path tar_path
+
+    if [ "$download_type" == "core" ]; then
+        version=$REALM_CORE_VERSION
+        url="https://static.realm.io/downloads/core/realm-core-${version}.tar.xz"
+    elif [ "$download_type" == "sync" ]; then
+        version=$REALM_SYNC_VERSION
+        url="https://static.realm.io/downloads/sync/realm-sync-cocoa-${version}.tar.xz"
+    else
+        echo "Unknown dowload_type: $download_type"
+        exit 1
+    fi
+
+    echo "Downloading dependency: ${download_type} ${version}"
+
+    if [ -z "$TMPDIR" ]; then
+        TMPDIR='/tmp'
+    fi
+    temp_dir=$(dirname "$TMPDIR/waste")/${download_type}_bin
+    mkdir -p "$temp_dir"
+    tar_path="${temp_dir}/${download_type}-${version}.tar.xz"
+    temp_path="${tar_path}.tmp"
+
+    while [ 0 -lt $tries_left ] && [ ! -f "$tar_path" ]; do
+        if ! error=$(/usr/bin/curl --fail --silent --show-error --location "$url" --output "$temp_path" 2>&1); then
+            tries_left=$[$tries_left-1]
+        else
+            mv "$temp_path" "$tar_path"
+        fi
+    done
+
+    if [ ! -f "$tar_path" ]; then
+        printf "Downloading ${download_type} failed:\n\t$url\n\t$error\n"
+        exit 1
+    fi
+
+    (
+        cd "$temp_dir"
+        rm -rf "$download_type"
+        tar xf "$tar_path" --xz
+        mv core "${download_type}-${version}"
+    )
+
+    rm -rf "${download_type}-${version}" core
+    mv "${temp_dir}/${download_type}-${version}" .
+    ln -s "${download_type}-${version}" core
+}
+
+download_core() {
+    download_common "core"
+}
+
+download_sync() {
+    download_common "sync"
+}
+
+######################################
+# Variables
+######################################
+
+COMMAND="$1"
+
+# Use Debug config if command ends with -debug, otherwise default to Release
+# Set IS_RUNNING_PACKAGING when running packaging steps to avoid running iOS static tests with Xcode 8.3.3
+case "$COMMAND" in
+    *-debug)
+        COMMAND="${COMMAND%-debug}"
+        CONFIGURATION="Debug"
+        ;;
+    package-*)
+        IS_RUNNING_PACKAGING=1
+        ;;
+esac
+export CONFIGURATION=${CONFIGURATION:-Release}
+export IS_RUNNING_PACKAGING=${IS_RUNNING_PACKAGING:-0}
+
+# Pre-choose Xcode and Swift versions for those operations that do not set them
+REALM_XCODE_VERSION=${xcode_version:-$REALM_XCODE_VERSION}
+REALM_SWIFT_VERSION=${swift_version:-$REALM_SWIFT_VERSION}
+source "${source_root}/scripts/swift-version.sh"
+set_xcode_and_swift_versions
+
+######################################
+# Commands
+######################################
+
+case "$COMMAND" in
+
+    ######################################
+    # Clean
+    ######################################
+    "clean")
+        find . -type d -name build -exec rm -r "{}" +
+        exit 0
+        ;;
+
+    ######################################
+    # Object Server
+    ######################################
+    "download-object-server")
+        download_object_server
+        exit 0
+        ;;
+
+    "reset-ros-server-state")
+        rm -rf "./test-ros-instance/data"
+        rm -rf "./test-ros-instance/realm-object-server"
+        exit 0
+        ;;
+
+    "reset-ros-client-state")
+        rm -rf ~/Library/Application\ Support/xctest
+        rm -rf ~/Library/Application\ Support/io.realm.TestHost
+        rm -rf ~/Library/Application\ Support/xctest-child
+        exit 0
+        ;;
+
+    "reset-object-server")
+        kill_object_server
+        # Add a short delay, so file system doesn't complain about files in use
+        sleep 1
+        sh build.sh reset-ros-server-state
+        sh build.sh reset-ros-client-state
+        # Add another delay to ensure files are actually gone from file system
+        sleep 1
+        exit 0
+        ;;
+
+    ######################################
+    # Core
+    ######################################
+    "download-core")
+        if [ "$REALM_CORE_VERSION" = "current" ]; then
+            echo "Using version of core already in core/ directory"
+            exit 0
+        fi
+        if [ -d core -a -d ../realm-core -a ! -L core ]; then
+          # Allow newer versions than expected for local builds as testing
+          # with unreleased versions is one of the reasons to use a local build
+          if ! $(grep -i "${REALM_CORE_VERSION} Release notes" core/release_notes.txt >/dev/null); then
+              echo "Local build of core is out of date."
+              exit 1
+          else
+              echo "The core library seems to be up to date."
+          fi
+        elif ! [ -L core ]; then
+            echo "core is not a symlink. Deleting..."
+            rm -rf core
+            download_core
+        # With a prebuilt version we only want to check the first non-empty
+        # line so that checking out an older commit will download the
+        # appropriate version of core if the already-present version is too new
+        elif ! $(grep -m 1 . core/release_notes.txt | grep -i "${REALM_CORE_VERSION} RELEASE NOTES" >/dev/null); then
+            download_core
+        else
+            echo "The core library seems to be up to date."
+        fi
+        exit 0
+        ;;
+
+    ######################################
+    # Sync
+    ######################################
+    "download-sync")
+        if [ "$REALM_SYNC_VERSION" = "current" ]; then
+            echo "Using version of core already in core/ directory"
+            exit 0
+        fi
+        if [ -d core -a -d ../realm-core -a -d ../realm-sync -a ! -L core ]; then
+          echo "Using version of core already in core/ directory"
+        elif ! [ -L core ]; then
+            echo "core is not a symlink. Deleting..."
+            rm -rf core
+            download_sync
+        elif [[ "$(cat core/version.txt)" != "$REALM_SYNC_VERSION" ]]; then
+            download_sync
+        else
+            echo "The core library seems to be up to date."
+        fi
+        exit 0
+        ;;
+
+    ######################################
+    # Swift versioning
+    ######################################
+    "set-swift-version")
+        version=${2:-$REALM_SWIFT_VERSION}
+
+        SWIFT_VERSION_FILE="RealmSwift/SwiftVersion.swift"
+        CONTENTS="let swiftLanguageVersion = \"$version\""
+        if [ ! -f "$SWIFT_VERSION_FILE" ] || ! grep -q "$CONTENTS" "$SWIFT_VERSION_FILE"; then
+            echo "$CONTENTS" > "$SWIFT_VERSION_FILE"
+        fi
+
+        exit 0
+        ;;
+
+    "prelaunch-simulator")
+        sh ${source_root}/scripts/reset-simulators.sh
+        ;;
+
+    ######################################
+    # Building
+    ######################################
+    "build")
+        sh build.sh ios-static
+        sh build.sh ios-dynamic
+        sh build.sh ios-swift
+        sh build.sh watchos
+        sh build.sh watchos-swift
+        sh build.sh tvos
+        sh build.sh tvos-swift
+        sh build.sh osx
+        sh build.sh osx-swift
+        exit 0
+        ;;
+
+    "ios-static")
+        build_combined 'Realm iOS static' Realm iphoneos iphonesimulator "-static"
+        exit 0
+        ;;
+
+    "ios-dynamic")
+        build_combined Realm Realm iphoneos iphonesimulator
+        exit 0
+        ;;
+
+    "ios-swift")
+        sh build.sh ios-dynamic
+        build_combined RealmSwift RealmSwift iphoneos iphonesimulator '' "/swift-$REALM_SWIFT_VERSION"
+        cp -R build/ios/Realm.framework build/ios/swift-$REALM_SWIFT_VERSION
+        exit 0
+        ;;
+
+    "watchos")
+        build_combined Realm Realm watchos watchsimulator
+        exit 0
+        ;;
+
+    "watchos-swift")
+        sh build.sh watchos
+        build_combined RealmSwift RealmSwift watchos watchsimulator '' "/swift-$REALM_SWIFT_VERSION"
+        cp -R build/watchos/Realm.framework build/watchos/swift-$REALM_SWIFT_VERSION
+        exit 0
+        ;;
+
+    "tvos")
+        build_combined Realm Realm appletvos appletvsimulator
+        exit 0
+        ;;
+
+    "tvos-swift")
+        sh build.sh tvos
+        build_combined RealmSwift RealmSwift appletvos appletvsimulator '' "/swift-$REALM_SWIFT_VERSION"
+        cp -R build/tvos/Realm.framework build/tvos/swift-$REALM_SWIFT_VERSION
+        exit 0
+        ;;
+
+    "osx")
+        xc "-scheme Realm -configuration $CONFIGURATION"
+        clean_retrieve "build/DerivedData/Realm/Build/Products/$CONFIGURATION/Realm.framework" "build/osx" "Realm.framework"
+        exit 0
+        ;;
+
+    "osx-swift")
+        sh build.sh osx
+        xc "-scheme 'RealmSwift' -configuration $CONFIGURATION build"
+        destination="build/osx/swift-$REALM_SWIFT_VERSION"
+        clean_retrieve "build/DerivedData/Realm/Build/Products/$CONFIGURATION/RealmSwift.framework" "$destination" "RealmSwift.framework"
+        cp -R build/osx/Realm.framework "$destination"
+        exit 0
+        ;;
+
+    ######################################
+    # Analysis
+    ######################################
+
+    "analyze-osx")
+        xc "-scheme Realm -configuration $CONFIGURATION analyze"
+        exit 0
+        ;;
+
+    ######################################
+    # Testing
+    ######################################
+    "test")
+        set +e # Run both sets of tests even if the first fails
+        failed=0
+        sh build.sh test-ios-static || failed=1
+        sh build.sh test-ios-dynamic || failed=1
+        sh build.sh test-ios-swift || failed=1
+        sh build.sh test-ios-devices || failed=1
+        sh build.sh test-tvos-devices || failed=1
+        sh build.sh test-osx || failed=1
+        sh build.sh test-osx-swift || failed=1
+        exit $failed
+        ;;
+
+    "test-all")
+        set +e
+        failed=0
+        sh build.sh test || failed=1
+        sh build.sh test-debug || failed=1
+        exit $failed
+        ;;
+
+    "test-ios-static")
+        test_ios_static "name=iPhone 6"
+        exit 0
+        ;;
+
+    "test-ios-dynamic")
+        xc "-scheme Realm -configuration $CONFIGURATION -sdk iphonesimulator -destination 'name=iPhone 6' build"
+        if (( $(xcode_version_major) < 9 )); then
+            xc "-scheme Realm -configuration $CONFIGURATION -sdk iphonesimulator -destination 'name=iPhone 6' test 'ARCHS=\$(ARCHS_STANDARD_32_BIT)'"
+        fi
+        xc "-scheme Realm -configuration $CONFIGURATION -sdk iphonesimulator -destination 'name=iPhone 6' test"
+        exit 0
+        ;;
+
+    "test-ios-swift")
+        xc "-scheme RealmSwift -configuration $CONFIGURATION -sdk iphonesimulator -destination 'name=iPhone 6' build"
+        if (( $(xcode_version_major) < 9 )); then
+            xc "-scheme RealmSwift -configuration $CONFIGURATION -sdk iphonesimulator -destination 'name=iPhone 6' test 'ARCHS=\$(ARCHS_STANDARD_32_BIT)'"
+        fi
+        xc "-scheme RealmSwift -configuration $CONFIGURATION -sdk iphonesimulator -destination 'name=iPhone 6' test"
+        exit 0
+        ;;
+
+    "test-ios-devices")
+        failed=0
+        trap "failed=1" ERR
+        sh build.sh test-ios-devices-objc
+        sh build.sh test-ios-devices-swift
+        exit $failed
+        ;;
+
+    "test-ios-devices-objc")
+        test_devices iphoneos "Realm" "$CONFIGURATION"
+        exit $?
+        ;;
+
+    "test-ios-devices-swift")
+        test_devices iphoneos "RealmSwift" "$CONFIGURATION"
+        exit $?
+        ;;
+
+    "test-tvos")
+        if (( $(xcode_version_major) >= 9 )); then
+            destination="Apple TV"
+        else
+            destination="Apple TV 1080p"
+        fi
+        xc "-scheme Realm -configuration $CONFIGURATION -sdk appletvsimulator -destination 'name=$destination' test"
+        exit $?
+        ;;
+
+    "test-tvos-swift")
+        if (( $(xcode_version_major) >= 9 )); then
+            destination="Apple TV"
+        else
+            destination="Apple TV 1080p"
+        fi
+        xc "-scheme RealmSwift -configuration $CONFIGURATION -sdk appletvsimulator -destination 'name=$destination' test"
+        exit $?
+        ;;
+
+    "test-tvos-devices")
+        test_devices appletvos TestHost "$CONFIGURATION"
+        ;;
+
+    "test-osx")
+        COVERAGE_PARAMS=""
+        if [[ "$CONFIGURATION" == "Debug" ]]; then
+            COVERAGE_PARAMS="GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES"
+        fi
+        xc "-scheme Realm -configuration $CONFIGURATION test $COVERAGE_PARAMS"
+        exit 0
+        ;;
+
+    "test-osx-swift")
+        xc "-scheme RealmSwift -configuration $CONFIGURATION test"
+        exit 0
+        ;;
+
+    "test-osx-object-server")
+        xc "-scheme 'Object Server Tests' -configuration $CONFIGURATION -sdk macosx test"
+        exit 0
+        ;;
+
+    ######################################
+    # Full verification
+    ######################################
+    "verify")
+        sh build.sh verify-cocoapods
+        sh build.sh verify-docs
+        sh build.sh verify-osx
+        sh build.sh verify-osx-debug
+        sh build.sh verify-osx-swift
+        sh build.sh verify-osx-swift-debug
+        sh build.sh verify-ios-static
+        sh build.sh verify-ios-static-debug
+        sh build.sh verify-ios-dynamic
+        sh build.sh verify-ios-dynamic-debug
+        sh build.sh verify-ios-swift
+        sh build.sh verify-ios-swift-debug
+        sh build.sh verify-ios-device-objc
+        sh build.sh verify-ios-device-swift
+        sh build.sh verify-watchos
+        sh build.sh verify-tvos
+        sh build.sh verify-tvos-debug
+        sh build.sh verify-tvos-device
+        sh build.sh verify-swiftlint
+        sh build.sh verify-osx-object-server
+        ;;
+
+    "verify-cocoapods")
+        if [[ -d .git ]]; then
+          # Verify the current branch, unless one was already specified in the sha environment variable.
+          if [[ -z $sha ]]; then
+            export sha=$(git rev-parse --abbrev-ref HEAD)
+          fi
+
+          if [[ $(git log -1 @{push}..) != "" ]] || ! git diff-index --quiet HEAD; then
+            echo "WARNING: verify-cocoapods will test the latest revision of $sha found on GitHub."
+            echo "         Any unpushed local changes will not be tested."
+            echo ""
+            sleep 1
+          fi
+        fi
+
+        cd examples/installation
+        sh build.sh test-ios-objc-cocoapods
+        sh build.sh test-ios-objc-cocoapods-dynamic
+        sh build.sh test-ios-swift-cocoapods
+        sh build.sh test-osx-objc-cocoapods
+        sh build.sh test-osx-swift-cocoapods
+        sh build.sh test-watchos-objc-cocoapods
+        sh build.sh test-watchos-swift-cocoapods
+        ;;
+
+    "verify-osx-encryption")
+        REALM_ENCRYPT_ALL=YES sh build.sh test-osx
+        exit 0
+        ;;
+
+    "verify-osx")
+        sh build.sh test-osx
+        sh build.sh analyze-osx
+        sh build.sh examples-osx
+
+        (
+            cd examples/osx/objc/build/DerivedData/RealmExamples/Build/Products/$CONFIGURATION
+            DYLD_FRAMEWORK_PATH=. ./JSONImport >/dev/null
+        )
+        exit 0
+        ;;
+
+    "verify-osx-swift")
+        sh build.sh test-osx-swift
+        exit 0
+        ;;
+
+    "verify-ios-static")
+        sh build.sh test-ios-static
+        sh build.sh examples-ios
+        ;;
+
+    "verify-ios-dynamic")
+        sh build.sh test-ios-dynamic
+        ;;
+
+    "verify-ios-swift")
+        sh build.sh test-ios-swift
+        sh build.sh examples-ios-swift
+        ;;
+
+    "verify-ios-device-objc")
+        sh build.sh test-ios-devices-objc
+        exit 0
+        ;;
+
+    "verify-ios-device-swift")
+        sh build.sh test-ios-devices-swift
+        exit 0
+        ;;
+
+    "verify-docs")
+        sh build.sh docs
+        for lang in swift objc; do
+            undocumented="docs/${lang}_output/undocumented.json"
+            if ruby -rjson -e "j = JSON.parse(File.read('docs/${lang}_output/undocumented.json')); exit j['warnings'].length != 0"; then
+              echo "Undocumented Realm $lang declarations:"
+              cat "$undocumented"
+              exit 1
+            fi
+        done
+        exit 0
+        ;;
+
+    "verify-watchos")
+        sh build.sh watchos-swift
+        exit 0
+        ;;
+
+    "verify-tvos")
+        sh build.sh test-tvos
+        sh build.sh test-tvos-swift
+        sh build.sh examples-tvos
+        sh build.sh examples-tvos-swift
+        exit 0
+        ;;
+
+    "verify-tvos-device")
+        sh build.sh test-tvos-devices
+        exit 0
+        ;;
+
+    "verify-swiftlint")
+        swiftlint lint --strict
+        exit 0
+        ;;
+
+    "verify-osx-object-server")
+        sh build.sh download-object-server
+        sh build.sh test-osx-object-server
+        sh build.sh reset-object-server
+        exit 0
+        ;;
+
+    ######################################
+    # Docs
+    ######################################
+    "docs")
+        build_docs objc
+        build_docs swift
+        exit 0
+        ;;
+
+    ######################################
+    # Examples
+    ######################################
+    "examples")
+        sh build.sh clean
+        sh build.sh examples-ios
+        sh build.sh examples-ios-swift
+        sh build.sh examples-osx
+        sh build.sh examples-tvos
+        sh build.sh examples-tvos-swift
+        exit 0
+        ;;
+
+    "examples-ios")
+        sh build.sh prelaunch-simulator
+        workspace="examples/ios/objc/RealmExamples.xcworkspace"
+        pod install --project-directory="$workspace/.." --no-repo-update
+        xc "-workspace $workspace -scheme Simple -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}"
+        xc "-workspace $workspace -scheme TableView -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}"
+        xc "-workspace $workspace -scheme Migration -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}"
+        xc "-workspace $workspace -scheme Backlink -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}"
+        xc "-workspace $workspace -scheme GroupedTableView -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}"
+        xc "-workspace $workspace -scheme RACTableView -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}"
+        xc "-workspace $workspace -scheme Encryption -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}"
+        xc "-workspace $workspace -scheme Draw -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}"
+
+        if [ ! -z "${JENKINS_HOME}" ]; then
+            xc "-workspace $workspace -scheme Extension -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}"
+        fi
+
+        exit 0
+        ;;
+
+    "examples-ios-swift")
+        sh build.sh prelaunch-simulator
+        workspace="examples/ios/swift/RealmExamples.xcworkspace"
+        if [[ ! -d "$workspace" ]]; then
+            workspace="${workspace/swift/swift-$REALM_SWIFT_VERSION}"
+        fi
+
+        xc "-workspace $workspace -scheme Simple -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}"
+        xc "-workspace $workspace -scheme TableView -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}"
+        xc "-workspace $workspace -scheme Migration -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}"
+        xc "-workspace $workspace -scheme Encryption -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}"
+        xc "-workspace $workspace -scheme Backlink -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}"
+        xc "-workspace $workspace -scheme GroupedTableView -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}"
+        exit 0
+        ;;
+
+    "examples-osx")
+        xc "-workspace examples/osx/objc/RealmExamples.xcworkspace -scheme JSONImport -configuration ${CONFIGURATION} build ${CODESIGN_PARAMS}"
+        ;;
+
+    "examples-tvos")
+        workspace="examples/tvos/objc/RealmExamples.xcworkspace"
+        if (( $(xcode_version_major) >= 9 )); then
+            destination="Apple TV"
+        else
+            destination="Apple TV 1080p"
+        fi
+
+        xc "-workspace $workspace -scheme DownloadCache -configuration $CONFIGURATION -destination 'name=$destination' build ${CODESIGN_PARAMS}"
+        xc "-workspace $workspace -scheme PreloadedData -configuration $CONFIGURATION -destination 'name=$destination' build ${CODESIGN_PARAMS}"
+        exit 0
+        ;;
+
+    "examples-tvos-swift")
+        workspace="examples/tvos/swift/RealmExamples.xcworkspace"
+        if [[ ! -d "$workspace" ]]; then
+            workspace="${workspace/swift/swift-$REALM_SWIFT_VERSION}"
+        fi
+
+        if (( $(xcode_version_major) >= 9 )); then
+            destination="Apple TV"
+        else
+            destination="Apple TV 1080p"
+        fi
+
+        xc "-workspace $workspace -scheme DownloadCache -configuration $CONFIGURATION -destination 'name=$destination' build ${CODESIGN_PARAMS}"
+        xc "-workspace $workspace -scheme PreloadedData -configuration $CONFIGURATION -destination 'name=$destination' build ${CODESIGN_PARAMS}"
+        exit 0
+        ;;
+
+    ######################################
+    # Versioning
+    ######################################
+    "get-version")
+        version_file="Realm/Realm-Info.plist"
+        echo "$(PlistBuddy -c "Print :CFBundleShortVersionString" "$version_file")"
+        exit 0
+        ;;
+
+    "set-version")
+        realm_version="$2"
+        version_files="Realm/Realm-Info.plist"
+
+        if [ -z "$realm_version" ]; then
+            echo "You must specify a version."
+            exit 1
+        fi
+        # The bundle version can contain only three groups of digits separated by periods,
+        # so strip off any -beta.x tag from the end of the version string.
+        bundle_version=$(echo "$realm_version" | cut -d - -f 1)
+        for version_file in $version_files; do
+            PlistBuddy -c "Set :CFBundleVersion $bundle_version" "$version_file"
+            PlistBuddy -c "Set :CFBundleShortVersionString $realm_version" "$version_file"
+        done
+        sed -i '' "s/^VERSION=.*/VERSION=$realm_version/" dependencies.list
+        exit 0
+        ;;
+
+    ######################################
+    # Bitcode Detection
+    ######################################
+
+    "binary-has-bitcode")
+        BINARY="$2"
+        # Although grep has a '-q' flag to prevent logging to stdout, grep
+        # behaves differently when used, so redirect stdout to /dev/null.
+        if otool -l "$BINARY" | grep "segname __LLVM" > /dev/null 2>&1; then
+            exit 0
+        fi
+        # Work around rdar://21826157 by checking for bitcode in thin binaries
+
+        # Get architectures for binary
+        archs="$(lipo -info "$BINARY" | rev | cut -d ':' -f1 | rev)"
+
+        archs_array=( $archs )
+        if [[ ${#archs_array[@]} -lt 2 ]]; then
+            exit 1 # Early exit if not a fat binary
+        fi
+
+        TEMPDIR=$(mktemp -d $TMPDIR/realm-bitcode-check.XXXX)
+
+        for arch in $archs; do
+            lipo -thin "$arch" "$BINARY" -output "$TEMPDIR/$arch"
+            if otool -l "$TEMPDIR/$arch" | grep -q "segname __LLVM"; then
+                exit 0
+            fi
+        done
+        exit 1
+        ;;
+
+    ######################################
+    # CocoaPods
+    ######################################
+    "cocoapods-setup")
+        if [ ! -d core ]; then
+          sh build.sh download-sync
+          rm core
+          mv sync-* core
+          mv core/librealm-ios.a core/librealmcore-ios.a
+          mv core/librealm-macosx.a core/librealmcore-macosx.a
+          mv core/librealm-tvos.a core/librealmcore-tvos.a
+          mv core/librealm-watchos.a core/librealmcore-watchos.a
+        fi
+
+        if [[ "$2" != "swift" ]]; then
+          if [ ! -d Realm/ObjectStore/src ]; then
+            cat >&2 <<EOM
+
+
+ERROR: One of Realm's submodules is missing!
+
+If you're using Realm and/or RealmSwift from a git branch, please add 'submodules: true' to
+their entries in your Podfile.
+
+
+EOM
+            exit 1
+          fi
+
+          rm -rf include
+          mkdir -p include
+          mv core/include include/core
+
+          mkdir -p include/impl/apple include/util/apple include/sync/impl/apple
+          cp Realm/*.hpp include
+          cp Realm/ObjectStore/src/*.hpp include
+          cp Realm/ObjectStore/src/sync/*.hpp include/sync
+          cp Realm/ObjectStore/src/sync/impl/*.hpp include/sync/impl
+          cp Realm/ObjectStore/src/sync/impl/apple/*.hpp include/sync/impl/apple
+          cp Realm/ObjectStore/src/impl/*.hpp include/impl
+          cp Realm/ObjectStore/src/impl/apple/*.hpp include/impl/apple
+          cp Realm/ObjectStore/src/util/*.hpp include/util
+          cp Realm/ObjectStore/src/util/apple/*.hpp include/util/apple
+
+          touch Realm/RLMPlatform.h
+          if [ -n "$COCOAPODS_VERSION" ]; then
+            # This variable is set for the prepare_command available
+            # from the 1.0 prereleases, which requires a different
+            # header layout within the header_mappings_dir.
+            cp Realm/*.h include
+          else
+            # For CocoaPods < 1.0, we need to scope the headers within
+            # the header_mappings_dir by another subdirectory to avoid
+            # Clang from complaining about non-modular headers.
+            mkdir -p include/Realm
+            cp Realm/*.h include/Realm
+          fi
+        else
+          sh build.sh set-swift-version
+        fi
+        ;;
+
+    ######################################
+    # Continuous Integration
+    ######################################
+
+    "ci-pr")
+        mkdir -p build/reports
+        # FIXME: Re-enable once CI can properly unlock the keychain
+        export REALM_DISABLE_METADATA_ENCRYPTION=1
+
+        # strip off the ios|tvos version specifier, e.g. the last part of: `ios-device-objc-ios8`
+        if [[ "$target" =~ ^((ios|tvos)-device(-(objc|swift))?)(-(ios|tvos)[[:digit:]]+)?$ ]]; then
+            export target=${BASH_REMATCH[1]}
+        fi
+
+        if [ "$target" = "docs" ]; then
+            sh build.sh set-swift-version
+            sh build.sh verify-docs
+        elif [ "$target" = "swiftlint" ]; then
+            sh build.sh verify-swiftlint
+        else
+            export sha=$GITHUB_PR_SOURCE_BRANCH
+            export CONFIGURATION=$configuration
+            export REALM_EXTRA_BUILD_ARGUMENTS='GCC_GENERATE_DEBUGGING_SYMBOLS=NO REALM_PREFIX_HEADER=Realm/RLMPrefix.h'
+            sh build.sh prelaunch-simulator
+
+            # Reset CoreSimulator.log
+            mkdir -p ~/Library/Logs/CoreSimulator
+            echo > ~/Library/Logs/CoreSimulator/CoreSimulator.log
+
+            if [ -d ~/Library/Developer/CoreSimulator/Devices/ ]; then
+                # Verify that no Realm files still exist
+                ! find ~/Library/Developer/CoreSimulator/Devices/ -name '*.realm' | grep -q .
+            fi
+
+            failed=0
+            sh build.sh verify-$target 2>&1 | tee build/build.log | xcpretty -r junit -o build/reports/junit.xml || failed=1
+            if [ "$failed" = "1" ] && cat build/build.log | grep -E 'DTXProxyChannel|DTXChannel|out of date and needs to be rebuilt|operation never finished bootstrapping'; then
+                echo "Known Xcode error detected. Running job again."
+                if cat build/build.log | grep -E 'out of date and needs to be rebuilt'; then
+                    rm -rf build/DerivedData
+                fi
+                failed=0
+                sh build.sh verify-$target | tee build/build.log | xcpretty -r junit -o build/reports/junit.xml || failed=1
+            elif [ "$failed" = "1" ] && tail ~/Library/Logs/CoreSimulator/CoreSimulator.log | grep -E "Operation not supported|Failed to lookup com.apple.coreservices.lsuseractivity.simulatorsupport"; then
+                echo "Known Xcode error detected. Running job again."
+                failed=0
+                sh build.sh verify-$target | tee build/build.log | xcpretty -r junit -o build/reports/junit.xml || failed=1
+            fi
+            if [ "$failed" = "1" ]; then
+                echo "\n\n***\nbuild/build.log\n***\n\n" && cat build/build.log || true
+                echo "\n\n***\nCoreSimulator.log\n***\n\n" && cat ~/Library/Logs/CoreSimulator/CoreSimulator.log
+                exit 1
+            fi
+        fi
+
+        if [ "$target" = "osx" ] && [ "$configuration" = "Debug" ]; then
+          gcovr -r . -f ".*Realm.*" -e ".*Tests.*" -e ".*core.*" --xml > build/reports/coverage-report.xml
+          WS=$(pwd | sed "s/\//\\\\\//g")
+          sed -i ".bak" "s/<source>\./<source>${WS}/" build/reports/coverage-report.xml
+        fi
+        ;;
+
+    ######################################
+    # Release packaging
+    ######################################
+
+    "package-examples")
+        ./scripts/package_examples.rb
+        zip --symlinks -r realm-examples.zip examples -x "examples/installation/*"
+        ;;
+
+    "package-test-examples")
+        if ! VERSION=$(echo realm-objc-*.zip | egrep -o '\d*\.\d*\.\d*-[a-z]*(\.\d*)?'); then
+            VERSION=$(echo realm-objc-*.zip | egrep -o '\d*\.\d*\.\d*')
+        fi
+        OBJC="realm-objc-${VERSION}"
+        SWIFT="realm-swift-${VERSION}"
+        unzip ${OBJC}.zip
+
+        cp $0 ${OBJC}
+        cp -r ${source_root}/scripts ${OBJC}
+        cd ${OBJC}
+        sh build.sh examples-ios
+        sh build.sh examples-tvos
+        sh build.sh examples-osx
+        cd ..
+        rm -rf ${OBJC}
+
+        unzip ${SWIFT}.zip
+
+        cp $0 ${SWIFT}
+        cp -r ${source_root}/scripts ${SWIFT}
+        cd ${SWIFT}
+        sh build.sh examples-ios-swift
+        sh build.sh examples-tvos-swift
+        cd ..
+        rm -rf ${SWIFT}
+        ;;
+
+    "package-ios-static")
+        sh build.sh prelaunch-simulator
+        sh build.sh ios-static
+
+        cd build/ios-static
+        zip --symlinks -r realm-framework-ios-static.zip Realm.framework
+        ;;
+
+    "package-ios")
+        sh build.sh prelaunch-simulator
+        sh build.sh ios-dynamic
+        cd build/ios
+        zip --symlinks -r realm-framework-ios.zip Realm.framework
+        ;;
+
+    "package-osx")
+        sh build.sh osx
+
+        cd build/DerivedData/Realm/Build/Products/Release
+        zip --symlinks -r realm-framework-osx.zip Realm.framework
+        ;;
+
+    "package-ios-swift")
+        for version in 8.3.3 9.0 9.1 9.2; do
+            REALM_XCODE_VERSION=$version
+            REALM_SWIFT_VERSION=
+            set_xcode_and_swift_versions
+            sh build.sh prelaunch-simulator
+            sh build.sh ios-swift
+        done
+
+        cd build/ios
+        ln -s swift-4.0 swift-3.2
+        ln -s swift-4.0.2 swift-3.2.2
+        ln -s swift-4.0.2 swift-3.2.3
+        ln -s swift-4.0.2 swift-4.0.3
+        zip --symlinks -r realm-swift-framework-ios.zip swift-3.1 swift-3.2 swift-3.2.2 swift-3.2.3 swift-4.0 swift-4.0.2 swift-4.0.3
+        ;;
+
+    "package-osx-swift")
+        for version in 8.3.3 9.0 9.1 9.2; do
+            REALM_XCODE_VERSION=$version
+            REALM_SWIFT_VERSION=
+            set_xcode_and_swift_versions
+            sh build.sh prelaunch-simulator
+            sh build.sh osx-swift
+        done
+
+        cd build/osx
+        ln -s swift-4.0 swift-3.2
+        ln -s swift-4.0.2 swift-3.2.2
+        ln -s swift-4.0.2 swift-3.2.3
+        ln -s swift-4.0.2 swift-4.0.3
+        zip --symlinks -r realm-swift-framework-osx.zip swift-3.1 swift-3.2 swift-3.2.2 swift-3.2.3 swift-4.0 swift-4.0.2 swift-4.0.3
+        ;;
+
+    "package-watchos")
+        sh build.sh prelaunch-simulator
+        sh build.sh watchos
+
+        cd build/watchos
+        zip --symlinks -r realm-framework-watchos.zip Realm.framework
+        ;;
+
+    "package-watchos-swift")
+        for version in 8.3.3 9.0 9.1 9.2; do
+            REALM_XCODE_VERSION=$version
+            REALM_SWIFT_VERSION=
+            set_xcode_and_swift_versions
+            sh build.sh prelaunch-simulator
+            sh build.sh watchos-swift
+        done
+
+        cd build/watchos
+        ln -s swift-4.0 swift-3.2
+        ln -s swift-4.0.2 swift-3.2.2
+        ln -s swift-4.0.2 swift-3.2.3
+        ln -s swift-4.0.2 swift-4.0.3
+        zip --symlinks -r realm-swift-framework-watchos.zip swift-3.1 swift-3.2 swift-3.2.2 swift-3.2.3 swift-4.0 swift-4.0.2 swift-4.0.3
+        ;;
+
+    "package-tvos")
+        sh build.sh prelaunch-simulator
+        sh build.sh tvos
+
+        cd build/tvos
+        zip --symlinks -r realm-framework-tvos.zip Realm.framework
+        ;;
+
+    "package-tvos-swift")
+        for version in 8.3.3 9.0 9.1 9.2; do
+            REALM_XCODE_VERSION=$version
+            REALM_SWIFT_VERSION=
+            set_xcode_and_swift_versions
+            sh build.sh prelaunch-simulator
+            sh build.sh tvos-swift
+        done
+
+        cd build/tvos
+        ln -s swift-4.0 swift-3.2
+        ln -s swift-4.0.2 swift-3.2.2
+        ln -s swift-4.0.2 swift-3.2.3
+        ln -s swift-4.0.2 swift-4.0.3
+        zip --symlinks -r realm-swift-framework-tvos.zip swift-3.1 swift-3.2 swift-3.2.2 swift-3.2.3 swift-4.0 swift-4.0.2 swift-4.0.3
+        ;;
+
+    package-*-swift-3.2)
+        PLATFORM=$(echo $COMMAND | cut -d - -f 2)
+        mkdir -p build/$PLATFORM
+        cd build/$PLATFORM
+        ln -s swift-4.0 swift-3.2
+        zip --symlinks -r realm-swift-framework-$PLATFORM-swift-3.2.zip swift-3.2
+        ;;
+
+    package-*-swift-3.2.2)
+        PLATFORM=$(echo $COMMAND | cut -d - -f 2)
+        mkdir -p build/$PLATFORM
+        cd build/$PLATFORM
+        ln -s swift-4.0.2 swift-3.2.2
+        zip --symlinks -r realm-swift-framework-$PLATFORM-swift-3.2.2.zip swift-3.2.2
+        ;;
+
+    package-*-swift-3.2.3)
+        PLATFORM=$(echo $COMMAND | cut -d - -f 2)
+        mkdir -p build/$PLATFORM
+        cd build/$PLATFORM
+        ln -s swift-4.0.2 swift-3.2.3
+        zip --symlinks -r realm-swift-framework-$PLATFORM-swift-3.2.3.zip swift-3.2.3
+        ;;
+
+    package-*-swift-4.0.3)
+        PLATFORM=$(echo $COMMAND | cut -d - -f 2)
+        mkdir -p build/$PLATFORM
+        cd build/$PLATFORM
+        ln -s swift-4.0.2 swift-4.0.3
+        zip --symlinks -r realm-swift-framework-$PLATFORM-swift-4.0.3.zip swift-4.0.3
+        ;;
+
+    package-*-swift-*)
+        PLATFORM=$(echo $COMMAND | cut -d - -f 2)
+        REALM_SWIFT_VERSION=$(echo $COMMAND | cut -d - -f 4)
+        REALM_XCODE_VERSION=
+
+        set_xcode_and_swift_versions
+        sh build.sh prelaunch-simulator
+        sh build.sh $PLATFORM-swift
+
+        cd build/$PLATFORM
+        zip --symlinks -r realm-swift-framework-$PLATFORM-swift-$REALM_SWIFT_VERSION.zip swift-$REALM_SWIFT_VERSION
+        ;;
+
+    "package-release")
+        LANG="$2"
+        TEMPDIR=$(mktemp -d $TMPDIR/realm-release-package-${LANG}.XXXX)
+
+        VERSION=$(sh build.sh get-version)
+
+        FOLDER=${TEMPDIR}/realm-${LANG}-${VERSION}
+
+        mkdir -p ${FOLDER}/osx ${FOLDER}/ios ${FOLDER}/watchos ${FOLDER}/tvos
+
+        if [[ "${LANG}" == "objc" ]]; then
+            mkdir -p ${FOLDER}/ios/static
+            mkdir -p ${FOLDER}/ios/dynamic
+            mkdir -p ${FOLDER}/Swift
+
+            (
+                cd ${FOLDER}/osx
+                unzip ${WORKSPACE}/realm-framework-osx.zip
+            )
+
+            (
+                cd ${FOLDER}/ios/static
+                unzip ${WORKSPACE}/realm-framework-ios-static.zip
+            )
+
+            (
+                cd ${FOLDER}/ios/dynamic
+                unzip ${WORKSPACE}/realm-framework-ios.zip
+            )
+
+            (
+                cd ${FOLDER}/watchos
+                unzip ${WORKSPACE}/realm-framework-watchos.zip
+            )
+
+            (
+                cd ${FOLDER}/tvos
+                unzip ${WORKSPACE}/realm-framework-tvos.zip
+            )
+        else
+            (
+                cd ${FOLDER}/osx
+                for f in ${WORKSPACE}/realm-swift-framework-osx-swift-*.zip; do
+                    unzip "$f"
+                done
+            )
+
+            (
+                cd ${FOLDER}/ios
+                for f in ${WORKSPACE}/realm-swift-framework-ios-swift-*.zip; do
+                    unzip "$f"
+                done
+            )
+
+            (
+                cd ${FOLDER}/watchos
+                for f in ${WORKSPACE}/realm-swift-framework-watchos-swift-*.zip; do
+                    unzip "$f"
+                done
+            )
+
+            (
+                cd ${FOLDER}/tvos
+                for f in ${WORKSPACE}/realm-swift-framework-tvos-swift-*.zip; do
+                    unzip "$f"
+                done
+            )
+        fi
+
+        (
+            cd ${WORKSPACE}
+            cp -R plugin ${FOLDER}
+            cp LICENSE ${FOLDER}/LICENSE.txt
+            if [[ "${LANG}" == "objc" ]]; then
+                cp Realm/Swift/RLMSupport.swift ${FOLDER}/Swift/
+            fi
+        )
+
+        (
+            cd ${FOLDER}
+            unzip ${WORKSPACE}/realm-examples.zip
+            cd examples
+            if [[ "${LANG}" == "objc" ]]; then
+                rm -rf ios/swift-* tvos/swift-*
+            else
+                rm -rf ios/objc ios/rubymotion osx tvos/objc
+            fi
+        )
+
+        cat > ${FOLDER}/docs.webloc <<EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+    <key>URL</key>
+    <string>https://realm.io/docs/${LANG}/${VERSION}</string>
+</dict>
+</plist>
+EOF
+
+        (
+          cd ${TEMPDIR}
+          zip --symlinks -r realm-${LANG}-${VERSION}.zip realm-${LANG}-${VERSION}
+          mv realm-${LANG}-${VERSION}.zip ${WORKSPACE}
+        )
+        ;;
+
+    "test-package-release")
+        # Generate a release package locally for testing purposes
+        # Real releases should always be done via Jenkins
+        if [ -z "${WORKSPACE}" ]; then
+            echo 'WORKSPACE must be set to a directory to assemble the release in'
+            exit 1
+        fi
+        if [ -d "${WORKSPACE}" ]; then
+            echo 'WORKSPACE directory should not already exist'
+            exit 1
+        fi
+
+        REALM_SOURCE="$(pwd)"
+        mkdir -p "$WORKSPACE"
+        WORKSPACE="$(cd "$WORKSPACE" && pwd)"
+        export WORKSPACE
+        cd $WORKSPACE
+        git clone --recursive $REALM_SOURCE realm-cocoa
+        cd realm-cocoa
+
+        echo 'Packaging iOS'
+        sh build.sh package-ios-static
+        cp build/ios-static/realm-framework-ios-static.zip ..
+        sh build.sh package-ios
+        cp build/ios/realm-framework-ios.zip ..
+        sh build.sh package-ios-swift
+        cp build/ios/realm-swift-framework-ios.zip ..
+
+        echo 'Packaging OS X'
+        sh build.sh package-osx
+        cp build/DerivedData/Realm/Build/Products/Release/realm-framework-osx.zip ..
+        sh build.sh package-osx-swift
+        cp build/osx/realm-swift-framework-osx.zip ..
+
+        echo 'Packaging watchOS'
+        sh build.sh package-watchos
+        cp build/watchos/realm-framework-watchos.zip ..
+        sh build.sh package-watchos-swift
+        cp build/watchos/realm-swift-framework-watchos.zip ..
+
+        echo 'Packaging tvOS'
+        sh build.sh package-tvos
+        cp build/tvos/realm-framework-tvos.zip ..
+        sh build.sh package-tvos-swift
+        cp build/tvos/realm-swift-framework-tvos.zip ..
+
+        echo 'Packaging examples'
+        sh build.sh package-examples
+        cp realm-examples.zip ..
+
+        echo 'Building final release packages'
+        sh build.sh package-release objc
+        sh build.sh package-release swift
+
+        echo 'Testing packaged examples'
+        sh build.sh package-test-examples
+        ;;
+
+    "github-release")
+        if [ -z "${GITHUB_ACCESS_TOKEN}" ]; then
+            echo 'GITHUB_ACCESS_TOKEN must be set to create GitHub releases'
+            exit 1
+        fi
+        ./scripts/github_release.rb
+        ;;
+
+    "add-empty-changelog")
+        empty_section=$(cat <<EOS
+x.x.x Release notes (yyyy-MM-dd)
+=============================================================
+
+### Breaking Changes
+
+* None.
+
+### Enhancements
+
+* None.
+
+### Bugfixes
+
+* None.
+EOS)
+        changelog=$(cat CHANGELOG.md)
+        echo "$empty_section" > CHANGELOG.md
+        echo >> CHANGELOG.md
+        echo "$changelog" >> CHANGELOG.md
+        ;;
+
+    *)
+        echo "Unknown command '$COMMAND'"
+        usage
+        exit 1
+        ;;
+esac