123 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env bash
 | |
| #
 | |
| # 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 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
 | |
|     RED=""
 | |
|     GRN=""
 | |
|     NRM=""
 | |
| else
 | |
|     RED="\033[31m"
 | |
|     GRN="\033[32m"
 | |
|     NRM="\033[0m"
 | |
| fi
 | |
| 
 | |
| # checkcommit GITHASH - check this commit's message and print result
 | |
| function checkcommit()
 | |
| {
 | |
|     HASH=${1}
 | |
|     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.
 | |
|     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 =~ (-|\.\.|\^!) ]]
 | |
| then
 | |
|     HASHES=$(git log --abbrev-commit --pretty=format:%h "$RANGE")
 | |
|     for HASH in $HASHES; do checkcommit "$HASH"; done
 | |
| else
 | |
|     MSG=$(cat "$1")
 | |
|     checkmsg "$MSG"
 | |
| fi
 | |
| 
 | |
| if [[ -z $STATUS ]]
 | |
| then
 | |
|     printf "" # "${GRN}Ok${NRM}\n"
 | |
| else
 | |
|     # shellcheck disable=SC2059
 | |
|     printf "\n${RED}Commit(s) not in preferred style.${NRM}\n"
 | |
|     cat <<EOF
 | |
| ---------------------------------------------------------------------------
 | |
| Commit messages should follow this format:
 | |
| 
 | |
|   [;]type[!]: [topic:] summary
 | |
| 
 | |
|   [Optional description, ready for release notes/changelog.]
 | |
| 
 | |
| Explanation:
 | |
| 
 | |
| The subject line should have a type: prefix. Common types:
 | |
|  feat imp fix            - end-user changes (->release notes & changelogs)
 | |
|  cha pkg lib             - packager/builder/lib-user changes (->changelogs)
 | |
|  dev doc test ci ref cln - developer changes
 | |
| 
 | |
| 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.
 | |
| More context: https://hledger.org/CONTRIBUTING.html#commit-messages
 | |
| 
 | |
| You can set up this script to check your commit messages locally:
 | |
| 1. before committing:
 | |
|    a. safer but must redo:  cp bin/commitlint .git/hooks/commit-msg
 | |
|    b. more convenient:      ln -s ../../bin/commitlint .git/hooks/commit-msg
 | |
| 2. before pushing:          bin/commitlint && git push
 | |
| ---------------------------------------------------------------------------
 | |
| EOF
 | |
| 
 | |
| fi
 | |
| 
 | |
| exit 0"$STATUS"
 |