# XLN Installer: common functions and environment.

# Abort on any command that exits with non-zero status.
set -e

# Standard error expected to be redirected to this file by
# all commands that might fail (exit with non-zero status).
# This is done for you if you invoke commands with the go()
# function below; also, the copyfiles() function does this.
STDERR=/tmp/xln-stderr-$$.out

# Handler invoked on exit. Prints output captured to ${STDERR},
# prefixed by "XLN_ERROR: " which is then detected by the
# installer process.
teardown() {
  if [ $? -ne 0 ]; then
    if [ -f ${STDERR} ]; then
      error_message=`cat ${STDERR}`
    else
      error_message="Unknown error"
    fi
    echo XLN_ERROR: "$error_message"
  fi
  
  rm -f ${STDERR}
  
  exit $?
}
trap teardown EXIT INT TERM

# Hack to avoid bash printing debug info if ditto aborts.
trap '' ABRT

# Wrapper for invoking commands, capturing standard error to
# a file read by teardown(), which is called on exit. Also
# silences any chatty output (as we want control over what the
# installer shows in the UI). It is recommended that all 
# commands are invoked with this.
go() {
  "$@" > /dev/null 2> ${STDERR}
}

# Deletes every file or directory given as argument, provided
# that they exist.
deletefiles() {
  for f in "$@"; do go rm -rf "${f}"; done
}

# Internal function. Deletes target ($2) if specific file or 
# folder is given, eg. dist/path/to/file.ext target/path/to/file.ext.
deleteifspecific() {
  set +e
  baseext=""
  if [ "$1" = ".zip" ]; then
    shift
    baseext=".zip"
  fi
  if [ $# -eq 2 ]; then
    if [ "`basename "$1" ${baseext}`" = "`basename "$2"`" ]; then
      deletefiles "$2"
    fi
  fi
  set -e
}

# Function for installing files from the distribution. Uses
# ditto(1) to copy entire hierarchies, preserving Mac forks
# and UNIX permissions. Relative paths are relative to the
# location of the installer app (ie. files and folders in
# same folder).
copyfiles() {
  go pushd ../../..
  deleteifspecific "$@"
  DITTOABORT=1 go ditto "$@"
  go popd
}

# Function for extracting files from a ZIP file in the
# distribution. Also uses ditto(1), to preserve Mac
# forks, etc. Relative paths are relative to the location
# of the installer app, as with copyfiles().
extractzip() {
  go pushd ../../..
  deleteifspecific ".zip" "$@"
  DITTOABORT=1 go ditto -xk "$@"
  go popd
}

# Function for syncing files from the distribution with,
# typically, a folder in the user's home directory. Uses
# rsync(1) to only copy files that aren't present in the
# destination. Relative paths are relative to the location
# of the installer app.
syncfiles() {
  go pushd ../../..
  go rsync -rptgoE --ignore-existing "$@"
  go popd
}
