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

[PATCH v2] generate-cmdlist: re-implement as shell script

From
Eric Sunshine <sunshine@sunshineco.com>
Date
Aug 23, 2015, 21:31 UTC
Message-ID
<1440365469-9928-1-git-send-email-sunshine@sunshineco.com>

527ec39 (generate-cmdlist: parse common group commands, 2015-05-21) replaced generate-cmdlist.sh with a more functional Perl version, generate-cmdlist.perl. The Perl version gleans named tags from a new "common groups" section in command-list.txt and recognizes those tags in "command list" section entries in place of the old 'common' tag. This allows git-help to, not only recognize, but also group common commands.

Although the tests require Perl, 527ec39 creates an unconditional dependence upon Perl in the build system itself, which can not be overridden with NO_PERL. Such a dependency may be undesirable; for instance, the 'git-lite' package in the FreeBSD ports tree is intended as a minimal Git installation (which may, for example, be useful on servers needing only local clone and update capability), which, historically, has not depended upon Perl[1].

Therefore, revive generate-cmdlist.sh and extend it to recognize "common groups" and its named tags. Retire generate-cmdlist.perl.

[1]: http://thread.gmane.org/gmane.comp.version-control.git/275905/focus=276132
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
Changes since v1 [2]:
* Avoid literal newline inside ${var:+val} when composing grep match
  patterns, lest some shells might trip over it. Instead, pass match
  patterns to grep via -f temporary file.
* Don't assume it's portable to feed commands-list.txt to script as
  stdin and expect one command (sed) to consume only part of it, leaving
  the rest for consumption by a subsequent command (grep). While this
  works on some platforms, in practice, the first command (sed) may
  buffer and eat more of the input than expected. Instead, pass
  commands-list.txt as argument and have each command independently open
  and consume it.
* Replace errant 'd' sed command with 'b' to skip comment lines. The end
  result is the same, but the other "skipping" actions use 'b', and 'b'
  was intended all along.

v2 is still a single patch since I couldn't quite figure out[3] whether Junio was asking for the patch to be submitted as a reversion plus a cleanup plus an enhancement or not.

[2]: http://thread.gmane.org/gmane.comp.version-control.git/276226 [3]: http://thread.gmane.org/gmane.comp.version-control.git/276226/focus=276256

 Makefile              |  4 ++--
 generate-cmdlist.perl | 50 --------------------------------------------------
 generate-cmdlist.sh   | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+), 52 deletions(-)
 delete mode 100755 generate-cmdlist.perl
 create mode 100755 generate-cmdlist.sh
diff --git a/Makefile b/Makefile
index e39ca6c..5d3e3b9 100644
--- a/Makefile
+++ b/Makefile
@@ -1697,10 +1697,10 @@ $(BUILT_INS): git$X
 	ln -s $< $@ 2>/dev/null || \
 	cp $< $@
 
-common-cmds.h: generate-cmdlist.perl command-list.txt
+common-cmds.h: generate-cmdlist.sh command-list.txt
 
 common-cmds.h: $(wildcard Documentation/git-*.txt)
-	$(QUIET_GEN)$(PERL_PATH) generate-cmdlist.perl command-list.txt > $@+ && mv $@+ $@
+	$(QUIET_GEN)./generate-cmdlist.sh command-list.txt >$@+ && mv $@+ $@
 
 SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):$(GIT_VERSION):\
 	$(localedir_SQ):$(NO_CURL):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\
diff --git a/generate-cmdlist.perl b/generate-cmdlist.perl
deleted file mode 100755
index 31516e3..0000000
--- a/generate-cmdlist.perl
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-
-print <<"EOT";
-/* Automatically generated by $0 */
-
-struct cmdname_help {
-	char name[16];
-	char help[80];
-	unsigned char group;
-};
-
-static char *common_cmd_groups[] = {
-EOT
-
-my $n = 0;
-my %grp;
-while (<>) {
-	last if /^### command list/;
-	next if (1../^### common groups/) || /^#/ || /^\s*$/;
-	chop;
-	my ($k, $v) = split ' ', $_, 2;
-	$grp{$k} = $n++;
-	print "\tN_(\"$v\"),\n";
-}
-
-print "};\n\nstatic struct cmdname_help common_cmds[] = {\n";
-
-while (<>) {
-	next if /^#/ || /^\s*$/;
-	my @tags = split;
-	my $cmd = shift @tags;
-	for my $t (@tags) {
-		if (exists $grp{$t}) {
-			my $s;
-			open my $f, '<', "Documentation/$cmd.txt" or die;
-			while (<$f>) {
-				($s) = /^$cmd - (.+)$/;
-				last if $s;
-			}
-			close $f;
-			$cmd =~ s/^git-//;
-			print "\t{\"$cmd\", N_(\"$s\"), $grp{$t}},\n";
-			last;
-		}
-	}
-}
-
-print "};\n";
diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh
new file mode 100755
index 0000000..6b39c62
--- /dev/null
+++ b/generate-cmdlist.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+echo "/* Automatically generated by $0 */
+struct cmdname_help {
+	char name[16];
+	char help[80];
+	unsigned char group;
+};
+
+static const char *common_cmd_groups[] = {"
+
+grps=grps$$.tmp
+match=match$$.tmp
+trap "rm -f $grps $match" 0 1 2 3 15
+
+sed -n '
+	1,/^### common groups/b
+	/^### command list/q
+	/^#/b
+	/^[ 	]*$/b
+	h;s/^[^ 	][^ 	]*[ 	][ 	]*\(.*\)/	N_("\1"),/p
+	g;s/^\([^ 	][^ 	]*\)[ 	].*/\1/w '$grps'
+	' $1
+printf '};\n\n'
+
+n=0
+>$match
+substnum=
+while read grp
+do
+	echo "^git-..*[ 	]$grp" >>$match
+	substnum="$substnum${substnum:+;}s/[ 	]$grp/$n/"
+	n=$(($n+1))
+done <$grps
+
+printf 'static struct cmdname_help common_cmds[] = {\n'
+grep -f $match $1 |
+sed 's/^git-//' |
+sort |
+while read cmd tags
+do
+	tag=$(echo $tags | sed "$substnum; s/[^0-9]//g")
+	sed -n '
+		/^NAME/,/git-'"$cmd"'/H
+		${
+			x
+			s/.*git-'"$cmd"' - \(.*\)/	{"'"$cmd"'", N_("\1"), '$tag'},/
+			p
+		}' "Documentation/git-$cmd.txt"
+done
+echo "};"
-- 
2.5.0.495.g1755c2e
Message 1 of 1 in “generate-cmdlist: re-implement as shell script”
  1. generate-cmdlist: re-implement as shell scriptEric Sunshine, Aug 23, 2015

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.