#!/bin/bash
#
# Redmine upgrade tool.
#
# For suggestion, bug reports, please contact Pierre-Yves Landuré <pierre-yves@landure.fr>

SCRIPT_NAME="$(command basename ${0})"

# Print this script help.
function usage {
  command echo "
Usage :

  ${SCRIPT_NAME} redmine_path
    Upgrade the Redmine instance present in the given path."

  exit 1
} # usage



# Get the absolute path for a file or directory.
#
# @param string $path A relative path.
#
# @return ${REALPATH} A absolute path.
REALPATH=""
function realpath {
  command test ${#} -ne 1 && exit 1
  REALPATH=$(/bin/readlink -f "${1}")
} # realpath



# Check if a binary is present
#
# @param string $binary The binary to check.
# @param string $package The package the binary come from.
#
# @return Exit with error if the binary is missing.
function check_binary {
  command test ${#} -ne 2 && exit 1

  # Test the binary presence.
  if [ -z "$(which "${1}")" ]; then
    echo "Error : '${1}' is missing. Please install package '${2}'."
    exit 1
  fi
} # check_binary



# Download a file from the given URL.
#
# @param string $url The URL of the file to download.
#
# @return ${DOWNLOAD_FILE} The path to the downloaded file.
DOWNLOAD_FILE=""
function download_file {
  command test ${#} -ne 1 && exit 1

  # Download a file.
  DOWNLOAD_FILE="$(command mktemp)"
  command wget --quiet "${1}" \
      --output-document="${DOWNLOAD_FILE}"

  if [ ! -s "${DOWNLOAD_FILE}" ]; then
    command rm "${DOWNLOAD_FILE}"
    echo "Error : Unable to download file from '${1}'."
    exit 1
  fi
} # download_file



# Download and uncompress a tgz file from the given URL.
#
# @param string $url The URL of the file to download.
#
# @return ${DOWNLOAD_TGZ} The path to the extracted content.
DOWNLOAD_TGZ=""
function download_tgz {
  command test ${#} -ne 1 && exit 1

  download_file "${1}"

  # Untar the downloaded file and place it at its final location.
  DOWNLOAD_TGZ="$(command mktemp -d)"
  command tar --directory "${DOWNLOAD_TGZ}" -xzf "${DOWNLOAD_FILE}"
  command rm "${DOWNLOAD_FILE}"

  if [ $(command ls -1 --all "${DOWNLOAD_TGZ}" | command wc --lines) -eq 0 ]; then
    echo "Error : unable to untar file downloaded from '${1}'."
    exit 1
  fi
} # download_tgz


# Check for binaries presence
check_binary "wget" "wget"
check_binary "sed" "sed"
check_binary "mktemp" "mktemp"
check_binary "tar" "tar"
check_binary "basename" "coreutils"
check_binary "dirname" "coreutils"

command test ${#} -ne 1 && usage

realpath "${1}"
INSTALL_PATH="${REALPATH}"

if [ ! -e "${INSTALL_PATH}/Rakefile" ]; then
  echo "Error : '${1}' is not a Redmine install."
  usage
fi

SOURCE_URL="$(command wget --quiet --output-document=- "http://rubyforge.org/frs/?group_id=1850" \
        | command grep --max-count=1 -e "redmine-.*.tar.gz" \
        | command sed -e 's|^.*href="\([^"]*\)".*$|http://rubyforge.org\1|')"

VERSION="$(echo "${SOURCE_URL}" | command sed -e 's|.*redmine-\(.*\)\.tar\.gz|\1|')"

command wget "${SOURCE_URL}" \
    --output-document="/tmp/redmine.tar.gz"

command tar --directory "/tmp" -xzf "/tmp/redmine.tar.gz"

command chown -R root:root "/tmp/redmine-${VERSION}/"
command chmod -R go-w "/tmp/redmine-${VERSION}/"

command rm -r "/tmp/redmine-${VERSION}/tmp"
command rm -r "/tmp/redmine-${VERSION}/log"
command rm -r "/tmp/redmine-${VERSION}/files"
if [ -e "/tmp/redmine-${VERSION}/public/plugin_assets" ]; then
  command rm -r "/tmp/redmine-${VERSION}/public/plugin_assets"
fi

command cp -a "${INSTALL_PATH}/config/database.yml" "/tmp/redmine-${VERSION}/config/database.yml"
command cp -a "${INSTALL_PATH}/config/email.yml" "/tmp/redmine-${VERSION}/config/email.yml"
command cp -a "${INSTALL_PATH}/tmp" "/tmp/redmine-${VERSION}/tmp"
command cp -a "${INSTALL_PATH}/log" "/tmp/redmine-${VERSION}/log"
command cp -a "${INSTALL_PATH}/files" "/tmp/redmine-${VERSION}/files"
command cp -a "${INSTALL_PATH}/public/plugin_assets" "/tmp/redmine-${VERSION}/public/plugin_assets"
if [ -e "${INSTALL_PATH}/public/.htaccess" ]; then
  command cp -a "${INSTALL_PATH}/public/.htaccess" "/tmp/redmine-${VERSION}/public/.htaccess"
fi

if [ -d "${INSTALL_PATH}.back" ]; then
  command rm -r "${INSTALL_PATH}.back"
fi

command mv "${INSTALL_PATH}" "${INSTALL_PATH}.back"

command mv "/tmp/redmine-${VERSION}" "${INSTALL_PATH}"

command cd "${INSTALL_PATH}"

command rake generate_session_store
command rake db:migrate RAILS_ENV=production
command rake db:migrate:upgrade_plugin_migrations RAILS_ENV=production
command rake db:migrate_plugins RAILS_ENV=production
command rake tmp:cache:clear
command rake tmp:sessions:clear
command test -x "/etc/init.d/lighttpd" && /etc/init.d/lighttpd force-reload
command test -x "/etc/init.d/apache2" && /etc/init.d/apache2 force-reload

