From 942fd88aa67e2064b37590958cf77c45a1515281 Mon Sep 17 00:00:00 2001 From: Karl Kuehn Date: Thu, 9 Feb 2017 15:08:46 -0800 Subject: [PATCH] find Xcode preferentially without spotlight - v2 (#4652) fixes #4534 and #4503 by looking in `/Applications` for Xcode before using Spotlight, and skipping the current default Xcode when running under Jenkins. --- build.sh | 43 ++++++--- examples/installation/build.sh | 3 +- scripts/swift-version.sh | 160 +++++++++++++++++++++------------ 3 files changed, 136 insertions(+), 70 deletions(-) mode change 100644 => 100755 scripts/swift-version.sh diff --git a/build.sh b/build.sh index 11eb4119b8..00a9d8fd2c 100755 --- a/build.sh +++ b/build.sh @@ -86,6 +86,7 @@ environment variables: 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 } @@ -377,7 +378,15 @@ case "$COMMAND" in esac export CONFIGURATION +# 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 @@ -486,10 +495,7 @@ case "$COMMAND" in # Swift versioning ###################################### "set-swift-version") - version="$2" - if [[ -z "$version" ]]; then - version="$REALM_SWIFT_VERSION" - fi + version=${2:-$REALM_SWIFT_VERSION} SWIFT_VERSION_FILE="RealmSwift/SwiftVersion.swift" CONTENTS="let swiftLanguageVersion = \"$version\"" @@ -1022,7 +1028,6 @@ EOM "ci-pr") mkdir -p build/reports - export REALM_XCODE_VERSION=$xcode_version # FIXME: Re-enable once CI can properly unlock the keychain export REALM_DISABLE_METADATA_ENCRYPTION=1 @@ -1134,8 +1139,11 @@ EOM "package-ios-swift") cd tightdb_objc for version in 8.0 8.1 8.2; do - REALM_XCODE_VERSION="$version" sh build.sh prelaunch-simulator - REALM_XCODE_VERSION="$version" sh build.sh ios-swift + 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 @@ -1145,8 +1153,11 @@ EOM "package-osx-swift") cd tightdb_objc for version in 8.0 8.1 8.2; do - REALM_XCODE_VERSION="$version" sh build.sh prelaunch-simulator - REALM_XCODE_VERSION="$version" sh build.sh osx-swift + 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 @@ -1164,8 +1175,11 @@ EOM "package-watchos-swift") cd tightdb_objc for version in 8.0 8.1 8.2; do - REALM_XCODE_VERSION="$version" sh build.sh prelaunch-simulator - REALM_XCODE_VERSION="$version" sh build.sh watchos-swift + 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 @@ -1183,8 +1197,11 @@ EOM "package-tvos-swift") cd tightdb_objc for version in 8.0 8.1 8.2; do - REALM_XCODE_VERSION="$version" sh build.sh prelaunch-simulator - REALM_XCODE_VERSION="$version" sh build.sh tvos-swift + 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 diff --git a/examples/installation/build.sh b/examples/installation/build.sh index 5e3632d318..786a9ff011 100755 --- a/examples/installation/build.sh +++ b/examples/installation/build.sh @@ -96,11 +96,12 @@ xctest() { } source "$(dirname "$0")/../../scripts/swift-version.sh" +set_xcode_and_swift_versions # exports REALM_SWIFT_VERSION, REALM_XCODE_VERSION, and DEVELOPER_DIR variables if not already set case "$COMMAND" in "test-all") for target in ios-swift-dynamic ios-swift-cocoapods osx-swift-dynamic ios-swift-carthage osx-swift-carthage watchos-objc-dynamic test-watchos-objc-cocoapods test-watchos-objc-carthage watchos-swift-dynamic test-watchos-swift-cocoapods test-watchos-swift-carthage; do - REALM_SWIFT_VERSION=3.0 ./build.sh test-$target || exit 1 + ./build.sh test-$target || exit 1 done ;; diff --git a/scripts/swift-version.sh b/scripts/swift-version.sh old mode 100644 new mode 100755 index d281a1d55f..64f0bc4d7e --- a/scripts/swift-version.sh +++ b/scripts/swift-version.sh @@ -1,82 +1,130 @@ +#!/usr/bin/env bash + get_swift_version() { - swift_command=$@ - $swift_command --version 2>/dev/null | sed -ne 's/^Apple Swift version \([^\b ]*\).*/\1/p' + "$1" --version 2>/dev/null | sed -ne 's/^Apple Swift version \([^\b ]*\).*/\1/p' } get_xcode_version() { - xcodebuild_command=$@ - $xcodebuild_command -version 2>/dev/null | sed -ne 's/^Xcode \([^\b ]*\).*/\1/p' + "$1" -version 2>/dev/null | sed -ne 's/^Xcode \([^\b ]*\).*/\1/p' } find_xcode_with_version() { - local xcodes dev_dir version - - # First check if the currently active one is fine - version="$(get_xcode_version xcodebuild)" - if [[ "$version" = "$1" ]]; then - export DEVELOPER_DIR="$(xcode-select -p)" - export REALM_SWIFT_VERSION=$(get_swift_version xcrun swift) + local path required_version + + if [ -z "$1" ]; then + echo "find_xcode_with_version requires an Xcode version" >&2 + exit 1 + fi + required_version=$1 + + # First check if the currently active one is fine, unless we are in a CI run + if [ -z "$JENKINS_HOME" ] && [ $(get_xcode_version xcodebuild) = "$required_version" ]; then + DEVELOPER_DIR=$(xcode-select -p) return 0 fi - - # Check all installed copies of Xcode for the desired version - xcodes=() - dev_dir="Contents/Developer" - for dir in $(mdfind "kMDItemCFBundleIdentifier == 'com.apple.dt.Xcode'" 2>/dev/null); do - [[ -d "$dir" && -n "$(ls -A "$dir/$dev_dir")" ]] && xcodes+=("$dir/$dev_dir") + + # Check all of the items in /Applications that look promising per #4534 + for path in /Applications/Xcode*.app/Contents/Developer; do + if [ $(get_xcode_version "$path/usr/bin/xcodebuild") = "$required_version" ]; then + DEVELOPER_DIR=$path + return 0 + fi done - - for xcode in "${xcodes[@]}"; do - version="$(get_xcode_version "$xcode/usr/bin/xcodebuild")" - if [[ "$version" = "$1" ]]; then - export DEVELOPER_DIR="$xcode" - export REALM_SWIFT_VERSION=$(get_swift_version xcrun swift) + + # Use Spotlight to see if we can find others installed copies of Xcode + for path in $(/usr/bin/mdfind "kMDItemCFBundleIdentifier == 'com.apple.dt.Xcode'" 2>/dev/null); do + path="$path/Contents/Developer" + if [ ! -d "$path" ]; then + continue + fi + if [ $(get_xcode_version "$path/usr/bin/xcodebuild") = "$required_version" ]; then + DEVELOPER_DIR=$path return 0 fi done - >&2 echo "No Xcode found with version $1" + echo "No Xcode found with version $required_version" >&2 + exit 1 +} + +test_xcode_for_swift_version() { + if [ -z "$1" ] || [ -z "$2" ]; then + echo "test_xcode_for_swift_version called with empty parameter(s): '$1' or '$2'" >&2 + exit 1 + fi + local path=$1 + local required_version=$2 + + for swift in "$path"/Toolchains/*.xctoolchain/usr/bin/swift; do + if [ $(get_swift_version "$swift") = "$required_version" ]; then + return 0 + fi + done return 1 } find_xcode_for_swift() { - local xcodes dev_dir version - - # First check if the currently active one is fine - version="$(get_swift_version xcrun swift || true)" - if [[ "$version" = "$1" ]]; then - export DEVELOPER_DIR="$(xcode-select -p)" + local path required_version + + if [ -z "$1" ]; then + echo "find_xcode_for_swift requires a Swift version" >&2 + exit 1 + fi + required_version=$1 + + # First check if the currently active one is fine, unless we are in a CI run + if [ -z "$JENKINS_HOME" ] && test_xcode_for_swift_version "$(xcode-select -p)" "$required_version"; then + DEVELOPER_DIR=$(xcode-select -p) return 0 fi - # Check all installed copies of Xcode for the desired Swift version - xcodes=() - dev_dir="Contents/Developer" - for dir in $(mdfind "kMDItemCFBundleIdentifier == 'com.apple.dt.Xcode'" 2>/dev/null); do - [[ -d "$dir" && -n "$(ls -A "$dir/$dev_dir")" ]] && xcodes+=("$dir/$dev_dir") + # Check all of the items in /Applications that look promising per #4534 + for path in /Applications/Xcode*.app/Contents/Developer; do + if test_xcode_for_swift_version "$path" "$required_version"; then + DEVELOPER_DIR=$path + return 0 + fi done - - for xcode in "${xcodes[@]}"; do - for swift in "$xcode"/Toolchains/*.xctoolchain/usr/bin/swift; do - version="$(get_swift_version $swift)" - if [[ "$version" = "$1" ]]; then - export DEVELOPER_DIR="$xcode" - return 0 - fi - done + + # Use Spotlight to see if we can find others installed copies of Xcode + for path in $(/usr/bin/mdfind "kMDItemCFBundleIdentifier == 'com.apple.dt.Xcode'" 2>/dev/null); do + path="$path/Contents/Developer" + if [ ! -d "$path" ]; then + continue + fi + if test_xcode_for_swift_version "$path" "$required_version"; then + DEVELOPER_DIR=$path + return 0 + fi done - - >&2 echo "No version of Xcode found that supports Swift $1" - return 1 + + echo "No version of Xcode found that supports Swift $required_version" >&2 + exit 1 } -if [[ "$REALM_XCODE_VERSION" ]]; then - find_xcode_with_version $REALM_XCODE_VERSION -elif [[ "$REALM_SWIFT_VERSION" ]]; then - find_xcode_for_swift $REALM_SWIFT_VERSION -else - REALM_SWIFT_VERSION=$(get_swift_version xcrun swift) - if [[ -z "$DEVELOPER_DIR" ]]; then - export DEVELOPER_DIR="$(xcode-select -p)" +set_xcode_and_swift_versions() { + if [ -n "$REALM_XCODE_VERSION" ]; then + find_xcode_with_version $REALM_XCODE_VERSION + + if [ -n "$REALM_SWIFT_VERSION" ] && ! test_xcode_for_swift_version "$DEVELOPER_DIR" "$REALM_SWIFT_VERSION"; then + echo "The version of Xcode specified ($REALM_XCODE_VERSION) does not support the Swift version required: $REALM_SWIFT_VERSION" + exit 1 + fi + elif [ -n "$REALM_SWIFT_VERSION" ]; then + find_xcode_for_swift $REALM_SWIFT_VERSION + elif [ -z "$DEVELOPER_DIR" ]; then + DEVELOPER_DIR="$(xcode-select -p)" + fi + export DEVELOPER_DIR + export REALM_XCODE_VERSION + + if [ -z "$REALM_SWIFT_VERSION" ]; then + REALM_SWIFT_VERSION=$(get_swift_version "$(xcrun -f swift)") fi -fi + export REALM_SWIFT_VERSION +} + +return 2>/dev/null || { # only run if called directly + set_xcode_and_swift_versions + echo "Found Swift version $REALM_SWIFT_VERSION in $DEVELOPER_DIR" +}