#!/bin/bash # refs data via STDIN - one line per target ref (where ref_data is: prev_sha curr_sha ref_file) # e.g. # a559985626bbf4448ccf9041857449078db6d731 1d5002ade3f71200274f1ba39e35a732d86220b5 refs/heads/master # 0000000000000000000000000000000000000000 1d5002ade3f71200274f1ba39e35a732d86220b5 refs/heads/new-branch ## constants ## readonly LOG_PBOT_GIT_HOOK=1 readonly LOG_DIR=/var/log/pbot readonly SHA_REGEX='^([0-9a-f]{40})$' ## logging ## LogFile() # (repo ref) { local repo=$1 local ref=$2 local log_file=${LOG_DIR}/notify-pbot-${repo}-${ref} echo ${log_file} } LogParseRefDataIn() # (ref_data prev_sha curr_sha ref_file repo ref is_deletion) { local ref_data=$1 ; local prev_sha=$2 ; local curr_sha=$3 ; local ref_file=$4 ; local repo=$5 ; local ref=$6 ; local is_deletion=$7 ; local log_file=$(LogFile ${repo} ${ref}) (( $LOG_PBOT_GIT_HOOK )) && echo "ref_data=${ref_data}" > ${log_file} && \ echo "prev=${prev_sha}" >> ${log_file} && \ echo "curr=${curr_sha}" >> ${log_file} && \ echo "ref_file=${ref_file}" >> ${log_file} && \ echo "ref=${ref}" >> ${log_file} && \ echo "is_deletion=${is_deletion}" >> ${log_file} } LogParseRefDataOut() # (hacker author log_msg n_behind n_ahead n_total repo ref) { local hacker=$1 ; local author=$2 ; local log_msg=$3 ; local n_behind=$4 ; local n_ahead=$5 ; local n_total=$6 ; local repo=$7 ; local ref=$8 ; local log_file=$(LogFile ${repo} ${ref}) (( $LOG_PBOT_GIT_HOOK )) && echo "hacker=${hacker}" >> ${log_file} && \ echo "author=${author}" >> ${log_file} && \ echo "log_msg=${log_msg}" >> ${log_file} && \ echo "n_behind=${n_behind}" >> ${log_file} && \ echo "n_ahead=${n_ahead}" >> ${log_file} && \ echo "n_total=${n_total}" >> ${log_file} && \ echo "repo=${repo}" >> ${log_file} } ## helpers ## ParseRefData() # (prev_sha curr_sha ref_file) { local prev_sha=$1 local curr_sha=$2 local ref_file=$3 local ref=${ref_file##*/} local repo=$(basename $(pwd)) local is_deletion=$(git show-ref "${ref}" > /dev/null && echo 0 || echo 1) LogParseRefDataIn "${ref_data}" ${prev_sha} ${curr_sha} ${ref_file} ${repo} ${ref} ${is_deletion} # validate ref data [[ "$#" == '3' ]] && \ [[ "${prev_sha}" =~ ${SHA_REGEX} ]] && \ [[ "${curr_sha}" =~ ${SHA_REGEX} ]] && \ [[ "${ref}" ]] || return # collect push details local hacker=$( /usr/lib/parabola-hackers/last-hacker-login ) local author="$( git log -1 --format='%an' ${curr_sha} )" local log_msg="$(git log -1 --format='%s' ${curr_sha} )" local n_behind=$(git rev-list --count ${curr_sha}..${prev_sha} 2> /dev/null) local n_ahead=$( git rev-list --count ${prev_sha}..${curr_sha} 2> /dev/null) local n_total=$( git rev-list --count ${ref} 2> /dev/null) LogParseRefDataOut ${hacker} ${author} ${log_msg} ${n_behind} ${n_ahead} ${n_total} ${repo} ${ref} # fall-back to author name if the hacker detector fails [[ "${hacker}" ]] || hacker="${author}" # detect new ref [[ ${prev_sha} =~ ^0{40}$ ]] && n_behind='∞' n_ahead=${n_total} # prepare pbot message if (( ${is_deletion} )) then echo "${hacker} deleted ${repo}/${ref}" else echo "${hacker} pushed (-${n_behind} +${n_ahead}) commits to ${repo}/${ref}: ${log_msg}" fi } ## main entry ## while read ref_data ; do pbot-say "$(ParseRefData ${ref_data})" ; done ;