Created
March 17, 2014 20:10
-
-
Save agarciadom/9607256 to your computer and use it in GitHub Desktop.
SVN hook that checks that the message mentions an open ticket in a PostgreSQL-backed Redmine installation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# SVN hook that checks that the message mentions an open ticket in a PostgreSQL-backed Redmine installation. | |
# Copyright (C) 2014 Antonio García Domínguez | |
# Licensed under the GPLv3. | |
## CONFIGURATION | |
SVNLOOK=/usr/bin/svnlook | |
PSQL=/usr/bin/psql | |
PERL=/usr/bin/perl | |
DBHOST=localhost | |
DBNAME=redmine | |
DBUSER=redmine | |
# The key is stored in ~/.pgpass, not here. | |
## ARGUMENTS | |
if [[ "$#" != 2 ]]; then | |
echo "Usage: $0 repo_path tx_id" >&2 | |
exit 200 | |
fi | |
REPO_PATH="$1" | |
TX_ID="$2" | |
## FUNCTIONS | |
commit_message() { | |
# Dumps to stdout the message for this commit. | |
"$SVNLOOK" log "$REPO_PATH" -t "$TX_ID" | |
} | |
get_issue_id() { | |
# Tries to find an issue ID in the first line of stdin. | |
"$PERL" -e '$line = <>; $line =~ /(?:refs|references|IssueID|closes|fixes|cierra|arregla)\s*#([0-9]+)/i && print $1;' | |
} | |
check_if_open() { | |
# Usage: check_if_open issue_id | |
# Preconditions: issue_id is an integer. | |
# Postconditions: zero status if issue_id is an open Redmine issue, non-zero otherwise. | |
# Use a read-only transaction to improve security. | |
cat <<EOF | | |
PREPARE check_if_open (int) AS | |
SELECT COUNT(*) AS result | |
FROM issues i JOIN issue_statuses s ON s.id = i.status_id | |
WHERE s.is_closed AND i.id = \$1; | |
BEGIN READ ONLY; | |
EXECUTE check_if_open($1); | |
EOF | |
"$PSQL" -h "$DBHOST" "$DBNAME" "$DBUSER" -qt | | |
"$PERL" -e '$line = <>; $line =~ /([0-9]+)/; exit 1 if 1 != $1;' | |
} | |
## MAIN PROGRAM | |
COMMIT_MSG=$(commit_message) | |
if [[ -z "$COMMIT_MSG" ]]; then | |
# No message | |
echo "The commit message must not be empty." >&2 | |
exit 1 | |
fi | |
ISSUE_ID=$(echo "$COMMIT_MSG" | get_issue_id) | |
if [[ -z "$ISSUE_ID" ]]; then | |
echo "The commit message does not mention any ticket on its first line." >&2 | |
echo "It should have something like 'refs #N', 'closes #N' or 'fixes #N'." >&2 | |
exit 2 | |
elif ! check_if_open "$ISSUE_ID"; then | |
echo "The ticket '$ISSUE_ID' does not exist or is not open." >&2 | |
exit 3 | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment