support automatique options verbosity et interaction

This commit is contained in:
Jephté Clain 2025-03-03 08:09:58 +04:00
parent 882549375c
commit ead5b5adcf
2 changed files with 111 additions and 37 deletions

View File

@ -124,8 +124,8 @@ optdesc
commence par ++, c'est une option avancée qui n'est pas affichée par défaut." commence par ++, c'est une option avancée qui n'est pas affichée par défaut."
function parse_args() { function parse_args() {
eval "$NULIB__DISABLE_SET_X" eval "$NULIB__DISABLE_SET_X"
[ -n "$NULIB_ARGS_ONERROR_RETURN" ] && set_die_return
local __r= local __r=
local __DIE='[ -n "$NULIB_ARGS_ONERROR_RETURN" ] && return 1 || die'
if ! is_array args; then if ! is_array args; then
eerror "Invalid args definition: args must be defined" eerror "Invalid args definition: args must be defined"
@ -145,17 +145,33 @@ function parse_args() {
__r=1 __r=1
else else
__DEFS=("$@") __DEFS=("$@")
__parse_args || __r=1 __nulib_args_parse_args || __r=1
fi fi
eval "$NULIB__ENABLE_SET_X" eval "$NULIB__ENABLE_SET_X"
if [ -n "$__r" ]; then if [ -n "$__r" ]; then
eval "$__DIE" die || return
fi fi
} }
function __parse_args() { function __nulib_args_add_sopt() {
local noauto="$1"; shift
local def
for def in "$@"; do
array_contains "$noauto" "$def" || __sopts="$__sopts$def"
done
}
function __nulib_args_add_lopt() {
local noauto="$1"; shift
local def
for def in "$@"; do
array_contains "$noauto" "$def" || __lopts="$__lopts${__lopts:+,}$def"
done
}
function __nulib_args_parse_args() {
## tout d'abord, construire la liste des options ## tout d'abord, construire la liste des options
local __AUTOH=1 __AUTOHELP=1 # faut-il gérer automatiquement l'affichage de l'aide? local __AUTOH=1 __AUTOHELP=1 # faut-il gérer automatiquement l'affichage de l'aide?
local __AUTOD=1 __AUTODEBUG=1 # faut-il rajouter les options -D et --debug local -a __NOAUTOL __NOAUTOLOGTO # faut-il rajouter les options pour gérer la journalisation?
local -a __NOAUTOV __NOAUTOVERBOSITY # options de verbosité qui ont été définies par l'utilisateur
local -a __NOAUTOI __NOAUTOINTERACTION # options d'interaction qui ont été définies par l'utilisateur
local __ADVHELP # y a-t-il des options avancées? local __ADVHELP # y a-t-il des options avancées?
local __popt __sopts __lopts local __popt __sopts __lopts
local -a __defs local -a __defs
@ -165,10 +181,10 @@ function __parse_args() {
+) __popt="$1"; shift; continue;; +) __popt="$1"; shift; continue;;
-) __popt="$1"; shift; continue;; -) __popt="$1"; shift; continue;;
-*) IFS=, read -a __defs <<<"$1"; shift;; -*) IFS=, read -a __defs <<<"$1"; shift;;
*) eerror "Invalid arg definition: expected option, got '$1'"; eval "$__DIE";; *) die "Invalid arg definition: expected option, got '$1'" || return;;
esac esac
# est-ce que l'option prend un argument? # est-ce que l'option prend un argument?
local __def __witharg __valdesc local __def __longdef __witharg __valdesc
__witharg= __witharg=
for __def in "${__defs[@]}"; do for __def in "${__defs[@]}"; do
if [ "${__def%::*}" != "$__def" ]; then if [ "${__def%::*}" != "$__def" ]; then
@ -180,23 +196,36 @@ function __parse_args() {
# définitions __sopts et __lopts # définitions __sopts et __lopts
for __def in "${__defs[@]}"; do for __def in "${__defs[@]}"; do
__def="${__def%%:*}" __def="${__def%%:*}"
__longdef=
if [[ "$__def" == --* ]]; then if [[ "$__def" == --* ]]; then
# --longopt # --longopt
__def="${__def#--}" __def="${__def#--}"
__lopts="$__lopts${__lopts:+,}$__def$__witharg" __lopts="$__lopts${__lopts:+,}$__def$__witharg"
__longdef=1
elif [[ "$__def" == -* ]] && [ ${#__def} -eq 2 ]; then elif [[ "$__def" == -* ]] && [ ${#__def} -eq 2 ]; then
# -o # -o
__def="${__def#-}" __def="${__def#-}"
__sopts="$__sopts$__def$__witharg" __sopts="$__sopts$__def$__witharg"
[ "$__def" == h ] && __AUTOH= case "$__def" in
[ "$__def" == D ] && __AUTOD= h) __AUTOH=;;
L) __NOAUTOL+=("-$__def");;
Q|q|v|D) __NOAUTOV+=("-$__def");;
b|y|i) __NOAUTOI+=("-$__def");;
esac
else else
# -longopt ou longopt # -longopt ou longopt
__def="${__def#-}" __def="${__def#-}"
__lopts="$__lopts${__lopts:+,}$__def$__witharg" __lopts="$__lopts${__lopts:+,}$__def$__witharg"
__longdef=1
fi
if [ -n "$__longdef" ]; then
case "$__def" in
help|help++) __AUTOHELP=;;
log-to) __NOAUTOLOGTO+=("--$__def");;
very-quiet|quiet|verbose|debug) __NOAUTOVERBOSITY+=("--$__def");;
batch|automatic|interactive) __NOAUTOINTERACTION+=("--$__def");;
esac
fi fi
[ "$__def" == help -o "$__def" == help++ ] && __AUTOHELP=
[ "$__def" == debug ] && __AUTODEBUG=
done done
# sauter l'action # sauter l'action
shift shift
@ -209,8 +238,12 @@ function __parse_args() {
[ -n "$__AUTOH" ] && __sopts="${__sopts}h" [ -n "$__AUTOH" ] && __sopts="${__sopts}h"
[ -n "$__AUTOHELP" ] && __lopts="$__lopts${__lopts:+,}help,help++" [ -n "$__AUTOHELP" ] && __lopts="$__lopts${__lopts:+,}help,help++"
[ -n "$__AUTOD" ] && __sopts="${__sopts}D" __nulib_args_add_sopt __NOAUTOL L
[ -n "$__AUTODEBUG" ] && __lopts="$__lopts${__lopts:+,}debug" __nulib_args_add_lopt __NOAUTOLOGTO log-to
__nulib_args_add_sopt __NOAUTOV Q q v D
__nulib_args_add_lopt __NOAUTOVERBOSITY very-quiet quiet verbose debug
__nulib_args_add_sopt __NOAUTOI b y i
__nulib_args_add_lopt __NOAUTOINTERACTION batch automatic interactive
__sopts="$__popt$__sopts" __sopts="$__popt$__sopts"
local -a __getopt_args local -a __getopt_args
@ -222,7 +255,7 @@ function __parse_args() {
else else
# relancer pour avoir le message d'erreur # relancer pour avoir le message d'erreur
LANG=C getopt "${__getopt_args[@]}" 2>&1 1>/dev/null LANG=C getopt "${__getopt_args[@]}" 2>&1 1>/dev/null
eval "$__DIE" die || return
fi fi
## puis traiter les options ## puis traiter les options
@ -373,7 +406,7 @@ $prefix$usage"
fi fi
[[ "$1" == -* ]] || break [[ "$1" == -* ]] || break
option_="$1"; shift option_="$1"; shift
__parse_opt "$option_" __nulib_args_parse_opt "$option_"
if [ -n "$__witharg" ]; then if [ -n "$__witharg" ]; then
# l'option prend un argument # l'option prend un argument
value_="$1"; shift value_="$1"; shift
@ -387,7 +420,7 @@ $prefix$usage"
unset -f inc@ res@ add@ set@ showhelp@ unset -f inc@ res@ add@ set@ showhelp@
args=("$@") args=("$@")
} }
function __parse_opt() { function __nulib_args_parse_opt() {
# $1 est l'option spécifiée # $1 est l'option spécifiée
local option_="$1" local option_="$1"
set -- "${__DEFS[@]}" set -- "${__DEFS[@]}"
@ -460,27 +493,62 @@ function __parse_opt() {
[ -n "$__found" ] && return 0 [ -n "$__found" ] && return 0
done done
if [ -n "$__AUTOH" -a "$option_" == -h ]; then case "$option_" in
__action="showhelp@" -h)
return 0 if [ -n "$__AUTOH" ]; then
fi __action='showhelp@'
if [ -n "$__AUTOHELP" ]; then
if [ "$option_" == --help ]; then
__action="showhelp@"
return 0
elif [ "$option_" == --help++ ]; then
__action="showhelp@ ++"
return 0 return 0
fi fi
fi ;;
if [ -n "$__AUTOD" -a "$option_" == -D ]; then --help)
__action=set_debug if [ -n "$__AUTOHELP" ]; then
return 0 __action='showhelp@'
fi return 0
if [ -n "$__AUTODEBUG" -a "$option_" == --debug ]; then fi
__action=set_debug ;;
return 0 --help++)
fi if [ -n "$__AUTOHELP" ]; then
__action='showhelp@ ++'
return 0
fi
;;
-L)
if ! array_contains __NOAUTOL "$option_"; then
__action='elogto $value_'
return 0
fi
;;
--log-to)
if ! array_contains __NOAUTOL "$option_"; then
__action='elogto $value_'
return 0
fi
;;
-Q|-q|-v|-D)
if ! array_contains __NOAUTOV "$option_"; then
__action='set_verbosity $option_'
return 0
fi
;;
--very-quiet|--quiet|--verbose|--debug)
if ! array_contains __NOAUTOVERBOSITY "$option_"; then
__action='set_verbosity $option_'
return 0
fi
;;
-b|-y|-i)
if ! array_contains __NOAUTOI "$option_"; then
__action='set_interaction $option_'
return 0
fi
;;
--batch|--automatic|--interactive)
if ! array_contains __NOAUTOINTERACTION "$option_"; then
__action='set_interaction $option_'
return 0
fi
;;
esac
# ici, l'option n'a pas été trouvée, on ne devrait pas arriver ici # ici, l'option n'a pas été trouvée, on ne devrait pas arriver ici
eerror "Unexpected option '$option_'"; eval "$__DIE" die "Unexpected option '$option_'" || return
} }

View File

@ -108,11 +108,17 @@ function set_interaction() {
# set_interaction en fonction des arguments de la ligne de commande. A utiliser # set_interaction en fonction des arguments de la ligne de commande. A utiliser
# de cette manière: # de cette manière:
# parse_opts ... "${PRETTYOPTS[@]}" @ args -- ... # parse_opts ... "${PRETTYOPTS[@]}" @ args -- ...
PRETTYOPTS=( # NB: ce n'est pas nécessaire, sauf si on veut afficher ces options dans l'aide
LOGTOOPTS=(
-L:,--log-to:LOGFILE '$elogto $value_' "++enregistrer les messages dans le fichier spécifié" -L:,--log-to:LOGFILE '$elogto $value_' "++enregistrer les messages dans le fichier spécifié"
)
VERBOSITYOPTS=(
-Q,--very-quiet,-q,--quiet,-v,--verbose,-D,--debug '$set_verbosity $option_' "++spécifier le niveau de verbiage" -Q,--very-quiet,-q,--quiet,-v,--verbose,-D,--debug '$set_verbosity $option_' "++spécifier le niveau de verbiage"
)
INTERACTIONOPTS=(
-b,--batch,-y,--automatic,-i,--interactive '$set_interaction $option_' "++spécifier le niveau d'interaction" -b,--batch,-y,--automatic,-i,--interactive '$set_interaction $option_' "++spécifier le niveau d'interaction"
) )
PRETTYOPTS=("${LOGTOOPTS[@]}" "${VERBOSITYOPTS[@]}" "${INTERACTIONOPTS[@]}")
function show_error() { [ "$__verbosity" -ge 1 ]; } function show_error() { [ "$__verbosity" -ge 1 ]; }
function show_warn() { [ "$__verbosity" -ge 2 ]; } function show_warn() { [ "$__verbosity" -ge 2 ]; }