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

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

Issue 667723002: [Android WebView] Prepare the copyrights scanner to run from presubmit scripts (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Simplified ShouldMatchReferenceOutput Created 6 years, 2 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
« no previous file with comments | « android_webview/tools/third_party_files_whitelist.txt ('k') | no next file » | 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 2014 The Chromium Authors. All rights reserved. 2 # Copyright 2014 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 26 matching lines...) Expand all
37 os.path.join(REPOSITORY_ROOT, 'third_party', 'PRESUBMIT.py')) 37 os.path.join(REPOSITORY_ROOT, 'third_party', 'PRESUBMIT.py'))
38 38
39 sys.path.append(os.path.join(REPOSITORY_ROOT, 'tools')) 39 sys.path.append(os.path.join(REPOSITORY_ROOT, 'tools'))
40 import licenses 40 import licenses
41 41
42 import copyright_scanner 42 import copyright_scanner
43 import known_issues 43 import known_issues
44 44
45 class InputApi(object): 45 class InputApi(object):
46 def __init__(self): 46 def __init__(self):
47 self.os_path = os.path
48 self.os_walk = os.walk
47 self.re = re 49 self.re = re
50 self.ReadFile = _ReadFile
48 51
49 def GetIncompatibleDirectories(): 52 def GetIncompatibleDirectories():
50 """Gets a list of third-party directories which use licenses incompatible 53 """Gets a list of third-party directories which use licenses incompatible
51 with Android. This is used by the snapshot tool. 54 with Android. This is used by the snapshot tool.
52 Returns: 55 Returns:
53 A list of directories. 56 A list of directories.
54 """ 57 """
55 58
56 result = [] 59 result = []
57 for directory in _FindThirdPartyDirs(): 60 for directory in _FindThirdPartyDirs():
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 known_incompatible = frozenset(known_incompatible) 95 known_incompatible = frozenset(known_incompatible)
93 return incompatible_directories.difference(known_incompatible) 96 return incompatible_directories.difference(known_incompatible)
94 97
95 98
96 class ScanResult(object): 99 class ScanResult(object):
97 Ok, Warnings, Errors = range(3) 100 Ok, Warnings, Errors = range(3)
98 101
99 # Needs to be a top-level function for multiprocessing 102 # Needs to be a top-level function for multiprocessing
100 def _FindCopyrightViolations(files_to_scan_as_string): 103 def _FindCopyrightViolations(files_to_scan_as_string):
101 return copyright_scanner.FindCopyrightViolations( 104 return copyright_scanner.FindCopyrightViolations(
102 REPOSITORY_ROOT, files_to_scan_as_string) 105 InputApi(), REPOSITORY_ROOT, files_to_scan_as_string)
103 106
104 def _ShardList(l, shard_len): 107 def _ShardList(l, shard_len):
105 return [l[i:i + shard_len] for i in range(0, len(l), shard_len)] 108 return [l[i:i + shard_len] for i in range(0, len(l), shard_len)]
106 109
107 def _CheckLicenseHeaders(excluded_dirs_list, whitelisted_files): 110 def _CheckLicenseHeaders(excluded_dirs_list, whitelisted_files):
108 """Checks that all files which are not in a listed third-party directory, 111 """Checks that all files which are not in a listed third-party directory,
109 and which do not use the standard Chromium license, are whitelisted. 112 and which do not use the standard Chromium license, are whitelisted.
110 Args: 113 Args:
111 excluded_dirs_list: The list of directories to exclude from scanning. 114 excluded_dirs_list: The list of directories to exclude from scanning.
112 whitelisted_files: The whitelist of files. 115 whitelisted_files: The whitelist of files.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 # Swarming tools, doesn't exist in the snapshot 153 # Swarming tools, doesn't exist in the snapshot
151 excluded_dirs_list.append('tools/swarming_client') 154 excluded_dirs_list.append('tools/swarming_client')
152 # Arm sysroot tools, doesn't exist in the snapshot 155 # Arm sysroot tools, doesn't exist in the snapshot
153 excluded_dirs_list.append('arm-sysroot') 156 excluded_dirs_list.append('arm-sysroot')
154 # Data is not part of open source chromium, but are included on some bots. 157 # Data is not part of open source chromium, but are included on some bots.
155 excluded_dirs_list.append('data') 158 excluded_dirs_list.append('data')
156 # This is not part of open source chromium, but are included on some bots. 159 # This is not part of open source chromium, but are included on some bots.
157 excluded_dirs_list.append('skia/tools/clusterfuzz-data') 160 excluded_dirs_list.append('skia/tools/clusterfuzz-data')
158 161
159 files_to_scan = copyright_scanner.FindFiles( 162 files_to_scan = copyright_scanner.FindFiles(
160 REPOSITORY_ROOT, ['.'], excluded_dirs_list) 163 InputApi(), REPOSITORY_ROOT, ['.'], excluded_dirs_list)
161 sharded_files_to_scan = _ShardList(files_to_scan, 2000) 164 sharded_files_to_scan = _ShardList(files_to_scan, 2000)
162 pool = multiprocessing.Pool() 165 pool = multiprocessing.Pool()
163 offending_files_chunks = pool.map_async( 166 offending_files_chunks = pool.map_async(
164 _FindCopyrightViolations, sharded_files_to_scan).get(999999) 167 _FindCopyrightViolations, sharded_files_to_scan).get(999999)
165 pool.close() 168 pool.close()
166 pool.join() 169 pool.join()
167 # Flatten out the result 170 # Flatten out the result
168 offending_files = \ 171 offending_files = \
169 [item for sublist in offending_files_chunks for item in sublist] 172 [item for sublist in offending_files_chunks for item in sublist]
170 173
(...skipping 15 matching lines...) Expand all
186 '\n'.join(sorted(missing)) 189 '\n'.join(sorted(missing))
187 190
188 if unknown: 191 if unknown:
189 return ScanResult.Errors 192 return ScanResult.Errors
190 elif stale or missing: 193 elif stale or missing:
191 return ScanResult.Warnings 194 return ScanResult.Warnings
192 else: 195 else:
193 return ScanResult.Ok 196 return ScanResult.Ok
194 197
195 198
196 def _ReadFile(path): 199 def _ReadFile(full_path, mode='rU'):
200 """Reads a file from disk. This emulates presubmit InputApi.ReadFile func.
201 Args:
202 full_path: The path of the file to read.
203 Returns:
204 The contents of the file as a string.
205 """
206
207 with open(full_path, mode) as f:
208 return f.read()
209
210
211 def _ReadLocalFile(path, mode='rb'):
197 """Reads a file from disk. 212 """Reads a file from disk.
198 Args: 213 Args:
199 path: The path of the file to read, relative to the root of the repository. 214 path: The path of the file to read, relative to the root of the repository.
200 Returns: 215 Returns:
201 The contents of the file as a string. 216 The contents of the file as a string.
202 """ 217 """
203 218
204 with open(os.path.join(REPOSITORY_ROOT, path), 'rb') as f: 219 return _ReadFile(os.path.join(REPOSITORY_ROOT, path), mode)
205 return f.read()
206 220
207 221
208 def _FindThirdPartyDirs(): 222 def _FindThirdPartyDirs():
209 """Gets the list of third-party directories. 223 """Gets the list of third-party directories.
210 Returns: 224 Returns:
211 The list of third-party directories. 225 The list of third-party directories.
212 """ 226 """
213 227
214 # Please don't add here paths that have problems with license files, 228 # Please don't add here paths that have problems with license files,
215 # as they will end up included in Android WebView snapshot. 229 # as they will end up included in Android WebView snapshot.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 all_licenses_valid = True 269 all_licenses_valid = True
256 for path in sorted(third_party_dirs): 270 for path in sorted(third_party_dirs):
257 try: 271 try:
258 licenses.ParseDir(path, REPOSITORY_ROOT) 272 licenses.ParseDir(path, REPOSITORY_ROOT)
259 except licenses.LicenseError, e: 273 except licenses.LicenseError, e:
260 if not (path in known_issues.KNOWN_ISSUES): 274 if not (path in known_issues.KNOWN_ISSUES):
261 print 'Got LicenseError "%s" while scanning %s' % (e, path) 275 print 'Got LicenseError "%s" while scanning %s' % (e, path)
262 all_licenses_valid = False 276 all_licenses_valid = False
263 277
264 # Second, check for non-standard license text. 278 # Second, check for non-standard license text.
265 files_data = _ReadFile(os.path.join('android_webview', 'tools', 279 files_data = _ReadLocalFile(os.path.join('android_webview', 'tools',
266 'third_party_files_whitelist.txt')) 280 'third_party_files_whitelist.txt'))
267 whitelisted_files = [] 281 whitelisted_files = []
268 for line in files_data.splitlines(): 282 for line in files_data.splitlines():
269 match = re.match(r'([^#\s]+)', line) 283 match = re.match(r'([^#\s]+)', line)
270 if match: 284 if match:
271 whitelisted_files.append(match.group(1)) 285 whitelisted_files.append(match.group(1))
272 licenses_check = _CheckLicenseHeaders(third_party_dirs, whitelisted_files) 286 licenses_check = _CheckLicenseHeaders(third_party_dirs, whitelisted_files)
273 287
274 return licenses_check if all_licenses_valid else ScanResult.Errors 288 return licenses_check if all_licenses_valid else ScanResult.Errors
275 289
276 290
277 def GenerateNoticeFile(): 291 def GenerateNoticeFile():
278 """Generates the contents of an Android NOTICE file for the third-party code. 292 """Generates the contents of an Android NOTICE file for the third-party code.
279 This is used by the snapshot tool. 293 This is used by the snapshot tool.
280 Returns: 294 Returns:
281 The contents of the NOTICE file. 295 The contents of the NOTICE file.
282 """ 296 """
283 297
284 third_party_dirs = _FindThirdPartyDirs() 298 third_party_dirs = _FindThirdPartyDirs()
285 299
286 # Don't forget Chromium's LICENSE file 300 # Don't forget Chromium's LICENSE file
287 content = [_ReadFile('LICENSE')] 301 content = [_ReadLocalFile('LICENSE')]
288 302
289 # We provide attribution for all third-party directories. 303 # We provide attribution for all third-party directories.
290 # TODO(steveblock): Limit this to only code used by the WebView binary. 304 # TODO(steveblock): Limit this to only code used by the WebView binary.
291 for directory in sorted(third_party_dirs): 305 for directory in sorted(third_party_dirs):
292 metadata = licenses.ParseDir(directory, REPOSITORY_ROOT, 306 metadata = licenses.ParseDir(directory, REPOSITORY_ROOT,
293 require_license_file=False) 307 require_license_file=False)
294 license_file = metadata['License File'] 308 license_file = metadata['License File']
295 if license_file and license_file != licenses.NOT_SHIPPED: 309 if license_file and license_file != licenses.NOT_SHIPPED:
296 content.append(_ReadFile(license_file)) 310 content.append(_ReadLocalFile(license_file))
297 311
298 return '\n'.join(content) 312 return '\n'.join(content)
299 313
300 314
301 def _ProcessIncompatibleResult(incompatible_directories): 315 def _ProcessIncompatibleResult(incompatible_directories):
302 if incompatible_directories: 316 if incompatible_directories:
303 print ("Incompatibly licensed directories found:\n" + 317 print ("Incompatibly licensed directories found:\n" +
304 "\n".join(sorted(incompatible_directories))) 318 "\n".join(sorted(incompatible_directories)))
305 return ScanResult.Errors 319 return ScanResult.Errors
306 return ScanResult.Ok 320 return ScanResult.Ok
(...skipping 30 matching lines...) Expand all
337 return scan_result 351 return scan_result
338 elif args[0] == 'notice': 352 elif args[0] == 'notice':
339 print GenerateNoticeFile() 353 print GenerateNoticeFile()
340 return ScanResult.Ok 354 return ScanResult.Ok
341 elif args[0] == 'incompatible_directories': 355 elif args[0] == 'incompatible_directories':
342 return _ProcessIncompatibleResult(GetUnknownIncompatibleDirectories()) 356 return _ProcessIncompatibleResult(GetUnknownIncompatibleDirectories())
343 elif args[0] == 'all_incompatible_directories': 357 elif args[0] == 'all_incompatible_directories':
344 return _ProcessIncompatibleResult(GetIncompatibleDirectories()) 358 return _ProcessIncompatibleResult(GetIncompatibleDirectories())
345 elif args[0] == 'display_copyrights': 359 elif args[0] == 'display_copyrights':
346 files = sys.stdin.read().splitlines() 360 files = sys.stdin.read().splitlines()
347 for f, c in zip(files, copyright_scanner.FindCopyrights('.', files)): 361 for f, c in \
362 zip(files, copyright_scanner.FindCopyrights(InputApi(), '.', files)):
348 print f, '\t', ' / '.join(sorted(c)) 363 print f, '\t', ' / '.join(sorted(c))
349 return ScanResult.Ok 364 return ScanResult.Ok
350 parser.print_help() 365 parser.print_help()
351 return ScanResult.Errors 366 return ScanResult.Errors
352 367
353 if __name__ == '__main__': 368 if __name__ == '__main__':
354 sys.exit(main()) 369 sys.exit(main())
OLDNEW
« no previous file with comments | « android_webview/tools/third_party_files_whitelist.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698