ufile: support des inclusions, d'un fichier de configuration alternatif

This commit is contained in:
Jephté Clain 2017-04-22 09:49:25 +04:00
parent d535df3629
commit c82c90840e
2 changed files with 116 additions and 40 deletions

View File

@ -1,12 +1,9 @@
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
# règles pour le classement des fichiers. chaque règle est de la forme # 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] # pattern:destdir[:renamef]
# renamef est une fonction qui permet de supporter le renommage d'un fichier
# lors de son classement. Sa signature est 'renamef filename pf destdir' où
# filename est le nom du fichier source, pf son chemin complet et destdir la
# valeur de destdir mentionnée dans la règle. La fonction doit définir la
# variable newname qui est le nouveau nom. Si le nouveau nom contient un chemin,
# destdir est ignoré et le fichier est déplacé dans le répertoire spécifié. Si
# la fonction retourne un code d'erreur autre que zéro, la règle est ignorée.
RULES=() RULES=()

143
ufile
View File

@ -2,28 +2,53 @@
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 # -*- 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 source "$(dirname "$0")/lib/ulib/ulib" || exit 1
urequire DEFAULTS urequire DEFAULTS
set_defaults ufile
function display_help() { function display_help() {
uecho "$scriptname: classer des fichiers selon certains règles uecho "$scriptname: classer des fichiers selon certains règles
Les règles sont dans le fichier ~/etc/default/ufile Les règles sont spécifiées dans le fichier ~/etc/default/ufile
Consulter ce fichier pour les détails
Dans ce fichier, le tableau RULES contient des règles qui sont chacune de la
forme pattern:destdir[:renamef]
- pattern est au format glob et identifie les fichiers auxquels s'applique la
règle
- destdir est le répertoire de destination dans lequel classer le fichier
- renamef est une fonction qui permet de supporter le renommage d'un fichier
lors de son classement. Sa signature est 'renamef filename pf destdir' où
filename est le nom du fichier source, pf son chemin complet et destdir la
valeur de destdir mentionnée dans la règle.
La fonction doit définir la variable dest qui est le nouveau nom. Si la
fonction retourne un code d'erreur autre que zéro, la règle est ignorée.
Si le nouveau nom contient un chemin, destdir est ignoré et le fichier est
déplacé dans le répertoire spécifié.
USAGE USAGE
$scriptname [options] <files...> $scriptname [options] <files...>
OPTIONS OPTIONS
-c, --config CONFIG
Utiliser le fichier de configuration spécifié au lieu de la valeur par
défaut ~/etc/default/ufile
-n, --fake -n, --fake
Afficher les opérations qui seraient faites Afficher les opérations qui seraient faites
-l, --list -l, --list
Lister les règles définies Lister les règles définies
-e, --edit -e, --edit
Lancer un éditeur pour mettre à jour les règles" Lancer un éditeur sur le fichier de configuration"
}
function joinp() {
# afficher le chemin $1/$2
local pf="$1"
[ -n "$2" -a "${pf%/}" == "$pf" ] && pf="$pf/"
pf="$pf${2#/}"
echo "$pf"
} }
args=(% args=(%
--help '$exit_with display_help' --help '$exit_with display_help'
-c:,--config: config=
-n,--fake fake=1 -n,--fake fake=1
-l,--list action=list -l,--list action=list
-e,--edit action=edit -e,--edit action=edit
@ -33,21 +58,54 @@ parse_args "$@"; set -- "${args[@]}"
[ -n "$action" ] || action=file [ -n "$action" ] || action=file
## charger toutes les règles
RULES=()
INCLUDES=()
if [ -n "$config" ]; then
if [ "$action" != edit ]; then
# le fichier doit exister, sauf en mode édition où il sera créé s'il
# n'existe pas déjà
[ -f "$config" ] || die "$config: fichier introuvable"
fi
if [ -f "$config" ]; then
source "$config" || die "$config: erreur lors de la lecture du fichier"
fi
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
## actions particulières
if [ "$action" == list ]; then if [ "$action" == list ]; then
echo "# $(echo_seta2 INCLUDES)"
array_to_lines RULES array_to_lines RULES
exit 0 exit 0
elif [ "$action" == edit ]; then elif [ "$action" == edit ]; then
setx ufile=get_user_defaults_file ufile [ -n "$config" ] || setx config=get_user_defaults_file ufile
if [ ! -f "$ufile" ]; then if [ ! -f "$config" ]; then
einfo "Le fichier $(ppath "$ufile") n'existe pas. Il sera créé avec un contenu par défaut" einfo "Le fichier $(ppath "$config") n'existe pas. Il sera créé avec un contenu par défaut"
mkdirof "$ufile" || die mkdirof "$config" || die
cp "$scriptdir/lib/defaults/ufile" "$ufile" cp "$scriptdir/lib/default/ufile" "$config"
fi fi
"${EDITOR:-vi}" "$ufile" "${EDITOR:-vi}" "$config"
exit $? exit $?
else
die "bug: $action: action non implémentée"
fi fi
[ "$action" == file ] || die "bug: $action: action non implémentée" ## classement des fichiers
if [ -n "$fake" ]; then if [ -n "$fake" ]; then
function docmd() { qvals "$@"; } function docmd() { qvals "$@"; }
@ -56,16 +114,29 @@ else
fi fi
[ $# -gt 0 ] || die "Vous devez spécifier des fichiers à classer" [ $# -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 ~/default/ufile" [ ${#RULES[*]} -gt 0 ] || die "Vous devez spécifier des règles pour le classement des fichiers dans ~/etc/default/ufile"
# vérifier les règles
for rule in "${RULES[@]}"; do
splitpair "$rule" pattern r2
splitpair "$r2" destdir r3
splitpair "$r3" renamef r4
if [ -z "$destdir" -o "${destdir#"~/"}" != "$destdir" ]; then
:
elif [ "${destdir#/}" == "$destdir" ]; then
ewarn "$rule: règle potentiellement problématique: destdir devrait être absolu"
fi
done
# faire le classement effectif
for file in "$@"; do for file in "$@"; do
[ -f "$file" -o -n "$fake" ] || { [ -f "$file" -o -n "$fake" ] || {
eerror "$file: fichier introuvable. il sera ignoré" eerror "$file: fichier introuvable. il sera ignoré"
continue continue
} }
setx pf=abspath "$file" setx pf=abspath "$file"
setx dir=dirname "$pf" setx dir=dirname -- "$pf"
setx filename=basename "$pf" setx filename=basename -- "$pf"
found= found=
for rule in "${RULES[@]}"; do for rule in "${RULES[@]}"; do
splitpair "$rule" pattern r2 splitpair "$rule" pattern r2
@ -73,30 +144,38 @@ for file in "$@"; do
splitpair "$r3" renamef r4 splitpair "$r3" renamef r4
if [ "${destdir#"~/"}" != "$destdir" ]; then if [ "${destdir#"~/"}" != "$destdir" ]; then
destdir="$HOME/${destdir#"~/"}" destdir="$HOME/${destdir#"~/"}"
elif [ "${destdir#/}" == "$destdir" ]; then
die "règle '$rule' invalide: destdir doit être absolu"
fi fi
if eval "[[ \"\$filename\" == $(qwc "$pattern") ]]"; then
if [ -n "$renamef" ]; then eval "[[ \"\$filename\" == $(qwc "$pattern") ]]" || continue
newname=
"$renamef" "$filename" "$pf" "$destdir" || continue destname="$filename"
if [ -z "$newname" ]; then if [ -n "$renamef" ]; then
destname="$filename" dest=
elif [[ "$newname" == */* ]]; then "$renamef" "$filename" "$pf" "$destdir" || continue
splitpath "$newname" destdir destname if [ -n "$dest" ]; then
if [[ "$dest" == */* ]]; then
setx dest=abspath "$dest"
setx destdir=dirname -- "$dest"
setx destname=dirname -- "$dest"
else else
destname="$newname" destname="$dest"
fi fi
else
destname="$filename"
fi fi
estep "$filename --> $destdir/$destname" fi
ask_yesno -i "Voulez-vous continuer?" O || { found=x; break; }
docmd mkdir -p "$destdir" || die "$destdir: impossible de créer le répertoire" if [ -z "$destdir" ]; then
docmd mv -i "$file" "$destdir/$destname" || die "problème lors du déplacement du fichier" eerror "$rule: règle invalide: destdir est vide"
found=1
break break
fi fi
setx dest=joinp "$destdir" "$destname"
estep "$filename --> $dest"
ask_yesno -i "Voulez-vous continuer?" O || { found=x; break; }
docmd mkdir -p "$destdir" || die "$destdir: impossible de créer le répertoire"
docmd mv -i "$file" "$dest" || die "problème lors du déplacement du fichier"
found=1
break
done done
if [ -z "$found" ]; then if [ -z "$found" ]; then
ewarn "$file: aucune correspondance n'a été trouvée" ewarn "$file: aucune correspondance n'a été trouvée"