{"thread":{"id":"40135","subject":"[PATCH] generate-cmdlist: re-implement as shell script","startedAt":"2015-08-19T20:18:48Z","lastAt":"2015-08-20T18:18:50Z","messageCount":5,"participants":["Eric Sunshine","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"268351","messageId":"1440015528-7791-1-git-send-email-sunshine@sunshineco.com","threadId":"40135","inReplyTo":null,"subject":"[PATCH] generate-cmdlist: re-implement as shell script","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-08-19T20:18:48Z","receivedAt":"2015-08-19T20:18:48Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"527ec39 (generate-cmdlist: parse common group commands, 2015-05-21)\nreplaced generate-cmdlist.sh with a more functional Perl version,\ngenerate-cmdlist.perl. The Perl version gleans named tags from a new\n\"common groups\" section in command-list.txt and recognizes those tags in\n\"command list\" section entries in place of the old 'common' tag. This\nallows git-help to, not only recognize, but also group common commands.\n\nAlthough the tests require Perl, 527ec39 creates an unconditional\ndependence upon Perl in the build system itself, which can not be\noverridden with NO_PERL. Such a dependency may be undesirable; for\ninstance, the 'git-lite' package in the FreeBSD ports tree is intended\nas a minimal Git installation (which may, for example, be useful on\nservers needing only local clone and update capability), which,\nhistorically, has not depended upon Perl[1].\n\nTherefore, revive generate-cmdlist.sh and extend it to recognize \"common\ngroups\" and its named tags. Retire generate-cmdlist.perl.\n\n[1]: http://thread.gmane.org/gmane.comp.version-control.git/275905/focus=276132\n\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n\nIn addition to reviving 527ec39^:generate-cmdlist.sh and extending it, I\nalso re-indented it with tabs instead of spaces, so it's helpful to\nignore whitespace changes when comparing the old and new versions of the\nshell script.\n\nMakefile              |  4 ++--\n generate-cmdlist.perl | 50 --------------------------------------------------\n generate-cmdlist.sh   | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 52 insertions(+), 52 deletions(-)\n delete mode 100755 generate-cmdlist.perl\n create mode 100755 generate-cmdlist.sh\n\ndiff --git a/Makefile b/Makefile\nindex e39ca6c..ddfe7a1 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1697,10 +1697,10 @@ $(BUILT_INS): git$X\n \tln -s $< $@ 2>/dev/null || \\\n \tcp $< $@\n \n-common-cmds.h: generate-cmdlist.perl command-list.txt\n+common-cmds.h: generate-cmdlist.sh command-list.txt\n \n common-cmds.h: $(wildcard Documentation/git-*.txt)\n-\t$(QUIET_GEN)$(PERL_PATH) generate-cmdlist.perl command-list.txt > $@+ && mv $@+ $@\n+\t$(QUIET_GEN)./generate-cmdlist.sh <command-list.txt >$@+ && mv $@+ $@\n \n SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):$(GIT_VERSION):\\\n \t$(localedir_SQ):$(NO_CURL):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\\\ndiff --git a/generate-cmdlist.perl b/generate-cmdlist.perl\ndeleted file mode 100755\nindex 31516e3..0000000\n--- a/generate-cmdlist.perl\n+++ /dev/null\n@@ -1,50 +0,0 @@\n-#!/usr/bin/perl\n-use strict;\n-use warnings;\n-\n-print <<\"EOT\";\n-/* Automatically generated by $0 */\n-\n-struct cmdname_help {\n-\tchar name[16];\n-\tchar help[80];\n-\tunsigned char group;\n-};\n-\n-static char *common_cmd_groups[] = {\n-EOT\n-\n-my $n = 0;\n-my %grp;\n-while (<>) {\n-\tlast if /^### command list/;\n-\tnext if (1../^### common groups/) || /^#/ || /^\\s*$/;\n-\tchop;\n-\tmy ($k, $v) = split ' ', $_, 2;\n-\t$grp{$k} = $n++;\n-\tprint \"\\tN_(\\\"$v\\\"),\\n\";\n-}\n-\n-print \"};\\n\\nstatic struct cmdname_help common_cmds[] = {\\n\";\n-\n-while (<>) {\n-\tnext if /^#/ || /^\\s*$/;\n-\tmy @tags = split;\n-\tmy $cmd = shift @tags;\n-\tfor my $t (@tags) {\n-\t\tif (exists $grp{$t}) {\n-\t\t\tmy $s;\n-\t\t\topen my $f, '<', \"Documentation/$cmd.txt\" or die;\n-\t\t\twhile (<$f>) {\n-\t\t\t\t($s) = /^$cmd - (.+)$/;\n-\t\t\t\tlast if $s;\n-\t\t\t}\n-\t\t\tclose $f;\n-\t\t\t$cmd =~ s/^git-//;\n-\t\t\tprint \"\\t{\\\"$cmd\\\", N_(\\\"$s\\\"), $grp{$t}},\\n\";\n-\t\t\tlast;\n-\t\t}\n-\t}\n-}\n-\n-print \"};\\n\";\ndiff --git a/generate-cmdlist.sh b/generate-cmdlist.sh\nnew file mode 100755\nindex 0000000..1ac329d\n--- /dev/null\n+++ b/generate-cmdlist.sh\n@@ -0,0 +1,50 @@\n+#!/bin/sh\n+\n+echo \"/* Automatically generated by $0 */\n+struct cmdname_help {\n+\tchar name[16];\n+\tchar help[80];\n+\tunsigned char group;\n+};\n+\n+static const char *common_cmd_groups[] = {\"\n+\n+tmp=cmdgrps$$.tmp\n+trap \"rm -fr $tmp\" 0 1 2 3 15\n+\n+sed -n '\n+\t1,/^### common groups/b\n+\t/^### command list/q\n+\t/^#/d; /^[ \t]*$/b\n+\th;s/^[^ \t][^ \t]*[ \t][ \t]*\\(.*\\)/\tN_(\"\\1\"),/p\n+\tg;s/^\\([^ \t][^ \t]*\\)[ \t].*/\\1/w '$tmp'\n+\t'\n+printf '};\\n\\n'\n+\n+n=0\n+matchgrp=\n+substnum=\n+while read grp\n+do\n+\tmatchgrp=\"$matchgrp${matchgrp:+\n+}^git-..*[ \t]$grp\"\n+\tsubstnum=\"$substnum${substnum:+;}s/[ \t]$grp/$n/\"\n+\tn=$(($n+1))\n+done <$tmp\n+\n+printf 'static struct cmdname_help common_cmds[] = {\\n'\n+grep \"$matchgrp\" |\n+sed 's/^git-//' |\n+sort |\n+while read cmd tags\n+do\n+\ttag=$(echo $tags | sed \"$substnum; s/[^0-9]//g\")\n+\tsed -n '\n+\t\t/^NAME/,/git-'\"$cmd\"'/H\n+\t\t${\n+\t\t\tx\n+\t\t\ts/.*git-'\"$cmd\"' - \\(.*\\)/\t{\"'\"$cmd\"'\", N_(\"\\1\"), '$tag'},/\n+\t\t\tp\n+\t\t}' \"Documentation/git-$cmd.txt\"\n+done\n+echo \"};\"\n-- \n2.5.0.457.gab17608\n"},{"id":"268353","messageId":"xmqqegiy9a4d.fsf@gitster.dls.corp.google.com","threadId":"40135","inReplyTo":"1440015528-7791-1-git-send-email-sunshine@sunshineco.com","subject":"Re: [PATCH] generate-cmdlist: re-implement as shell script","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-08-19T22:38:58Z","receivedAt":"2015-08-19T22:38:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eric Sunshine <sunshine@sunshineco.com> writes:\n\n> In addition to reviving 527ec39^:generate-cmdlist.sh and extending it, I\n> also re-indented it with tabs instead of spaces, so it's helpful to\n> ignore whitespace changes when comparing the old and new versions of the\n> shell script.\n\nHmph.  Perhaps we can view it as part of reverting 527ec39 and then\nredoing it in shell.  The way the shell script accumulates matchgrp\nvariable (i.e. the literal LF in ${var:+string}) makes me feel some\npossible portability scare, which might be solved in a more stupid\n(i.e. not giving various reimplementations of Bourne shells a chance\nto screw it up) way by using another temporary file, but other than\nthat the resurrected script looks OK to me.\n\nThanks.\n\n> diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh\n> new file mode 100755\n> index 0000000..1ac329d\n> --- /dev/null\n> +++ b/generate-cmdlist.sh\n> @@ -0,0 +1,50 @@\n> +#!/bin/sh\n> +\n> +echo \"/* Automatically generated by $0 */\n> +struct cmdname_help {\n> +\tchar name[16];\n> +\tchar help[80];\n> +\tunsigned char group;\n> +};\n> +\n> +static const char *common_cmd_groups[] = {\"\n> +\n> +tmp=cmdgrps$$.tmp\n> +trap \"rm -fr $tmp\" 0 1 2 3 15\n> +\n> +sed -n '\n> +\t1,/^### common groups/b\n> +\t/^### command list/q\n> +\t/^#/d; /^[ \t]*$/b\n> +\th;s/^[^ \t][^ \t]*[ \t][ \t]*\\(.*\\)/\tN_(\"\\1\"),/p\n> +\tg;s/^\\([^ \t][^ \t]*\\)[ \t].*/\\1/w '$tmp'\n> +\t'\n> +printf '};\\n\\n'\n> +\n> +n=0\n> +matchgrp=\n> +substnum=\n> +while read grp\n> +do\n> +\tmatchgrp=\"$matchgrp${matchgrp:+\n> +}^git-..*[ \t]$grp\"\n> +\tsubstnum=\"$substnum${substnum:+;}s/[ \t]$grp/$n/\"\n> +\tn=$(($n+1))\n> +done <$tmp\n> +\n> +printf 'static struct cmdname_help common_cmds[] = {\\n'\n> +grep \"$matchgrp\" |\n> +sed 's/^git-//' |\n> +sort |\n> +while read cmd tags\n> +do\n> +\ttag=$(echo $tags | sed \"$substnum; s/[^0-9]//g\")\n> +\tsed -n '\n> +\t\t/^NAME/,/git-'\"$cmd\"'/H\n> +\t\t${\n> +\t\t\tx\n> +\t\t\ts/.*git-'\"$cmd\"' - \\(.*\\)/\t{\"'\"$cmd\"'\", N_(\"\\1\"), '$tag'},/\n> +\t\t\tp\n> +\t\t}' \"Documentation/git-$cmd.txt\"\n> +done\n> +echo \"};\"\n"},{"id":"268378","messageId":"xmqqmvxl7u0l.fsf@gitster.dls.corp.google.com","threadId":"40135","inReplyTo":"1440015528-7791-1-git-send-email-sunshine@sunshineco.com","subject":"Re: [PATCH] generate-cmdlist: re-implement as shell script","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-08-20T17:24:26Z","receivedAt":"2015-08-20T17:24:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eric Sunshine <sunshine@sunshineco.com> writes:\n\n> diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh\n> new file mode 100755\n> index 0000000..1ac329d\n> --- /dev/null\n> +++ b/generate-cmdlist.sh\n> @@ -0,0 +1,50 @@\n> +#!/bin/sh\n> +\n> +echo \"/* Automatically generated by $0 */\n> +struct cmdname_help {\n> +\tchar name[16];\n> +\tchar help[80];\n> +\tunsigned char group;\n> +};\n> +\n> +static const char *common_cmd_groups[] = {\"\n> +\n> +tmp=cmdgrps$$.tmp\n> +trap \"rm -fr $tmp\" 0 1 2 3 15\n> +\n> +sed -n '\n> +\t1,/^### common groups/b\n> +\t/^### command list/q\n> +\t/^#/d; /^[ \t]*$/b\n> +\th;s/^[^ \t][^ \t]*[ \t][ \t]*\\(.*\\)/\tN_(\"\\1\"),/p\n> +\tg;s/^\\([^ \t][^ \t]*\\)[ \t].*/\\1/w '$tmp'\n> +\t'\n> +printf '};\\n\\n'\n\nUnfortunately, this does not seem to work for me.  Even though sed\nstops reading after seeing the \"### command list\" line, I suspect\nthat its stdin buffer has been filled with other lines that follow\nit from the input to the buffer size, consuming what you meant to\nfeed the later 'grep $matchgrp\"' with.\n\nThis is a one-time thing, so I do not mind to update the Makefile\nso that it does not feed command-list.txt from the standard input\nbut gives the path as \"$1\" to this script.\n\n> +n=0\n> +matchgrp=\n> +substnum=\n> +while read grp\n> +do\n> +\tmatchgrp=\"$matchgrp${matchgrp:+\n> +}^git-..*[ \t]$grp\"\n> +\tsubstnum=\"$substnum${substnum:+;}s/[ \t]$grp/$n/\"\n> +\tn=$(($n+1))\n> +done <$tmp\n> +\n> +printf 'static struct cmdname_help common_cmds[] = {\\n'\n> +grep \"$matchgrp\" |\n> +sed 's/^git-//' |\n> +sort |\n> +while read cmd tags\n> +do\n> +\ttag=$(echo $tags | sed \"$substnum; s/[^0-9]//g\")\n> +\tsed -n '\n> +\t\t/^NAME/,/git-'\"$cmd\"'/H\n> +\t\t${\n> +\t\t\tx\n> +\t\t\ts/.*git-'\"$cmd\"' - \\(.*\\)/\t{\"'\"$cmd\"'\", N_(\"\\1\"), '$tag'},/\n> +\t\t\tp\n> +\t\t}' \"Documentation/git-$cmd.txt\"\n> +done\n> +echo \"};\"\n"},{"id":"268379","messageId":"CAPig+cROaXkRVbpRJYiAL1yiXB1HV_12To=VMO8kZVk_AFE+2w@mail.gmail.com","threadId":"40135","inReplyTo":"xmqqegiy9a4d.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH] generate-cmdlist: re-implement as shell script","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-08-20T18:11:41Z","receivedAt":"2015-08-20T18:11:41Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Aug 19, 2015 at 6:38 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Eric Sunshine <sunshine@sunshineco.com> writes:\n>> In addition to reviving 527ec39^:generate-cmdlist.sh and extending it, I\n>> also re-indented it with tabs instead of spaces, so it's helpful to\n>> ignore whitespace changes when comparing the old and new versions of the\n>> shell script.\n>\n> Hmph.  Perhaps we can view it as part of reverting 527ec39 and then\n> redoing it in shell.\n\nI'm having trouble understanding. Are you asking that this be\npresented as a series of patches which first revert 527ec39, then do\nthe whitespace cleanup, and then augment the script for the extended\nfunctionality? If so, it's a bit problematic because the original\nscript still expects the 'common' tag to be present, but that tag was\nremoved by the subsequent patch 2f5b495 (command-list.txt: drop the\n\"common\" tag, 2015-05-21). So, reverting 527ec39 would also require\nreverting 2f5b495.\n\n> The way the shell script accumulates matchgrp\n> variable (i.e. the literal LF in ${var:+string}) makes me feel some\n> possible portability scare, which might be solved in a more stupid\n> (i.e. not giving various reimplementations of Bourne shells a chance\n> to screw it up) way by using another temporary file[...]\n\nIn addition to the literal newline and the temporary file, other\noptions I considered included assigning the newline to a variable and\nthen interpolating that variable (${var:+$LF}), or expanding the list\nof patterns into a set of '-e' arguments for grep. But, I think I'll\njust go with the temporary file.\n"},{"id":"268380","messageId":"CAPig+cRgMTZ1DUgcFHn+S0nZaRf-5NAWdhPnALwR4TqJPqcO6w@mail.gmail.com","threadId":"40135","inReplyTo":"xmqqmvxl7u0l.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH] generate-cmdlist: re-implement as shell script","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-08-20T18:18:50Z","receivedAt":"2015-08-20T18:18:50Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Thu, Aug 20, 2015 at 1:24 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Eric Sunshine <sunshine@sunshineco.com> writes:\n>> +sed -n '\n>> +     1,/^### common groups/b\n>> +     /^### command list/q\n>> +     /^#/d; /^[      ]*$/b\n>> +     h;s/^[^         ][^     ]*[     ][      ]*\\(.*\\)/       N_(\"\\1\"),/p\n>> +     g;s/^\\([^       ][^     ]*\\)[   ].*/\\1/w '$tmp'\n>> +     '\n>> +printf '};\\n\\n'\n>\n> Unfortunately, this does not seem to work for me.  Even though sed\n> stops reading after seeing the \"### command list\" line, I suspect\n> that its stdin buffer has been filled with other lines that follow\n> it from the input to the buffer size, consuming what you meant to\n> feed the later 'grep $matchgrp\"' with.\n>\n> This is a one-time thing, so I do not mind to update the Makefile\n> so that it does not feed command-list.txt from the standard input\n> but gives the path as \"$1\" to this script.\n\nThe original generate-cmdlist.sh doesn't take any arguments and just\nhardcodes \"command-list.txt\". Feeding it instead on stdin seemed a\nnice way to avoid reading the file twice, but alas is too fragile. I\ndon't mind passing it as an argument either, or just hardcoding it\nagain (though my preference leans toward passing it as an argument).\n"}]}