Skip to content

Instantly share code, notes, and snippets.

@curiositycasualty
Created March 19, 2016 18:35
Show Gist options
  • Save curiositycasualty/7002462b37eabf3a4e0d to your computer and use it in GitHub Desktop.
Save curiositycasualty/7002462b37eabf3a4e0d to your computer and use it in GitHub Desktop.
Install Xcode SDK major releases from Xcode 6.1.1 - 7.2.1 into a host's Xcode.app
#!/usr/bin/env bash
PREFIX='./xcodes'
DMGs=(xcode_6.1.1.dmg
Xcode_6.2.dmg
Xcode_6.3.2.dmg
Xcode_6.4.dmg
Xcode_7.0.1.dmg
Xcode_7.1.1.dmg
Xcode_7.2.1.dmg)
# DISCLAIMER: These are not official checksums from Apple,
# just ones I've generated from my dropbox copy of the DMGs.
url_611="https://www.dropbox.com/s/f0fgbj43wbgmukh/xcode_6.1.1.dmg?dl=0"
md5_611="00773faa3ddc9a0b7b94bab8496aa522"
url_62="https://www.dropbox.com/s/kv711z3c2x76vvw/Xcode_6.2.dmg?dl=0"
md5_62="fe4c6c99182668cf14bfa5703bedeed6"
url_632="https://www.dropbox.com/s/amnisaibwfpr6jw/Xcode_6.3.2.dmg?dl=0"
md5_632="a61d18cc7abf5de83f24ae7dc4ee281a"
url_64="https://www.dropbox.com/s/m8pq8rfgz3y58d9/Xcode_6.4.dmg?dl=0"
md5_64="fc57760b91df8d45ee57ba80436e49a9"
url_701="https://www.dropbox.com/s/xiqafaa99wkwxr7/Xcode_7.0.1.dmg?dl=0"
md5_701="3702b5291ed8127781158eb6a79d03cb"
url_711="https://www.dropbox.com/s/cwpsd42f57szcsw/Xcode_7.1.1.dmg?dl=0"
md5_711="25e4af4f0a0251e08446cd51485041f1"
url_721="https://www.dropbox.com/s/6gsm40zdt9i519k/Xcode_7.2.1.dmg?dl=0"
md5_721="e9c6ec03fd269cb2802180800fb7fb0e"
#
# preflight()
#
# Make sure we have an Xcode.app on the host and all the DMGs
# we are expecting before we do any heavy lifting.
#
function preflight() {
echo "INFO: Starting preflight check."
# is first xcode installed?
if [ -d "/Applications/Xcode.app" ]; then
# do you have all the DMGs?
declare -a missing
for dmg in "${DMGs[@]}"; do
if [ ! -s "${PREFIX}/${dmg}" ]; then
missing=(${missing[@]} $dmg)
fi
done
if [[ ! -z ${missing[@]} ]]; then
echo "ERR: Preflight check failed: Missing some DMGs"
echo "ERR: Missing: ${missing[@]}"
exit 255
fi
else
echo "ERR: Preflight check failed: No base Xcode detected."
echo "ERR: Please install the most recent Xcode via the App Store."
exit 256
fi
echo "INFO: Preflight check passed!"
}
#
# main()
#
# Where all the pieces come together except the preflight check.
#
function main() {
attach-all
copy-all "iPhoneOS"
copy-all "iPhoneSimulator"
detach-all
}
#
# copy-all()
#
# Given a platform ("iPhoneOS", "AppleTVOS", etc.) copy all
# the files from that Xcode's version into the host's Xcode.app.
#
# Also renames the host's Xcode.app's version of said platform
# SDK and removes the symlinking to the latest version.
#
function copy-all() {
if [ -z "${@}" ]; then
echo "ERR: Which SDK to consolidate not specified."
exit 255
fi
platform="$1"
base="/Applications/Xcode.app/Contents/Developer/Platforms/${platform}.platform/Developer/SDKs"
echo "INFO: Removing latest symlink and moving original into place."
sym="$(find ${base} -type l -maxdepth 1)"
name="${sym##*/}"
sudo rm -rfv $sym
sudo mv -v "${base}/${platform}.sdk" "${sym}"
echo "INFO: Copying ${platform} SDKs"
for SDK in /Volumes/dmg.*/Xcode.app/Contents/Developer/Platforms/${platform}*/Developer/SDKs/${platform}*[0-9]*.sdk; do
name="${SDK##*/}"
real="${SDK%%${platform}[0-9]*}${platform}.sdk"
sudo rsync -a --ignore-existing "$real" "${base}/${name}" &
done
for pid in $(jobs -p); do
wait $pid
done
echo
}
#
# attach()
#
# Attach a single .DMG file to a path matching the pattern:
# /Volumes/dmg.[a-zA-Z0-9]{6} (per the "-mountrandom" flag).
# Close any resultant Finder.app windows with the title "Xcode."
#
# Does not handle EULAs. Will verify if DMG specified is
# already attached, but will not attach duplicates of the
# same DMG.
#
function attach() {
dmg="${PREFIX}/$1"
path="$(hdiutil attach "${dmg}" -mountrandom "/Volumes" | grep Volumes | awk '{ print substr($0, index($0,$3)) }')"
while ( ( osascript -e 'tell application "Finder" to close Finder window "Xcode"' 2>&1 ) > /dev/null ); do
sleep 1
done
echo "$path"
}
#
# attach-all()
#
# Loop through $DMGs and attach() each.
#
function attach-all() {
for dmg in "${DMGs[@]}"; do
path="$(attach "$dmg")"
version="${dmg//[^0-9.]}"
version="${version%%.}"
echo -e "${dmg} (${version})\t:\t${path}"
done
}
#
# detach()
#
# Detach a single attached volume specified by path.
#
function detach() {
path="$1"
echo "INFO: Detaching ${path}..."
if (hdiutil detach "$path" 2>&1 > /dev/null); then
echo "INFO: Success!"
else
echo "ERR: Failure. :("
fi
}
#
# detach-all()
#
# Detach all attached volumes that resemble the pattern:
# /Volumes/dmg.[a-zA-Z0-9]{6}
#
function detach-all() {
echo "INFO: Detaching all Xcode DMGs from /Volumes/dmg.*"
for dmg in /Volumes/dmg.*; do
detach "$dmg"
done
}
preflight
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment