run-*d.sh: really fix --shell support when interrupted
[girocco.git] / shlib.sh
blobb88aa8c95c42ea002b038fdb1056a44eb954f364
1 #!/bin/sh
3 # This is generic shell library for all the scripts used by Girocco;
4 # most importantly, it introduces all the $cfg_* shell variables.
7 # Import all the variables from Girocco::Config to the local environment,
8 # prefixing them with 'cfg_'. E.g. $cfg_admin is admin's mail address now.
9 __girocco_conf="$GIROCCO_CONF"
10 [ -n "$__girocco_conf" ] || __girocco_conf="Girocco::Config"
11 [ -z "$basedir" ] || __girocco_extrainc="-I$basedir"
12 eval $(perl -I@basedir@ $__girocco_extrainc -M$__girocco_conf -le \
13 'foreach (keys %Girocco::Config::) {
14 my $val = ${$Girocco::Config::{$_}}; $val ||= "";
15 print "cfg_$_=\"$val\"";
16 }')
19 git() { "$cfg_git_bin" "$@"; }
21 nc_openbsd() { "$cfg_nc_openbsd_bin" "$@"; }
23 _addrlist() {
24 _list=
25 for _addr in "$@"; do
26 [ -z "$_list" ] || _list="$_list, "
27 _list="$_list$_addr"
28 done
29 echo "$_list"
32 _sendmail() {
33 _mailer="${cfg_sendmail_bin:-/usr/sbin/sendmail}"
34 if [ -n "$cfg_sender" ]; then
35 "$_mailer" -i -f "$cfg_sender" "$@"
36 else
37 "$_mailer" -i "$@"
41 mail() {
42 _subject=
43 if [ "$1" = "-s" ]; then
44 shift
45 _subject="$1"
46 shift
49 echo "From: \"$cfg_name\" ($cfg_title) <$cfg_admin>"
50 echo "To: $(_addrlist "$@")"
51 [ -z "$_subject" ] || echo "Subject: $_subject"
52 echo "Auto-Submitted: auto-generated"
53 echo ""
54 cat
55 } | _sendmail "$@"
58 # Supports both the bang CMD... and bang_eval CMD... functions
59 # Called when the command fails
60 # Should only be called from bang and bang_eval functions
61 bang_err() {
62 if ! [ -e .banged ]; then
63 bangmailok=true
64 ! [ -f HEAD -a -f config -a -d objects ] ||
65 bangmailok="$(GIT_DIR=. git config --bool gitweb.statusupdates 2>/dev/null || echo true)"
66 bangaddrs=''
67 [ "$bangmailok" = "false" -o -z "$mail" ] || bangaddrs="$mail"
68 [ -z "$cfg_admincc" -o "$cfg_admincc" = "0" -o -z "$cfg_admin" ] ||
69 if [ -z "$bangaddrs" ]; then bangaddrs="$cfg_admin"; else bangaddrs="$bangaddrs,$cfg_admin"; fi
70 [ -z "$bangaddrs" ] ||
72 echo "$* failed with error code $errcode"
73 echo ""
74 [ ! -n "$bang_once" ] || echo "you will not receive any more notifications until recovery"
75 echo "this status message may be disabled on the project admin page"
76 echo ""
77 echo "Log follows:"
78 echo ""
79 cat "$bang_log"
80 } | mail -s "[$cfg_name] $proj $bang_action failed" "$bangaddrs"
82 touch .banged
83 bang_trap
84 exit 1
87 # bang CMD... will execute the command with well-defined failure mode;
88 # set bang_action to string of the failed action ('clone', 'update', ...);
89 # pre-set bang_once=1 to make sure jobs banging on a repo repeatedly will
90 # not spam the owner; re-define the bang_trap() function to do custom
91 # cleanup before bailing out
92 bang() {
93 if [ -n "$show_progress" ]; then
94 exec 3>&1
95 errcode=
96 read -r errcode <<-EOT || :
98 exec 4>&3 3>&1 1>&4 4>&-
99 { "$@" 3>&- || echo $? >&3; } 2>&1 | tee -a "$bang_log"
102 exec 3>&-
103 if [ -z "$errcode" ]; then
104 # All right. Cool.
105 return;
107 else
108 if "$@" >>"$bang_log" 2>&1; then
109 # All right. Cool.
110 return;
111 else
112 errcode="$?"
115 bang_err "$@"
118 # bang_eval CMD... will evaluate the command with well-defined failure mode;
119 # Identical to bang CMD... except the command is eval'd instead of executed.
120 bang_eval() {
121 if [ -n "$show_progress" ]; then
122 exec 3>&1
123 errcode=
124 read -r errcode <<-EOT || :
126 exec 4>&3 3>&1 1>&4 4>&-
127 { eval "$*" 3>&- || echo $? >&3; } 2>&1 | tee -a "$bang_log"
130 exec 3>&-
131 if [ -z "$errcode" ]; then
132 # All right. Cool.
133 return;
135 else
136 if eval "$*" >>"$bang_log" 2>&1; then
137 # All right. Cool.
138 return;
139 else
140 errcode="$?"
143 bang_err "$@"
146 # Default bang settings:
147 bang_setup() {
148 bang_action="lame_programmer"
149 bang_once=
150 bang_trap() { :; }
151 bang_log="$(mktemp -t repomgr-XXXXXX)"
152 trap "rm \"\$bang_log\"" EXIT
156 # Progress report - if show_progress is set, shows the given message.
157 progress() {
158 [ ! -n "$show_progress" ] || echo "$@"
162 # Project config accessors; must be run in project directory
163 config_get() {
164 git config "gitweb.$1"
167 config_set() {
168 git config "gitweb.$1" "$2" && chgrp repo config && chmod g+w config
171 config_set_raw() {
172 git config "$1" "$2" && chgrp repo config && chmod g+w config
176 # Tool for checking whether given number of seconds has not passed yet
177 check_interval() {
178 od="$(config_get "$1" || :)"
179 [ -n "$od" ] || return 1
180 os="$(perl -I@basedir@ -MGirocco::Util -e "print parse_rfc2822_date('$od')")"
181 [ -n "$os" ] || return 1
182 ns="$(date +%s)"
183 [ $ns -lt $(($os+$2)) ]
187 # List all Git repositories, with given prefix if specified, one-per-line
188 get_repo_list() {
189 if [ -n "$1" ]; then
190 cut -d : -f 1,3 "$cfg_chroot"/etc/group | grep "^$1"
191 else
192 cut -d : -f 1,3 "$cfg_chroot"/etc/group
193 fi | while IFS=: read name id; do
194 [ $id -lt 65536 ] || echo "$name"
195 done