{{{testport}}} is a Bash script to test install a specified port in a custom MacPorts location in the {{{/opt}}} directory. The default location is {{{/opt/macports-test}}}. ---- {{{ #!/bin/bash # testport -- test install a specified port in /opt/macports-test (default) # 1. move the /opt/local MacPorts system to ${opt_local_off} to make sure it is not interfering with the custom ${MP_PREFIX} MacPorts build process # 2. move /usr/local to ${usr_local_off} to make sure it is not interfering with the custom ${MP_PREFIX} MacPorts build process # 3. install a fresh MacPorts 2.0.4 system to "${MP_PREFIX}" # 4. install the specified port to the custom ${MP_PREFIX} MacPorts system # Small getopts tutorial, # http://wiki.bash-hackers.org/howto/getopts_tutorial # usage: # testport gawk # testport -n -l /opt/macports-gnu gawk # testport -c -r -e -v clang-3.1 # testport -s clang-3.1 show_usage() { echo echo "$(basename $0) -- test install a specified port in /opt/macports-test (default)" echo echo "Usage: $(basename $0) [-c] [-d] [-e] [-h] [-n] [-p] [-r] [-s] [-u] [-v] [-l dir] portname" echo ' -c: clean all installed ports -d: enable debug mode -e: fetch & extract the distribution files for portname -h: help -n: delete /opt/macports-test (default) & perform a new MacPorts install from scratch -p: print PATH variable value -r: remove / uninstall specified port before reinstalling it -s: build and install from source only -u: update MacPorts system and uprade outdated ports -v: enable verbose mode -l dir: specify dir as location of MacPorts system (otherwise defaults to /opt/macports-test) ' return 0 } trapcount=0 # cf. http://fvue.nl/wiki/Bash:_Error_handling on_exit() { #set -xv trapcount=$((trapcount + 1)) if [[ $trapcount -eq 1 ]]; then cd # avoid: sudo: cannot get working directory #find -x "${tmpDir}" -ls 1>&2 echo [[ -d "${tmpDir}" ]] && rm -rf "${tmpDir}" [[ -d "${usr_local_off}" ]] && sudo mv -iv "${usr_local_off}" /usr/local [[ -d "${opt_local_off}" ]] && sudo mv -iv "${opt_local_off}" /opt/local printf "\n\n\n" echo dscl . -change /Users/macports NFSHomeDirectory "${MP_PREFIX}/var/macports/home" "${dsclHome}" current_dscl_home="$(dscl . -read /Users/macports NFSHomeDirectory | sed 's/^NFSHomeDirectory: *//')" if [[ "${current_dscl_home}" != "${dsclHome}" ]]; then dscl . -change /Users/macports NFSHomeDirectory "${MP_PREFIX}/var/macports/home" "${dsclHome}" fi printf '\n\n%s\n\n\n' "export PATH=\"${MP_PREFIX}/bin:${MP_PREFIX}/sbin:/usr/bin:/bin:/usr/sbin:/sbin\"" fi exit } unset CDPATH PATH IFS LC_ALL MP_PREFIX all_new IFS=$' \t\n' LC_ALL=C PATH='/sbin:/usr/bin:/bin:/usr/sbin:/sbin' export IFS LC_ALL PATH MP_PREFIX="" all_new=0 update=0 remove=0 verbose=0 debug=0 printpath=0 extract=0 build_source=0 clean_all=0 while getopts ":cdehl:nprsuv" opt; do case "$opt" in c) clean_all=1 ;; d) debug=1 ;; e) extract=1 ;; h) show_usage exit ;; l) MP_PREFIX="$OPTARG" ;; n) all_new=1 ;; p) printpath=1 ;; r) remove=1 ;; s) build_source=1 ;; u) update=1 ;; v) verbose=1 ;; \?) echo "Invalid option: -$OPTARG" 1>&2 show_usage 1>&2 exit 1 ;; :) echo "Option -$OPTARG requires an argument." 1>&2 show_usage 1>&2 exit 1 ;; esac done shift $((OPTIND-1)) if [[ -z "$MP_PREFIX" ]]; then MP_PREFIX='/opt/macports-test' fi if [[ "$MP_PREFIX" == '/opt/local' ]]; then echo 'Use of /opt/local is not allowed!' 1>&2 exit 1 fi if [[ "$MP_PREFIX" == '/' ]]; then echo 'Use of / is not allowed!' 1>&2 exit 1 fi if [[ $(dirname "${MP_PREFIX}") != '/opt' ]]; then echo 'Use: /opt/somedir' 1>&2 exit 1 fi if [[ ! -d "$MP_PREFIX" ]]; then all_new=1 fi if [[ $all_new -eq 1 ]]; then clean_all=0 remove=0 update=0 fi declare -rx MP_PREFIX unset PATH PATH="${MP_PREFIX}/bin:${MP_PREFIX}/sbin:/usr/bin:/bin:/usr/sbin:/sbin" export PATH if [[ $printpath -eq 1 ]]; then printf '\n\n%s\n\n\n' "export PATH=\"${MP_PREFIX}/bin:${MP_PREFIX}/sbin:/usr/bin:/bin:/usr/sbin:/sbin\"" exit fi if [[ $all_new -ne 1 ]] && [[ ! -x "${MP_PREFIX}/bin/port" ]]; then echo "No port command found at: ${MP_PREFIX}/bin/port" 1>&2 exit 1 fi if [[ $# -eq 0 ]]; then if [[ $clean_all -eq 1 ]]; then ( port -f clean --all installed 2>/dev/null ) || true exit elif [[ $update -eq 1 ]]; then port -f clean --all installed port selfupdate port outdated ( port upgrade -R -u outdated 2>/dev/null ) || true exit else echo echo 'No port to install given!' show_usage 1>&2 exit 1 fi fi if [[ $(id -u) -ne 0 ]] || [[ "${HOME}" != '/var/root' ]]; then echo 'This script must be run in a root shell to prevent sudo timeout!' 1>&2 echo 'Use: sudo -H -i' 1>&2 exit 1 fi dsclHome="$(dscl . -read /Users/macports NFSHomeDirectory | sed 's/^NFSHomeDirectory: *//')" dscl . -change /Users/macports NFSHomeDirectory "${dsclHome}" "${MP_PREFIX}/var/macports/home" # make sure the current working directory exists pwd -P 1>/dev/null || exit 1 # prevent idle sleep pmset -a force sleep 0 displaysleep 0 disksleep 0 sleep 1 unset usr_local_off opt_local_off tmpDir usr_local_off="/usr/local-off-$(date '+%Y-%m-%d-%H_%M_%S')" opt_local_off="/opt/local-off-$(date '+%Y-%m-%d-%H_%M_%S')" tmpDir="$(mktemp -d /tmp/macports.XXXXXX)" || exit 1 declare -rx usr_local_off opt_local_off tmpDir trap on_exit EXIT TERM HUP INT QUIT echo # make sure /usr/local is not interfering with MacPorts build processes for /opt/local [[ -d '/usr/local' ]] && sudo mv -iv /usr/local "${usr_local_off}" # back up the old MacPorts system [[ -d '/opt/local' ]] && sudo mv -iv /opt/local "${opt_local_off}" echo # clean up previous "${MP_PREFIX}" directory if [[ -x "${MP_PREFIX}/bin/port" ]]; then if [[ $clean_all -eq 1 ]]; then ( port -f clean --all installed 2>/dev/null ) || true else ( port -f clean --work "$@" 2>/dev/null ) || true fi fi if [[ $all_new -eq 1 ]]; then if [[ -x "${MP_PREFIX}/bin/port" ]]; then ( port -f uninstall installed 2>/dev/null ) || true fi # since "rm -rf" is a dangerous command, we restrict its use to /opt/somedir if [[ -d "${MP_PREFIX}" ]] && [[ $(dirname "${MP_PREFIX}") == '/opt' ]]; then rm -rf "${MP_PREFIX}" fi # get a fresh MacPorts 2.0.4 install in ${MP_PREFIX} cd "${tmpDir}" || exit 1 # cf. http://guide.macports.org/#installing.macports.source.multiple unset PATH export PATH='/bin:/sbin:/usr/bin:/usr/sbin' curl -L -O https://distfiles.macports.org/MacPorts/MacPorts-2.0.4.tar.bz2 || exit 1 tar -xjf MacPorts-2.0.4.tar.bz2 cd MacPorts-2.0.4 || exit 1 #--with-install-user=$owner --with-install-group=$group --with-directory-mode=$perms" ./configure --prefix="${MP_PREFIX}" --with-tclpackage="${MP_PREFIX}/tcl" --with-applications-dir="${MP_PREFIX}/Applications" make make install # get the Portfiles and update the system "${MP_PREFIX}/bin/port" selfupdate fi # all_new cd "${tmpDir}" || exit 1 unset PATH PATH="${MP_PREFIX}/bin:${MP_PREFIX}/sbin:/usr/bin:/bin:/usr/sbin:/sbin" export PATH if [[ $update -eq 1 ]]; then port -f clean --all installed port selfupdate port outdated ( port upgrade -R -u outdated 2>/dev/null ) || true fi if [[ $remove -eq 1 ]]; then port -f clean --all "$@" port -f -v uninstall "$@" fi if [[ $extract -eq 1 ]] && [[ $verbose -eq 1 ]]; then port -f clean --all "$@" port -f -v extract "$@" elif [[ $extract -eq 1 ]] && [[ $debug -eq 1 ]]; then port -f clean --all "$@" port -f -d extract "$@" elif [[ $extract -eq 1 ]]; then port -f clean --all "$@" port -f extract "$@" elif [[ $build_source -eq 1 ]] && [[ $verbose -eq 1 ]]; then port -f clean --all "$@" port -f -s -v install "$@" elif [[ $build_source -eq 1 ]] && [[ $debug -eq 1 ]]; then port -f -s -d install "$@" elif [[ $build_source -eq 1 ]]; then port -f -s install "$@" elif [[ $verbose -eq 1 ]]; then port -f -v install "$@" elif [[ $debug -eq 1 ]]; then port -f -d install "$@" else port -f install "$@" fi exit 0 }}}