Intégration de la branche ufile-named-rules

This commit is contained in:
Jephté Clain 2017-12-27 10:21:42 +04:00
commit bc4c8cbb81
4 changed files with 84 additions and 26 deletions

View File

@ -3,3 +3,6 @@
# Règles pour le classement des fichiers. Chaque règle est de la forme # Règles pour le classement des fichiers. Chaque règle est de la forme
# pattern:destdir[:renamef] # pattern:destdir[:renamef]
RULES=() RULES=()
# Règles nommées. Chaque règle est de la forme name:destdir[:renamef]
NRULES=()

View File

@ -106,7 +106,7 @@ function copy_update() {
fi fi
} }
COPY_UPDATE_ASK_DEFAULT=
function copy_update_ask() { function copy_update_ask() {
# Copier ou mettre à jour le fichier $1 vers le fichier $2. # 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 # Si le fichier existe déjà, la différence est affichée, et une confirmation
@ -128,7 +128,7 @@ function copy_update_ask() {
[ -f "$dest" ] || copy_replace "$src" "$dest" [ -f "$dest" ] || copy_replace "$src" "$dest"
if testdiff "$src" "$dest"; then if testdiff "$src" "$dest"; then
check_interaction "$interopt" && diff -u "$dest" "$src" check_interaction "$interopt" && diff -u "$dest" "$src"
if ask_yesno "$interopt" "Voulez-vous remplacer $(ppath "$dest") par la nouvelle version?" C; then if ask_yesno "$interopt" "Voulez-vous remplacer $(ppath "$dest") par la nouvelle version?" "${COPY_UPDATE_ASK_DEFAULT:-C}"; then
copy_replace "$src" "$dest" "$3" copy_replace "$src" "$dest" "$3"
return $? return $?
elif ! check_interaction "$interopt"; then elif ! check_interaction "$interopt"; then

View File

@ -239,6 +239,7 @@ function conf_load_files() {
done done
} }
CONF_INSTALL_ASK_DEFAULT=
function conf_install() { function conf_install() {
# USAGE: conf_install DEST PREFIX SRCS... # USAGE: conf_install DEST PREFIX SRCS...
# installer les fichiers de SRCS dans le répertoire standardisé DEST avec le # installer les fichiers de SRCS dans le répertoire standardisé DEST avec le
@ -278,6 +279,7 @@ function conf_install() {
fi fi
done done
[ ${#srcs[*]} -gt 0 ] || return 0 [ ${#srcs[*]} -gt 0 ] || return 0
local COPY_UPDATE_ASK_DEFAULT="${CONF_INSTALL_ASK_DEFAULT:-$COPY_UPDATE_ASK_DEFAULT}"
if [ -n "$prefix" ]; then if [ -n "$prefix" ]; then
if [ ${#srcs[*]} -eq 1 ]; then if [ ${#srcs[*]} -eq 1 ]; then
copy_update_ask -y "$src" "$dest/$prefix.conf" copy_update_ask -y "$src" "$dest/$prefix.conf"

101
ufile
View File

@ -8,17 +8,22 @@ function display_help() {
Les règles sont spécifiées dans le fichier ~/etc/default/ufile Les règles sont spécifiées dans le fichier ~/etc/default/ufile
Dans ce fichier, le tableau RULES contient des règles qui sont chacune de la Dans ce fichier, deux tableaux contiennent les règles applicables:
forme pattern:destdir[:renamef] * le tableau RULES contient des règles de la forme pattern:destdir[:renamef] et
permet de classer des fichiers correspondant à des patterns
* le tableau NRULES contient des règles de fle forme name:destdir[:renamef] et
permet de classer des fichiers quelconques en spécifiant la règle à utiliser
- pattern est au format glob et identifie les fichiers auxquels s'applique la Les champs sont:
* name est un nom quelconque, utilisé avec l'option --name
* pattern est au format glob et identifie les fichiers auxquels s'applique la
règle, sauf si la chaine commence par / auquel cas il s'agit d'une expression règle, sauf si la chaine commence par / auquel cas il s'agit d'une expression
régulière reconnue par awk. Par exemple, les deux patterns suivants sont régulière reconnue par awk. Par exemple, les deux patterns suivants sont
équivalents: équivalents:
[ab]cd*.pdf [ab]cd*.pdf
/[ab]cd.*\\\\.pdf\$ /[ab]cd.*\\\\.pdf\$
- destdir est le répertoire de destination dans lequel classer le fichier * 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 * 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ù 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 filename est le nom du fichier source, pf son chemin complet et destdir la
valeur de destdir mentionnée dans la règle. valeur de destdir mentionnée dans la règle.
@ -43,6 +48,14 @@ USAGE
$scriptname [options] <files...> $scriptname [options] <files...>
$scriptname [options] -r <files|dirs...> $scriptname [options] -r <files|dirs...>
ACTIONS
--file
Classer les fichiers spécifiés. C'est l'action par défaut
-l, --list
Lister les règles définies
-e, --edit
Lancer un éditeur sur le fichier de configuration
OPTIONS OPTIONS
-c, --config CONFIG -c, --config CONFIG
Utiliser le fichier de configuration spécifié au lieu de la valeur par Utiliser le fichier de configuration spécifié au lieu de la valeur par
@ -50,8 +63,16 @@ OPTIONS
-C, --other-configs -C, --other-configs
Charger les fichiers ~/etc/ufile.d/*.conf en plus du fichier spécifié Charger les fichiers ~/etc/ufile.d/*.conf en plus du fichier spécifié
avec --config. Cette option est ignorée si --config n'est pas utilisé. avec --config. Cette option est ignorée si --config n'est pas utilisé.
--file -j, --nrule NAME
Classer les fichiers spécifiés. C'est l'action par défaut Spécifier une règle du tableau NRULES à utiliser pour classer les
fichiers spécifiés. Cette option peut être spécifiée autant de fois que
nécessaire.
Par défaut, seul le tableau RULES est utilisé pour trouver la règle à
appliquer. Avec cette option, seul le tableau NRULES est utilisé.
-v, --var NAME=VALUE
Définir une variable qui sera utilisée par la fonction renamef. Cette
option peut être spécifiée autant de fois que nécessaire.
Les noms commençant par _ sont réservés et ne peuvent pas être définis.
--force-cp --force-cp
Spécifier le mode de classement des fichiers. Par défaut, le fichier est Spécifier le mode de classement des fichiers. Par défaut, le fichier est
déplacé dans la destination s'il s'agit d'un classement local, ou copié déplacé dans la destination s'il s'agit d'un classement local, ou copié
@ -71,11 +92,7 @@ OPTIONS
Classer récursivement tous les fichiers d'un répertoire. Sans cette Classer récursivement tous les fichiers d'un répertoire. Sans cette
option, il n'est pas autorisé de fournir un répertoire comme argument. option, il n'est pas autorisé de fournir un répertoire comme argument.
-n, --fake -n, --fake
Afficher les opérations qui seraient faites Afficher les opérations qui seraient faites"
-l, --list
Lister les règles définies
-e, --edit
Lancer un éditeur sur le fichier de configuration"
} }
function joinp() { function joinp() {
@ -123,11 +140,25 @@ function __set_dest() {
return 0 return 0
} }
function define_vars() {
local _name _value
for _name in "$@"; do
splitvar "$_name" _name _value
if [[ "$_name" == _* ]]; then
ewarn "$_name: cette variable ne peut être définie"
else
setv "$_name" "$_value"
fi
done
}
args=(% args=(%
--help '$exit_with display_help' --help '$exit_with display_help'
-c:,--config: config= -c:,--config: config=
-C,--other-configs other_configs=1 -C,--other-configs other_configs=1
--file action=file --file action=file
-j:,--nrule: _nrules
-v:,--var: _vars
--force-cp force_cp=1 --force-cp force_cp=1
-S:,--ssh: SSH= -S:,--ssh: SSH=
--force-scp force_scp=1 --force-scp force_scp=1
@ -143,7 +174,7 @@ parse_args "$@"; set -- "${args[@]}"
## charger toutes les règles ## charger toutes les règles
conf_init -a RULES conf_init -a RULES NRULES
if [ -n "$config" ]; then if [ -n "$config" ]; then
if [ "$action" != edit ]; then if [ "$action" != edit ]; then
# le fichier doit exister, sauf en mode édition où il sera créé s'il # le fichier doit exister, sauf en mode édition où il sera créé s'il
@ -162,7 +193,10 @@ fi
## actions particulières ## actions particulières
if [ "$action" == list ]; then if [ "$action" == list ]; then
echo "# RULES"
array_to_lines RULES array_to_lines RULES
echo "# NRULES"
array_to_lines NRULES
exit 0 exit 0
elif [ "$action" == edit ]; then elif [ "$action" == edit ]; then
[ -n "$config" ] || setx config=get_user_defaults_file ufile [ -n "$config" ] || setx config=get_user_defaults_file ufile
@ -185,11 +219,20 @@ else
function docmd() { "$@"; } function docmd() { "$@"; }
fi fi
if [ ${#_nrules[*]} -gt 0 ]; then
array_fix_paths _nrules ,
array_copy _rules NRULES
_nrule=1
else
array_copy _rules RULES
_nrule=
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 ~/etc/default/ufile ou ~/etc/ufile.d/*.conf" [ ${#_rules[*]} -gt 0 ] || die "Il faut définir des règles ${_nrule:+N}RULES dans ~/etc/default/ufile ou ~/etc/ufile.d/*.conf"
# vérifier les règles # vérifier les règles
for rule in "${RULES[@]}"; do for rule in "${_rules[@]}"; do
splitpair "$rule" pattern r2 splitpair "$rule" pattern r2
splitpair "$r2" destdir r3 splitpair "$r2" destdir r3
splitpair "$r3" renamef r4 splitpair "$r3" renamef r4
@ -201,15 +244,15 @@ for rule in "${RULES[@]}"; do
done done
# faire la liste des fichiers # faire la liste des fichiers
files=() _files=()
for file in "$@"; do for file in "$@"; do
if [ -d "$file" -a -n "$recursive" ]; then if [ -d "$file" -a -n "$recursive" ]; then
setx file=abspath "$file" setx file=abspath "$file"
array_from_lines rfiles "$(find "$file" -type f)" array_from_lines rfiles "$(find "$file" -type f)"
array_extendu files rfiles array_extendu _files rfiles
elif [ -f "$file" ]; then elif [ -f "$file" ]; then
setx file=abspath "$file" setx file=abspath "$file"
array_addu files "$file" array_addu _files "$file"
elif [ -n "$fake" ]; then elif [ -n "$fake" ]; then
: # on est en mode fake, pas grave si le fichier n'est pas trouvé : # on est en mode fake, pas grave si le fichier n'est pas trouvé
elif [ -d "$file" ]; then elif [ -d "$file" ]; then
@ -221,12 +264,12 @@ done
# faire le classement effectif # faire le classement effectif
r= r=
for file in "${files[@]}"; do for file in "${_files[@]}"; do
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
splitpair "$r2" odestdir r3 splitpair "$r2" odestdir r3
splitpair "$r3" renamef r4 splitpair "$r3" renamef r4
@ -236,16 +279,26 @@ for file in "${files[@]}"; do
odestdir="$HOME" odestdir="$HOME"
fi fi
if [ "${pattern#/}" != "$pattern" ]; then if [ -n "$_nrule" ]; then
awk -v filename="$filename" -v pattern="${pattern#/}" 'BEGIN { exit(filename ~ pattern? 0: 1) }' || continue array_contains _nrules "$pattern" || continue
else else
eval "[[ \"\$filename\" == $(qwc "$pattern") ]]" || continue if [ "${pattern#/}" != "$pattern" ]; then
awk -v filename="$filename" -v pattern="${pattern#/}" 'BEGIN { exit(filename ~ pattern? 0: 1) }' || continue
else
eval "[[ \"\$filename\" == $(qwc "$pattern") ]]" || continue
fi
fi fi
unset dest unset dest
interaction=--DEFAULT-- interaction=--DEFAULT--
if [ -n "$renamef" ]; then if [ -n "$renamef" ]; then
"$renamef" "$filename" "$pf" "$odestdir" || continue # protéger les variables nécessaires au lancement de renamef
_renamef="$renamef"
_filename="$filename"
_pf="$pf"
_odestdir="$odestdir"
define_vars "${_vars[@]}"
"$_renamef" "$_filename" "$_pf" "$_odestdir" || continue
fi fi
if is_array dest; then if is_array dest; then
array_copy tmpdests dest array_copy tmpdests dest