]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
DEV: makefile: add a new "range" target to iteratively build all commits
authorWilly Tarreau <w@1wt.eu>
Wed, 9 Aug 2023 14:52:28 +0000 (16:52 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 9 Aug 2023 16:02:30 +0000 (18:02 +0200)
This will iterate over all commits in the range passed in RANGE, or all
those from master to RANGE if no ".." exists in RANGE, and run "make all"
with the exact same variables. This aims to ease the verification that
no build failure exists inside a series. In case of error, it prints the
faulty commit and stops there with the tree checked out. Example:

  $ make-disctcc range RANGE=HEAD
  Found 14 commit(s) in range master..HEAD.
  Current branch is 20230809-plock+tbl+peers-4
  Starting to building now...
  [ 1/14 ]   392922bc5 #############################
  (...)
  Done! 14 commit(s) built successfully for RANGE master..HEAD

Maybe in the future it will automatically use HEAD as a default for RANGE
depending on the feedback.

It's not listed in the help target so as not to encourage users to try it
as it can very quickly become confusing due to the checkouts.

Makefile

index 30a556e040615b93ca7aa154b6dfab8c84835525..329c64ba2f83ea2441f30c159070affad91cef48 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1212,3 +1212,38 @@ reg-tests-help:
        @echo "(see --help option of this script for more information)."
 
 .PHONY: reg-tests reg-tests-help
+
+# "make range" iteratively builds using "make all" and the exact same build
+# options for all commits within RANGE. RANGE may be either a git range
+# such as ref1..ref2 or a single commit, in which case all commits from
+# the master branch to this one will be tested.
+
+range:
+       $(Q)[ -d .git/. ] || { echo "## Fatal: \"make $@\" may only be used inside a Git repository."; exit 1; }
+
+       $(Q)if git diff-index --name-only HEAD 2>/dev/null | grep -q ^; then \
+               echo "Fatal: \"make $@\" requires a clean working tree."; exit 1; fi
+
+       $(Q)[ -n "$(RANGE)" ] || { echo "## Fatal: \"make $@\" requires a git commit range in RANGE."; exit 1; }
+       $(Q)[ -n "$(TARGET)" ] || { echo "## Fatal: \"make $@\" needs the same variables as \"all\" (TARGET etc)."; exit 1; }
+
+       $(Q) (  die() { echo;echo "## Stopped in error at index [ $$index/$$count ] commit $$commit";\
+                       echo "Previous branch was $$BRANCH"; exit $$1; }; \
+               BRANCH=$$(git branch --show-current HEAD 2>/dev/null); \
+               [ -n "$$BRANCH" ] || { echo "Fatal: \"make $@\" may only be used inside a checked out branch."; exit 1; }; \
+               [ -z "$${RANGE##*..*}" ] || RANGE="master..$${RANGE}"; \
+               COMMITS=( $$(git rev-list --abbrev-commit --reverse "$${RANGE}") ); \
+               index=1; count=$${#COMMITS[@]}; \
+               [ "$${count}" -gt 0 ] || { echo "## Fatal: no commit(s) found in range $${RANGE}."; exit 1; }; \
+               echo "Found $${count} commit(s) in range $${RANGE}." ; \
+               echo "Current branch is $$BRANCH"; \
+               echo "Starting to building now..."; \
+               for commit in $${COMMITS[@]}; do \
+                       echo "[ $$index/$$count ]   $$commit #############################"; \
+                       git checkout -q $$commit || die 1; \
+                       $(MAKE) all || die 1; \
+                       ((index++)); \
+               done; \
+               echo;echo "Done! $${count} commit(s) built successfully for RANGE $${RANGE}" ; \
+               git checkout -q "$$BRANCH"; \
+       )