update.sh 11.8 KB
#!/bin/bash

# ----------------------------------------------------------------------------------------------------------------
# Ce script permet de mettre à jour automatiquement le code source du logiciel, ainsi que la BD (si besoin).
# C'est une bonne pratique de l'exécuter assez régulièrement pour garder un logiciel bien à jour.

# Il ne fait essentiellement qu'un "git pull" suivi de la mise à jour de la BD (si besoin).

# La BD est mise à jour SEULEMENT s'il existe au moins 1 NOUVEAU script de mise à jour db-update-YYYY-MM-DD.sh
# récupéré avec git pull (dans le dossier database/update/).
# S'il y en a plusieurs, ils sont exécutés dans l'ordre chronologique.
# ----------------------------------------------------------------------------------------------------------------

# (Bash Arrays : cf https://www.cyberciti.biz/faq/finding-bash-shell-array-length-elements/)


# Version pour MacOS si MACOS=1
MACOS=0
#MACOS=1

# Ne pas vider le fichier $ftpf (CLEAN=1 pour le vider)
CLEAN=0

# Normal mode
TEST=0
# Test mode
#TEST=1

#db_update_scripts_folder="../database/update"
db_update_scripts_folder="../database/update/script_sql"
#db_update_scripts_folder_tmp=/tmp/database_update
db_update_scripts_folder_tmp=/tmp/database_update_script_sql

# files_to_process.txt file
ftpf=files_to_process.txt

function abort() {
	error_msg=$1
	echo "******************************************************"
	echo "!!! Script $0 aborté à cause d'une erreur d'exécution !!!"	
	echo "******************************************************"
	echo $error_msg
	exit 1
}




# Ce script peut être appelé avec une option "-c" (CLEAN) en 1er argument ($1)
if [[ $1 != '' ]] ; then
	[[ $1 != '-c' ]] && abort "Option $1 inconnue !"
	CLEAN=1
fi
# Si option CLEAN => vider le fichier $ftpf
if [[ $CLEAN == 1 ]] ; then
	cat /dev/null > $ftpf
	[[ -s $ftpf ]] && abort "Le fichier $ftpf n'est pas vide alors qu'il devrait l'être (1) !"
	echo "Le fichier $ftpf a été vidé"
fi 



# ----------------------------------------
# 0a) Affichage de la version courante du logiciel
# ----------------------------------------

echo
echo "**************************************"
echo "Version actuelle du logiciel"
echo "**************************************"
grep "^Version:" ../README.md
grep "^Date:" ../README.md
echo
echo


# TEST only
#[[ $TEST == 1 ]] && (rm ../database/update/test.txt ; rm ../database/update/db-update-2014-*.sh ; touch ../database/update/db-update-2014-08-23.sh)
if [[ $TEST == 1 ]] ; then
	MACOS=1
	echo "(TEST MODE)"
	echo "Suppression des fichiers de test créés précédemment (si besoin)"
	(rm $db_update_scripts_folder/test.txt ; rm $db_update_scripts_folder/db-update-2014-*.sql ; touch $db_update_scripts_folder/db-update-2014-08-23.sql)
fi
#mv ../database/update/db-update-2019-01-12.sh /tmp/ 

# ----------------------------------------
# 0b) Sauvegarde de certains éléments (dans /tmp) 
# (pour voir s'ils vont changer après le "git pull") 
# ----------------------------------------

# a) Sauvegarde du fichier composer.json
cp -fp ../composer.json /tmp/ || abort
######[[ $TEST == 1 ]] && cp ../composer.lock /tmp/composer.json
composer_json_prev=/tmp/composer.json

# b) Sauvegarde du dossier database/update/script_sql/
#db_update_scripts_before=( "key1" "key2" "key3" "key4" "key5" "key6" "key7" "key8" "key9" "key10" )
rm -rf $db_update_scripts_folder_tmp/ || abort
mkdir $db_update_scripts_folder_tmp/ || abort
#cp -fp $db_update_scripts_folder/db-update-????-??-??.sh $db_update_scripts_folder_tmp/ || abort
cp -fp $db_update_scripts_folder/db-update-????-??-??.sql $db_update_scripts_folder_tmp/ || abort
cd $db_update_scripts_folder_tmp/ || abort
#db_update_scripts_before=$(ls -1 db-update-????-??-??.sh) || abort
db_update_scripts_before=$(ls -1 db-update-????-??-??.sql) || abort
cd -   >/dev/null || abort
#echo ; echo ${db_update_scripts_before[@]}



# ----------------------------------------
# 1) Mise à jour du code source (git pull)
# ----------------------------------------
#db_update_scripts_after=( "key1" "key2" "key3" "key4" "key5" "key6" "key7" "key8" "key9" "key10" "key0" "key11" )
echo
echo "* 1) Mise à jour du code source (git pull) (o/n) ? [o]"
read do_it ; [[ -z $do_it ]] && do_it="o"
#echo $do_it
[[ $do_it != "o" ]] && exit 0

cd ../ || abort

# TODO: AVIRER dès que ca a été fait au moins 1 fois (dans tous les labos utilisateurs)
# Temporairement nécessaire pour nettoyer définitivement vendor/
#rm -rf vendor/*

#git pull || abort
git -c http.sslVerify=false pull || abort

# Utile à faire si pb avec docs attachés
chmod 777 webroot/files/
chmod 777 webroot/img/photos/

cd - >/dev/null || abort

# ----------------------------------------
# 1b) Affichage de la nouvelle version
# ----------------------------------------
echo
echo "**************************************"
echo "Nouvelle Version du logiciel"
echo "**************************************"
grep "^Version:" ../README.md
grep "^Date:" ../README.md
echo
echo


# ----------------------------------------
# 2) Mise a jour des plugins php (dossier vendor/) si nécessaire 
# (seulement si le fichier composer.json a changé)
# ----------------------------------------
echo
echo "* 2) Mise à jour des plugins php (seulement si nécessaire) :"
plugins_dir=../vendor
# Creation dossier vendor/ si n'existe pas encore
if [ ! -d $plugins_dir ] ; then
	mkdir $plugins_dir
	chmod 777 $plugins_dir
fi
chmod +x plugins_set.sh
chmod +x plugins_update.sh
chmod +x plugins_install.sh
diff ../composer.json $composer_json_prev >/dev/null
# Attention, ne pas faire "update" mais "install"
# car "install" n'installe que les NOUVEAUX plugins non déjà installés
# et "update" risquerait aussi d'installer des versions plus récentes
# que les plugins qui sont déjà installés (et donc pas encore testés)
##[[ $? == 1 ]] && ./plugins_install.sh
if [[ $? == 0 ]] ; then
	echo "==> PAS NÉCESSAIRE"
else
	#echo "OUI"
	./plugins_install.sh
fi



# ----------------------------------------
# 3) Mise a jour de la BD (si nécessaire) 
# (seulement s'il y a au moins 1 nouveau script db-update-YYYY-MM-DD.sql dans database/update/script_sql/)
# ----------------------------------------

echo
echo "* 3) Mise à jour de la Base de Données (seulement si nécessaire) :"

# Créer le fichier files_to_process.txt s'il n'existe pas encore 
[ ! -f $ftpf ] && touch $ftpf


# a) On fait la différence entre les fichiers de mise à jour BD présents après le git et avant

# TEST only
#[[ $TEST == 1 ]] && (rm ../database/update/db-update-2014-08-23.sh ; touch ../database/update/test.txt ; touch ../database/update/db-update-2014-08-24.sh ; touch ../database/update/db-update-2014-08-25.sh; chmod +x ../database/update/db-update-2014-*.sh)
[[ $TEST == 1 ]] && (rm $db_update_scripts_folder/db-update-2014-08-23.sql ; touch $db_update_scripts_folder/test.txt ; touch $db_update_scripts_folder/db-update-2014-08-24.sql ; touch $db_update_scripts_folder/db-update-2014-08-25.sql)
#mv /tmp/db-update-2019-01-12.sh ../database/update/

cd $db_update_scripts_folder/ || abort 
#db_update_scripts_after=$(ls -1 db-update-????-??-??.sh) || abort
db_update_scripts_after=$(ls -1 db-update-????-??-??.sql) || abort
cd - >/dev/null || abort
#echo ; echo ${db_update_scripts_after[@]}

db_update_scripts_new=$( echo ${db_update_scripts_before[@]} ${db_update_scripts_after[@]} | tr ' ' '\n' | sort | uniq -u ) || abort
#temp=() ; for t in ${db_update_scripts_new[@]} ; do temp+=($t) ; done ; temp+=('toto') ; db_update_scripts_new=$temp
#echo ${#db_update_scripts_new[@]} ; echo ${db_update_scripts_new[@]}
# Pas de nouveau script de mise à jour BD à exécuter => exit
#[[ $db_update_scripts_new == '' ]] && echo "==> PAS NÉCESSAIRE" ; exit 0

# On ajoute les anciens fichiers (de l'itération précédente) restant à traiter
echo "- (a) Fichiers restant à traiter de l'itération précédente"
#cat $ftpf
#if [[ $TEST == 2 ]] ; then
if [[ $TEST == 1 ]] ; then
	echo "db-update-2014-08-23.sql" > $ftpf 
	echo "db-update-2014-08-24.sql" >> $ftpf 
	echo "db-update-2014-08-26.sql" >> $ftpf
	db_update_scripts_new+=("db-update-2014-08-10.sql")
fi
db_update_scripts_old=$(cat $ftpf)
#echo $db_update_scripts_old
echo ${db_update_scripts_old[*]}

echo "- (b) Nouveaux fichiers à traiter (pour cette itération)"
#echo ${db_update_scripts_new[@]}
echo ${db_update_scripts_new[*]}

# Ensemble des fichiers à traiter (anciens || nouveaux) : anciens UNION nouveaux (fusion sans doublon)"
echo "- (c) Ensemble des fichiers à traiter (a + b)"
declare -a db_update_scripts
#[[ " ${a[@]} " =~ " ${val} " ]] && echo "true" || echo "false
# foreach old script, add it to array db_update_scripts (only if not duplicate)
for db_update_script_old in ${db_update_scripts_old[*]} ; do
	if [[ ! "${db_update_scripts_new[*]}" =~ "${db_update_script_old}" ]] ; then
		db_update_scripts_new+=($db_update_script_old) || abort
	fi
done
db_update_scripts_new_tmp=$( echo ${db_update_scripts_new[*]} | tr ' ' '\n' | sort ) || abort
db_update_scripts_new=(${db_update_scripts_new_tmp[*]})
#echo ${db_update_scripts_new[*]}


# On sauve les noms des nouveaux fichiers à traiter dans le fichier ftpf (MERGE)
# D'abord, on le vide
cat /dev/null > $ftpf
# Puis, on le remplit
for db_update_script_new in ${db_update_scripts_new[*]} ; do
	echo $db_update_script_new >> $ftpf
done

# Si pas de nouveau fichier à traiter (ftpf est vide), rien à faire, on stoppe
#if [ ! -s $ftpf ] ; then
if [[ $db_update_scripts_new == '' ]] ; then 
	#echo "Le fichier ftpf est vide"
	echo "==> PAS NÉCESSAIRE"
	echo
	exit 0
fi
#nb_scripts=${#db_update_scripts_new[@]}
#[[ $nb_scripts == 0 ]] && exit 0


# b) Mise a jour de la BD 

#echo "Voici le(s) script(s) à exécuter :" 
#cat $ftpf
#echo $db_update_scripts_new
echo ${db_update_scripts_new[*]}

# Remove files that were DELETED by "git pull"
for db_update_script_new in ${db_update_scripts_new[@]} ; do
	[[ ! -f ../database/update/script_sql/$db_update_script_new ]] && echo "$db_update_script_new sera ignoré car supprimé par le 'git pull'" # TODO: supprimer cet element du tableau
done

# On va dans le dossier database/update/ :
#cd $db_update_scripts_folder/ || abort
echo "* Exécuter ces scripts SQL (o/n) ? [o]"
read do_it ; [[ -z $do_it ]] && do_it="o"
#echo $do_it
[[ $do_it != "o" ]] && exit 0

# Retour à database/update/
cd $db_update_scripts_folder/../ || abort
for db_update_script_new in ${db_update_scripts_new[@]} ; do
	# Ignorer les fichiers supprimés par le "git pull"
	#[[ ! -f $db_update_script_new ]] && continue
	#[[ ! -f script_sql/$db_update_script_new ]] && continue
	if [[ ! -f script_sql/$db_update_script_new ]] ; then
		echo "$db_update_script_new ignoré car supprimé par le 'git pull'" # TODO: supprimer cet element du tableau
	else
		echo ; echo
		#echo "- Execution du script de mise à jour de la BD $db_update_scripts_folder/$db_update_script_new (o/n) ? [o]"
		echo "- Execution du script de mise à jour de la BD $db_update_scripts_folder/$db_update_script_new"
		#read do_it ; [[ -z $do_it ]] && do_it="o" ; echo $do_it
		#if [[ $do_it == "o" ]] ; then
		#ls -l ./$db_update_script_new_ || abort
		#./$db_update_script_new || abort
		####./db-update.sh script_sql/$db_update_script_new || abort
		#fi
	fi
	# On supprime le fichier traité de $ftpf
	#echo "Suppression $db_update_script_new de $ftpf"
	#echo "- avant suppr"
	#cat ../../install/$ftpf
	if [[ $MACOS == 1 ]] ; then
		# For Mac OS :
		sed -e "/$db_update_script_new/d" -i '' ../../install/$ftpf || abort
	else
		# For Linux : 
		sed -e "/$db_update_script_new/d" -i ../../install/$ftpf || abort
	fi 
	#echo "- après suppr"
	#cat ../../install/$ftpf
done


#[[ $TEST == 1 ]] && (rm test.txt ; rm db-update-2014-*.sh)
[[ $TEST == 1 ]] && (rm script_sql/test.txt ; rm script_sql/db-update-2014-*.sql)
cd -   >/dev/null

# A ce stade, $ftpf doit être vide, sinon abort
#cat $ftpf
[[ -s $ftpf ]] && abort "Le fichier $ftpf n'est pas vide alors qu'il devrait l'être (2) !"


echo
#echo "=> MISE À JOUR TERMINÉE"