More efficient changelog generation
Stefan Bund [Mon, 9 Nov 2009 12:09:01 +0000 (13:09 +0100)]
Makefile

index a66e17c..e004e09 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,55 +1,71 @@
 
 lib/00_version.sh:
-       echo "version='`git describe --tag`'" >"`dirname "$0"`"/lib/00_version.sh
+       echo "version='`git describe --tag`'" >$@
 .PHONY: lib/00_version.sh
 
-mapsectorsh: mapsector lib/[0-9][0-9]_*.sh
+# The $(wildcard ...) return value is sorted and duplicates are
+# removed from the list of dependencies. I need to mention
+# lib/00_version.sh explicitly since it might not yet exist
+mapsectorsh: mapsector lib/00_version.sh $(wildcard lib/[0-9][0-9]_*.sh)
        @echo "generating $@"
        @(                                                      \
-       sed -n -e '1p' $<;                                      \
-       echo "#";                                               \
-       echo "# $@ automatically generated from";               \
-       for script in $^; do                                    \
+           sed -n -e '1p' $<;                                  \
+           echo "#";                                           \
+           echo "# $@ automatically generated from";           \
+           for script in $^; do                                \
                echo "#         $$script";                      \
-       done;                                                   \
-       sed -n -e '2,/^load$$/p' $<;                            \
-       for script in `ls lib/[0-9][0-9]_*.sh | sort`; do       \
+           done;                                               \
+           sed -n -e '2,/^load$$/p' $<;                        \
+           for script in $^; do                                \
+               if [ "$$script" == "$<" ]; then continue; fi;   \
                echo "#### $$script";                           \
                echo;                                           \
                cat $$script;                                   \
                echo;                                           \
-       done;                                                   \
-       sed -n -e '/^load$$/,$$p' $<;                           \
+           done;                                               \
+           sed -n -e '/^load$$/,$$p' $<;                       \
        ) >$@
-       @sed -i -e 's/^load$$/###########################################################################/' $@
+       @sed -i -e 's/^load$$/####/' -eT -eh -eG -eH -eG -eH -eG -e'y/\n/#/' $@
        @chmod ugo+rx $@
 
-debian/changelog:
-       @echo "generating debian/changelog"
-       @(                                                                                        \
-       lasttag="HEAD";                                                                           \
-       (git tag -l 'v*'; echo) | while read tag; do                                              \
-               case "$$lasttag" in                                                               \
-               HEAD) version="`git describe --tag --match='v*' | sed -e 's/-/~/' -e 's/-/./g'`"; \
-                     release="UNRELEASED" ;;                                                     \
-               v*)   version="$${lasttag#v}";                                                    \
-                     release="unstable" ;;                                                       \
-               esac;                                                                             \
-               echo "mapsector ($$version) $$release; urgency=low";                              \
-               echo;                                                                             \
-               git log --pretty=oneline --abbrev-commit $$tag$${tag:+..}$$lasttag                \
-                       | while read commit description; do                                       \
-                       echo "  * [$$commit] $$description";                                      \
-               done;                                                                             \
-               echo;                                                                             \
-               date="`git log --format='%cD' $$lasttag'^!'`";                                    \
-               author="`git log --format='%an <%ae>' $$lasttag'^!'`";                            \
-               echo " -- $$author  $$date";                                                      \
-               echo;                                                                             \
-               lasttag="$$tag" ;                                                                 \
-       done;                                                                                     \
-       ) >debian/changelog
-.PHONY: debian/changelog
+NAME       := mapsector
+CLOGDIR    := .git/changelogs
+CHANGELOGS := $(shell lasttag=HEAD;                                                            \
+                      (git tag -l 'v*'; echo)                                                  \
+                          | while read tag; do                                                 \
+                             echo $(CLOGDIR)/$${tag}$${tag:+-}$$lasttag;       \
+                              lasttag=$$tag;                                                   \
+                          done)
+
+$(CHANGELOGS): %:
+       @echo "generating $@"
+       @mkdir -p "$(CLOGDIR)"
+       @(                                                                                      \
+            version="$@"; version="$${version#$(CLOGDIR)/}";                                   \
+           from="$${version%-*}"; version="$${version#*-}"; to="$$version";                    \
+           if [ "$$from" == "$$to" ]; then from=""; fi;                                        \
+            case "$$version" in                                                                        \
+            HEAD) version="`git describe --tag --match='v*' | sed -e 's/-/~/' -e 's/-/./g'`";  \
+                  release="UNRELEASED" ;;                                                      \
+            v*)   version="$${version#v}";                                                     \
+                  release="unstable" ;;                                                                \
+           esac;                                                                               \
+           echo "$(NAME) ($$version) $$release; urgency=low";                                  \
+           echo;                                                                               \
+           git log --pretty=oneline --abbrev-commit $$from$${from:+..}$$to                     \
+               | while read commit description; do                                             \
+                   echo "  * [$$commit] $$description";                                        \
+           done;                                                                               \
+           echo;                                                                               \
+           date="`git log --format='%cD' $$to'^!'`";                                           \
+           author="`git log --format='%an <%ae>' $$to'^!'`";                                   \
+           echo " -- $$author  $$date";                                                        \
+           echo;                                                                               \
+       ) >$@
+.PHONY: $(word 1,$(CHANGELOGS))
+
+debian/changelog: $(CHANGELOGS)
+       cat $^ > $@
 
 prepare: lib/00_version.sh debian/changelog
 .PHONY: prepare
@@ -58,4 +74,5 @@ clean:
        rm -f mapsectorsh
        rm -f debian/changelog
        rm -f lib/00_version.sh
+       rm -rf .git/changelogs
 .PHONY: clean