commit: eb36c3077fd69b7cbc5ef64c68d42baff50b3d43 Author: Kerin Millar <kfm <AT> plushkava <DOT> net> AuthorDate: Wed Feb 15 07:02:48 2023 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Wed Feb 15 07:32:45 2023 +0000 URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=eb36c307
Implement proper TTY detection, once and for all Following a litany of ill-considered bodges and hacks over the years, it is high time that the matter of tty detection was conclusively dealt with. This commit aims to accomplish exactly that, in a fashion that can be described twofold. Firstly, the recently introduced _eprint() function will now test whether STDOUT is a tty at the time of invocation. If found to be a tty, ECMA-48 SGR sequences shall be incorporated into the message. Otherwise, they shall not be. This positively affects the following functions. - ebegin - einfo - einfon - eerror - eerrorn - ewarnn - ewarn - vebegin - veinfo - veinfon - veerror - veerrorn - vewarnn - vewarn Note that the *eerror* and *ewarn* functions duplicate file descriptor 2 (STDERR) to file descriptor 1 (STDOUT), meaning that the -t 1 test will always be in the context of the appropriate file descriptor. Secondly, the _eend() function will now test whether STDOUT is a tty at the time of invocation. Just as with _eprint(), ECMA-48 SGR sequences will be omitted in the case that STDOUT is found not to be a tty However, the fact that _eend() prints a so-called end column must also be taken into account. The end column string is not defined by this function, but may or may not incorporate ECMA-48 CSI sequences that are intended to move the cursor up - and to the end of - the previous line. Previously, _eend() would always use the end column if was found to be non-empty, despite containing such sequences. Now, it will refrain from printing the end column where STDOUT is not a tty. Instead, it will fall back to the method of printing the success/failure indicator on the current line. Furthemore, if the fallback method is used under these exact circumstances, the number of available columns will be assumed as being 80 for the scope of the function call. After all, the width of the controlling terminal is wholly immaterial unless printing to it. This positively affects the following functions. - eend - ewend - veend - vewend Consequently, all eighteen of the aformentioned functions will act properly, in accordance with the state of both STDOUT and STDERR, at the time that they are called. As such, the truly repulsive hack that was to permanently disable colour if _either_ were found not to be a tty at the time of sourcing functions.sh has been jettisoned. Good riddance. Signed-off-by: Kerin Millar <kfm <AT> plushkava.net> Bug: https://bugs.gentoo.org/631870 Signed-off-by: Sam James <sam <AT> gentoo.org> functions.sh | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/functions.sh b/functions.sh index 151775f..a0422b6 100644 --- a/functions.sh +++ b/functions.sh @@ -16,7 +16,11 @@ _eprint() { if [ -z "${genfun_endcol}" ] && [ "${genfun_lastcall}" = "ebegin" ]; then printf '\n' fi - printf ' %s*%s %s%b' "${color}" "${NORMAL}" "${genfun_indent}" "$*" + if [ -t 1 ]; then + printf ' %s*%s %s%b' "${color}" "${NORMAL}" "${genfun_indent}" "$*" + else + printf ' * %s%b' "${genfun_indent}" "$*" + fi } # @@ -202,7 +206,7 @@ ebegin() # _eend() { - local efunc msg retval + local cols efunc is_tty msg retval efunc=$1 shift @@ -217,22 +221,44 @@ _eend() shift fi + if [ -t 1 ]; then + is_tty=1 + cols=${genfun_cols} + else + # STDOUT is not currently a TTY. Therefore, the width of the + # controlling terminal, if any, is irrelevant. For this call, + # consider the number of columns as being 80. + is_tty=0 + cols=80 + fi + if [ "${retval}" -ne 0 ]; then + # If a message was given, print it with the specified function. if _is_visible "$*"; then "${efunc}" "$*" fi - msg="${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}" + # Generate an indicator for ebegin's unsuccessful conclusion. + if [ "${is_tty}" -eq 0 ]; then + msg="[ !! ]" + else + msg="${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}" + fi elif yesno "${EINFO_QUIET}"; then return "${retval}" else - msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}" + # Generate an indicator for ebegin's successful conclusion. + if [ "${is_tty}" -eq 0 ]; then + msg="[ ok ]" + else + msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}" + fi fi - if [ -n "${genfun_endcol}" ]; then + if [ "${is_tty}" -eq 1 ] && [ -n "${genfun_endcol}" ]; then printf '%s %s\n' "${genfun_endcol}" "${msg}" else [ "${genfun_lastcall}" = ebegin ] || genfun_lastbegun_strlen=0 - printf "%$(( genfun_cols - genfun_lastbegun_strlen - 6 ))s%s\n" '' "${msg}" + printf "%$(( cols - genfun_lastbegun_strlen - 6 ))s%s\n" '' "${msg}" fi return "${retval}" @@ -452,15 +478,6 @@ unset -v genfun_endcol # Set the initial value for e-message indentation. genfun_indent= -# If either STDOUT or STDERR is not a tty, disable coloured output. A useful -# improvement for the future would be to have the individual logging functions -# act as they should. For example, ewarn prints to STDOUT whereas eerror prints -# to STDERR. For now, this is a reasonable compromise. -if [ ! -t 1 ] || [ ! -t 2 ]; then - RC_NOCOLOR="yes" - genfun_endcol= -fi - for arg in "$@" ; do case "${arg}" in # Lastly check if the user disabled it with --nocolor argument