diff --git a/bin/commitlint b/bin/commitlint index b32899c82..1b144ea49 100755 --- a/bin/commitlint +++ b/bin/commitlint @@ -1,21 +1,23 @@ #!/usr/bin/env bash -# shellcheck disable=SC2059 # -# Check git commits for compliance with hledger's conventions, -# described at https://hledger.org/CONTRIBUTING.html#commit-messages. -# -# Usage: -# commitlint [GITREV|GITRANGE] -# Checks unpushed commits, or the specified commit or range. -# If the argument contains - or .. it's a range, otherwise a single commit. +# commitlint [GITRANGE|FILE] + +# Check unpushed commits, or commits in the specified range, or a +# commit message in FILE, for compliance with hledger's conventions +# (https://hledger.org/CONTRIBUTING.html#commit-messages). If the +# argument contains - or .. or ^! it's a range, otherwise a file +# containing a proposed commit message. +# Run interactively, or symlink as .git/hooks/commit-msg to check +# your messages before commit. # # Examples: -# commitlint # unpushed commits -# commitlint HEAD # last commit -# commitlint d5d19f841 # this commit +# commitlint foo # commit message in ./foo +# commitlint HEAD^! # last commit +# commitlint d5d19f841^! # this commit # commitlint -20 # last 20 commits # commitlint master.. # commits in this branch # commitlint 1.21..1.22 | grep -F [FAIL] # bad commits in 1.22 release cycle +# commitlint # unpushed commits if [[ -n ${NO_COLOR+set} ]] then @@ -32,39 +34,54 @@ fi function checkcommit() { HASH=${1} - SUMMARY=$(git log -1 "$HASH" --pretty=format:"%s") + MSG=$(git log -1 "$HASH" --pretty=format:"%s%n%b") + checkmsg "$MSG" +} + +# checkmsg MSG [GITHASH] - check this commit message and print result +function checkmsg() +{ + MSG=${1} + HASH=${2} + if [[ -n $HASH ]] + then + HASH="$HASH " + fi + + SUMMARY=$(echo "$MSG" | head -1) + FMT="%s%-60s %b${NRM}\n" # Does the summary have a type: prefix ? # Can begin with ; and/or end with !, some spaces are tolerated. - FMT="%s %-60s %b${NRM}\n" if ! echo "$SUMMARY" | grep -qE '^(; *)?\w+:[ \w]+!?' then + # shellcheck disable=SC2059 printf "$FMT" "$HASH" "$SUMMARY" "${RED}[FAIL]" STATUS=1 else + # shellcheck disable=SC2059 printf "$FMT" "$HASH" "$SUMMARY" "${GRN}[ok]" fi } +STATUS= RANGE=${*:-"@{u}.."} # @{u} = upstream -if [[ ! $RANGE =~ (-|\.\.) ]] +if [[ $RANGE =~ (-|\.\.|\^!) ]] then - RANGE=$RANGE^! # assume range is a single commit + HASHES=$(git log --abbrev-commit --pretty=format:%h "$RANGE") + for HASH in $HASHES; do checkcommit "$HASH"; done +else + MSG=$(cat "$1") + checkmsg "$MSG" fi -HASHES=$(git log --abbrev-commit --pretty=format:%h "$RANGE") - -STATUS= -for HASH in $HASHES; do - checkcommit "$HASH" -done - if [[ -z $STATUS ]] then printf "" # "${GRN}Ok${NRM}\n" else - printf "\n${RED}Some commits are not in preferred style.${NRM}\n" + # shellcheck disable=SC2059 + printf "\n${RED}Commit(s) not in preferred style.${NRM}\n" cat <changelogs) dev doc test ci ref cln - developer changes -It may additionally have a topic prefix such as: +It may additionally have a topic(s) prefix such as: + bin examples install cli ui web print reg bal bs balcmds journal csv ... (see https://hledger.org/CONTRIBUTING.html#open-issues -> COMPONENT) Mention any related issues, usually parenthesised at end of summary: (#1234) ! indicates a breaking change. ; skips expensive CI tests. -These conventions are evolving. In practice, any type or topic will -do. Use your best judgement and we'll polish during code review. +These conventions are evolving. In practice, any type or topic will do. +Use your best judgement and we'll polish during code review. More detail: https://hledger.org/CONTRIBUTING.html#commit-messages --------------------------------------------------------------------------- EOF