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

Re: [PATCH 2/2] test-lib: teach test_seq the -f option

From
Justin Tobler <jltobler@gmail.com>
Date
Jun 23, 2025, 16:25 UTC
Message-ID
<oai7p5xmq3q7c3ovdpmbyimoidvgw4lhxfd727qdid5ulcdn3n@7n6vqa6wn3pe>
In-Reply-To
<20250623105625.GB654412@coredump.intra.peff.net>
On 25/06/23 06:56AM, Jeff King wrote:
Show 12 quoted lines
> The "seq" tool has a "-f" option to produce printf-style formatted
> lines. Let's teach our test_seq helper the same trick. This lets us get
> rid of some shell loops in test snippets (which are particularly verbose
> in our test suite because we have to "|| return 1" to keep the &&-chain
> going).
> 
> This converts a few call-sites I found by grepping around the test
> suite. A few notes on these:
> 
>   - In "seq", the format specifier is a "%g" float. Since test_seq only
>     supports integers, I've kept the more natural "%d" (which is what
>     these call sites were using already).
Sticking with "%d" definately feels more natural.
Show 55 quoted lines
>   - Like "seq", test_seq automatically adds a newline to the specified
>     format. This is what all callers are doing already except for t0021,
>     but there we do not care about the exact format. We are just trying
>     to printf a large number of bytes to a file. It's not worth
>     complicating other callers or adding an option to avoid the newline
>     in that caller.
> 
>   - Most conversions are just replacing a shell loop (which does get rid
>     of an extra fork, since $() requires a subshell). In t0612 we can
>     replace an awk invocation, which I think makes the end result more
>     readable, as there's less quoting.
> 
>   - In t7422 we can replace one loop, but sadly we have to leave the
>     loop directly above it. This is because that earlier loop wants to
>     include the seq value twice in the output, which test_seq does not
>     support (nor does regular seq). If you run:
> 
>       test_seq -f "foo-%d %d" 10
> 
>     the second "%d" will always be the empty string. You might naively
>     think that test_seq could add some extra arguments, like:
> 
>       # 3 ought to be enough for anyone...
>       printf "$fmt\n" "$i "$i" $i"
> 
>     but that just triggers printf to format multiple lines, one per
>     extra set of arguments.
> 
>     So we'd have to actually parse the format string, figure out how
>     many "%" placeholders are there, and then feed it that many
>     instances of the sequence number. The complexity isn't worth it.
> 
> Signed-off-by: Jeff King <peff@peff.net>
> ---
>  t/t0021-conversion.sh                  |  4 ++--
>  t/t0610-reftable-basics.sh             |  6 +-----
>  t/t0612-reftable-jgit-compatibility.sh | 13 +++++--------
>  t/t0613-reftable-write-options.sh      | 24 ++++--------------------
>  t/t1400-update-ref.sh                  | 10 ++--------
>  t/t5004-archive-corner-cases.sh        |  5 +----
>  t/t6422-merge-rename-corner-cases.sh   | 10 ++--------
>  t/t7422-submodule-output.sh            |  6 +-----
>  t/test-lib-functions.sh                |  9 ++++++++-
>  9 files changed, 26 insertions(+), 61 deletions(-)
> 
> diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh
> index bf10d253ec..f0d50d769e 100755
> --- a/t/t0021-conversion.sh
> +++ b/t/t0021-conversion.sh
> @@ -281,7 +281,7 @@ test_expect_success 'required filter with absent smudge field' '
>  test_expect_success 'filtering large input to small output should use little memory' '
>  	test_config filter.devnull.clean "cat >/dev/null" &&
>  	test_config filter.devnull.required true &&
> -	for i in $(test_seq 1 30); do printf "%1048576d" 1 || return 1; done >30MB &&
> +	test_seq -f "%1048576d" 1 30 >30MB &&
Very nice quality of life improvement indeed. :)
>  	echo "30MB filter=devnull" >.gitattributes &&
>  	GIT_MMAP_LIMIT=1m GIT_ALLOC_LIMIT=1m git add 30MB
>  '
[snip]
Show 12 quoted lines
> diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
> index bee4a2ca34..8c176f4efc 100644
> --- a/t/test-lib-functions.sh
> +++ b/t/test-lib-functions.sh
> @@ -1454,6 +1454,13 @@ test_cmp_fspath () {
>  # from 1.
>  
>  test_seq () {
> +	local fmt="%d"
> +	case "$1" in
> +	-f)
> +		fmt="$2"

With the `-f` option, the default format string gets overwritten to what is provided by the user. Makes sense.

If we want, we could update the comment above this function to mention this new option.

Show 12 quoted lines
> +		shift 2
> +		;;
> +	esac
>  	case $# in
>  	1)	set 1 "$@" ;;
>  	2)	;;
> @@ -1462,7 +1469,7 @@ test_seq () {
>  	test_seq_counter__=$1
>  	while test "$test_seq_counter__" -le "$2"
>  	do
> -		echo "$test_seq_counter__"
> +		printf "$fmt\n" "$test_seq_counter__"
Nice and simple! Each of the updated callsites also look good to me.
-Justin
Show 6 quoted lines
>  		test_seq_counter__=$(( $test_seq_counter__ + 1 ))
>  	done
>  }
> -- 
> 2.50.0.385.g2a828bf5b7
> 
Previous: Junio C HamanoNext: Jeff King
Message 7 of 14 in “test_seq format option”
  1. 0/2 test_seq format optionJeff King, Jun 23, 2025
  2. 1/2 t7422: replace confusing printf with echoJeff King, Jun 23, 2025
  3. Eric SunshineJun 23, 2025
  4. Jeff KingJun 24, 2025
  5. 2/2 test-lib: teach test_seq the -f optionJeff King, Jun 23, 2025
  6. Junio C HamanoJun 23, 2025
  7. Justin ToblerJun 23, 2025
  8. 3/2 test-lib: document test_seq's "-f" optionJeff King, Jun 24, 2025
  9. Justin ToblerJun 25, 2025
  10. Todd ZullingerJun 23, 2025
  11. Jeff KingJun 24, 2025
  12. Todd ZullingerJun 24, 2025
  13. Eric SunshineJun 24, 2025
  14. Jeff KingJun 24, 2025

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.