diff options
-rw-r--r-- | CONTRIBUTING.md | 3 | ||||
-rw-r--r-- | Makefile | 8 | ||||
-rwxr-xr-x | contrib/check-patches | 2 | ||||
-rwxr-xr-x | contrib/sendemail-validate | 87 |
4 files changed, 64 insertions, 36 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fc96e9ab..340eef83 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,8 +65,7 @@ defaults: $ make gitconfig git config format.subjectPrefix "PATCH aerc" git config sendemail.to "~rjarry/aerc-devel@lists.sr.ht" - git config sendemail.validate true - ln -sf ../../contrib/sendemail-validate-series .git/hooks/sendemail-validate + '.git/hooks/sendemail-validate' -> '../../contrib/sendemail-validate' And send the patch to the mailing list ([step-by-step instructions][git-send-email-tutorial]): @@ -206,10 +206,12 @@ uninstall: gitconfig: git config format.subjectPrefix "PATCH aerc" git config sendemail.to "~rjarry/aerc-devel@lists.sr.ht" - git config sendemail.validate true @mkdir -p .git/hooks - @rm -f .git/hooks/sendemail-validate - ln -sf ../../contrib/sendemail-validate .git/hooks/sendemail-validate-series + @rm -f .git/hooks/sendemail-validate* + @if grep -q GIT_SENDEMAIL_FILE_COUNTER `git --exec-path`/git-send-email 2>/dev/null; then \ + ln -svf ../../contrib/sendemail-validate .git/hooks/sendemail-validate && \ + git config sendemail.validate true; \ + fi .PHONY: check-patches check-patches: diff --git a/contrib/check-patches b/contrib/check-patches index 20291eb6..3ae2e834 100755 --- a/contrib/check-patches +++ b/contrib/check-patches @@ -26,7 +26,7 @@ for rev in $(git rev-list --reverse "$revision_range"); do body=$(git log --format='%b' -1 "$rev") body=${body%$(git log --format='%(trailers)' -1 "$rev")} if [ "$(echo "$body" | wc -w)" -lt 3 ]; then - echo "error [PATCH $n/$total] '$title' body has less than three words, please elaborate" >&2 + echo "error [PATCH $n/$total] '$title' body has less than three words, please describe your changes" >&2 fail=true fi diff --git a/contrib/sendemail-validate b/contrib/sendemail-validate index d94f6c3e..35b7d9e3 100755 --- a/contrib/sendemail-validate +++ b/contrib/sendemail-validate @@ -1,41 +1,68 @@ #!/bin/sh -set -e +# An example hook script to validate a patch (and/or patch series) before +# sending it via email. +# +# The hook should exit with non-zero status after issuing an appropriate +# message if it wants to prevent the email(s) from being sent. +# +# To enable this hook, rename this file to "sendemail-validate". +# +# By default, it will only check that the patch(es) can be applied on top of +# the default upstream branch without conflicts in a secondary worktree. After +# validation (successful or not) of the last patch of a series, the worktree +# will be deleted. +# +# The following config variables can be set to change the default remote and +# remote ref that are used to apply the patches against: +# +# sendemail.validateRemote (default: origin) +# sendemail.validateRemoteRef (default: HEAD) -die() { - echo "error: $*" >&2 - exit 1 +validate_cover_letter () { + file="$1" + true } -run() { - echo "+ $*" >&2 - "$@" +validate_patch () { + file="$1" + # Ensure that the patch applies without conflicts. + git am -3 "$file" } -set -- -while read -r file; do - # skip empty patches (cover letter) - if grep -q "^diff --git " "$file"; then - set -- "$@" "$file" - fi -done -if [ $# -eq 0 ]; then - exit 0 -fi +validate_series () { + make all tests lint check-patches +} -echo 'Cloning upstream repo in temp dir ...' -tmp=$(mktemp -d) -trap "rm -rf -- $tmp" EXIT -run git clone -q --depth=1 "https://git.sr.ht/~rjarry/aerc" "$tmp" || - die "Failed to clone upstream repository. No network connection?" -export GIT_DIR="$tmp/.git" +# main ------------------------------------------------------------------------- -run cd $tmp +if test "$GIT_SENDEMAIL_FILE_COUNTER" = 1 +then + remote=$(git config --default origin --get sendemail.validateRemote) && + ref=$(git config --default HEAD --get sendemail.validateRemoteRef) && + worktree=$(mktemp --tmpdir -d sendemail-validate.XXXXXXX) && + git worktree add -fd --checkout "$worktree" "refs/remotes/$remote/$ref" && + git config --replace-all sendemail.validateWorktree "$worktree" +else + worktree=$(git config --get sendemail.validateWorktree) +fi || { + echo "sendemail-validate: error: failed to prepare worktree" >&2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && -run git am -3 "$@" || - die "Failed to apply patch on upstream master branch. git pull --rebase?" +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && -for target in all lint tests check-patches; do - run make $target || - die "Please fix the above issues and amend your patch(es)." -done +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi |