1#!/bin/bash
2
3# Run command on every commit within the range specified. If no command is
4# provided, use the default one to clean and build the whole tree.
5#
6# The default rune is rather simple. To do a cross-build, please put your usual
7# build rune in a shell script and invoke it with this script.
8#
9# Set NON_SYMBOLIC_REF=1 if you want to use this script in detached HEAD state.
10# This is currently used by automated test system.
11
12# Colors with ANSI escape sequences
13txt_info=''
14txt_err=''
15txt_clr=''
16
17# $GITLAB_CI should be "true" or "false".
18if [ "$GITLAB_CI" != true ]; then
19    GITLAB_CI=false
20fi
21
22gitlab_log_section() {
23    if $GITLAB_CI; then
24        echo -n "section_$1:$(date +%s):$2
24"
25    fi
26    if [ $# -ge 3 ]; then
27        echo "$3"
28    fi
29}
30log_section_last=
31log_section_start() {
32    log_section_last="${1%\[collapsed=true\]}"
33    gitlab_log_section 'start' "$1" "${txt_info}$2${txt_clr}"
34}
35log_section_end() {
36    if [ "$log_section_last" ]; then
37        gitlab_log_section 'end' "$log_section_last"
38        log_section_last=
39    fi
40}
41
42
43if test $# -lt 2 ; then
44    echo "Usage:"
45    echo " $0 <BASE> <TIP> [CMD]"
46    echo " If [CMD] is not specified, run the default command"
47    echo "     git clean -fdx && ./configure && make -j4"
48    exit 1
49fi
50
51pushd `git rev-parse --show-toplevel`
52
53if ! $GITLAB_CI; then
54    status=`git status -s`
55    if test -n "$status"; then
56        echo "Tree is dirty, aborted"
57        exit 1
58    fi
59fi
60
61BASE=$1; shift
62TIP=$1; shift
63
64if [[ "_${NON_SYMBOLIC_REF}" != "_1" ]]; then
65    ORIG=`git symbolic-ref -q --short HEAD`
66    if test $? -ne 0; then
67        echo "Detached HEAD, aborted"
68        exit 1
69    fi
70else
71    ORIG=`git rev-parse HEAD`
72fi
73
74ret=1
75while read num rev; do
76    log_section_start "commit_$rev[collapsed=true]" "Testing #$num $(git log -1 --abbrev=12 --format=tformat:'%h ("%s")' $rev)"
77
78    git checkout $rev
79    ret=$?
80    if test $ret -ne 0; then
81        log_section_end
82        echo "${txt_err}Failed to checkout $num $rev with $ret${txt_clr}"
83        break
84    fi
85
86    if test $# -eq 0 ; then
87        git clean -fdx && ./configure && make -j4
88    elif $GITLAB_CI; then
89        "$@" > "build-$num.log" 2>&1
90    else
91        "$@"
92    fi
93    ret=$?
94    if test $ret -ne 0; then
95        if $GITLAB_CI; then
96            cat "build-$num.log"
97        fi
98        log_section_end
99        echo "${txt_err}Failed at $num $rev with $ret${txt_clr}"
100        break
101    fi
102    echo
103    log_section_end
104done < <(git rev-list $BASE..$TIP | nl -ba | tac)
105
106echo "Restoring original HEAD"
107git checkout $ORIG
108gco_ret=$?
109if test $gco_ret -ne 0; then
110    echo "Failed to restore orignal HEAD. Check tree status before doing anything else!"
111    exit $gco_ret
112fi
113
114if test $ret -eq 0; then
115    echo "ok."
116fi
117exit $ret
118