Intégration de la branche add-multiconf
This commit is contained in:
commit
8e17fb1fb3
|
@ -1,9 +1,5 @@
|
|||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
|
||||
# Fichiers externes à inclure. Chacun de ces fichiers peut contenir des
|
||||
# définitions de fonctions et de la variables RULES
|
||||
INCLUDES=()
|
||||
|
||||
# Règles pour le classement des fichiers. Chaque règle est de la forme
|
||||
# pattern:destdir[:renamef]
|
||||
RULES=()
|
||||
|
|
|
@ -111,7 +111,15 @@ function copy_update_ask() {
|
|||
# Copier ou mettre à jour le fichier $1 vers le fichier $2.
|
||||
# Si le fichier existe déjà, la différence est affichée, et une confirmation
|
||||
# est demandée pour l'écrasement du fichier.
|
||||
# si $1 commence par '-' alors on s'en sert comme option pour configurer le
|
||||
# niveau d'interaction pour demander la confirmation. les paramètres sont
|
||||
# alors décalés
|
||||
# Retourner vrai si le fichier a été copié sans erreur.
|
||||
local interopt=-c
|
||||
if [[ "$1" == -* ]]; then
|
||||
interopt="$1"
|
||||
shift
|
||||
fi
|
||||
local src="$1" dest="$2"
|
||||
|
||||
[ -d "$dest" ] && dest="$dest/$(basename -- "$src")"
|
||||
|
@ -119,10 +127,14 @@ function copy_update_ask() {
|
|||
|
||||
[ -f "$dest" ] || copy_replace "$src" "$dest"
|
||||
if testdiff "$src" "$dest"; then
|
||||
diff -u "$dest" "$src"
|
||||
if ask_yesno -c "Voulez-vous remplacer $(ppath "$dest") par la nouvelle version?" C; then
|
||||
check_interaction "$interopt" && diff -u "$dest" "$src"
|
||||
if ask_yesno "$interopt" "Voulez-vous remplacer $(ppath "$dest") par la nouvelle version?" C; then
|
||||
copy_replace "$src" "$dest" "$3"
|
||||
return $?
|
||||
elif ! check_interaction "$interopt"; then
|
||||
ewarn "Les mises à jours suivantes sont disponibles:"
|
||||
diff -u "$dest" "$src"
|
||||
ewarn "Le fichier $(ppath "$dest") n'a pas été mis à jour"
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
## Gestion de fichiers de configuration et de répertoires de configuration
|
||||
##@cooked nocomments
|
||||
uprovide multiconf
|
||||
urequire install
|
||||
|
||||
function conf_local() {
|
||||
# afficher les commandes pour définir comme locales les variables utilisées
|
||||
# par les fonctions conf_*
|
||||
# cela permet d'utiliser ces fonctions à l'intérieur d'autres fonctions sans
|
||||
# polluer l'espace de nom
|
||||
echo "local -a __CONF_ARRAY_VARS"
|
||||
}
|
||||
|
||||
function conf_auto() {
|
||||
# charger la configuration pour l'outil $1 avec les variables $2..@
|
||||
# conf_init n'est appelé que si des variables sont spécifiées, ce qui permet
|
||||
# d'appeler conf_init au préalable si une configuration spécifique doit être
|
||||
# faite.
|
||||
# Ainsi:
|
||||
# conf_auto NAME VARS...
|
||||
# est équivalent à:
|
||||
# conf_init VARS...
|
||||
# conf_auto NAME
|
||||
# est équivalent à:
|
||||
# conf_init VARS...
|
||||
# conf_find_files __CONF_FILES ~/etc/default/NAME.conf ~/etc/NAME.d/*.conf
|
||||
# conf_load_files "${__CONF_FILES[@]}"
|
||||
# Pour supporter les scénarii où les fichiers de configuration sont ailleurs
|
||||
# que dans ~/etc/default, l'argument NAME peut être un chemin:
|
||||
# conf_auto PATH/TO/NAME VARS...
|
||||
# est équivalent à:
|
||||
# conf_init VARS...
|
||||
# conf_find_files __CONF_FILES PATH/TO/NAME.conf PATH/TO/NAME.d/*.conf
|
||||
# conf_load_files "${__CONF_FILES[@]}"
|
||||
local __name="$1"; shift
|
||||
[ -n "$__name" ] || return 1
|
||||
[ $# -gt 0 ] && conf_init "$@"
|
||||
local -a __CONF_FILES
|
||||
if [[ "$__name" == */* ]]; then
|
||||
conf_load "$__name.conf" "$__name.d/*.conf"
|
||||
else
|
||||
conf_load "$HOME/etc/default/$__name.conf" "$HOME/etc/$__name.d/*.conf"
|
||||
fi
|
||||
}
|
||||
|
||||
function conf_init() {
|
||||
# définir les variables attendues lors du chargement des fichiers de
|
||||
# configuration par conf_load_files
|
||||
# par défaut, les variables sont en mode scalaire: la définition d'une
|
||||
# variable écrase la valeur précédente. Avec l'option -a les variables sont
|
||||
# en mode tableau: les nouvelles valeurs sont rajoutées à la fin du tableau.
|
||||
# dans l'exemple suivant:
|
||||
# conf_init NAME VALUE -a SRCDIRS DESTDIRS
|
||||
# NAME et VALUE sont scalaires alors que SRCDIRS et DESTDIRS sont tableaux
|
||||
# Les variables scalaires sont initialisées à la valeur vide ou à la valeur
|
||||
# spécifiée e.g.:
|
||||
# conf_init VAR=value
|
||||
# Les variables tableaux sont toujours initialisées à la valeur vide
|
||||
# L'option -s permet de revenir au mode scalaire
|
||||
__CONF_ARRAY_VARS=()
|
||||
local __var __array
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-a|--array) __array=1;;
|
||||
-s|--scalar) __array=;;
|
||||
*)
|
||||
if [ -n "$__array" ]; then
|
||||
eval "${1%%=*}=()"
|
||||
array_addu __CONF_ARRAY_VARS "${1%%=*}"
|
||||
else
|
||||
setv "$1"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
function conf_load() {
|
||||
# charger les fichiers de configuration spécifiés
|
||||
# conf_load SPECS...
|
||||
# est équivalent à:
|
||||
# conf_find_files __CONF_FILES SPECS...
|
||||
# conf_load_files "${__CONF_FILES[@]}"
|
||||
local -a __CONF_FILES
|
||||
conf_find_files __CONFS_FILES "$@"
|
||||
conf_load_files "${__CONFS_FILES[@]}"
|
||||
}
|
||||
|
||||
function conf_find_files() {
|
||||
# initialiser le tableau $1 avec les fichiers de configuration correspondant
|
||||
# aux arguments $2..@
|
||||
# - si on spécifie un fichier, il est pris tel quel s'il existe
|
||||
# - si on spécifie un répertoire, tous les fichiers *.conf de ce répertoire
|
||||
# sont pris
|
||||
# - si on spécifie un pattern e.g path/to/*.conf alors tous les fichiers
|
||||
# correspondant au pattern sont pris
|
||||
# - sinon l'argument est ignoré
|
||||
local __conf_dest="$1"; shift
|
||||
local -a __conf_files
|
||||
local __conf_spec __conf_dir __conf_wc
|
||||
array_new "$__conf_dest"
|
||||
for __conf_spec in "$@"; do
|
||||
if [ -f "$__conf_spec" ]; then
|
||||
array_add "$__conf_dest" "$__conf_spec"
|
||||
continue
|
||||
elif [ -d "$__conf_spec" ]; then
|
||||
__conf_spec="$__conf_spec/*.conf"
|
||||
fi
|
||||
splitwcs "$__conf_spec" __conf_dir __conf_wc
|
||||
array_lsfiles __conf_files "${__conf_dir:-.}" "$__conf_wc"
|
||||
array_extend "$__conf_dest" __conf_files
|
||||
done
|
||||
}
|
||||
|
||||
function conf_load_files() {
|
||||
# sourcer les fichiers spécifiés en faisant ce qui est nécessaire pour que
|
||||
# les variables de __CONF_ARRAY_VARS soient correctement traitées.
|
||||
local -a __conf_backups __conf_values
|
||||
local __conf_file __conf_name __conf_i __conf_backup
|
||||
for __conf_file in "$@"; do
|
||||
# faire une copie de sauvegarde puis supprimer les variables tableaux
|
||||
__conf_backups=()
|
||||
for __conf_name in "${__CONF_ARRAY_VARS[@]}"; do
|
||||
__conf_backups=("${__conf_backups[@]}" "$(declare -p "$__conf_name")")
|
||||
unset "$__conf_name"
|
||||
done
|
||||
# charger le fichier
|
||||
source "$__conf_file"
|
||||
# puis restaurer les variables ou les fusionner avec une éventuelle nouvelle valeur
|
||||
__conf_i=0
|
||||
for __conf_name in "${__CONF_ARRAY_VARS[@]}"; do
|
||||
__conf_backup="${__conf_backups[$__conf_i]}"
|
||||
__conf_backup="${__conf_backup#declare * }"
|
||||
if [ -n "$(declare -p "$__conf_name" 2>/dev/null)" ]; then
|
||||
# la variable a été redéfinie, la fusionner avec la précédente valeur
|
||||
array_copy __conf_values "$__conf_name"
|
||||
eval "$__conf_backup"
|
||||
array_extend "$__conf_name" __conf_values
|
||||
else
|
||||
# la variable n'a pas été redéfinie, restaurer la précédente valeur
|
||||
eval "$__conf_backup"
|
||||
fi
|
||||
__conf_i=$(($__conf_i + 1))
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
function conf_install() {
|
||||
# USAGE: conf_install DEST SRCS...
|
||||
# installer les fichiers de SRCS dans le répertoire standardisé DEST
|
||||
# ## destination
|
||||
# - si DEST est un nom sans chemin, e.g NAME, alors la destination est
|
||||
# ~/etc/NAME.d
|
||||
# - si DEST est un nom avec chemin, alors la valeur est prise telle quelle
|
||||
# comme destination, et le répertoire est créé le cas échéant.
|
||||
# Si un fichier existe déjà dans la destination, afficher une demande de
|
||||
# confirmation avant de l'écraser
|
||||
# ## source
|
||||
# - si SRC est un fichier, le prendre tel quel
|
||||
# - si SRC est un répertoire, prendre tous les fichiers SRC/*.conf
|
||||
# - si SRC est un pattern, prendre tous les fichiers correspondant
|
||||
local -a srcs
|
||||
local src dir wc
|
||||
local dest="$1"; shift
|
||||
[[ "$dest" == */* ]] || dest="$HOME/etc/$dest.d"
|
||||
mkdir -p "$dest" || return 1
|
||||
for src in "$@"; do
|
||||
if [ -f "$src" ]; then
|
||||
srcs=("$src")
|
||||
elif [ -d "$src" ]; then
|
||||
array_lsfiles srcs "$src" "*.conf"
|
||||
else
|
||||
splitwcs "$src" dir wc
|
||||
array_lsfiles srcs "$dir" "$wc"
|
||||
fi
|
||||
for src in "${srcs[@]}"; do
|
||||
copy_update_ask -y "$src" "$dest"
|
||||
done
|
||||
done
|
||||
}
|
20
ufile
20
ufile
|
@ -1,7 +1,7 @@
|
|||
#!/bin/bash
|
||||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
source "$(dirname "$0")/lib/ulib/ulib" || exit 1
|
||||
urequire DEFAULTS
|
||||
urequire DEFAULTS multiconf
|
||||
|
||||
function display_help() {
|
||||
uecho "$scriptname: classer des fichiers selon certains règles
|
||||
|
@ -126,8 +126,7 @@ parse_args "$@"; set -- "${args[@]}"
|
|||
|
||||
## charger toutes les règles
|
||||
|
||||
RULES=()
|
||||
INCLUDES=()
|
||||
conf_init -a RULES
|
||||
if [ -n "$config" ]; then
|
||||
if [ "$action" != edit ]; then
|
||||
# le fichier doit exister, sauf en mode édition où il sera créé s'il
|
||||
|
@ -140,22 +139,11 @@ if [ -n "$config" ]; then
|
|||
else
|
||||
set_defaults ufile
|
||||
fi
|
||||
array_copy rules RULES
|
||||
for include in "${INCLUDES[@]}"; do
|
||||
if [ -f "$include" ]; then
|
||||
RULES=()
|
||||
source "$include"
|
||||
array_extend rules RULES
|
||||
else
|
||||
ewarn "$include: fichier introuvable"
|
||||
fi
|
||||
done
|
||||
array_copy RULES rules
|
||||
conf_load "$HOME/etc/ufile.d/*.conf"
|
||||
|
||||
## actions particulières
|
||||
|
||||
if [ "$action" == list ]; then
|
||||
echo "# $(echo_seta2 INCLUDES)"
|
||||
array_to_lines RULES
|
||||
exit 0
|
||||
elif [ "$action" == edit ]; then
|
||||
|
@ -180,7 +168,7 @@ else
|
|||
fi
|
||||
|
||||
[ $# -gt 0 ] || die "Vous devez spécifier des fichiers à classer"
|
||||
[ ${#RULES[*]} -gt 0 ] || die "Vous devez spécifier des règles pour le classement des fichiers dans ~/etc/default/ufile"
|
||||
[ ${#RULES[*]} -gt 0 ] || die "Vous devez spécifier des règles pour le classement des fichiers dans ~/etc/default/ufile ou ~/etc/ufile.d/*.conf"
|
||||
|
||||
# vérifier les règles
|
||||
for rule in "${RULES[@]}"; do
|
||||
|
|
Loading…
Reference in New Issue