[5129] | 1 | #!/bin/bash |
---|
| 2 | #------------------------------------------------------------------------------- |
---|
| 3 | # Copyright (C) 2006-2021 British Crown (Met Office) & Contributors. |
---|
| 4 | # |
---|
| 5 | # This file is part of FCM, tools for managing and building source code. |
---|
| 6 | # |
---|
| 7 | # FCM is free software: you can redistribute it and/or modify |
---|
| 8 | # it under the terms of the GNU General Public License as published by |
---|
| 9 | # the Free Software Foundation, either version 3 of the License, or |
---|
| 10 | # (at your option) any later version. |
---|
| 11 | # |
---|
| 12 | # FCM is distributed in the hope that it will be useful, |
---|
| 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 15 | # GNU General Public License for more details. |
---|
| 16 | # |
---|
| 17 | # You should have received a copy of the GNU General Public License |
---|
| 18 | # along with FCM. If not, see <http://www.gnu.org/licenses/>. |
---|
| 19 | #------------------------------------------------------------------------------- |
---|
| 20 | # NAME |
---|
| 21 | # pre-commit |
---|
| 22 | # |
---|
| 23 | # SYNOPSIS |
---|
| 24 | # pre-commit REPOS TXN |
---|
| 25 | # |
---|
| 26 | # ARGUMENTS |
---|
| 27 | # REPOS - the path to the Subversion repository |
---|
| 28 | # TXN - the commit transaction |
---|
| 29 | # |
---|
| 30 | # DESCRIPTION |
---|
| 31 | # This script performs pre-commit check, including: |
---|
| 32 | # 1. Path-based permission check using "svnperms.py", if |
---|
| 33 | # "$REPOS/hooks/svnperms.conf" exists. |
---|
| 34 | # 2. Size check. Transaction should occupy less than 10MB, or the number of |
---|
| 35 | # MB specified in "$REPOS/hooks/pre-commit-size-threshold.conf". |
---|
| 36 | # 3. Runs "$REPOS/hooks/pre-commit-custom" if it exists. |
---|
| 37 | # |
---|
| 38 | # ENVIRONMENT VARIABLES |
---|
| 39 | # FCM_SVN_HOOK_ADMIN_EMAIL |
---|
| 40 | # The name of the admin team. (Default is "Admin".) |
---|
| 41 | #------------------------------------------------------------------------------- |
---|
| 42 | set -eu |
---|
| 43 | |
---|
| 44 | REPOS=$1 |
---|
| 45 | TXN=$2 |
---|
| 46 | |
---|
| 47 | export PATH=${PATH:-'/usr/local/bin:/bin:/usr/bin'}:$(dirname $0) |
---|
| 48 | THIS=$(basename $0) |
---|
| 49 | USER=${USER:-$(whoami)} |
---|
| 50 | NAME=$(basename "$REPOS") |
---|
| 51 | LOG_TXN="$REPOS/log/$THIS-$TXN.log" |
---|
| 52 | |
---|
| 53 | begin() { |
---|
| 54 | local NOW=$(date -u +%FT%H:%M:%SZ) |
---|
| 55 | local AUTHOR=$(svnlook author -t "$TXN" "$REPOS") |
---|
| 56 | echo "$NOW+ $TXN by $AUTHOR" |
---|
| 57 | svnlook changed -t "$TXN" "$REPOS" |
---|
| 58 | } |
---|
| 59 | |
---|
| 60 | main() { |
---|
| 61 | local ADMIN_EMAIL=${FCM_SVN_HOOK_ADMIN_EMAIL:-Admin} |
---|
| 62 | |
---|
| 63 | # Check size. |
---|
| 64 | local MB=1048576 |
---|
| 65 | local THRESHOLD=10 |
---|
| 66 | local SIZE_THRESHOLD_FILE="$REPOS/hooks/$THIS-size-threshold.conf" |
---|
| 67 | if [[ -f "$SIZE_THRESHOLD_FILE" && -r "$SIZE_THRESHOLD_FILE" ]]; then |
---|
| 68 | THRESHOLD=$(<"$SIZE_THRESHOLD_FILE") |
---|
| 69 | fi |
---|
| 70 | local TXN_FILE="$REPOS/db/txn-protorevs/$TXN.rev" |
---|
| 71 | local SIZE=$(du -b "$TXN_FILE" | cut -f 1) |
---|
| 72 | if ((SIZE > THRESHOLD * MB)); then |
---|
| 73 | SIZE=$(du -h "$TXN_FILE" | cut -f 1) |
---|
| 74 | echo "$NAME@$TXN: changeset size ${SIZE}B exceeds ${THRESHOLD}MB." >&2 |
---|
| 75 | echo "Email $ADMIN_EMAIL if you need to bypass this restriction." >&2 |
---|
| 76 | return 1 |
---|
| 77 | elif ((SIZE > MB)); then |
---|
| 78 | # Log any changesets bigger than 1MB |
---|
| 79 | SIZE=$(du -h "$TXN_FILE" | cut -f 1) |
---|
| 80 | echo "$NAME@$TXN: changeset size ${SIZE}B exceeds 1MB." >&2 |
---|
| 81 | fi |
---|
| 82 | |
---|
| 83 | # Check permission. |
---|
| 84 | local PERM_CONFIG="$REPOS/hooks/svnperms.conf" |
---|
| 85 | if [[ -r "$PERM_CONFIG" && -s "$PERM_CONFIG" ]]; then |
---|
| 86 | svnperms.py -r "$REPOS" -t "$TXN" -f "$PERM_CONFIG" || return $? |
---|
| 87 | elif [[ -L "$PERM_CONFIG" ]]; then |
---|
| 88 | echo "$NAME: permission configuration file not found." >&2 |
---|
| 89 | echo "$ADMIN_EMAIL has been notified." >&2 |
---|
| 90 | return 1 |
---|
| 91 | fi |
---|
| 92 | |
---|
| 93 | # Verify owner of any new branches, if relevant |
---|
| 94 | local COMMIT_CONFIG="${REPOS}/hooks/commit.conf" |
---|
| 95 | if grep -q 'verify-branch-owner' "$COMMIT_CONFIG" 2>/dev/null; then |
---|
| 96 | pre-commit-verify-branch-owner "$REPOS" "$TXN" || return $? |
---|
| 97 | fi |
---|
| 98 | |
---|
| 99 | # Custom checking, if required |
---|
| 100 | local CUSTOM_HOOK="$REPOS/hooks/$THIS-custom" |
---|
| 101 | if [[ -x "$CUSTOM_HOOK" ]]; then |
---|
| 102 | "$CUSTOM_HOOK" "$REPOS" "$TXN" || return $? |
---|
| 103 | fi |
---|
| 104 | } |
---|
| 105 | |
---|
| 106 | RET_CODE=0 |
---|
| 107 | begin 1>"${LOG_TXN}" 2>&1 |
---|
| 108 | LOG_TXN_SIZE="$(stat -c '%s' "${LOG_TXN}")" |
---|
| 109 | if ! main 1>>"${LOG_TXN}" 2>&1; then |
---|
| 110 | if [[ -n ${FCM_SVN_HOOK_ADMIN_EMAIL:-} ]]; then |
---|
| 111 | FROM= |
---|
| 112 | if [[ -n ${FCM_SVN_HOOK_NOTIFICATION_FROM:-} ]]; then |
---|
| 113 | FROM="-r${FCM_SVN_HOOK_NOTIFICATION_FROM:-}" |
---|
| 114 | fi |
---|
| 115 | mail "$FROM" -s "[$THIS] $REPOS@$TXN" \ |
---|
| 116 | "$FCM_SVN_HOOK_ADMIN_EMAIL" <"$LOG_TXN" || true |
---|
| 117 | fi |
---|
| 118 | cat "$LOG_TXN" |
---|
| 119 | cat "$LOG_TXN" >&2 |
---|
| 120 | RET_CODE=1 |
---|
| 121 | elif [[ "${LOG_TXN_SIZE}" != "$(stat -c '%s' "${LOG_TXN}")" ]]; then |
---|
| 122 | cat "$LOG_TXN" |
---|
| 123 | fi |
---|
| 124 | rm -f "$LOG_TXN" |
---|
| 125 | exit $RET_CODE |
---|