Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(110)

Side by Side Diff: android_webview/tools/webview_licenses.py

Issue 12209034: [Android WebView] Make 3rd party licenses checker to turn bot red (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Keep the check on the FYI bot Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | build/android/buildbot/bb_run_bot.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Checks third-party licenses for the purposes of the Android WebView build. 6 """Checks third-party licenses for the purposes of the Android WebView build.
7 7
8 The Android tree includes a snapshot of Chromium in order to power the system 8 The Android tree includes a snapshot of Chromium in order to power the system
9 WebView. This tool checks that all code uses open-source licenses compatible 9 WebView. This tool checks that all code uses open-source licenses compatible
10 with Android, and that we meet the requirements of those licenses. It can also 10 with Android, and that we meet the requirements of those licenses. It can also
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 if metadata.get('License Android Compatible', 'no') == 'yes': 67 if metadata.get('License Android Compatible', 'no') == 'yes':
68 continue 68 continue
69 license = re.split(' [Ll]icenses?$', metadata['License'])[0] 69 license = re.split(' [Ll]icenses?$', metadata['License'])[0]
70 tokens = [x.strip() for x in re.split(' and |,', license) if len(x) > 0] 70 tokens = [x.strip() for x in re.split(' and |,', license) if len(x) > 0]
71 for token in tokens: 71 for token in tokens:
72 if not re.match(regex, token, re.IGNORECASE): 72 if not re.match(regex, token, re.IGNORECASE):
73 result.append(directory) 73 result.append(directory)
74 break 74 break
75 return result 75 return result
76 76
77 class ScanResult(object):
78 Ok, Warnings, Errors = range(3)
77 79
78 def _CheckLicenseHeaders(excluded_dirs_list, whitelisted_files): 80 def _CheckLicenseHeaders(excluded_dirs_list, whitelisted_files):
79 """Checks that all files which are not in a listed third-party directory, 81 """Checks that all files which are not in a listed third-party directory,
80 and which do not use the standard Chromium license, are whitelisted. 82 and which do not use the standard Chromium license, are whitelisted.
81 Args: 83 Args:
82 excluded_dirs_list: The list of directories to exclude from scanning. 84 excluded_dirs_list: The list of directories to exclude from scanning.
83 whitelisted_files: The whitelist of files. 85 whitelisted_files: The whitelist of files.
84 Returns: 86 Returns:
85 True if all files with non-standard license headers are whitelisted and the 87 ScanResult.Ok if all files with non-standard license headers are whitelisted
86 whitelist contains no stale entries, otherwise false. 88 and the whitelist contains no stale entries;
89 ScanResult.Warnings if there are stale entries;
90 ScanResult.Errors if new non-whitelisted entries found.
87 """ 91 """
88 92
89 excluded_dirs_list = [d for d in excluded_dirs_list if not 'third_party' in d] 93 excluded_dirs_list = [d for d in excluded_dirs_list if not 'third_party' in d]
90 # Using a commond pattern for third-partyies makes the ignore regexp shorter 94 # Using a commond pattern for third-partyies makes the ignore regexp shorter
91 excluded_dirs_list.append('third_party') 95 excluded_dirs_list.append('third_party')
92 # VCS dirs 96 # VCS dirs
93 excluded_dirs_list.append('.git') 97 excluded_dirs_list.append('.git')
94 excluded_dirs_list.append('.svn') 98 excluded_dirs_list.append('.svn')
95 # Build output 99 # Build output
96 excluded_dirs_list.append('out/Debug') 100 excluded_dirs_list.append('out/Debug')
(...skipping 25 matching lines...) Expand all
122 for l in lines: 126 for l in lines:
123 entries = l.split('\t') 127 entries = l.split('\t')
124 if entries[1] == "GENERATED FILE": 128 if entries[1] == "GENERATED FILE":
125 continue 129 continue
126 copyrights = entries[1].split(' / ') 130 copyrights = entries[1].split(' / ')
127 for c in copyrights: 131 for c in copyrights:
128 if c and not allowed_copyrights_re.match(c): 132 if c and not allowed_copyrights_re.match(c):
129 offending_files.append(os.path.normpath(entries[0])) 133 offending_files.append(os.path.normpath(entries[0]))
130 break 134 break
131 135
132 all_files_valid = True
133 unknown = set(offending_files) - set(whitelisted_files) 136 unknown = set(offending_files) - set(whitelisted_files)
134 if unknown: 137 if unknown:
135 print 'The following files contain a third-party license but are not in ' \ 138 print 'The following files contain a third-party license but are not in ' \
136 'a listed third-party directory and are not whitelisted. You must ' \ 139 'a listed third-party directory and are not whitelisted. You must ' \
137 'add the following files to the whitelist.\n%s' % \ 140 'add the following files to the whitelist.\n%s' % \
138 '\n'.join(sorted(unknown)) 141 '\n'.join(sorted(unknown))
139 all_files_valid = False
140 142
141 stale = set(whitelisted_files) - set(offending_files) 143 stale = set(whitelisted_files) - set(offending_files)
142 if stale: 144 if stale:
143 print 'The following files are whitelisted unnecessarily. You must ' \ 145 print 'The following files are whitelisted unnecessarily. You must ' \
144 ' remove the following files from the whitelist.\n%s' % \ 146 ' remove the following files from the whitelist.\n%s' % \
145 '\n'.join(sorted(stale)) 147 '\n'.join(sorted(stale))
146 all_files_valid = False
147 148
148 return all_files_valid 149 if unknown:
150 return ScanResult.Errors
151 elif stale:
152 return ScanResult.Warnings
153 else:
154 return ScanResult.Ok
149 155
150 156
151 def _ReadFile(path): 157 def _ReadFile(path):
152 """Reads a file from disk. 158 """Reads a file from disk.
153 Args: 159 Args:
154 path: The path of the file to read, relative to the root of the repository. 160 path: The path of the file to read, relative to the root of the repository.
155 Returns: 161 Returns:
156 The contents of the file as a string. 162 The contents of the file as a string.
157 """ 163 """
158 164
(...skipping 20 matching lines...) Expand all
179 # The llvm-build doesn't exist for non-clang builder 185 # The llvm-build doesn't exist for non-clang builder
180 os.path.join('third_party', 'llvm-build'), 186 os.path.join('third_party', 'llvm-build'),
181 # Binaries doesn't apply to android 187 # Binaries doesn't apply to android
182 os.path.join('third_party', 'widevine'), 188 os.path.join('third_party', 'widevine'),
183 ] 189 ]
184 third_party_dirs = licenses.FindThirdPartyDirs(prune_paths, REPOSITORY_ROOT) 190 third_party_dirs = licenses.FindThirdPartyDirs(prune_paths, REPOSITORY_ROOT)
185 return licenses.FilterDirsWithFiles(third_party_dirs, REPOSITORY_ROOT) 191 return licenses.FilterDirsWithFiles(third_party_dirs, REPOSITORY_ROOT)
186 192
187 193
188 def _Scan(): 194 def _Scan():
189 """Checks that license meta-data is present for all third-party code. 195 """Checks that license meta-data is present for all third-party code and
196 that all non third-party code doesn't contain external copyrighted code.
190 Returns: 197 Returns:
191 Whether the check succeeded. 198 ScanResult.Ok if everything is in order;
199 ScanResult.Warnings if there are non-fatal problems (e.g. stale whitelist
200 entries)
201 ScanResult.Errors otherwise.
192 """ 202 """
193 203
194 third_party_dirs = _FindThirdPartyDirs() 204 third_party_dirs = _FindThirdPartyDirs()
195 205
196 # First, check designated third-party directories using src/tools/licenses.py. 206 # First, check designated third-party directories using src/tools/licenses.py.
197 all_licenses_valid = True 207 all_licenses_valid = True
198 for path in sorted(third_party_dirs): 208 for path in sorted(third_party_dirs):
199 try: 209 try:
200 licenses.ParseDir(path, REPOSITORY_ROOT) 210 licenses.ParseDir(path, REPOSITORY_ROOT)
201 except licenses.LicenseError, e: 211 except licenses.LicenseError, e:
202 if not (path in known_issues.KNOWN_ISSUES): 212 if not (path in known_issues.KNOWN_ISSUES):
203 print 'Got LicenseError "%s" while scanning %s' % (e, path) 213 print 'Got LicenseError "%s" while scanning %s' % (e, path)
204 all_licenses_valid = False 214 all_licenses_valid = False
205 215
206 # Second, check for non-standard license text. 216 # Second, check for non-standard license text.
207 files_data = _ReadFile(os.path.join('android_webview', 'tools', 217 files_data = _ReadFile(os.path.join('android_webview', 'tools',
208 'third_party_files_whitelist.txt')) 218 'third_party_files_whitelist.txt'))
209 whitelisted_files = [] 219 whitelisted_files = []
210 for line in files_data.splitlines(): 220 for line in files_data.splitlines():
211 match = re.match(r'([^#\s]+)', line) 221 match = re.match(r'([^#\s]+)', line)
212 if match: 222 if match:
213 whitelisted_files.append(match.group(1)) 223 whitelisted_files.append(match.group(1))
214 return _CheckLicenseHeaders(third_party_dirs, whitelisted_files) \ 224 licenses_check = _CheckLicenseHeaders(third_party_dirs, whitelisted_files)
215 and all_licenses_valid 225
226 return licenses_check if all_licenses_valid else ScanResult.Errors
216 227
217 228
218 def GenerateNoticeFile(): 229 def GenerateNoticeFile():
219 """Generates the contents of an Android NOTICE file for the third-party code. 230 """Generates the contents of an Android NOTICE file for the third-party code.
220 This is used by the snapshot tool. 231 This is used by the snapshot tool.
221 Returns: 232 Returns:
222 The contents of the NOTICE file. 233 The contents of the NOTICE file.
223 """ 234 """
224 235
225 third_party_dirs = _FindThirdPartyDirs() 236 third_party_dirs = _FindThirdPartyDirs()
(...skipping 22 matching lines...) Expand all
248 259
249 parser = optparse.OptionParser(formatter=FormatterWithNewLines(), 260 parser = optparse.OptionParser(formatter=FormatterWithNewLines(),
250 usage='%prog [options]') 261 usage='%prog [options]')
251 parser.description = (__doc__ + 262 parser.description = (__doc__ +
252 '\nCommands:\n' \ 263 '\nCommands:\n' \
253 ' scan Check licenses.\n' \ 264 ' scan Check licenses.\n' \
254 ' notice Generate Android NOTICE file on stdout') 265 ' notice Generate Android NOTICE file on stdout')
255 (options, args) = parser.parse_args() 266 (options, args) = parser.parse_args()
256 if len(args) != 1: 267 if len(args) != 1:
257 parser.print_help() 268 parser.print_help()
258 return 1 269 return ScanResult.Errors
259 270
260 if args[0] == 'scan': 271 if args[0] == 'scan':
261 if _Scan(): 272 scan_result = _Scan()
273 if scan_result == ScanResult.Ok:
262 print 'OK!' 274 print 'OK!'
263 return 0 275 return scan_result
264 else:
265 return 1
266 elif args[0] == 'notice': 276 elif args[0] == 'notice':
267 print GenerateNoticeFile() 277 print GenerateNoticeFile()
268 return 0 278 return ScanResult.Ok
269 279
270 parser.print_help() 280 parser.print_help()
271 return 1 281 return ScanResult.Errors
272 282
273 if __name__ == '__main__': 283 if __name__ == '__main__':
274 sys.exit(main()) 284 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | build/android/buildbot/bb_run_bot.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698