##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 ## Affichage en couleur, et support de niveaux de "verbosité" et d'interaction ##@cooked nocomments ##@require base uprovide pretty urequire base ################################################################################ # Gestion des couleurs function __get_color() { [ -z "$*" ] && set RESET echo_ $'\e[' local sep while [ -n "$1" ]; do [ -n "$sep" ] && echo_ ";" case "$1" in z|RESET) echo_ "0";; o|BLACK) echo_ "30";; r|RED) echo_ "31";; g|GREEN) echo_ "32";; y|YELLOW) echo_ "33";; b|BLUE) echo_ "34";; m|MAGENTA) echo_ "35";; c|CYAN) echo_ "36";; w|WHITE) echo_ "37";; DEFAULT) echo_ "39";; O|BLACK_BG) echo_ "40";; R|RED_BG) echo_ "41";; G|GREEN_BG) echo_ "42";; Y|YELLOW_BG) echo_ "43";; B|BLUE_BG) echo_ "44";; M|MAGENTA_BG) echo_ "45";; C|CYAN_BG) echo_ "46";; W|WHITE_BG) echo_ "47";; DEFAULT_BG) echo_ "49";; @|BOLD) echo_ "1";; -|FAINT) echo_ "2";; _|UNDERLINED) echo_ "4";; ~|REVERSE) echo_ "7";; n|NORMAL) echo_ "22";; esac sep=1 shift done echo_ "m" } function get_color() { [ -n "$NO_COLORS" ] && return __get_color "$@" } function __set_no_colors() { if [ -z "$1" ]; then if [ -n "$UTOOLS_NO_COLORS" ]; then NO_COLORS=1 elif out_isatty && err_isatty; then NO_COLORS= else NO_COLORS=1 fi else is_yes "$1" && NO_COLORS=1 || NO_COLORS= fi COULEUR_ROUGE="$(get_color RED BOLD)" COULEUR_VERTE="$(get_color GREEN BOLD)" COULEUR_JAUNE="$(get_color YELLOW BOLD)" COULEUR_BLEUE="$(get_color BLUE BOLD)" COULEUR_BLANCHE="$(get_color WHITE BOLD)" COULEUR_NORMALE="$(get_color RESET)" } __set_no_colors function __eerror() { tooenc "$(__edate)${__tlevel}${COULEUR_ROUGE}* error:${COULEUR_NORMALE} $(__indent "$1")"; } function __ewarn() { tooenc "$(__edate)${__tlevel}${COULEUR_JAUNE}* warning:${COULEUR_NORMALE} $(__indent "$1")"; } function __enote() { tooenc "$(__edate)${__tlevel}${COULEUR_VERTE}* note:${COULEUR_NORMALE} $(__indent "$1")"; } function __ebanner() { local maxi="${COLUMNS:-80}" local -a lines local psfix line psfix="$(__edate)${__tlevel}" while [ ${#psfix} -lt $maxi ]; do psfix="$psfix="; done tooenc "$COULEUR_ROUGE$psfix" maxi=$(($maxi - 1)) array_from_xlines lines "$1" for line in "" "${lines[@]}" ""; do line="$(__edate)${__tlevel}= $line" if [ ${#line} -le $maxi ]; then while [ ${#line} -lt $maxi ]; do line="$line "; done line="$line=" fi tooenc "$line" done tooenc "$psfix$COULEUR_NORMALE" } function __eimportant() { tooenc "$(__edate)${__tlevel}${COULEUR_ROUGE}* important:${COULEUR_NORMALE} $(__indent "$1")"; } function __eattention() { tooenc "$(__edate)${__tlevel}${COULEUR_JAUNE}* attention:${COULEUR_NORMALE} $(__indent "$1")"; } function __einfo() { tooenc "$(__edate)${__tlevel}${COULEUR_BLEUE}* info:${COULEUR_NORMALE} $(__indent "$1")"; } function __edebug() { tooenc "$(__edate)${__tlevel}${COULEUR_BLANCHE}* debug:${COULEUR_NORMALE} $(__indent "$1")"; } function __estep() { tooenc "$(__edate)${__tlevel}${COULEUR_BLANCHE}*${COULEUR_NORMALE} $(__indent "$1")"; } function __estepe() { tooenc "$(__edate)${__tlevel}${COULEUR_ROUGE}*${COULEUR_NORMALE} $(__indent "$1")"; } function __estepw() { tooenc "$(__edate)${__tlevel}${COULEUR_JAUNE}*${COULEUR_NORMALE} $(__indent "$1")"; } function __estepn() { tooenc "$(__edate)${__tlevel}${COULEUR_VERTE}*${COULEUR_NORMALE} $(__indent "$1")"; } function __estepi() { tooenc "$(__edate)${__tlevel}${COULEUR_BLEUE}*${COULEUR_NORMALE} $(__indent "$1")"; } function __estep_() { tooenc_ "$(__edate)${__tlevel}${COULEUR_BLANCHE}*${COULEUR_NORMALE} $(__indent "$1")"; } function __estepe_() { tooenc_ "$(__edate)${__tlevel}${COULEUR_ROUGE}*${COULEUR_NORMALE} $(__indent "$1")"; } function __estepw_() { tooenc_ "$(__edate)${__tlevel}${COULEUR_JAUNE}*${COULEUR_NORMALE} $(__indent "$1")"; } function __estepn_() { tooenc_ "$(__edate)${__tlevel}${COULEUR_VERTE}*${COULEUR_NORMALE} $(__indent "$1")"; } function __estepi_() { tooenc_ "$(__edate)${__tlevel}${COULEUR_BLEUE}*${COULEUR_NORMALE} $(__indent "$1")"; } function __etitle() { tooenc "$(__edate)${__tlevel}${COULEUR_BLEUE}+++ $(get_color _)$(__indent "$1")${COULEUR_NORMALE}"; } function __ebegin() { tooenc_ "$(__edate)${__tlevel}${COULEUR_BLANCHE}*${COULEUR_NORMALE} $(__indent "$1"): "; } function __edoto() { echo_ "."; } function __edotw() { echo_ "${COULEUR_JAUNE}w${COULEUR_NORMALE}"; } function __edotx() { echo_ "${COULEUR_ROUGE}x${COULEUR_NORMALE}"; } function __edotp() { echo_ "${COULEUR_JAUNE}+${COULEUR_NORMALE}"; } function __edotd() { tooenc "($1)"; } function __eendo() { echo "${COULEUR_VERTE}[ok]${COULEUR_NORMALE}"; } function __eendx() { echo "${COULEUR_ROUGE}[error]${COULEUR_NORMALE}"; } # 5=afficher les messages de debug; 4=afficher les message verbeux; # 3=afficher les message informatifs; 2=afficher les warnings et les notes; # 1=afficher les erreurs; 0=ne rien afficher export __verbosity [ -z "$__verbosity" ] && __verbosity=3 function set_verbosity() { [ -z "$__verbosity" ] && __verbosity=3 case "$1" in -Q|--very-quiet) __verbosity=0;; -q|--quiet) [ "$__verbosity" -gt 0 ] && let __verbosity=$__verbosity-1;; -v|--verbose) [ "$__verbosity" -lt 5 ] && let __verbosity=$__verbosity+1;; -c|--default) __verbosity=3;; -D|--debug) __verbosity=5; DEBUG=1;; *) return 1;; esac return 0 } # 3=interaction maximale; 2=interaction par défaut # 1= interaction minimale; 0=pas d'interaction export __interaction [ -z "$__interaction" ] && __interaction=2 function set_interaction() { [ -z "$__interaction" ] && __interaction=2 case "$1" in -b|--batch) __interaction=0;; -y|--automatic) [ "$__interaction" -gt 0 ] && let __interaction=$__interaction-1;; -i|--interactive) [ "$__interaction" -lt 3 ] && let __interaction=$__interaction+1;; -c|--default) __interaction=2;; *) return 1;; esac return 0 } # Variable à inclure pour lancer automatiquement set_verbosity et # set_interaction en fonction des arguments de la ligne de commande. A utiliser # de cette manière: # parse_opts ... "${PRETTYOPTS[@]}" @ args -- ... PRETTYOPTS=( -L:,--log-to: '$elogto $value_' -Q,--very-quiet,-q,--quiet,-v,--verbose,-D,--debug '$set_verbosity $option_' -b,--batch,-y,--automatic,-i,--interactive '$set_interaction $option_' ) function show_error() { [ "$__verbosity" -ge 1 ]; } function show_warn() { [ "$__verbosity" -ge 2 ]; } function show_info() { [ "$__verbosity" -ge 3 ]; } function show_verbose() { [ "$__verbosity" -ge 4 ]; } function show_debug() { [ -n "$DEBUG" -o "$__verbosity" -ge 5 ]; } # Vérifier le niveau de verbosité actuel par rapport à l'argument. $1 peut valoir: # -Q retourner true si on peut afficher les messages d'erreur # -q retourner true si on peut afficher les messages d'avertissement # -c retourner true si on peut afficher les message normaux # -v retourner true si on peut afficher les messages verbeux # -D retourner true si on peut afficher les messages de debug function check_verbosity() { case "$1" in -Q|--very-quiet) [ "$__verbosity" -ge 1 ];; -q|--quiet) [ "$__verbosity" -ge 2 ];; -c|--default) [ "$__verbosity" -ge 3 ];; -v|--verbose) [ "$__verbosity" -ge 4 ];; -D|--debug) [ -n "$DEBUG" -o "$__verbosity" -ge 5 ];; *) return 0;; esac } # Retourner l'option correspondant au niveau de verbosité actuel function get_verbosity_option() { case "$__verbosity" in 0) echo --very-quiet;; 1) echo --quiet --quiet;; 2) echo --quiet;; 4) echo --verbose;; 5) echo --debug;; esac } # Vérifier le niveau d'interaction autorisé par rapport à l'argument. Par # exemple, 'check_interaction -y' signifie "Il ne faut interagir avec # l'utilisateur qu'à partir du niveau d'interaction -y. Suis-je dans les # condition voulues pour autoriser l'interaction?" # $1 peut valoir: # -b retourner true # -y retourner true si on est au moins en interaction minimale # -c retourner true si on est au moins en interaction normale # -i retourner true si on est au moins en interaction maximale function check_interaction() { case "$1" in -b|--batch) return 0;; -y|--automatic) [ -n "$__interaction" -a "$__interaction" -ge 1 ];; -c|--default) [ -n "$__interaction" -a "$__interaction" -ge 2 ];; -i|--interactive) [ -n "$__interaction" -a "$__interaction" -ge 3 ];; *) return 0;; esac } # Vérifier le niveau d'interaction dans lequel on se trouve actuellement. $1 # peut valoir: # -b retourner true si l'une des options -b ou -yy a été spécifiée # -Y retourner true si l'une des options -b, -yy, ou -y a été spécifiée # -y retourner true si l'option -y a été spécifiée # -c retourner true si aucune option n'a été spécifiée # -i retourner true si l'option -i a été spécifiée # -C retourner true si aucune option ou l'option -i ont été spécifiés function is_interaction() { case "$1" in -b|--batch) [ -n "$__interaction" -a "$__interaction" -eq 0 ];; -Y) [ -n "$__interaction" -a "$__interaction" -le 1 ];; -y|--automatic) [ -n "$__interaction" -a "$__interaction" -eq 1 ];; -c|--default) [ -n "$__interaction" -a "$__interaction" -eq 2 ];; -i|--interactive) [ -n "$__interaction" -a "$__interaction" -eq 3 ];; -C) [ -n "$__interaction" -a "$__interaction" -ge 2 ];; *) return 1;; esac } # Retourner l'option correspondant au niveau d'interaction actuel function get_interaction_option() { case "$__interaction" in 0) echo --batch;; 1) echo --automatic;; 3) echo --interactive;; esac } ##XXX les fonctions ci-dessous restent à migrer ##function edot() { ## # Une étape d'une opération commencée par ebegin, matérialisée par un "." ## # Si l'argument est un fichier, utiliser -f pour que "$HOME" et "$(pwd)/" ## # soient remplacés respectivement par "~" et "" (afin que les chemins soient ## # plus courts) ## # Si l'argument est un commentaire, utiliser -m pour le spécifier. -w ## # indique que l'argument est un warning: un x jaune est affiché, avec le ## # message associé si on est en mode debug. ## # Sinon, l'argument est un status. 0 affiche un ".", sinon on affiche un "x" ## local status=$? ## local warn= color= ## ## if [ -n "$utools_edot_first_" ]; then ## # au premier dot, afficher un espace d'abord ## echo_ " " ## utools_edot_first_= ## fi ## ## eval `check_verbosity --action "$1" 2` ## if is_debug; then ## local msg paths path ## if [ "$1" = "-f" ]; then ## # chemins ## shift ## for path in "$@"; do ## paths="${paths:+$paths,}$(ppath "$path")" ## done ## msg="$paths" ## elif [ "$1" = "-m" -o "$1" = "-w" ]; then ## # message ## [ "$1" = "-w" ] && warn=1 # message de warning ## shift ## msg="$(tooenc "$*")" ## else ## # status ## [ -n "$1" ] && status="$1" ## fi ## ## [ "$utools_ESTATUS_" -eq 0 -a "$status" -ne 0 ] && utools_ESTATUS_="$status" ## if [ "$status" -eq 0 -a -z "$warn" ]; then ## echo_ "${msg:+ ## }.${msg:+($msg)}" ## else ## color="$COULEUR_ROUGE" ## [ -n "$warn" ] && color="$COULEUR_JAUNE" ## echo_ "${msg:+ ## }${color}x${COULEUR_NORMALE}${msg:+($msg)}" ## fi ## else ## if [ "$1" = "-f" -o "$1" = "-m" -o "$1" = "-w" ]; then ## [ "$1" = "-w" ] && warn=1 # message de warning ## shift ## else ## [ -n "$1" ] && status="$1" ## fi ## ## [ "$utools_ESTATUS_" -eq 0 -a "$status" -ne 0 ] && utools_ESTATUS_="$status" ## if [ "$status" -eq 0 -a -z "$warn" ]; then ## echo_ "." ## else ## color="$COULEUR_ROUGE" ## [ -n "$warn" ] && color="$COULEUR_JAUNE" ## echo_ "${color}x${COULEUR_NORMALE}" ## fi ## fi ##}