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
|