226 lines
7.3 KiB
Bash
226 lines
7.3 KiB
Bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
|
##@cooked nocomments
|
|
module: template "Mise à jour de templates à partir de modèles"
|
|
|
|
function: template_locals "\
|
|
Afficher les variables qui doivent être locales
|
|
|
|
Utiliser de cette façon:
|
|
~~~
|
|
eval \$(template_locals)
|
|
~~~"
|
|
function template_locals() {
|
|
echo "local -a userfiles; local updated"
|
|
}
|
|
|
|
function: template_copy_replace "\
|
|
Copier \$1 vers \$2 de façon inconditionnelle
|
|
|
|
Si \$2 n'est pas spécifié, on assume que \$1 est de la forme '.file.ext'
|
|
et \$2 vaudra alors 'file'
|
|
|
|
si un fichier \${2#.}.local existe, prendre ce fichier à la place comme source
|
|
|
|
Ajouter file au tableau userfiles"
|
|
function template_copy_replace() {
|
|
local src="$1" dest="$2"
|
|
local srcdir srcname lsrcname
|
|
setx srcdir=dirname "$src"
|
|
setx srcname=basename "$src"
|
|
if [ -z "$dest" ]; then
|
|
dest="${srcname#.}"
|
|
dest="${dest%.*}"
|
|
dest="$srcdir/$dest"
|
|
fi
|
|
|
|
lsrcname="${srcname#.}.local"
|
|
[ -e "$srcdir/$lsrcname" ] && src="$srcdir/$lsrcname"
|
|
|
|
userfiles+=("$dest")
|
|
cp -P "$src" "$dest"
|
|
return 0
|
|
}
|
|
|
|
function: template_copy_missing "\
|
|
Copier \$1 vers \$2 si ce fichier n'existe pas déjà
|
|
|
|
Si \$2 n'est pas spécifié, on assume que \$1 est de la forme '.file.ext'
|
|
et \$2 vaudra alors 'file'
|
|
|
|
si un fichier \${2#.}.local existe, prendre ce fichier à la place comme source
|
|
|
|
Ajouter file au tableau userfiles"
|
|
function template_copy_missing() {
|
|
local src="$1" dest="$2"
|
|
local srcdir srcname lsrcname
|
|
setx srcdir=dirname "$src"
|
|
setx srcname=basename "$src"
|
|
if [ -z "$dest" ]; then
|
|
dest="${srcname#.}"
|
|
dest="${dest%.*}"
|
|
dest="$srcdir/$dest"
|
|
fi
|
|
|
|
userfiles+=("$dest")
|
|
if [ ! -e "$dest" ]; then
|
|
lsrcname="${srcname#.}.local"
|
|
[ -e "$srcdir/$lsrcname" ] && src="$srcdir/$lsrcname"
|
|
|
|
cp -P "$src" "$dest"
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
function: template_dump_vars "\
|
|
Lister les variables mentionnées dans les fichiers \$@
|
|
|
|
Seules sont prises en compte les variables dont le nom est de la forme
|
|
[A-Z][A-Za-z_]*
|
|
|
|
Cette fonction est utilisée par template_source_envs(). Elle utilise la
|
|
fonction outil _template_dump_vars() qui peut être redéfinie si nécessaire."
|
|
function template_dump_vars() {
|
|
_template_dump_vars "$@"
|
|
}
|
|
function _template_dump_vars() {
|
|
[ $# -gt 0 ] || return 0
|
|
cat "$@" |
|
|
grep -E '^[A-Z][A-Za-z_]*=' |
|
|
sed 's/=.*//' |
|
|
sort -u
|
|
}
|
|
|
|
function: template_source_envs "\
|
|
Cette fonction doit être implémentée par l'utilisateur et doit:
|
|
- initialiser le tableau template_vars qui donne la liste des variables scalaires
|
|
- initialiser te tableau template_lists qui donne la liste des variables listes
|
|
- charger ces variables depuis les fichiers \$@
|
|
|
|
Cette fonction utilise la fonction outil _template_source_envs() qui peut être
|
|
redéfinie si nécessaire."
|
|
function template_source_envs() {
|
|
_template_source_envs "$@"
|
|
}
|
|
function _template_source_envs() {
|
|
local e_
|
|
for e_ in "$@"; do
|
|
[ -f "$e_" ] && source "$e_"
|
|
done
|
|
setx -a template_vars=template_dump_vars "$@"
|
|
template_lists=()
|
|
}
|
|
|
|
function: template_resolve_scripts "\
|
|
Générer le script awk \$1 et le script sed \$2 qui remplacent dans les fichiers
|
|
destination les marqueurs @@VAR@@ par la valeur de la variable \$VAR
|
|
correspondante
|
|
|
|
Les fichiers \$3..@ contiennent les valeurs des variables
|
|
|
|
Les marqueurs supportés sont les suivants et sont évalués dans cet ordre:
|
|
- XXXRANDOMXXX remplacer cette valeur par une chaine de 16 caractères au hasard
|
|
- @@FOR:VARS@@ VARS étant une liste de valeurs séparées par des espaces:
|
|
dupliquer la ligne autant de fois qu'il y a de valeurs dans \$VARS
|
|
dans chaque ligne, remplacer les occurrences de @@VAR@@ par la valeur
|
|
de l'itération courante
|
|
- #@@IF:VAR@@ afficher la ligne si VAR est non vide, supprimer la ligne sinon
|
|
- #@@UL:VAR@@ afficher la ligne si VAR est vide, supprimer la ligne sinon
|
|
- #@@if:VAR@@
|
|
- #@@ul:VAR@@ variantes qui ne suppriment pas la ligne mais sont remplacées par #
|
|
- @@VAR:-string@@ remplacer par 'string' si VAR a une valeur vide ou n'est pas défini, \$VAR sinon
|
|
- @@VAR:+string@@ remplacer par 'string' si VAR est défini a une valeur non vide
|
|
"
|
|
function template_generate_scripts() {
|
|
local awkscript="$1"; shift
|
|
local sedscript="$1"; shift
|
|
(
|
|
template_source_envs "$@"
|
|
|
|
NL=$'\n'
|
|
# random, for
|
|
exec >"$awkscript"
|
|
echo '@include "base.tools.awk"'
|
|
echo 'BEGIN {'
|
|
for list in "${template_lists[@]}"; do
|
|
items="${!list}"; read -a items <<<"${items//
|
|
/ }"
|
|
let i=0
|
|
echo " $list[0] = 0; delete $list"
|
|
for item in "${items[@]}"; do
|
|
item="${item//\\/\\\\}"
|
|
item="${item//\"/\\\"}"
|
|
echo " $list[$i] = \"$item\""
|
|
let i=i+1
|
|
done
|
|
done
|
|
echo '}'
|
|
echo '{ if (should_generate_password()) { generate_password() } }'
|
|
for list in "${template_lists[@]}"; do
|
|
items="${!list}"; read -a items <<<"${items//
|
|
/ }"
|
|
echo "/@@FOR:$list@@/ {"
|
|
if [ ${#items[*]} -gt 0 ]; then
|
|
if [ "${list%S}" != "$list" ]; then item="${list%S}"
|
|
elif [ "${list%s}" != "$list" ]; then item="${list%s}"
|
|
else item="$list"
|
|
fi
|
|
echo " sub(/@@FOR:$list@@/, \"\")"
|
|
echo " for (i in $list) {"
|
|
echo " print gensub(/@@$item@@/, $list[i], \"g\")"
|
|
echo " }"
|
|
fi
|
|
echo " next"
|
|
echo "}"
|
|
done
|
|
echo '{ print }'
|
|
|
|
# if, ul, var
|
|
exec >"$sedscript"
|
|
for var in "${template_vars[@]}"; do
|
|
value="${!var}"
|
|
value="${value//\//\\\/}"
|
|
value="${value//[/\\[}"
|
|
value="${value//\*/\\\*}"
|
|
value="${value//$NL/\\n}"
|
|
if [ -n "$value" ]; then
|
|
echo "s/#@@IF:${var}@@//g"
|
|
echo "s/#@@if:${var}@@//g"
|
|
echo "/#@@UL:${var}@@/d"
|
|
echo "s/#@@ul:${var}@@/#/g"
|
|
echo "s/@@${var}:-([^@]*)@@/${value}/g"
|
|
echo "s/@@${var}:+([^@]*)@@/\\1/g"
|
|
else
|
|
echo "/#@@IF:${var}@@/d"
|
|
echo "s/#@@if:${var}@@/#/g"
|
|
echo "s/#@@UL:${var}@@//g"
|
|
echo "s/#@@ul:${var}@@//g"
|
|
echo "s/@@${var}:-([^@]*)@@/\\1/g"
|
|
echo "s/@@${var}:+([^@]*)@@//g"
|
|
fi
|
|
echo "s/@@${var}@@/${value}/g"
|
|
done
|
|
)
|
|
#etitle "awkscript" cat "$awkscript"
|
|
#etitle "sedscript" cat "$sedscript"
|
|
}
|
|
|
|
function template_process_userfiles() {
|
|
local awkscript sedscript workfile userfile
|
|
ac_set_tmpfile awkscript
|
|
ac_set_tmpfile sedscript
|
|
template_generate_scripts "$awkscript" "$sedscript" "$@"
|
|
|
|
ac_set_tmpfile workfile
|
|
for userfile in "${userfiles[@]}"; do
|
|
if cat "$userfile" | awk -f "$awkscript" | sed -rf "$sedscript" >"$workfile"; then
|
|
if testdiff "$workfile" "$userfile"; then
|
|
# n'écrire le fichier que s'il a changé
|
|
cat "$workfile" >"$userfile"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
ac_clean "$awkscript" "$sedscript" "$workfile"
|
|
}
|