git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 2/3] Windows: a test_cmp that is agnostic to random LF <> CRLF conversions

From
Johannes Sixt <j6t@kdbg.org>
Date
Oct 26, 2013, 19:17 UTC
Message-ID
<e64878fec3f026802e8d3958a1e6213428cab778.1382814437.git.j6t@kdbg.org>
In-Reply-To
<cover.1382814437.git.j6t@kdbg.org>

In a number of tests, output that was produced by a shell script is compared to expected output using test_cmp. Unfortunately, the MSYS bash-- when invoked via git, such as in hooks--converts LF to CRLF on output (as produced by echo and printf), which leads to many false positives.

Implements a diff tool that undoes the converted CRLF. To avoid that sub-processes are spawned (which is very slow on Windows), the tool is implemented as a shell function. Diff is invoked as usual only when a difference is detected by the shell code.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
 t/test-lib-functions.sh | 66 +++++++++++++++++++++++++++++++++++++++++++++++++
 t/test-lib.sh           |  1 +
 2 files changed, 67 insertions(+)
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index a7e9aac..f987694 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -710,3 +710,69 @@ test_ln_s_add () {
 		git update-index --add --cacheinfo 120000 $ln_s_obj "$2"
 	fi
 }
+
+# The following mingw_* functions obey POSIX shell syntax, but are actually
+# bash scripts, and are meant to be used only with bash on Windows.
+
+# A test_cmp function that treats LF and CRLF equal and avoids to fork
+# diff when possible.
+mingw_test_cmp () {
+	# Read text into shell variables and compare them. If the results
+	# are different, use regular diff to report the difference.
+	local test_cmp_a= test_cmp_b=
+
+	# When text came from stdin (one argument is '-') we must feed it
+	# to diff.
+	local stdin_for_diff=
+
+	# Since it is difficult to detect the difference between an
+	# empty input file and a failure to read the files, we go straight
+	# to diff if one of the inputs is empty.
+	if test -s "$1" && test -s "$2"
+	then
+		# regular case: both files non-empty
+		mingw_read_file_strip_cr_ test_cmp_a <"$1"
+		mingw_read_file_strip_cr_ test_cmp_b <"$2"
+	elif test -s "$1" && test "$2" = -
+	then
+		# read 2nd file from stdin
+		mingw_read_file_strip_cr_ test_cmp_a <"$1"
+		mingw_read_file_strip_cr_ test_cmp_b
+		stdin_for_diff='<<<"$test_cmp_b"'
+	elif test "$1" = - && test -s "$2"
+	then
+		# read 1st file from stdin
+		mingw_read_file_strip_cr_ test_cmp_a
+		mingw_read_file_strip_cr_ test_cmp_b <"$2"
+		stdin_for_diff='<<<"$test_cmp_a"'
+	fi
+	test -n "$test_cmp_a" &&
+	test -n "$test_cmp_b" &&
+	test "$test_cmp_a" = "$test_cmp_b" ||
+	eval "diff -u \"\$@\" $stdin_for_diff"
+}
+
+# $1 is the name of the shell variable to fill in
+mingw_read_file_strip_cr_ () {
+	# Read line-wise using LF as the line separator
+	# and use IFS to strip CR.
+	local line
+	while :
+	do
+		if IFS=$'\r' read -r -d $'\n' line
+		then
+			# good
+			line=$line$'\n'
+		else
+			# we get here at EOF, but also if the last line
+			# was not terminated by LF; in the latter case,
+			# some text was read
+			if test -z "$line"
+			then
+				# EOF, really
+				break
+			fi
+		fi
+		eval "$1=\$$1\$line"
+	done
+}
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 0fa7dfd..77e487b 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -817,6 +817,7 @@ case $(uname -s) in
 	test_set_prereq NOT_CYGWIN
 	test_set_prereq SED_STRIPS_CR
 	test_set_prereq GREP_STRIPS_CR
+	GIT_TEST_CMP=mingw_test_cmp
 	;;
 *CYGWIN*)
 	test_set_prereq POSIXPERM
-- 
1.8.4.33.gd68f7e8

-- 
-- 
*** Please reply-to-all at all times ***
*** (do not pretend to know who is subscribed and who is not) ***
*** Please avoid top-posting. ***
The msysGit Wiki is here: https://github.com/msysgit/msysgit/wiki - Github accounts are free.

You received this message because you are subscribed to the Google
Groups "msysGit" group.
To post to this group, send email to msysgit@googlegroups.com
To unsubscribe from this group, send email to
msysgit+unsubscribe@googlegroups.com
For more options, and view previous threads, visit this group at
http://groups.google.com/group/msysgit?hl=en_US?hl=en

--- 
You received this message because you are subscribed to the Google Groups "msysGit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to msysgit+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
Previous: Johannes SixtNext: Sebastian Schuberth
Message 3 of 8 in “Fix tests on Windows caused by random CRLF output”
  1. 0/3 Fix tests on Windows caused by random CRLF outputJohannes Sixt, Oct 26, 2013
  2. 1/3 t5300-pack-object: do not compare binary data using test_cmpJohannes Sixt, Oct 26, 2013
  3. 2/3 Windows: a test_cmp that is agnostic to random LF <> CRLF conversionsJohannes Sixt, Oct 26, 2013
  4. Sebastian SchuberthNov 2, 2013
  5. Johannes SixtNov 2, 2013
  6. Sebastian SchuberthNov 2, 2013
  7. Johannes SixtNov 3, 2013
  8. 3/3 tests: undo special treatment of CRLF for WindowsJohannes Sixt, Oct 26, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.