#!/bin/bash # # hg_commit_message.sh # # Copyright (C) 2013, Branko Majic # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # program="hg_commit_message.sh" version="0.1-dev" function usage() { cat <. EOF } function version() { cat < | | | | This program is free software: you can redistribute it and/or modify | | it under the terms of the GNU General Public License as published by | | the Free Software Foundation, either version 3 of the License, or | | (at your option) any later version. | | | | This program is distributed in the hope that it will be useful, | | but WITHOUT ANY WARRANTY; without even the implied warranty of | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | | GNU General Public License for more details. | | | | You should have received a copy of the GNU General Public License | | along with this program. If not, see . | +-----------------------------------------------------------------------+ EOF } # Set-up colours for message printing if we're not piping and terminal is # capable of outputting the colors. _color_terminal=$(tput colors 2>&1) if [[ -t 1 ]] && (( ${_color_terminal} > 0 )); then _text_bold=$(tput bold) _text_white=$(tput setaf 7) _text_blue=$(tput setaf 6) _text_green=$(tput setaf 2) _text_yellow=$(tput setaf 3) _text_red=$(tput setaf 1) _text_reset=$(tput sgr0) else _text_bold="" _text_white="" _text_blue="" _text_green="" _text_yellow="" _text_red="" _text_reset="" fi # Set-up functions for printing coloured messages. function debug() { echo "${_text_bold}${_text_blue}[DEBUG]${_text_reset}" "$@" } function info() { echo "${_text_bold}${_text_white}[INFO] ${_text_reset}" "$@" } function success() { echo "${_text_bold}${_text_green}[OK] ${_text_reset}" "$@" } function warning() { echo "${_text_bold}${_text_yellow}[WARN] ${_text_reset}" "$@" } function error() { echo "${_text_bold}${_text_red}[ERROR]${_text_reset}" "$@" >&2 } # Set-up the error codes. ERR_INVALID_ARGUMENT=1 ERR_INVALID_FORMAT=2 ERR_INVALID_CALL=3 # If no arguments were given, just show usage help. if [[ -z $1 ]]; then usage exit 0 fi # Set-up some defaults. grep_options="-qe" error_message="The following commit message did not validate against the regular expression '%s':" config_section="commit_message" # Parse the arguments while getopts "em:vh" opt; do case "$opt" in e) grep_options="-qEe";; m) error_message="$OPTARG";; v) version exit 0;; h) usage exit 0;; *) usage exit $ERR_INVALID_ARGUMENT;; esac done i=$OPTIND shift $(($i-1)) # Make sure that only one positional argument was provided. if [[ ${#@} != 1 ]]; then error "Incorrect number of positional arguments was provided (${#@} instead of 1)." exit $ERR_INVALID_ARGUMENT fi # Read the positional arguments. regex="$1" # Read options from the Mercurial configuration files. if [[ $regex == "hgrc" ]]; then regex=$(hg showconfig "${config_section}.regex") if [[ $(hg showconfig "${config_section}.extended_regex") == "True" ]]; then grep_options="-qEe" fi hgrc_error_message=$(hg showconfig "${config_section}.error_message") if [[ -n "$hgrc_error_message" ]]; then error_message="$hgrc_error_message" fi fi # Verify the arguments. if [[ -z $regex ]]; then error "Regular expression may not be empty." exit $ERR_INVALID_ARGUMENT fi if [[ -z $error_message ]]; then error "Error message may not be empty." exit $ERR_INVALID_ARGUMENT fi if [[ -z $HG_NODE ]]; then error "Improper use of hook. No HG_NODE variable was set prior to hook execution." exit $ERR_INVALID_CALL fi # Validate all commit messages, starting from the first new node, all the way up # to the tip. for node in $(hg log -r "${HG_NODE}:tip" --template '{node}\n'); do message=$(hg log -r "$node" --template '{desc}') if ! echo "$message" | grep "$grep_options" "$regex"; then error "$(printf "$error_message" "$regex")" error "Changeset: $node" error "^${message}$" exit $ERR_INVALID_FORMAT fi done success "All commit messages have passed the format validation." exit 0