-
-
Save NorseGaud/7fbb7d5526abb43a6f81b3c3c8399e98 to your computer and use it in GitHub Desktop.
Xcode Installer Script, pulling from a remote server that stores the xip files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -exo pipefail | |
# IMPORTANT!! | |
# SET THESE TWO | |
XCODE_STORAGE_SERVER_IP="xxx.xxx.xxx.xxx" | |
XCODE_STORAGE_SERVER_USERNAME="" | |
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) | |
cd "${SCRIPT_DIR}" | |
if [[ -z "$(command -v unxip)" ]]; then | |
sudo mkdir -p /usr/local/bin | |
pushd /usr/local/bin | |
sudo curl -O -L https://github.com/saagarjha/unxip/releases/download/v1.1.1/unxip | |
sudo chmod +x unxip | |
popd | |
fi | |
XCODE_VERSION= | |
XCODE_DESTINATION="/Applications" | |
if [[ -z "${SHORT_MACOS_VERSION}" ]]; then | |
SHORT_MACOS_VERSION="$(sw_vers -productVersion)" | |
fi | |
if [[ -d "${XCODE_DESTINATION}/Xcode.app" ]]; then | |
echo "Xcode.app exists already!" | |
exit | |
fi | |
# Install the latest xcode | |
function test_version() { | |
MIN_VERSION="${1}" | |
MACOS_VERSION="${2}" | |
MIN_VERSION_MAJOR="$(echo $MIN_MACOS_VERSION | cut -d. -f1)" | |
MIN_VERSION_MINOR="$(echo $MIN_MACOS_VERSION | cut -d. -f2)" | |
MIN_VERSION_PATCH="$(echo $MIN_MACOS_VERSION | cut -d. -f3)" | |
MACOS_VERSION_MAJOR="$(echo $MACOS_VERSION | cut -d. -f1)" | |
MACOS_VERSION_MINOR="$(echo $MACOS_VERSION | cut -d. -f2)" | |
MACOS_VERSION_PATCH="$(echo $MACOS_VERSION | cut -d. -f3)" | |
[[ $MACOS_VERSION_MAJOR -ne $MIN_VERSION_MAJOR ]] && return 1 | |
[[ "${MIN_VERSION}" == "${MACOS_VERSION}" ]] && return 0 | |
[[ ! "${MACOS_VERSION}" =~ \. ]] && return 1 | |
## Support when min version is just a few minor versions less than | |
[[ | |
$MACOS_VERSION_MAJOR -eq $MIN_VERSION_MAJOR \ | |
&& $MACOS_VERSION_MINOR -ge $MIN_VERSION_MINOR \ | |
&& $MACOS_VERSION_PATCH -ge $MIN_VERSION_PATCH \ | |
]] && return 0 | |
MACOS_VERSION="${MACOS_VERSION%.*}" | |
test_version "${MIN_VERSION}" "${MACOS_VERSION}" \ | |
&& return 0 \ | |
|| return 1 | |
} | |
function download_xcode_xip() { | |
if [[ -n "${1}" ]]; then | |
XCODE_VERSION="${1}" | |
else # get latest xcode from server | |
LATEST_XCODE="$(ssh -o "StrictHostKeyChecking=no" -o BatchMode=yes ${XCODE_STORAGE_SERVER_USERNAME}@$XCODE_STORAGE_SERVER_IP ls -t _xcode-xips/ | head -1)" | |
XCODE_VERSION="$(echo ${LATEST_XCODE} | cut -d_ -f2 | sed 's/.xip//g')" | |
fi | |
ENDING="$(echo $XCODE_VERSION | rev | cut -d. -f1 | rev)" | |
[ $ENDING -lt 0 ] && return 1 | |
if ssh -o "StrictHostKeyChecking=no" -o BatchMode=yes ${XCODE_STORAGE_SERVER_USERNAME}@$XCODE_STORAGE_SERVER_IP ls _xcode-xips/Xcode_${XCODE_VERSION}.xip; then | |
pushd ${XCODE_DESTINATION} &>/dev/null | |
echo "found Xcode_${XCODE_VERSION}.xip on $XCODE_STORAGE_SERVER_IP" | |
echo "${XCODE_VERSION}" > /Applications/XCODE_VERSION | |
rsync -e 'ssh -o BatchMode=yes -o StrictHostKeyChecking=no' -avzP ${XCODE_STORAGE_SERVER_USERNAME}@$XCODE_STORAGE_SERVER_IP:_xcode-xips/Xcode_${XCODE_VERSION}.xip ./ && return 0 | |
popd &>/dev/null | |
return 1 | |
else | |
if [ "$(echo ${XCODE_VERSION} | grep -o "\." | wc -l | xargs)" -eq 1 ]; then | |
ENDING=9 | |
NO_ENDING=true | |
XCODE_VERSION="${XCODE_VERSION}.${ENDING}" | |
else | |
if $NO_ENDING; then | |
XCODE_VERSION="$(echo $XCODE_VERSION | sed 's/.[0-9]$//')" | |
XCODE_VERSION="${XCODE_VERSION}.$(($ENDING-1))" | |
fi | |
fi | |
fi | |
[ "$(echo ${XCODE_VERSION} | grep -o "\." | wc -l | xargs)" -eq 0 ] && return 1 | |
download_xcode_xip "${XCODE_VERSION}" \ | |
&& return 0 \ | |
|| return 1 | |
} | |
################## | |
# Get list of Xcode versions and their minimum MacOS version so we can match the proper versions to install | |
set +x | |
HTML_TABLE="$(echo "$(curl -s https://developer.apple.com/support/xcode/)" | sed -n '/<tbody/,/tbody>/p')" | |
OUTPUT=() | |
TR=false | |
COUNT=0 | |
oldIFS="${IFS}" | |
IFS=$'\n' | |
VERSION=() | |
function join_by { local IFS="$1"; shift; echo "$*"; } | |
for line in $(echo "${HTML_TABLE}"); do | |
line=$(echo "${line}" | xargs) | |
if [[ "<tr>" =~ "${line}" ]]; then | |
TR=true | |
continue | |
fi | |
if $TR; then | |
if [ $COUNT -lt 2 ]; then | |
sanline=$(echo "${line}" | sed 's/[^0-9.]*\([0-9.x]*\).*/\1/') | |
VERSION+=($sanline) | |
[ $COUNT -eq 1 ] && OUTPUT+=($(join_by , "${VERSION[@]}")) | |
fi | |
((COUNT+=1)) | |
fi | |
if [[ "</tr>" =~ "${line}" ]]; then | |
TR=false | |
VERSION=() | |
COUNT=0 | |
fi | |
done | |
IFS="${oldIFS}" | |
# echo -n "XCODE, Min MacOS Version" | |
set -x | |
MATCH=false | |
for versions in ${OUTPUT[*]}; do | |
NO_ENDING=false | |
XCODE_VERSION=$(echo $versions | cut -d, -f1 | sed 's/\.x$//') | |
MIN_MACOS_VERSION=$(echo $versions | cut -d, -f2) | |
if test_version "${MIN_MACOS_VERSION}" "${SHORT_MACOS_VERSION}"; then | |
MATCH=true | |
echo "${SHORT_MACOS_VERSION}" | |
if ! download_xcode_xip "${XCODE_VERSION}"; then | |
continue | |
else | |
echo "downloaded!" | |
break | |
fi | |
fi | |
done | |
# Handle if the current MacOS version wasn't found on Apple's page | |
if ! $MATCH; then | |
if ! download_xcode_xip; then | |
echo "failure to download latest Xcode" | |
exit 1 | |
else | |
echo "downloaded!" | |
fi | |
fi | |
# XCODE_VERSION is available for you to interpolate onto the Xcode.app if you need to have multiple versions on the same host. | |
pushd "${XCODE_DESTINATION}" | |
if ! ls ./*.xip; then | |
echo "No installer found..." | |
exit 1 | |
fi | |
unxip *.xip || xip --expand *.xip | |
sudo xattr -r -d com.apple.quarantine Xcode.app | |
popd | |
sudo /usr/sbin/dseditgroup -o edit -a everyone -t group _developer | |
sudo xcode-select -s ${XCODE_DESTINATION}/Xcode.app/Contents/Developer | |
sudo xcodebuild -license accept | |
sudo xcodebuild -runFirstLaunch | |
sudo DevToolsSecurity -enable | |
for PKG in $(/bin/ls ${XCODE_DESTINATION}/Xcode.app/Contents/Resources/Packages/*.pkg); do | |
sudo /usr/sbin/installer -pkg "$PKG" -target / | |
done | |
sudo rm -f "${XCODE_DESTINATION}/*.xip" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment