Re: [PATCH] Makefile: implement help target

11 messages, 7 authors, 2016-06-15 · open the first message on its own page

Re: [PATCH] Makefile: implement help target

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:49:38

Michael J Gruber [off-list ref] writes:
How's this for a version without maintenance issues?
Something along these lines would be closer to what I had in mind,
actually.

Traditionally a multi-line sed command embed in Makefile has been
portability nightmare, which is a bit worrysome.

Isn't there a "makedoc" ala "perldoc" or "javadoc", by the way?
...
+#H# Show help for main make targets
+help:
+	@sed -n  -e '/^#H#/ {N'\
+		-e 's/^#H# \(.*\)\n\([a-z0-9_-]*\):.*/\2 \1/p'\
+		-e '}' <Makefile | sort --key=2 | while read target txt;\
+	do \
+		printf "%-20s: %s\n" "$$target" "$$txt"; \
+	done
-- 
1.7.3.98.g5ad7d

Re: [PATCH] Makefile: implement help target

From: Michael J Gruber <hidden>
Date: 2016-06-15 22:49:38

Junio C Hamano venit, vidit, dixit 28.09.2010 17:33:
Michael J Gruber [off-list ref] writes:
quoted
How's this for a version without maintenance issues?
Something along these lines would be closer to what I had in mind,
actually.

Traditionally a multi-line sed command embed in Makefile has been
portability nightmare, which is a bit worrysome.
Yes, but I thought for "make help" it's not such problem if it works on
most platforms only - others can read inline ;)

If portability is an issue one can work around it - is "grep -A 1"
portable? I'd also have to get rid of sort --key=2.
Isn't there a "makedoc" ala "perldoc" or "javadoc", by the way?
There is a "makedoc" but that's something different...

Michael

Re: [PATCH] Makefile: implement help target

From: Ævar Arnfjörð Bjarmason <hidden>
Date: 2016-06-15 22:49:38

On Tue, Sep 28, 2010 at 15:47, Michael J Gruber
[off-list ref] wrote:
If portability is an issue one can work around it - is "grep -A 1"
portable? I'd also have to get rid of sort --key=2.
No says http://man.cx/grep(1posix)

On the other hand I don't think portability is that important here.

But if you want to make it portable using awk to do most of the work
is probably easiest.

[PATCHv2] Makefile: implement help target

From: Michael J Gruber <hidden>
Date: 2016-06-15 22:49:38

with automatic help text collection from lines starting with "# Help: " and
preceding a make target.

Suggested-by: Stephen Boyd <redacted>
Helped-by: Andreas Ericsson [off-list ref]
Signed-off-by: Michael J Gruber <redacted>
---
Now how's this for portability and such? New output:

Build targets:
    all:                Build the Git suite
    dist:               Build git-$(GIT_VERSION).tar.gz source
    dist-doc:           Build $(manpages).tar.gz and $(htmldocs).tar.gz
    doc:                Build man pages and HTML docs
    html:               Build HTML doc
    info:               Build info docs
    man:                Build man pages
    pdf:                Build PDF docs
    rpm:                Build source and binary RPM packages
Clean targets:
    clean:              Remove generated files but keep the configure script
    distclean:          Remove generated files and the configure script
Develop targets:
    cscope:             Generate cscope index
    tags:               Generate tags using ctags
    TAGS:               Generate tags using etags
Help targets:
    help:               Show help for main make targets
Install targets:
    install-doc:        Install man pages
    install-html:       Install HTML docs
    install-info:       Install info docs
    install:            Install the Git suite
    install-man:        Install man pages
    install-pdf:        Install PDF docs
    quick-install-doc:  Install pregenerated man pages from origin/man
    quick-install-html: Install pregenerated HTML pages from origin/html
    quick-install-man:  Install pregenerated man pages from origin/man
Test targets:
    check-docs:         Check documentation coverage
    coverage:           Check test coverage
    cover_db_html:      Check test coverage and create HTML report
    test:               Check the build by running the test suite

 Makefile |   43 +++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index db2efd6..497dd92 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,5 @@
 # The default target of this Makefile is...
+# Help: Build: Build the Git suite
 all::
 
 # Define V=1 to have a more verbose compile.
@@ -1952,29 +1953,37 @@ $(XDIFF_LIB): $(XDIFF_OBJS)
 $(VCSSVN_LIB): $(VCSSVN_OBJS)
 	$(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(VCSSVN_OBJS)
 
+# Help: Build: Build man pages and HTML docs
 doc:
 	$(MAKE) -C Documentation all
 
+# Help: Build: Build man pages
 man:
 	$(MAKE) -C Documentation man
 
+# Help: Build: Build HTML doc
 html:
 	$(MAKE) -C Documentation html
 
+# Help: Build: Build info docs
 info:
 	$(MAKE) -C Documentation info
 
+# Help: Build: Build PDF docs
 pdf:
 	$(MAKE) -C Documentation pdf
 
+# Help: Develop: Generate tags using etags
 TAGS:
 	$(RM) TAGS
 	$(FIND) . -name '*.[hcS]' -print | xargs etags -a
 
+# Help: Develop: Generate tags using ctags
 tags:
 	$(RM) tags
 	$(FIND) . -name '*.[hcS]' -print | xargs ctags -a
 
+# Help: Develop: Generate cscope index
 cscope:
 	$(RM) cscope*
 	$(FIND) . -name '*.[hcS]' -print | xargs cscope -b
@@ -2040,6 +2049,7 @@ export NO_SVN_TESTS
 
 ### Testing rules
 
+# Help: Test: Check the build by running the test suite
 test: all
 	$(MAKE) -C t/ all
 
@@ -2099,6 +2109,7 @@ export gitexec_instdir
 
 install_bindir_programs := $(patsubst %,%$X,$(BINDIR_PROGRAMS_NEED_X)) $(BINDIR_PROGRAMS_NO_X)
 
+# Help: Install: Install the Git suite
 install: all
 	$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
 	$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
@@ -2155,27 +2166,35 @@ endif
 install-gitweb:
 	$(MAKE) -C gitweb install
 
+# Help: Install: Install man pages
 install-doc:
 	$(MAKE) -C Documentation install
 
+# Help: Install: Install man pages
 install-man:
 	$(MAKE) -C Documentation install-man
 
+# Help: Install: Install HTML docs
 install-html:
 	$(MAKE) -C Documentation install-html
 
+# Help: Install: Install info docs
 install-info:
 	$(MAKE) -C Documentation install-info
 
+# Help: Install: Install PDF docs
 install-pdf:
 	$(MAKE) -C Documentation install-pdf
 
+# Help: Install: Install pregenerated man pages from origin/man
 quick-install-doc:
 	$(MAKE) -C Documentation quick-install
 
+# Help: Install: Install pregenerated man pages from origin/man
 quick-install-man:
 	$(MAKE) -C Documentation quick-install-man
 
+# Help: Install: Install pregenerated HTML pages from origin/html
 quick-install-html:
 	$(MAKE) -C Documentation quick-install-html
 
@@ -2188,6 +2207,7 @@ git.spec: git.spec.in
 	mv $@+ $@
 
 GIT_TARNAME=git-$(GIT_VERSION)
+# Help: Build: Build git-$(GIT_VERSION).tar.gz source
 dist: git.spec git-archive$(X) configure
 	./git-archive --format=tar \
 		--prefix=$(GIT_TARNAME)/ HEAD^{tree} > $(GIT_TARNAME).tar
@@ -2203,6 +2223,7 @@ dist: git.spec git-archive$(X) configure
 	@$(RM) -r $(GIT_TARNAME)
 	gzip -f -9 $(GIT_TARNAME).tar
 
+# Help: Build: Build source and binary RPM packages
 rpm: dist
 	$(RPMBUILD) \
 		--define "_source_filedigest_algorithm md5" \
@@ -2211,6 +2232,8 @@ rpm: dist
 
 htmldocs = git-htmldocs-$(GIT_VERSION)
 manpages = git-manpages-$(GIT_VERSION)
+
+# Help: Build: Build $(manpages).tar.gz and $(htmldocs).tar.gz
 dist-doc:
 	$(RM) -r .doc-tmp-dir
 	mkdir .doc-tmp-dir
@@ -2230,10 +2253,11 @@ dist-doc:
 	$(RM) -r .doc-tmp-dir
 
 ### Cleaning rules
-
+# Help: Clean: Remove generated files and the configure script
 distclean: clean
 	$(RM) configure
 
+# Help: Clean: Remove generated files but keep the configure script
 clean:
 	$(RM) *.o block-sha1/*.o ppc/*.o compat/*.o compat/*/*.o xdiff/*.o vcs-svn/*.o \
 		builtin/*.o $(LIB_FILE) $(XDIFF_LIB) $(VCSSVN_LIB)
@@ -2268,7 +2292,7 @@ endif
 .PHONY: FORCE TAGS tags cscope
 
 ### Check documentation
-#
+# Help: Test: Check documentation coverage
 check-docs::
 	@(for v in $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git gitk; \
 	do \
@@ -2335,6 +2359,7 @@ check-builtins::
 #
 .PHONY: coverage coverage-clean coverage-build coverage-report
 
+# Help: Test: Check test coverage
 coverage:
 	$(MAKE) coverage-build
 	$(MAKE) coverage-report
@@ -2370,5 +2395,19 @@ coverage-untested-functions: coverage-report
 cover_db: coverage-report
 	gcov2perl -db cover_db *.gcov
 
+# Help: Test: Check test coverage and create HTML report
 cover_db_html: cover_db
 	cover -report html -outputdir cover_db_html cover_db
+
+# Help: Help: Show help for main make targets
+help:
+	@awk '/^# Help:/ { l=substr($$0,8); \
+		getline; \
+		j=index(l,":"); \
+		print substr(l,1,j-1), substr($$0,1,index($$0,":")), substr(l,j+2); \
+		}' <Makefile | sort | while read category target text; \
+	do \
+		test "$$category" = "$$currcat" || printf "$$category targets:\n"; \
+		currcat="$$category"; \
+		printf "    %-20s%s\n" "$$target" "$$text"; \
+	done
-- 
1.7.3.98.g5ad7d

Re: [PATCHv2] Makefile: implement help target

From: Sverre Rabbelier <hidden>
Date: 2016-06-15 22:49:38

Heya,

On Tue, Sep 28, 2010 at 22:38, Michael J Gruber
[off-list ref] wrote:
Now how's this for portability and such?
I applaud your leet awk skills :).
Clean targets:
   clean:              Remove generated files but keep the configure script
   distclean:          Remove generated files and the configure script
Develop targets:
   cscope:             Generate cscope index
   tags:               Generate tags using ctags
   TAGS:               Generate tags using etags
Perhaps an extra newline after the end of a category? Otherwise, looks nice.

I haven't looked at the awk script itself wrt portability though.

-- 
Cheers,

Sverre Rabbelier

Re: [PATCHv2] Makefile: implement help target

From: Jakub Narebski <hidden>
Date: 2016-06-15 22:49:38

I'm sorry for duplicated post; I made mistake that made vger anti-SPAM
filter stop it.

Michael J Gruber [off-list ref] writes:
with automatic help text collection from lines starting with "# Help: " and
preceding a make target.

Suggested-by: Stephen Boyd <redacted>
Helped-by: Andreas Ericsson [off-list ref]
Signed-off-by: Michael J Gruber <redacted>
---
Now how's this for portability and such? New output:

Build targets:
    all:                Build the Git suite
    dist:               Build git-$(GIT_VERSION).tar.gz source
    dist-doc:           Build $(manpages).tar.gz and $(htmldocs).tar.gz
    doc:                Build man pages and HTML docs
    html:               Build HTML doc
    info:               Build info docs
    man:                Build man pages
    pdf:                Build PDF docs
    rpm:                Build source and binary RPM packages
Clean targets:
    clean:              Remove generated files but keep the configure script
    distclean:          Remove generated files and the configure script
[...]

Shouldn't some excerpt of this be put in the commit message as example
output fragment?

quoted hunk
 Makefile |   43 +++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index db2efd6..497dd92 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,5 @@
 # The default target of this Makefile is...
+# Help: Build: Build the Git suite
 all::
[...]
 ### Testing rules
Why can't you use existing headers in Makefile, like the one above, to
divide list of targets in "make help" output into categories of
targets?
+
+# Help: Help: Show help for main make targets
+help:
+	@awk '/^# Help:/ { l=substr($$0,8); \
Doesn't it need to be $(AWK) not awk?
+		getline; \
+		j=index(l,":"); \
+		print substr(l,1,j-1), substr($$0,1,index($$0,":")), substr(l,j+2); \
+		}' <Makefile | sort | while read category target text; \
+	do \
+		test "$$category" = "$$currcat" || printf "$$category targets:\n"; \
+		currcat="$$category"; \
+		printf "    %-20s%s\n" "$$target" "$$text"; \
+	done
-- 
1.7.3.98.g5ad7d
-- 
Jakub Narebski
Poland
ShadeHawk on #git

Re: [PATCHv2] Makefile: implement help target

From: Brandon Casey <hidden>
Date: 2016-06-15 22:49:38

On 09/28/2010 03:38 PM, Michael J Gruber wrote:
with automatic help text collection from lines starting with "# Help: " and
preceding a make target.

Suggested-by: Stephen Boyd <redacted>
Helped-by: Andreas Ericsson [off-list ref]
Signed-off-by: Michael J Gruber <redacted>
---
Now how's this for portability and such? New output:

Build targets:
    all:                Build the Git suite
    dist:               Build git-$(GIT_VERSION).tar.gz source
    dist-doc:           Build $(manpages).tar.gz and $(htmldocs).tar.gz
<snip>
 Makefile |   43 +++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 41 insertions(+), 2 deletions(-)

Very nice.  Too bad we have more targets than fit in my 33-line terminal.

/bikeshed

How about this micro-tweak:

  1) Remove the colon from the targets so they sort correctly.
     i.e. so "dist" sorts before "dist-doc" and "install" sorts
          before "install-*"
  2) Add " - " prefix to description strings and reduce target
     width accordingly so we still have just as much room for
     the description string.

So the output looks like this:

Build targets:
    all                - Build the Git suite
    dist               - Build git-$(GIT_VERSION).tar.gz source
    dist-doc           - Build $(manpages).tar.gz and $(htmldocs).tar.gz
    doc                - Build man pages and HTML docs
    html               - Build HTML doc
    info               - Build info docs
    man                - Build man pages
    pdf                - Build PDF docs
    rpm                - Build source and binary RPM packages
Clean targets:
    clean              - Remove generated files but keep the configure script
    distclean          - Remove generated files and the configure script
Develop targets:
    TAGS               - Generate tags using etags
    cscope             - Generate cscope index
    tags               - Generate tags using ctags
Help targets:
    help               - Show help for main make targets
Install targets:
    install            - Install the Git suite
    install-doc        - Install man pages
    install-html       - Install HTML docs
    install-info       - Install info docs
    install-man        - Install man pages
    install-pdf        - Install PDF docs
    quick-install-doc  - Install pregenerated man pages from origin/man
    quick-install-html - Install pregenerated HTML pages from origin/html
    quick-install-man  - Install pregenerated man pages from origin/man
Test targets:
    check-docs         - Check documentation coverage
    cover_db_html      - Check test coverage and create HTML report
    coverage           - Check test coverage
    test               - Check the build by running the test suite


(Warning: copy/pasted):
diff --git a/Makefile b/Makefile
index c7f0bb7..2803aa1 100644
--- a/Makefile
+++ b/Makefile
@@ -2398,10 +2398,10 @@ help:
        @awk '/^# Help:/ { l=substr($$0,8); \
                getline; \
                j=index(l,":"); \
-               print substr(l,1,j-1), substr($$0,1,index($$0,":")), substr(l,j+2); \
+               print substr(l,1,j-1), substr($$0,1,index($$0,":")-1), substr(l,j+2); \
                }' <Makefile | sort | while read category target text; \
        do \
                test "$$category" = "$$currcat" || printf "$$category targets:\n"; \
                currcat="$$category"; \
-               printf "    %-20s%s\n" "$$target" "$$text"; \
+               printf "    %-18s - %s\n" "$$target" "$$text"; \
        done

Oh, by the way, tested and works on Solaris 10 and IRIX 6.5.

-Brandon

Re: [PATCHv2] Makefile: implement help target

From: Jeff King <hidden>
Date: 2016-06-15 22:49:39

On Tue, Sep 28, 2010 at 10:38:04PM +0200, Michael J Gruber wrote:
+help:
+	@awk '/^# Help:/ { l=substr($$0,8); \
+		getline; \
+		j=index(l,":"); \
+		print substr(l,1,j-1), substr($$0,1,index($$0,":")), substr(l,j+2); \
+		}' <Makefile | sort | while read category target text; \
+	do \
+		test "$$category" = "$$currcat" || printf "$$category targets:\n"; \
+		currcat="$$category"; \
+		printf "    %-20s%s\n" "$$target" "$$text"; \
+	done
Surely this is why we have perl?

help:
	@perl -n0777 \
	  -e 'push @{$$h{$$1}}, [$$3, $$2] while /^# Help: (.*?): (.*)\n(.*?):/mg;' \
	  -e 'for (sort keys(%h)) {' \
	  -e '  print "$$_:\n";' \
	  -e '  printf("    %-20s%s\n", @$$_) for (@{$$h{$$_}});' \
	  -e '}' Makefile

Note that mine will actually print the targets in a heading in the order
in which they appear in the Makefile, which I consider slightly more
useful (especially in that we can tweak the order easily). It would also
be easy to sort the headers in some more meaningful way, but here I just
did it lexically.

-Peff

Re: [PATCHv2] Makefile: implement help target

From: Michael J Gruber <hidden>
Date: 2016-06-15 22:49:39

Jeff King venit, vidit, dixit 29.09.2010 07:16:
On Tue, Sep 28, 2010 at 10:38:04PM +0200, Michael J Gruber wrote:
quoted
+help:
+	@awk '/^# Help:/ { l=substr($$0,8); \
+		getline; \
+		j=index(l,":"); \
+		print substr(l,1,j-1), substr($$0,1,index($$0,":")), substr(l,j+2); \
+		}' <Makefile | sort | while read category target text; \
+	do \
+		test "$$category" = "$$currcat" || printf "$$category targets:\n"; \
+		currcat="$$category"; \
+		printf "    %-20s%s\n" "$$target" "$$text"; \
+	done
Surely this is why we have perl?
I don't speak perl.

Honestly, this is slowly going on my nerves. Maybe it's because I'm
reading too many "can't we do it this way" responses in one go and
without being coffeinated, and without seeing how "different" is better.
[I've been heeding all advise on portability and readability, as you can
see.]

So far we've been using neither awk nor perl in the Makefile, but sed.
help:
	@perl -n0777 \
	  -e 'push @{$$h{$$1}}, [$$3, $$2] while /^# Help: (.*?): (.*)\n(.*?):/mg;' \
On top of everything else, you're even slashing mg! (See, I'm less
grumpy already...)
	  -e 'for (sort keys(%h)) {' \
	  -e '  print "$$_:\n";' \
	  -e '  printf("    %-20s%s\n", @$$_) for (@{$$h{$$_}});' \
	  -e '}' Makefile
How portable are the regexps and the array/dictionary push?
Note that mine will actually print the targets in a heading in the order
in which they appear in the Makefile, which I consider slightly more
useful (especially in that we can tweak the order easily).
I don't think Makefile order would be useful. If you know exactly what
you're looking for you need no sorting, you can just search for that
term. (I would do a 'grep -A20 "^target:" Makefile' or hit "/^target" in
my vim but I'm sure there's a different way of doing it in perl...)

If you're trying to find your way around you guess a generic term and
look for that, and that's easier to do when the categories are sorted
alphabetically.

Michael

Re: [PATCHv2] Makefile: implement help target

From: Jeff King <hidden>
Date: 2016-06-15 22:49:39

On Wed, Sep 29, 2010 at 09:03:35AM +0200, Michael J Gruber wrote:
quoted
Surely this is why we have perl?
I don't speak perl.

Honestly, this is slowly going on my nerves. Maybe it's because I'm
reading too many "can't we do it this way" responses in one go and
without being coffeinated, and without seeing how "different" is better.
[I've been heeding all advise on portability and readability, as you can
see.]
I should have been more clear about my motivations. It was mainly "I
wonder how short I can make this in perl?" The alternate sorting was
something that happened incidentally, though it did make more sense to
me.

So you can just ignore me if you like. :)
quoted
	  -e 'for (sort keys(%h)) {' \
	  -e '  print "$$_:\n";' \
	  -e '  printf("    %-20s%s\n", @$$_) for (@{$$h{$$_}});' \
	  -e '}' Makefile
How portable are the regexps and the array/dictionary push?
AFAIK, it should work with any perl5. I don't have any ancient versions
handy to test these days, though.
quoted
Note that mine will actually print the targets in a heading in the order
in which they appear in the Makefile, which I consider slightly more
useful (especially in that we can tweak the order easily).
I don't think Makefile order would be useful. If you know exactly what
you're looking for you need no sorting, you can just search for that
term. (I would do a 'grep -A20 "^target:" Makefile' or hit "/^target" in
my vim but I'm sure there's a different way of doing it in perl...)
What I was trying to say was more that alphabetical is not necessarily
the most useful order to present things in the help screen. Probably
there is some hand-selected order that presents the entries in the least
confusing way. And one way of representing that is to have the topics in
that order in the Makefile, which in theory probably makes reading the
Makefile itself simpler.

But yeah, this is way over-thinking the issue. It's a fricking list of
Makefile targets. I am happy with your original patch.

-Peff

Re: [PATCHv2] Makefile: implement help target

From: Michael J Gruber <hidden>
Date: 2016-06-15 22:49:39

Brandon Casey venit, vidit, dixit 29.09.2010 00:00:
On 09/28/2010 03:38 PM, Michael J Gruber wrote:
quoted
with automatic help text collection from lines starting with "# Help: " and
preceding a make target.

Suggested-by: Stephen Boyd <redacted>
Helped-by: Andreas Ericsson [off-list ref]
Signed-off-by: Michael J Gruber <redacted>
---
Now how's this for portability and such? New output:

Build targets:
    all:                Build the Git suite
    dist:               Build git-$(GIT_VERSION).tar.gz source
    dist-doc:           Build $(manpages).tar.gz and $(htmldocs).tar.gz
<snip>
quoted
 Makefile |   43 +++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 41 insertions(+), 2 deletions(-)

Very nice.  Too bad we have more targets than fit in my 33-line terminal.

/bikeshed

How about this micro-tweak:

  1) Remove the colon from the targets so they sort correctly.
     i.e. so "dist" sorts before "dist-doc" and "install" sorts
          before "install-*"
  2) Add " - " prefix to description strings and reduce target
     width accordingly so we still have just as much room for
     the description string.

So the output looks like this:
....
Install targets:
    install            - Install the Git suite
    install-doc        - Install man pages
    install-html       - Install HTML docs
    install-info       - Install info docs
    install-man        - Install man pages
    install-pdf        - Install PDF docs
    quick-install-doc  - Install pregenerated man pages from origin/man
    quick-install-html - Install pregenerated HTML pages from origin/html
    quick-install-man  - Install pregenerated man pages from origin/man
Sounds good, although the sort order depends on the locale. "LANG=C
sort" takes care of that.
Oh, by the way, tested and works on Solaris 10 and IRIX 6.5.
Thanks!
Michael
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help