Files
shell-scripting-templates/setupScripts/install_command_line_tools.sh
2015-09-25 09:27:32 -04:00

359 lines
11 KiB
Bash
Executable File

#!/usr/bin/env bash
# ##################################################
#
# # This script was taken in its entirety from:
# https://github.com/rtrouton/rtrouton_scripts/
#
# This script will download and install the Xcode command line
# tools on Macs running 10.7.x and higher.
#
# How the script works:
#
# On 10.9.x and 10.10.x:
#
# 1. Creates a placeholder file in $tmpDir. This file's existence is checked by the
# softwareupdate tool before allowing the installation of the Xcode command line tools.
#
# 2. Runs the softwareupdate tool and checks for the latest version of the Xcode command
# line tools for the OS in question.
#
# 3. Uses the softwareupdate tool to install the latest version of the Xcode command
# line tools for the OS in question.
#
# 4. Removes the placeholder file stored in /tmp.
#
#
# On 10.7.x and 10.8.x:
#
# 1. Uses curl to download a disk image containing the specified Xcode Command Line
# Tools installer from Apple's web site
#
# 2. Renames the downloaded disk image to cltools.dmg.
#
# 2. Mounts the disk image silently in $tmpDir. Disk image will not be visible to any
# logged-in user.
#
# 3. Installs the Xcode Command Line Tools using the installer package stored on the
# disk image
#
# 4. After installation, unmounts the disk image and removes it from the Mac in question.
#
version="1.0.0" # Sets version variable
#
scriptTemplateVersion="1.4.1" # Version of scriptTemplate.sh that this script is based on
#
# HISTORY:
#
# * 2015-06-21 - v1.0.0 - First Creation
#
# ##################################################
# Provide a variable with the location of this script.
scriptPath="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Source Scripting Utilities
# -----------------------------------
# These shared utilities provide many functions which are needed to provide
# the functionality in this boilerplate. This script will fail if they can
# not be found.
# -----------------------------------
utilsLocation="${scriptPath}/../lib/utils.sh" # Update this path to find the utilities.
if [ -f "${utilsLocation}" ]; then
source "${utilsLocation}"
else
echo "Please find the file util.sh and add a reference to it in this script. Exiting."
exit 1
fi
# trapCleanup Function
# -----------------------------------
# Any actions that should be taken if the script is prematurely
# exited. Always call this function at the top of your script.
# -----------------------------------
function trapCleanup() {
echo ""
if is_dir "${tmpDir}"; then
rm -r "${tmpDir}"
fi
die "Exit trapped." # Edit this if you like.
}
# Set Flags
# -----------------------------------
# Flags which can be overridden by user input.
# Default values are below
# -----------------------------------
quiet=0
printLog=0
verbose=0
force=0
strict=0
debug=0
args=()
# Set Temp Directory
# -----------------------------------
# Create temp directory with three random numbers and the process ID
# in the name. This directory is removed automatically at exit.
# -----------------------------------
tmpDir="/tmp/${scriptName}.$RANDOM.$RANDOM.$RANDOM.$$"
(umask 077 && mkdir "${tmpDir}") || {
die "Could not create temporary directory! Exiting."
}
# Logging
# -----------------------------------
# Log is only used when the '-l' flag is set.
#
# To never save a logfile change variable to '/dev/null'
# Save to Desktop use: $HOME/Desktop/${scriptBasename}.log
# Save to standard user log location use: $HOME/Library/Logs/${scriptBasename}.log
# -----------------------------------
logFile="${HOME}/Library/Logs/${scriptBasename}.log"
# Check for Dependencies
# -----------------------------------
# Arrays containing package dependencies needed to execute this script.
# The script will fail if dependencies are not installed. For Mac users,
# most dependencies can be installed automatically using the package
# manager 'Homebrew'. Mac applications will be installed using
# Homebrew Casks. Ruby and gems via RVM.
# -----------------------------------
homebrewDependencies=()
caskDependencies=()
gemDependencies=()
function mainScript() {
############## Begin Script Here ###################
####################################################
# Installing the Xcode command line tools on 10.7.x or higher
osx_vers=$(sw_vers -productVersion | awk -F "." '{print $2}')
cmd_line_tools_temp_file="${tmpDir}/.com.apple.dt.CommandLineTools.installondemand.in-progress"
# invoke verbose usage when set
if ${verbose}; then v="-v" ; fi
# Installing the latest Xcode command line tools on 10.9.x or higher
if [[ "${osx_vers}" -ge 9 ]]; then
# Create the placeholder file which is checked by the softwareupdate tool
# before allowing the installation of the Xcode command line tools.
touch "${cmd_line_tools_temp_file}"
# Find the last listed update in the Software Update feed with "Command Line Tools" in the name
cmd_line_tools=$(softwareupdate -l | awk '/\*\ Command Line Tools/ { $1=$1;print }' | tail -1 | sed 's/^[[ \t]]*//;s/[[ \t]]*$//;s/*//' | cut -c 2-)
#Install the command line tools
softwareupdate -i "${cmd_line_tools}" -v
# Remove the temp file
if [[ -f "${cmd_line_tools_temp_file}" ]]; then
rm ${v} "${cmd_line_tools_temp_file}"
fi
fi
# Installing the latest Xcode command line tools on 10.7.x and 10.8.x
# on 10.7/10.8, instead of using the software update feed, the command line tools are downloaded
# instead from public download URLs, which can be found in the dvtdownloadableindex:
# https://devimages.apple.com.edgekey.net/downloads/xcode/simulators/index-3905972D-B609-49CE-8D06-51ADC78E07BC.dvtdownloadableindex
if [[ "${osx_vers}" -eq 7 ]] || [[ "${osx_vers}" -eq 8 ]]; then
if [[ "${osx_vers}" -eq 7 ]]; then
DMGURL=http://devimages.apple.com/downloads/xcode/command_line_tools_for_xcode_os_x_lion_april_2013.dmg
fi
if [[ "${osx_vers}" -eq 8 ]]; then
DMGURL=http://devimages.apple.com/downloads/xcode/command_line_tools_for_osx_mountain_lion_april_2014.dmg
fi
TOOLS=cltools.dmg
curl "${DMGURL}" -o "${TOOLS}"
TMPMOUNT=`/usr/bin/mktemp -d ${tmpDir}/clitools.XXXX`
hdiutil attach "${TOOLS}" -mountpoint "${TMPMOUNT}" -nobrowse
# The "-allowUntrusted" flag has been added to the installer
# command to accomodate for now-expired certificates used
# to sign the downloaded command line tools.
installer -allowUntrusted -pkg "$(find ${TMPMOUNT} -name '*.mpkg')" -target /
hdiutil detach "${TMPMOUNT}"
rm -rf ${v} "${TMPMOUNT}"
rm ${v} "${TOOLS}"
fi
####################################################
############### End Script Here ####################
}
############## Begin Options and Usage ###################
# Print usage
usage() {
echo -n "${scriptName} [OPTION]... [FILE]...
This script will download and install the Xcode command line tools on Macs
running 10.7.x and higher.
How the script works:
On 10.9.x and 10.10.x:
1. Creates a placeholder file in /tmp. This file's existence is checked by
the softwareupdate tool before allowing the installation of the Xcode command
line tools.
2. Runs the softwareupdate tool and checks for the latest version of the Xcode
command line tools for the OS in question.
3. Uses the softwareupdate tool to install the latest version of the Xcode command
line tools for the OS in question.
4. Removes the placeholder file stored in /tmp.
On 10.7.x and 10.8.x:
1. Uses curl to download a disk image containing the specified Xcode Command Line
Tools installer from Apple's web site
2. Renames the downloaded disk image to cltools.dmg.
2. Mounts the disk image silently in /tmp. Disk image will not be visible to any
logged-in user.
3. Installs the Xcode Command Line Tools using the installer package stored on the
disk image
4. After installation, unmounts the disk image and removes it from the Mac in question.
This script was taken in its entirety from:
https://github.com/rtrouton/rtrouton_scripts/
Options:
-q, --quiet Quiet (no output)
-l, --log Print log to file
-s, --strict Exit script with null variables. i.e 'set -o nounset'
-v, --verbose Output more information. (Items echoed to 'verbose')
-d, --debug Runs script in BASH debug mode (set -x)
-h, --help Display this help and exit
--version Output version information and exit
"
}
# Iterate over options breaking -ab into -a -b when needed
# and --foo=bar into --foo bar
optstring=h
unset options
while (($#)); do
case $1 in
# If option is of type -ab
-[!-]?*)
# Loop over each character starting with the second
for ((i=1; i < ${#1}; i++)); do
c=${1:i:1}
# Add current char to options
options+=("-$c")
# If option takes a required argument, and it's not the last char make
# the rest of the string its argument
if [[ $optstring = *"$c:"* && ${1:i+1} ]]; then
options+=("${1:i+1}")
break
fi
done
;;
# If option is of type --foo=bar
--?*=*) options+=("${1%%=*}" "${1#*=}") ;;
# add --endopts for --
--) options+=(--endopts) ;;
# Otherwise, nothing special
*) options+=("$1") ;;
esac
shift
done
set -- "${options[@]}"
unset options
# Print help if no arguments were passed.
# Uncomment to force arguments when invoking the script
# [[ $# -eq 0 ]] && set -- "--help"
# Read the options and set stuff
while [[ $1 = -?* ]]; do
case $1 in
-h|--help) usage >&2; safeExit ;;
--version) echo "$(basename $0) ${version}"; safeExit ;;
-u|--username) shift; username=${1} ;;
-p|--password) shift; echo "Enter Pass: "; stty -echo; read PASS; stty echo;
echo ;;
-v|--verbose) verbose=true ;;
-l|--log) printLog=1 ;;
-q|--quiet) quiet=1 ;;
-s|--strict) strict=1;;
-d|--debug) debug=1;;
--force) force=1 ;;
--endopts) shift; break ;;
*) die "invalid option: '$1'." ;;
esac
shift
done
# Store the remaining part as arguments.
args+=("$@")
############## End Options and Usage ###################
# ############# ############# #############
# ## TIME TO RUN THE SCRIPT ##
# ## ##
# ## You shouldn't need to edit anything ##
# ## beneath this line ##
# ## ##
# ############# ############# #############
# Trap bad exits with your cleanup function
trap trapCleanup EXIT INT TERM
# Set IFS to preferred implementation
IFS=$'\n\t'
# Exit on error. Append '||true' when you run the script if you expect an error.
set -o errexit
# Run in debug mode, if set
if [ "${debug}" == "1" ]; then
set -x
fi
# Exit on empty variable
if [ "${strict}" == "1" ]; then
set -o nounset
fi
# Bash will remember & return the highest exitcode in a chain of pipes.
# This way you can catch the error in case mysqldump fails in `mysqldump |gzip`, for example.
set -o pipefail
# Invoke the checkDependenices function to test for Bash packages
# checkDependencies
# Run your script
mainScript
safeExit # Exit cleanly