1+ #! /bin/bash
2+
3+ # Inspired from https://github.com/scikit-learn/scikit-learn/blob/master/build_tools/travis/flake8_diff.sh
4+
5+ # This script is used in Travis to check that PRs do not add obvious
6+ # flake8 violations. It relies on two things:
7+ # - find common ancestor between branch and
8+ # openml/openml-python remote
9+ # - run flake8 --diff on the diff between the branch and the common
10+ # ancestor
11+ #
12+ # Additional features:
13+ # - the line numbers in Travis match the local branch on the PR
14+ # author machine.
15+ # - ./ci_scripts/flake8_diff.sh can be run locally for quick
16+ # turn-around
17+
18+ set -e
19+ # pipefail is necessary to propagate exit codes
20+ set -o pipefail
21+
22+ PROJECT=openml/openml-python
23+ PROJECT_URL=https://github.com/$PROJECT .git
24+
25+ # Find the remote with the project name (upstream in most cases)
26+ REMOTE=$( git remote -v | grep $PROJECT | cut -f1 | head -1 || echo ' ' )
27+
28+ # Add a temporary remote if needed. For example this is necessary when
29+ # Travis is configured to run in a fork. In this case 'origin' is the
30+ # fork and not the reference repo we want to diff against.
31+ if [[ -z " $REMOTE " ]]; then
32+ TMP_REMOTE=tmp_reference_upstream
33+ REMOTE=$TMP_REMOTE
34+ git remote add $REMOTE $PROJECT_URL
35+ fi
36+
37+ echo " Remotes:"
38+ echo ' --------------------------------------------------------------------------------'
39+ git remote --verbose
40+
41+ # Travis does the git clone with a limited depth (50 at the time of
42+ # writing). This may not be enough to find the common ancestor with
43+ # $REMOTE/develop so we unshallow the git checkout
44+ if [[ -a .git/shallow ]]; then
45+ echo -e ' \nTrying to unshallow the repo:'
46+ echo ' --------------------------------------------------------------------------------'
47+ git fetch --unshallow
48+ fi
49+
50+ if [[ " $TRAVIS " == " true" ]]; then
51+ if [[ " $TRAVIS_PULL_REQUEST " == " false" ]]
52+ then
53+ # In main repo, using TRAVIS_COMMIT_RANGE to test the commits
54+ # that were pushed into a branch
55+ if [[ " $PROJECT " == " $TRAVIS_REPO_SLUG " ]]; then
56+ if [[ -z " $TRAVIS_COMMIT_RANGE " ]]; then
57+ echo " New branch, no commit range from Travis so passing this test by convention"
58+ exit 0
59+ fi
60+ COMMIT_RANGE=$TRAVIS_COMMIT_RANGE
61+ fi
62+ else
63+ # We want to fetch the code as it is in the PR branch and not
64+ # the result of the merge into develop. This way line numbers
65+ # reported by Travis will match with the local code.
66+ LOCAL_BRANCH_REF=travis_pr_$TRAVIS_PULL_REQUEST
67+ # In Travis the PR target is always origin
68+ git fetch origin pull/$TRAVIS_PULL_REQUEST /head:refs/$LOCAL_BRANCH_REF
69+ fi
70+ fi
71+
72+ # If not using the commit range from Travis we need to find the common
73+ # ancestor between $LOCAL_BRANCH_REF and $REMOTE/develop
74+ if [[ -z " $COMMIT_RANGE " ]]; then
75+ if [[ -z " $LOCAL_BRANCH_REF " ]]; then
76+ LOCAL_BRANCH_REF=$( git rev-parse --abbrev-ref HEAD)
77+ fi
78+ echo -e " \nLast 2 commits in $LOCAL_BRANCH_REF :"
79+ echo ' --------------------------------------------------------------------------------'
80+ git --no-pager log -2 $LOCAL_BRANCH_REF
81+
82+ REMOTE_DEV_REF=" $REMOTE /develop"
83+ # Make sure that $REMOTE_DEV_REF is a valid reference
84+ echo -e " \nFetching $REMOTE_DEV_REF "
85+ echo ' --------------------------------------------------------------------------------'
86+ git fetch $REMOTE develop:refs/remotes/$REMOTE_DEV_REF
87+ LOCAL_BRANCH_SHORT_HASH=$( git rev-parse --short $LOCAL_BRANCH_REF )
88+ REMOTE_DEV_SHORT_HASH=$( git rev-parse --short $REMOTE_DEV_REF )
89+
90+ COMMIT=$( git merge-base $LOCAL_BRANCH_REF $REMOTE_DEV_REF ) || \
91+ echo " No common ancestor found for $( git show $LOCAL_BRANCH_REF -q) and $( git show $REMOTE_DEV_REF -q) "
92+
93+ if [ -z " $COMMIT " ]; then
94+ exit 1
95+ fi
96+
97+ COMMIT_SHORT_HASH=$( git rev-parse --short $COMMIT )
98+
99+ echo -e " \nCommon ancestor between $LOCAL_BRANCH_REF ($LOCAL_BRANCH_SHORT_HASH )" \
100+ " and $REMOTE_DEV_REF ($REMOTE_DEV_SHORT_HASH ) is $COMMIT_SHORT_HASH :"
101+ echo ' --------------------------------------------------------------------------------'
102+ git --no-pager show --no-patch $COMMIT_SHORT_HASH
103+
104+ COMMIT_RANGE=" $COMMIT_SHORT_HASH ..$LOCAL_BRANCH_SHORT_HASH "
105+
106+ if [[ -n " $TMP_REMOTE " ]]; then
107+ git remote remove $TMP_REMOTE
108+ fi
109+
110+ else
111+ echo " Got the commit range from Travis: $COMMIT_RANGE "
112+ fi
113+
114+ echo -e ' \nRunning flake8 on the diff in the range' " $COMMIT_RANGE " \
115+ " ($( git rev-list $COMMIT_RANGE | wc -l) commit(s)):"
116+ echo ' --------------------------------------------------------------------------------'
117+ # We need the following command to exit with 0 hence the echo in case
118+ # there is no match
119+ MODIFIED_FILES=" $( git diff --name-only $COMMIT_RANGE || echo " no_match" ) "
120+
121+ check_files () {
122+ files=" $1 "
123+ shift
124+ options=" $* "
125+ if [ -n " $files " ]; then
126+ # Conservative approach: diff without context (--unified=0) so that code
127+ # that was not changed does not create failures
128+ git diff --unified=0 $COMMIT_RANGE -- $files | flake8 --ignore E402 --diff --show-source $options
129+ fi
130+ }
131+
132+ if [[ " $MODIFIED_FILES " == " no_match" ]]; then
133+ echo " No file has been modified"
134+ else
135+
136+ check_files " $( echo " $MODIFIED_FILES " | grep -v ^examples) "
137+ check_files " $( echo " $MODIFIED_FILES " | grep ^examples) " \
138+ --config ./examples/.flake8
139+ fi
140+ echo -e " No problem detected by flake8\n"
0 commit comments