Skip to content

Commit

Permalink
find Xcode preferentially without spotlight - v2 (#4652)
Browse files Browse the repository at this point in the history
fixes #4534 and #4503 by looking in `/Applications` for Xcode before using Spotlight, and skipping the current default Xcode when running under Jenkins.
  • Loading branch information
larkost committed Feb 9, 2017
1 parent 46ee1d0 commit 942fd88
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 70 deletions.
43 changes: 30 additions & 13 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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\""
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
3 changes: 2 additions & 1 deletion examples/installation/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
;;

Expand Down
160 changes: 104 additions & 56 deletions scripts/swift-version.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -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"
}

0 comments on commit 942fd88

Please sign in to comment.