test-lib.sh: fix color support when tput needs ~/.terminfo

If tput needs ~/.terminfo for the current $TERM, then tput will succeed before HOME is changed to $TRASH_DIRECTORY (causing color to be set to 't') but fail afterward. One possible way to fix this is to treat HOME like TERM: back up the original value and temporarily restore it before say_color() runs tput. Instead, pre-compute and save the color control sequences before changing either TERM or HOME. Use the saved control sequences in say_color() rather than call tput each time. This avoids the need to back up and restore the TERM and HOME variables, and it avoids the overhead of a subshell and two invocations of tput per call to say_color(). Signed-off-by: Richard Hansen <rhansen@bbn.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Richard Hansen committed Jun 17, 2015 at 17:11 UTC d5c1b7c286b2ad2206afe2f86ae228744bd283fb
1 file changed +28 -29
t/test-lib.sh
+28 -29
@@ -15,9 +15,6 @@
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see http://www.gnu.org/licenses/ .
17
18 -# Keep the original TERM for say_color
19 -ORIGINAL_TERM=$TERM
20 -
18 # Test the binaries we have just built. The tests are kept in
19 # t/ subdirectory and are run in 'trash directory' subdirectory.
20 if test -z "$TEST_DIRECTORY"
@@ -68,12 +65,12 @@ done,*)
65 esac
66
67 # For repeatability, reset the environment to known value.
68 +# TERM is sanitized below, after saving color control sequences.
69 LANG=C
70 LC_ALL=C
71 PAGER=cat
72 TZ=UTC
75 -TERM=dumb
76 -export LANG LC_ALL PAGER TERM TZ
73 +export LANG LC_ALL PAGER TZ
74 EDITOR=:
75 # A call to "unset" with no arguments causes at least Solaris 10
76 # /usr/xpg4/bin/sh and /bin/ksh to bail out. So keep the unsets
@@ -184,9 +181,7 @@ export _x05 _x40 _z40 LF u200c
181 # This test checks if command xyzzy does the right thing...
182 # '
183 # . ./test-lib.sh
187 -test "x$ORIGINAL_TERM" != "xdumb" && (
188 - TERM=$ORIGINAL_TERM &&
189 - export TERM &&
184 +test "x$TERM" != "xdumb" && (
185 test -t 1 &&
186 tput bold >/dev/null 2>&1 &&
187 tput setaf 1 >/dev/null 2>&1 &&
@@ -260,29 +255,30 @@ fi
255
256 if test -n "$color"
257 then
258 + # Save the color control sequences now rather than run tput
259 + # each time say_color() is called. This is done for two
260 + # reasons:
261 + # * TERM will be changed to dumb
262 + # * HOME will be changed to a temporary directory and tput
263 + # might need to read ~/.terminfo from the original HOME
264 + # directory to get the control sequences
265 + # Note: This approach assumes the control sequences don't end
266 + # in a newline for any terminal of interest (command
267 + # substitutions strip trailing newlines). Given that most
268 + # (all?) terminals in common use are related to ECMA-48, this
269 + # shouldn't be a problem.
270 + say_color_error=$(tput bold; tput setaf 1) # bold red
271 + say_color_skip=$(tput setaf 4) # blue
272 + say_color_warn=$(tput setaf 3) # brown/yellow
273 + say_color_pass=$(tput setaf 2) # green
274 + say_color_info=$(tput setaf 6) # cyan
275 + say_color_reset=$(tput sgr0)
276 + say_color_="" # no formatting for normal text
277 say_color () {
264 - (
265 - TERM=$ORIGINAL_TERM
266 - export TERM
267 - case "$1" in
268 - error)
269 - tput bold; tput setaf 1;; # bold red
270 - skip)
271 - tput setaf 4;; # blue
272 - warn)
273 - tput setaf 3;; # brown/yellow
274 - pass)
275 - tput setaf 2;; # green
276 - info)
277 - tput setaf 6;; # cyan
278 - *)
279 - test -n "$quiet" && return;;
280 - esac
278 + test -z "$1" && test -n "$quiet" && return
279 + eval "say_color_color=\$say_color_$1"
280 shift
282 - printf "%s" "$*"
283 - tput sgr0
284 - echo
285 - )
281 + printf "%s\\n" "$say_color_color$*$say_color_reset"
282 }
283 else
284 say_color() {
@@ -292,6 +288,9 @@ else
288 }
289 fi
290
291 +TERM=dumb
292 +export TERM
293 +
294 error () {
295 say_color error "error: $*"
296 GIT_EXIT_OK=t