File: validate.sh

package info (click to toggle)
buildbot 4.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 21,080 kB
  • sloc: python: 174,183; sh: 1,204; makefile: 332; javascript: 119; xml: 16
file content (207 lines) | stat: -rwxr-xr-x 6,184 bytes parent folder | download | duplicates (2)
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#! /bin/bash
TEST='buildbot.test buildbot_worker.test'

# if stdout is a terminal define some colors
# validate.sh can be run as hook from GUI git clients, such as git-gui
if test -t 1; then
    # plain
    _ESC=$'\e'
    GREEN="$_ESC[0;32m"
    MAGENTA="$_ESC[0;35m"
    RED="$_ESC[0;31m"
    LTCYAN="$_ESC[1;36m"
    YELLOW="$_ESC[1;33m"
    NORM="$_ESC[0;0m"
fi

## parse options

quick=false
no_js=false
help=false
while [ $# -gt 0 ]; do
    case $1 in
        --quick) quick=true ;;
        --no-js) no_js=true ;;
        --help) help=true ;;
        -*) echo "$0: error - unrecognized option $1" 1>&2; help=true ;;
        *) REVRANGE="$1..HEAD" ;;
    esac
    shift
done

if $help; then
    echo "USAGE: common/validate.sh [oldrev] [--quick] [--no-js] [--help]"
    echo "  This script will test a set of patches (oldrev..HEAD) for basic acceptability as a patch"
    echo "  Run it in an activated virtualenv with the current Buildbot installed, as well as"
    echo "      sphinx, ruff and so on"
    echo "To use a different directory for tests, pass TRIALTMP=/path as an env variable"
    echo "if --quick is passed validate will skip unit tests and concentrate on coding style"
    echo "if --no-js is passed validate will skip tests that require Node and NPM"
    echo "if --help is passed validate will output this message and exit"
    echo "if no oldrev is passed validate will assume master...HEAD"
    exit 1
fi

[ -z "$REVRANGE" ] && REVRANGE="master..HEAD"

status() {
    echo "${LTCYAN}-- ${*} --${NORM}"
}

ok=true
problem_summary=""
not_ok() {
    ok=false
    echo "${RED}** ${*} **${NORM}"
    problem_summary="$problem_summary"$'\n'"${RED}**${NORM} ${*}"
}

warning() {
    echo "${YELLOW}** ${*} **${NORM}"
    problem_summary="$problem_summary"$'\n'"${YELLOW}**${NORM} ${*} (warning)"
}

check_tabs() {
    git diff "$REVRANGE" | grep -q $'+.*\t'
}

check_long_lines() {
    # only check python files
    local long_lines=false
    for f in $(git diff --name-only --stat "$REVRANGE" | grep '.py$'); do
        # don't try to check removed files
        [ ! -f "$f" ] && continue
        if [ $(git diff "$REVRANGE" $f | grep -E -c '^\+.{80}') != 0 ]; then
            echo " $f"
            long_lines=true
        fi
    done
    $long_lines
}


check_relnotes() {
    if git diff --exit-code "$REVRANGE" master/docs/relnotes/index.rst >/dev/null 2>&1; then
        return 1
    else
        return 0
    fi
}

check_sa_Table() {
    local bad_files=$(git grep -l 'sa\.Table(' | grep '\.py$' | grep -v '^master/buildbot/util/sautils\.py$')
    if [ -n "${bad_files}" ]; then
        echo "${YELLOW}Source files found containing 'sa.Table':${NORM}"
        for f in $bad_files; do
            echo " ${YELLOW}*${NORM} $f"
        done
        echo "${YELLOW}import buildbot.util.sautils and use sautils.Table instead.${NORM}"
        return 1
    fi
    return 0
}

run_tests() {
    if [ -n "${TRIALTMP}" ]; then
        TEMP_DIRECTORY_OPT="--temp-directory ${TRIALTMP}"
    else
        warning "please provide a TRIALTMP env variable pointing to a ramfs for 30x speed up of the integration tests"
    fi
    find . -name \*.pyc -exec rm {} \;
    trial --reporter text ${TEMP_DIRECTORY_OPT} ${TEST}
}

if ! git diff --no-ext-diff --quiet --exit-code; then
    not_ok "changed files in working copy"
    if ! $quick; then
        exit 1
    fi
fi

# get a list of changed files, used below; this uses a tempfile to work around
# shell behavior when piping to 'while'
tempfile=$(mktemp -t tmp.XXXXXX)
trap "rm -f ${tempfile}; exit 1" 1 2 3 15
git diff --name-only $REVRANGE | grep '\.py$' | grep -v '\(^master/docs\|/setup\.py\)' > ${tempfile}
py_files=()
while read line; do
    if test -f "${line}"; then
        py_files+=($line)
    fi
done < ${tempfile}

echo "${MAGENTA}Validating the following commits:${NORM}"
git log "$REVRANGE" --pretty=oneline || exit 1

if ! $quick && ! $no_js; then
    for module in www/base www/console_view www/grid_view www/waterfall_view www/wsgi_dashboards www/badges;
    do
        status "running 'pip install -e' for $module"
        if ! (cd $module; pip install -e . >/dev/null ); then
            warning "pip install -e for $module failed; retrying with cleared build/ dist/"
            rm -rf "$module/build" "$module/dist"
            (cd $module; pip install -e . >/dev/null ) || not_ok "$module/setup.py failed"
        fi
    done
else
    warning "Skipping JavaScript Tests"
fi

if ! $quick; then
    status "running Python tests"
    run_tests || not_ok "Python tests failed"
elif [ -z `command -v cctrial` ]; then
    warning "Skipping Python Tests ('pip install cctrial' for quick tests)"
else
    cctrial -H buildbot buildbot_worker || not_ok "Python tests failed"
fi

status "checking formatting"
check_tabs && not_ok "$REVRANGE adds tabs"
check_long_lines && warning "$REVRANGE adds long lines"

status "checking for use of sa.Table"
check_sa_Table || warning "use (buildbot.util.)sautils.Table instead of sa.Table"

status "checking for release notes"
check_relnotes || warning "$REVRANGE does not add release notes"

if [ ${#py_files[@]} -ne 0 ]; then
    status "checking import module convention in modified files"
    if [[ -z `command -v ruff` ]]; then
        warning "ruff is not installed"
    else
        if ! ruff --fix ${py_files[@]}; then
            warning "unable to run ruff on modified files"
        else
            if ! git diff --quiet --exit-code ${py_files[@]}; then
                not_ok "ruff made changes"
            fi
        fi
    fi
fi

if git diff --name-only $REVRANGE | grep ^master/docs/ ; then
    status "building docs"
    # Don't clean builddir if built in quick mode
    if ! $quick ; then
        make -C master/docs clean || not_ok "docs cleanup failed"
    fi
    make -C master/docs VERSION=latest html || not_ok "docs failed"
else
    status "not building docs, because it was not changed"
fi

echo ""
if $ok; then
    if [ -z "${problem_summary}" ]; then
        echo "${GREEN}GOOD!${NORM}"
    else
        echo "${YELLOW}WARNINGS${NORM}${problem_summary}"
    fi
    exit 0
else
    echo "${RED}NO GOOD!${NORM}${problem_summary}"
    exit 1
fi