@@ -107,22 +107,30 @@ def is_production_filename(filename):
107107 or filename .startswith ('regression' ))
108108
109109
110- def get_files_for_linting ():
110+ def get_files_for_linting (allow_limited = True ):
111111 """Gets a list of files in the repository.
112112
113- By default, returns all files via `git ls-files`. However, in some cases
113+ By default, returns all files via `` git ls-files` `. However, in some cases
114114 uses a specific commit or branch (a so-called diff base) to compare
115- against for changed files.
115+ against for changed files. (This requires ``allow_limited=True``.)
116116
117117 To speed up linting on Travis pull requests against master, we manually
118118 set the diff base to origin/master. We don't do this on non-pull requests
119119 since origin/master will be equivalent to the currently checked out code.
120120 One could potentially use ${TRAVIS_COMMIT_RANGE} to find a diff base but
121121 this value is not dependable.
122122
123- To allow faster local `tox` runs, the environment variables
124- `GCLOUD_REMOTE_FOR_LINT` and `GCLOUD_BRANCH_FOR_LINT` can be set to specify
125- a remote branch to diff against.
123+ To allow faster local ``tox`` runs, the environment variables
124+ ``GCLOUD_REMOTE_FOR_LINT`` and ``GCLOUD_BRANCH_FOR_LINT`` can be set to
125+ specify a remote branch to diff against.
126+
127+ :type allow_limited: boolean
128+ :param allow_limited: Boolean indicating if a reduced set of files can
129+ be used.
130+
131+ :rtype: pair
132+ :returns: Tuple of the diff base using the the list of filenames to be
133+ linted.
126134 """
127135 diff_base = None
128136 if (os .getenv ('TRAVIS_BRANCH' ) == 'master' and
@@ -137,34 +145,41 @@ def get_files_for_linting():
137145 if remote is not None and branch is not None :
138146 diff_base = '%s/%s' % (remote , branch )
139147
140- if diff_base is None :
141- print 'Diff base not specified, listing all files in repository.'
142- result = subprocess .check_output (['git' , 'ls-files' ])
143- else :
148+ if diff_base is not None and allow_limited :
144149 result = subprocess .check_output (['git' , 'diff' , '--name-only' ,
145150 diff_base ])
146151 print 'Using files changed relative to %s:' % (diff_base ,)
147152 print '-' * 60
148153 print result .rstrip ('\n ' ) # Don't print trailing newlines.
149154 print '-' * 60
155+ else :
156+ print 'Diff base not specified, listing all files in repository.'
157+ result = subprocess .check_output (['git' , 'ls-files' ])
150158
151- return result .rstrip ('\n ' ).split ('\n ' )
159+ return result .rstrip ('\n ' ).split ('\n ' ), diff_base
152160
153161
154- def get_python_files ():
162+ def get_python_files (all_files = None ):
155163 """Gets a list of all Python files in the repository that need linting.
156164
157- Relies on get_files_for_linting() to determine which files should be
158- considered.
165+ Relies on :func:`get_files_for_linting()` to determine which files should
166+ be considered.
167+
168+ NOTE: This requires ``git`` to be installed and requires that this
169+ is run within the ``git`` repository.
159170
160- NOTE: This requires `git` to be installed and requires that this
161- is run within the `git` repository .
171+ :type all_files: list or ``NoneType``
172+ :param all_files: Optional list of files to be linted .
162173
163- :rtype: `tuple`
164- :returns: A tuple containing two lists. The first list contains
165- all production files and the next all test/demo files.
174+ :rtype: tuple
175+ :returns: A tuple containing two lists and a boolean. The first list
176+ contains all production files, the next all test/demo files and
177+ the boolean indicates if a restricted fileset was used.
166178 """
167- all_files = get_files_for_linting ()
179+ using_restricted = False
180+ if all_files is None :
181+ all_files , diff_base = get_files_for_linting ()
182+ using_restricted = diff_base is not None
168183
169184 library_files = []
170185 non_library_files = []
@@ -175,7 +190,7 @@ def get_python_files():
175190 else :
176191 non_library_files .append (filename )
177192
178- return library_files , non_library_files
193+ return library_files , non_library_files , using_restricted
179194
180195
181196def lint_fileset (filenames , rcfile , description ):
@@ -202,9 +217,21 @@ def lint_fileset(filenames, rcfile, description):
202217def main ():
203218 """Script entry point. Lints both sets of files."""
204219 make_test_rc (PRODUCTION_RC , TEST_RC_ADDITIONS , TEST_RC )
205- library_files , non_library_files = get_python_files ()
206- lint_fileset (library_files , PRODUCTION_RC , 'library code' )
207- lint_fileset (non_library_files , TEST_RC , 'test and demo code' )
220+ library_files , non_library_files , using_restricted = get_python_files ()
221+ try :
222+ lint_fileset (library_files , PRODUCTION_RC , 'library code' )
223+ lint_fileset (non_library_files , TEST_RC , 'test and demo code' )
224+ except SystemExit :
225+ if not using_restricted :
226+ raise
227+
228+ message = 'Restricted lint failed, expanding to full fileset.'
229+ print >> sys .stderr , message
230+ all_files , _ = get_files_for_linting (allow_limited = False )
231+ library_files , non_library_files , _ = get_python_files (
232+ all_files = all_files )
233+ lint_fileset (library_files , PRODUCTION_RC , 'library code' )
234+ lint_fileset (non_library_files , TEST_RC , 'test and demo code' )
208235
209236
210237if __name__ == '__main__' :
0 commit comments