summaryrefslogtreecommitdiff
path: root/buildscripts/install-hooks
blob: 282c79f040256556eeacda5147792d82a3b3c325 (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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/bin/bash

# Create a git hook driver in this repo. The hook will run all
# excutable scripts in the directory ~/.githooks/<repo name>/[HOOK_TRIGGER]/
# where HOOK_TRIGGER can be any one of the following:
# https://git-scm.com/docs/githooks#_hooks
# If you add a new type of HOOK_TRIGGER, this script needs to be run again.

# Find out the repo name and where the .git directory is for this repo
origin="$(git config remote.origin.url)"
repo="$(basename -s .git $origin)"
tld="$(git rev-parse --show-toplevel)"

# Location for the hooks.
# WARNING: if you change this you'll need to change the value of the
# "hooks_dir" variable in the heredoc below as well
hooks_dir="$HOME/.githooks/$repo"

tmp_hook=$(mktemp)

usage() {
    echo "Usage: $(basename $0) [-f|-h]"
    echo
    echo "  git hooks in $tld/.git/hooks that run scripts in $hooks_dir"
    echo "  -f force overwriting existing hooks"
    echo "  -h print this help"
    echo
    return
}

if [ ! -d "$hooks_dir" ]; then
  # Bail out if the githooks directory doesn't exist.
  echo "Place your scripts in the directory $hooks_dir/[HOOK_TRIGGER]/ where [HOOK_TRIGGER] is the"
  echo "name of the git hook that you want your script to run under, like 'pre-push' or 'pre-commit'"
  echo
  echo "See the full list of git hooks here: https://git-scm.com/docs/githooks#_hooks"
  echo
  echo "Once you have placed your scripts, re-run this file."
  echo
  return
fi

# --- Command line options ---
force=0
while getopts fh opt_arg; do
    case $opt_arg in
        f) force=1 ;;
        *) usage   ;;
    esac
done
shift $(expr $OPTIND - 1)
# ----------------------------

set -e

cat > $tmp_hook <<'EOF'
#!/bin/bash

# set GITHOOKS_QUIET to anything to anything to make this script quiet
quiet=${GITHOOKS_QUIET:-""}
[ -z "$quiet" ] && echo -e "[INFO] Starting up hook runner ..."

origin="$(git config remote.origin.url)"
repo="$(basename -s .git $origin)"
this_script=$(basename "$0")

hooks_dir=$HOME/.githooks/$repo/$this_script
if [ ! -d "$hooks_dir" ]; then
    echo "[WARNING] Hooks directory doesn't exist: $hooks_dir. Running $this_script anyway"
    sleep 2
    exit 0
fi

# Only run if the remote URL matches the MongoDB repo.
url=$2
if [ "$this_script" == "pre-push" ] && ! [[ $url =~ (mongodb|10gen)/ ]]; then
    echo "Skipping pre-push hook for non-MongoDB remote URL: $url"
    exit 0
fi

num_hooks_run=0
all_hooks="$(/bin/ls -1 $hooks_dir 2>/dev/null)"

for hook_name in $(echo $all_hooks) ; do
    hook_path=$hooks_dir/$hook_name

    if [ -e "$hook_path" ]; then
        [ -z "$quiet" ] && echo -e "[INFO] Running hook: $hook_path"
        $hook_path "$@"
        
        hook_status=$?
        num_hooks_run=$((num_hooks_run + 1))
        
        if [ $hook_status -ne 0 ]; then
            echo "[ERROR] Hook $hook_path returned non-zero status: $hook_status"
            exit $hook_status
        else
            [ -z "$quiet" ] && echo "[INFO] Done."
        fi
    fi
done

if [ $num_hooks_run -eq 0 ]; then
    echo "[WARNING] Couldn't find any hooks to run in $hooks_dir. Running $this_script anyway"
    sleep 2
fi

exit 0
EOF

hook_types=($(ls -d $hooks_dir/*))

for cur_hook_full_path in "${hook_types[@]}"
do
    cur_hook_type=$(basename $cur_hook_full_path)
    cur_hook_path="$tld/.git/hooks/$cur_hook_type"

    echo "Installing $cur_hook_type hook in $cur_hook_path ..."

    # If there's already a hook installed, bail out. We don't want to overwrite it.
    # (unless -f is passed in the command line)
    if [ -e "$cur_hook_path" -a $force -eq 0 ]; then
        echo "[ERROR] Found an existing $cur_hook_type hook: $cur_hook_path"
        exit 1
    fi

    cp $tmp_hook $cur_hook_path
    chmod +x $cur_hook_path
done

rm $tmp_hook
echo "Done."