#!/bin/bash

#       -------------------------------------------------------------------
#
#       script sh pour switcher les plugins vers leurs nouvelles url sur la zone
#
#       Copyright 2009, cy_altern <cy_altern@yahoo.fr>
#
#       This program is free software; you can redistribute it and/or
#       modify it under the terms of the GNU General Public License as
#       published by the Free Software Foundation; either version 2 of the
#       License, or (at your option) any later version. 
#
#       This program is distributed in the hope that it will be useful, but
#       WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
#       General Public License for more details.
#
#       Description: ce script scanne un repertoire plugins pour trouver tous les
#       sous-reps ayant un fichier /.svn/entry 
#       lit le chemin du repository indique dans ce fichier 
#       lance le svn switch correspondant
# 
#       -------------------------------------------------------------------

        PROGNAME=$(basename $0)
        VERSION="0.0.1"

#       -------------------------------------------------------------------
#       Functions
#       -------------------------------------------------------------------
function make_temp_files
{
        # Use user's local tmp directory if it exists

        if [ -d ~/tmp ]; then
                TEMP_DIR=~/tmp
        else
                TEMP_DIR=/tmp
        fi

        # Temp file for this script, using paranoid method of creation to
        # insure that file name is not predictable.  This is for security to
        # avoid "tmp race" attacks.  If more files are needed, create using
        # the same form.

        TEMP_FILE1=$(mktemp -q "${TEMP_DIR}/${PROGNAME}.$$.XXXXXX")
        if [ "$TEMP_FILE1" = "" ]; then
                error_exit "cannot create temp file!"
        fi
}

function clean_up
{
        rm -f ${TEMP_FILE1}
}

function error_exit
{
        echo "${PROGNAME}: ${1:-"Unknown Error"}" >&2
        clean_up
        exit 1
}

function graceful_exit
{
        clean_up
        exit
}

function signal_exit
{
        case $1 in
                INT)    echo "$PROGNAME: Program aborted by user" >&2
                        clean_up
                        exit
                        ;;
                TERM)   echo "$PROGNAME: Program terminated" >&2
                        clean_up
                        exit
                        ;;
                *)      error_exit "$PROGNAME: Terminating on unknown signal"
                        ;;
        esac
}

function usage
{
        echo "Usage: ${PROGNAME} [-h | --help] [-r repertoire/des/plugins] [-d chemin/fichier/temp] [-t oui|non]"
}

function helptext
{
        local tab=$(echo -en "\t\t")

        cat <<- -EOF-

        ${PROGNAME} ver. ${VERSION}
        Script de switch SVN des plugins de la zone

        $(usage)

        Options:

        -h, --help               afficher ce message et quitter
        
        -r  chemin/rep/plugins   chemin du repertoire des plugins (relatif si pas de / initial)
                                 si absent de la ligne de commande, sera demandé interactivement
                                 
        -d  chemin/rep/temp      facultatif
                           . si présent, chemin du répertoire où générer le fichier de 
                           commandes avec délais mes_switch.sh pour ne pas harceler 
                           la zone de svn switch en rafale
                           . si absent les commandes svn switch sont envoyées directement 
                           par ce script
  
  -l  chemin/rep/log       facultatif
                           . si présent, chemin du répertoire où générer le fichier de 
                           log switch.log des opérations de switch lancées
                           
  -t  oui | non            mode test si l'option -d est sélectionnée
                           . non : lancement immédiat du fichier différé
                           . oui : fichier différé pas lancé: il faudra le lancer par 
                           la suite manuellement (= mode test)
-EOF-
}

function root_check
{
        if [ "$(id | sed 's/uid=\([0-9]*\).*/\1/')" != "0" ]; then
                error_exit "You must be the superuser to run this script."
        fi
}


#       -------------------------------------------------------------------
#       Program starts here
#       -------------------------------------------------------------------

##### Initialization And Setup #####

# Set file creation mask so that all files are created with 600 permissions.

umask 066
#root_check

# Trap TERM, HUP, and INT signals and properly exit

trap "signal_exit TERM" TERM HUP
trap "signal_exit INT"  INT


##### Command Line Processing #####

if [ "$1" = "--help" ]; then
        helptext
        graceful_exit
fi

#les parametres ayant une valeur par defaut
#rep=plugins
delais=0
log=0
tester="non"

#recuperation des valeurs passees par la ligne de commande
while getopts ":hr:d:l:t:" opt; do
        case $opt in
                r )     rep=$OPTARG;;
    d ) delais=$OPTARG;;
    l ) log=$OPTARG;;
    t ) tester=$OPTARG;;
                h )     helptext
                        graceful_exit ;;
                * )     usage

                        exit 1
        esac
done

#saisie interactive du paramètre obligatoire si absent de la ligne de commande
if [ -z $rep ]; then
        echo -n "chemin du répertoire des plugins (relatif si pas de / initial): "
    read reponse
    if [ -n "$reponse" ]; then
        rep=$reponse
        else
                error_exit "erreur: il manque le parametre rep (-r chemin/rep/plugins)"
    fi  
fi


#verifier que le rep des plugins existe & est accessible
if [ ! -d $rep ]; then
        error_exit "le repertoire $rep n'existe pas ou n'est pas accessible"
fi

#si delais, vérifier que l'on peut écrire le fichier mes_switch.sh
if [[ $delais != "0" ]]; then
  if ! echo "echo depart de $delais/mes_switch.sh" > $delais/mes_switch.sh  ; then
      echo -n "erreur: le fichier de commandes intermédiaires $delais/mes_switch.sh ne peut être créé: voulez vous poursuivre sans l'option -d (o | n)?"
      read reponse
      if [[ $reponse = "n" ]]; then
          error_exit "Abandon par l'utilisateur"
      else
          delais=0
      fi        
  fi
fi

#si log, vérifier que l'on peut ecrire le fichier switch.log
if [[ $log != "0" ]]; then
  if ! echo "fichier de log des svn switch" > $log/switch.log  ; then
      echo -n "erreur: le fichier de log $log/switch.log ne peut être créé: voulez vous poursuivre sans l'option -l (o | n)?"
      read reponse
      if [[ $reponse = "n" ]]; then
          error_exit "Abandon par l'utilisateur"
      else
          log=0
      fi        
  fi
fi

#si mode test vérifier que le mode -d est actif
if [[ $tester != "non" ]]; then
  if [[ $delais = "0" ]]; then
     error_exit "erreur: en mode test (-t oui) le mode -d (commandes différées) doit être actif"
  fi
fi


##### routine principale #####
for rep_ec in $( find $rep -type f -name plugin.xml )
do
        repn=$( dirname $rep_ec )
        if [ -f $repn/.svn/entries ]; then 
    svn_old=""
    svn_new=""
    
#trouver tous les plugins à traiter    
    if svn_old=$( egrep "svn://zone.spip.org/spip-zone/_plugins_/_test_/.*" $repn/.svn/entries ) ; then
        svn_new=${svn_old:0:40}${svn_old:47}
                fi
                if svn_old=$( egrep "svn://zone.spip.org/spip-zone/_plugins_/_stable_/.*" $repn/.svn/entries ) ; then
                  svn_new=${svn_old:0:40}${svn_old:49}
                fi
                if svn_old=$( egrep "svn://zone.spip.org/spip-zone/_plugins_/_dev_/.*" $repn/.svn/entries ) ; then
                  svn_new=${svn_old:0:40}${svn_old:46}
                fi
                if svn_old=$( egrep "svn://zone.spip.org/spip-zone/_plugins_/_core_/.*" $repn/.svn/entries ) ; then
                  svn_new=${svn_old:0:31}"core_/plugins/"${svn_old:47}
                fi

#soit lancer les commandes svn switch en direct soit les stocker pour lancement différé avec délais
    if [[ $svn_old != "" || $svn_new != "" ]]; then
      if [[ $delais != "0" ]]; then
          if [[ $log != "0" ]]; then
              echo "echo switch $svn_new >> $log/switch.log"  >> $delais/mes_switch.sh
              echo "svn switch $svn_new $repn >> $log/switch.log && sleep 15;" >> $delais/mes_switch.sh
          else 
              echo "echo switch $svn_new"  >> $delais/mes_switch.sh
              echo "svn switch $svn_new $repn && sleep 15;" >> $delais/mes_switch.sh
          fi
      else
          if [[ $log != "0" ]]; then
              echo "switch $svn_new"  >> $log/switch.log
               svn switch $svn_new $repn >> $log
          else 
               svn switch $svn_new $repn
          fi
      fi
    fi
    
        fi
done


#lancement du fichier de commandes intermédiaire si nécessaire
if [[ $delais != "0" ]]; then
    echo "echo fin des switch SVN lancés par $delais/mes_switch.sh"  >> $delais/mes_switch.sh
    chmod 700 $delais/mes_switch.sh
    if [[ $tester = "non" ]]; then
        . $delais/mes_switch.sh
    fi
fi