Skip to content

Commit 4566251

Browse files
lestevejnothman
authored andcommitted
[MRG+3] Add flake8 linting of the diff in Travis (scikit-learn#7127)
* Add flake8 linting on the diff with respect to common ancestor of branch and scikit-learn/scikit-learn remote. Add a flake8-diff target in the Makefile and mention it in the doc. * Only install flake8 when needed
1 parent 845e702 commit 4566251

File tree

6 files changed

+151
-36
lines changed

6 files changed

+151
-36
lines changed

.travis.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ env:
4242
- DISTRIB="conda" PYTHON_VERSION="3.5" INSTALL_MKL="true"
4343
NUMPY_VERSION="1.10.4" SCIPY_VERSION="0.17.0" CYTHON_VERSION="0.23.4"
4444
CACHED_BUILD_DIR="$HOME/sklearn_build_latest"
45+
# flake8 linting on diff wrt common ancestor with upstream/master
46+
- RUN_FLAKE8="true" SKIP_TESTS="true"
47+
DISTRIB="conda" PYTHON_VERSION="3.5" INSTALL_MKL="true"
48+
NUMPY_VERSION="1.10.4" SCIPY_VERSION="0.17.0" CYTHON_VERSION="0.23.4"
49+
CACHED_BUILD_DIR="$HOME/dummy"
50+
4551

4652
matrix:
4753
allow_failures:

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,6 @@ doc-noplot: inplace
6868
code-analysis:
6969
flake8 sklearn | grep -v __init__ | grep -v external
7070
pylint -E -i y sklearn/ -d E1103,E0611,E1101
71+
72+
flake8-diff:
73+
./build_tools/travis/flake8_diff.sh

build_tools/travis/flake8_diff.sh

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/bin/bash
2+
3+
# This script is used in Travis to check that PRs do not add obvious
4+
# flake8 violations. It relies on two things:
5+
# - find common ancestor between branch and
6+
# scikit-learn/scikit-learn remote
7+
# - run flake8 --diff on the diff between the branch and the common
8+
# ancestor
9+
#
10+
# Additional features:
11+
# - the line numbers in Travis match the local branch on the PR
12+
# author machine.
13+
# - ./build_tools/travis/flake8_diff.sh can be run locally for quick
14+
# turn-around
15+
16+
set -e
17+
18+
PROJECT=scikit-learn/scikit-learn
19+
PROJECT_URL=https://github.com/$PROJECT.git
20+
21+
echo "Remotes:"
22+
git remote --verbose
23+
24+
# Find the remote with the project name (upstream in most cases)
25+
REMOTE=$(git remote -v | grep $PROJECT | cut -f1 | head -1)
26+
27+
# Add a temporary remote if needed. For example this is necessary when
28+
# Travis is configured to run in a fork. In this case 'origin' is the
29+
# fork and not the reference repo we want to diff against.
30+
if [[ -z "$REMOTE" ]]; then
31+
TMP_REMOTE=tmp_reference_upstream
32+
REMOTE=$TMP_REMOTE
33+
git remote add $REMOTE $PROJECT_URL
34+
fi
35+
36+
if [[ "$TRAVIS" == "true" ]]; then
37+
if [[ "$TRAVIS_PULL_REQUEST" == "false" ]]
38+
then
39+
# Travis does the git clone with a limited depth (50 at the time of
40+
# writing). This may not be enough to find the common ancestor with
41+
# $REMOTE/master so we unshallow the git checkout
42+
git fetch --unshallow || echo "Unshallowing the git checkout failed"
43+
else
44+
# We want to fetch the code as it is in the PR branch and not
45+
# the result of the merge into master. This way line numbers
46+
# reported by Travis will match with the local code.
47+
BRANCH_NAME=travis_pr_$TRAVIS_PULL_REQUEST
48+
git fetch $REMOTE pull/$TRAVIS_PULL_REQUEST/head:$BRANCH_NAME
49+
git checkout $BRANCH_NAME
50+
fi
51+
fi
52+
53+
54+
echo -e '\nLast 2 commits:'
55+
echo '--------------------------------------------------------------------------------'
56+
git log -2 --pretty=short
57+
58+
git fetch $REMOTE master
59+
REMOTE_MASTER_REF="$REMOTE/master"
60+
61+
# Find common ancestor between HEAD and remotes/$REMOTE/master
62+
COMMIT=$(git merge-base @ $REMOTE_MASTER_REF) || \
63+
echo "No common ancestor found for $(git show @ -q) and $(git show $REMOTE_MASTER_REF -q)"
64+
65+
if [[ -n "$TMP_REMOTE" ]]; then
66+
git remote remove $TMP_REMOTE
67+
fi
68+
69+
if [ -z "$COMMIT" ]; then
70+
exit 1
71+
fi
72+
73+
echo -e "\nCommon ancestor between HEAD and $REMOTE_MASTER_REF is:"
74+
echo '--------------------------------------------------------------------------------'
75+
git show --no-patch $COMMIT
76+
77+
echo -e '\nRunning flake8 on the diff in the range'\
78+
"$(git rev-parse --short $COMMIT)..$(git rev-parse --short @)" \
79+
"($(git rev-list $COMMIT.. | wc -l) commit(s)):"
80+
echo '--------------------------------------------------------------------------------'
81+
82+
# Conservative approach: diff without context so that code that was
83+
# not changed does not create failures
84+
git diff --unified=0 $COMMIT | flake8 --diff --show-source
85+
echo -e "No problem detected by flake8\n"

build_tools/travis/install.sh

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ if [[ "$DISTRIB" == "conda" ]]; then
5353
if [[ "$INSTALL_MKL" == "true" ]]; then
5454
conda create -n testenv --yes python=$PYTHON_VERSION pip nose \
5555
numpy=$NUMPY_VERSION scipy=$SCIPY_VERSION numpy scipy \
56-
cython=$CYTHON_VERSION libgfortran mkl
56+
cython=$CYTHON_VERSION libgfortran mkl flake8
5757
else
5858
conda create -n testenv --yes python=$PYTHON_VERSION pip nose \
5959
numpy=$NUMPY_VERSION scipy=$SCIPY_VERSION cython=$CYTHON_VERSION \
@@ -95,18 +95,26 @@ if [[ "$COVERAGE" == "true" ]]; then
9595
pip install coverage coveralls
9696
fi
9797

98-
if [ ! -d "$CACHED_BUILD_DIR" ]; then
99-
mkdir -p $CACHED_BUILD_DIR
100-
fi
98+
if [[ "$SKIP_TESTS" == "true" ]]; then
99+
echo "No need to build scikit-learn when not running the tests"
100+
else
101+
if [ ! -d "$CACHED_BUILD_DIR" ]; then
102+
mkdir -p $CACHED_BUILD_DIR
103+
fi
101104

102-
rsync -av --exclude '.git/' --exclude='testvenv/' \
103-
$TRAVIS_BUILD_DIR $CACHED_BUILD_DIR
105+
rsync -av --exclude '.git/' --exclude='testvenv/' \
106+
$TRAVIS_BUILD_DIR $CACHED_BUILD_DIR
104107

105-
cd $CACHED_BUILD_DIR/scikit-learn
108+
cd $CACHED_BUILD_DIR/scikit-learn
106109

107-
# Build scikit-learn in the install.sh script to collapse the verbose
108-
# build output in the travis output when it succeeds.
109-
python --version
110-
python -c "import numpy; print('numpy %s' % numpy.__version__)"
111-
python -c "import scipy; print('scipy %s' % scipy.__version__)"
112-
python setup.py develop
110+
# Build scikit-learn in the install.sh script to collapse the verbose
111+
# build output in the travis output when it succeeds.
112+
python --version
113+
python -c "import numpy; print('numpy %s' % numpy.__version__)"
114+
python -c "import scipy; print('scipy %s' % scipy.__version__)"
115+
python setup.py develop
116+
fi
117+
118+
if [[ "$RUN_FLAKE8" == "true" ]]; then
119+
conda install flake8
120+
fi

build_tools/travis/test_script.sh

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,42 @@
88

99
set -e
1010

11-
# Get into a temp directory to run test from the installed scikit learn and
12-
# check if we do not leave artifacts
13-
mkdir -p $TEST_DIR
14-
# We need the setup.cfg for the nose settings
15-
cp setup.cfg $TEST_DIR
16-
cd $TEST_DIR
17-
1811
python --version
1912
python -c "import numpy; print('numpy %s' % numpy.__version__)"
2013
python -c "import scipy; print('scipy %s' % scipy.__version__)"
2114
python -c "import multiprocessing as mp; print('%d CPUs' % mp.cpu_count())"
2215

23-
# Skip tests that require large downloads over the network to save bandwidth
24-
# usage as travis workers are stateless and therefore traditional local
25-
# disk caching does not work.
26-
export SKLEARN_SKIP_NETWORK_TESTS=1
27-
28-
if [[ "$COVERAGE" == "true" ]]; then
29-
nosetests -s --with-coverage --with-timer --timer-top-n 20 sklearn
30-
else
31-
nosetests -s --with-timer --timer-top-n 20 sklearn
16+
run_tests() {
17+
# Get into a temp directory to run test from the installed scikit learn and
18+
# check if we do not leave artifacts
19+
mkdir -p $TEST_DIR
20+
# We need the setup.cfg for the nose settings
21+
cp setup.cfg $TEST_DIR
22+
cd $TEST_DIR
23+
24+
# Skip tests that require large downloads over the network to save bandwidth
25+
# usage as travis workers are stateless and therefore traditional local
26+
# disk caching does not work.
27+
export SKLEARN_SKIP_NETWORK_TESTS=1
28+
29+
if [[ "$COVERAGE" == "true" ]]; then
30+
nosetests -s --with-coverage --with-timer --timer-top-n 20 sklearn
31+
else
32+
nosetests -s --with-timer --timer-top-n 20 sklearn
33+
fi
34+
35+
# Is directory still empty ?
36+
ls -ltra
37+
38+
# Test doc
39+
cd $CACHED_BUILD_DIR/scikit-learn
40+
make test-doc test-sphinxext
41+
}
42+
43+
if [[ "$RUN_FLAKE8" == "true" ]]; then
44+
source build_tools/travis/flake8_diff.sh
3245
fi
3346

34-
# Is directory still empty ?
35-
ls -ltra
36-
37-
# Test doc
38-
cd $CACHED_BUILD_DIR/scikit-learn
39-
make test-doc test-sphinxext
47+
if [[ "$SKIP_TESTS" != "true" ]]; then
48+
run_tests
49+
fi

doc/developers/contributing.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,10 @@ Contributing pull requests
157157
It is recommended to check that your contribution complies with the following
158158
rules before submitting a pull request:
159159

160-
* Follow the `coding-guidelines`_ (see below).
160+
* Follow the `coding-guidelines`_ (see below). To make sure that
161+
your PR does not add PEP8 violations you can run
162+
`./build_tools/travis/flake8_diff.sh` or `make flake8-diff` on a
163+
Unix-like system.
161164

162165
* When applicable, use the validation tools and other code in the
163166
``sklearn.utils`` submodule. A list of utility routines available

0 commit comments

Comments
 (0)