summaryrefslogtreecommitdiff
path: root/notify-pbot-git-hook
blob: 8331c149e139be6080815c534e129acb395bc01a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/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 ;