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

Re: [PATCH 4/4] Documentation: stop depending on Perl to generate command list

From
Junio C Hamano <gitster@pobox.com>
Date
Apr 15, 2025, 16:32 UTC
Message-ID
<xmqqmschmllq.fsf@gitster.g>
In-Reply-To
<20250415-b4-pks-drop-perl-v1-4-c6addf175858@pks.im>
Patrick Steinhardt <ps@pks.im> writes:
Show 28 quoted lines
> The "cmd-list.perl" script is used to extract the list of commands part
> of a specific category and extracts the description of each command from
> its respective manpage. The generated output is then included in git(1)
> to list all Git commands.
>
> The script is written in Perl. Refactor it to use shell scripting
> exclusively so that we can get rid of the mandatory dependency on Perl
> to build our documentation.
>
> The converted script is slower compared to its Perl implementation. But
> by being careful and not spawning external commands in `format_one ()`
> we can mitigate the performance hit to a reasonable level:
>
>     Benchmark 1: Perl
>       Time (mean ± σ):      10.3 ms ±   0.2 ms    [User: 7.0 ms, System: 3.3 ms]
>       Range (min … max):    10.0 ms …  11.1 ms    200 runs
>
>     Benchmark 2: Shell
>       Time (mean ± σ):      74.4 ms ±   0.4 ms    [User: 48.6 ms, System: 24.7 ms]
>       Range (min … max):    73.1 ms …  75.5 ms    200 runs
>
>     Summary
>       Perl ran
>         7.23 ± 0.13 times faster than Shell
>
> While a sevenfold slowdown is significant, the benefit of not requiring
> Perl for a fully-functioning Git installation outweighs waiting a couple
> of milliseconds longer during the build process.

I personally do not feel Perl such a drag but whether it is 10ms vs 75ms, as long as we won't run the script excessively (and either meson or make should be set-up to avoid unnecessary work already), I do not think a shell script being slightly slower than a Perl script is a big deal. Thanks for working on this.

Show 27 quoted lines
> diff --git a/Documentation/cmd-list.sh b/Documentation/cmd-list.sh
> new file mode 100755
> index 00000000000..fa90781f3c7
> --- /dev/null
> +++ b/Documentation/cmd-list.sh
> @@ -0,0 +1,104 @@
> +#!/bin/sh
> +
> +set -e
> +
> +format_one () {
> +	source_dir="$1"
> +	command="$2"
> +	attributes="$3"
> +
> +	path="$source_dir/Documentation/$command.adoc"
> +	if ! test -f "$path"
> +	then
> +		echo >&2 "No such file $path"
> +		exit 1
> +	fi
> +
> +	state=0
> +	while read line
> +	do
> +		case "$state" in
> +			0)
Style. label and "case" and "esac" align, just like ...
> +				case "$line" in
> +				git*\(*\)|scalar*\(*\))
> +					mansection="${line##*\(}"
... this one.
Show 6 quoted lines
> +					mansection="${mansection%\)}"
> +					;;
> +				NAME)
> +					state=1;;
> +				esac
> +				;;
> +	case "$description" in
> +		"$command - "*)
Likewise.
Show 5 quoted lines
> +			text="${description#$command - }"
> +
> +			printf "linkgit:%s[%s]::\n\t" "$command" "$mansection"
> +			case "$attributes" in
> +				*" deprecated "*)
Ditto.
Show 17 quoted lines
> +					printf "(deprecated) "
> +					;;
> +			esac
> +			printf "$text.\n\n"
> +			;;
> +		*)
> +			echo >&2 "Description does not match $command: $description"
> +			exit 1
> +			;;
> +	esac
> +}
> +
> +source_dir="$1"
> +build_dir="$2"
> +shift 2
> +
> +for out in "$@"
Let's omit 'in "$@"' when iterationg over "$@".
Show 25 quoted lines
> +do
> +	category="${out#cmds-}"
> +	category="${category%.adoc}"
> +	path="$build_dir/$out"
> +
> +	while read command command_category attributes
> +	do
> +		case "$command" in
> +		"#"*)
> +			continue;;
> +		esac
> +
> +		case "$command_category" in
> +		"$category")
> +			format_one "$source_dir" "$command" " $attributes ";;
> +		esac
> +	done <"$source_dir/command-list.txt" >"$build_dir/$out+"
> +
> +	if cmp "$build_dir/$out+" "$build_dir/$out" >/dev/null 2>&1
> +	then
> +		rm "$build_dir/$out+"
> +	else
> +		mv "$build_dir/$out+" "$build_dir/$out"
> +	fi
> +done
OK.
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 9 of 14 in “Drop Perl dependency in a couple of subsystems”
  1. 0/4 Drop Perl dependency in a couple of subsystemsPatrick Steinhardt, Apr 15, 2025
  2. 1/4 filter-branch: stop depending on PerlPatrick Steinhardt, Apr 15, 2025
  3. Junio C HamanoApr 15, 2025
  4. 2/4 request-pull: stop depending on PerlPatrick Steinhardt, Apr 15, 2025
  5. Junio C HamanoApr 15, 2025
  6. Patrick SteinhardtApr 16, 2025
  7. 3/4 Documentation: stop depending on Perl to massage user manualPatrick Steinhardt, Apr 15, 2025
  8. 4/4 Documentation: stop depending on Perl to generate command listPatrick Steinhardt, Apr 15, 2025
  9. Junio C HamanoApr 15, 2025
  10. 0/4 Drop Perl dependency in a couple of subsystemsPatrick Steinhardt, Apr 16, 2025
  11. 1/4 filter-branch: stop depending on PerlPatrick Steinhardt, Apr 16, 2025
  12. 2/4 request-pull: stop depending on PerlPatrick Steinhardt, Apr 16, 2025
  13. 4/4 Documentation: stop depending on Perl to generate command listPatrick Steinhardt, Apr 16, 2025
  14. 3/4 Documentation: stop depending on Perl to massage user manualPatrick Steinhardt, Apr 16, 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.