#!/usr/bin/env bash
#
# Script to synchronise SVN mirrors from their sources
#
# Written by Michel Jouvin - CNRS/LAL - 15/7/2019

svn_mirrors_root=/pdisk/subversion/mirrors
source_svn_user=apache_lal
source_svn_server=svn.lal.in2p3.fr
source_svn_root=/wwwdata/subversion
svn_ssh_key=/pdisk/trac/site-config/ssh/trac_backup_rsa
svn_ssh_known_hosts=/pdisk/trac/site-config/ssh/trac_known_hosts
pre_revprop_change_hook_path=hooks/pre-revprop-change

pre_revprop_change_hook() {
    cat <<'EOF'
#!/bin/sh
#
# pre_revprop_change hook for svnsync to ensure that only the appropriate user can do a revprop change

REPOS="$1"
REV="$2"
USER="$3"
PROPNAME="$4"
ACTION="$5"

sync_user=root

if [ "$USER" = ${sync_user} ]; then exit 0; fi

echo "Only user ${sync_user} can propagate revision changes" >&2
exit 1
EOF
}

usage () {
    echo "usage: $(basename $0) [-all|repository]"
    echo ""
    echo "repository: repository path relative to ${source_svn_root} or ${svn_mirrors_root}"

    exit 1
}


global_status=0
svn_repos_list=''
while [ -n "$(echo $1 | grep '^-')" ]
do
  case "$1" in
    -all)
      svn_repos_list=$(find ${svn_mirrors_root} -name db -type d)
      ;;

    *)
      usage
      exit
      ;;
  esac

  shift
done

if [ -z "${svn_repos_list}" ]
then
  if [ -n "$1" ]
  then
    repo="${svn_mirrors_root}/$1/db"
    if [ ! -d "${repo}" ]
    then
        echo "ERROR: Project $1 not found"
        exit 2
    fi
    svn_repos_list=${repo}
  else
    usage
    exit
  fi
elif [ -n "$1" ]
then
    usage
    exit
fi

# -q is required to avoid a "Killed by signal 15" message (normal behaviouri, 
# -q used by default when SVN_SSH is not defined)
export SVN_SSH="ssh -i ${svn_ssh_key} -o UserKnownHostsFile=${svn_ssh_known_hosts} -q"

for repo_db_path in ${svn_repos_list}
do
    repo_path=$(echo ${repo_db_path} | sed -e "s%/db$%%")
    repo_name=$(echo ${repo_path} | sed -e "s%${svn_mirrors_root}/%%" -e "s%/db$%%")
    repo_source="svn+ssh://${source_svn_user}@${source_svn_server}/${source_svn_root}/${repo_name}"
    echo "Syncing repository ${repo_name} from ${repo_source}..."

    if [ ! -x ${repo_path}/${pre_revprop_change_hook_path} ]
    then
        echo "    Adding pre-revprop-change hook for svnsync..."
        echo "$(pre_revprop_change_hook)" > ${repo_path}/${pre_revprop_change_hook_path}
        chmod 755 ${repo_path}/${pre_revprop_change_hook_path}
        echo "    Initialising svnsync..."
        svnsync initialize --allow-non-empty file:///${repo_path} ${repo_source} 
    fi

    svnsync synchronize file:///${repo_path} ${repo_source}
    status=$?
    if [ ${status} -eq 0 ]
    then
        echo "    Repository ${repo_name} synchronisation done successfully"
    else
        echo "    ERROR: an error occurred during repository ${repo_name} synchronisation"
        global_status=${status}
    fi
done

exit ${global_status}
