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

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

Issue 929223002: Implement without patch retries and src-side script for webview_licenses.py (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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
« no previous file with comments | « no previous file | testing/buildbot/chromium.linux.json » ('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 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
11 be used to generate an Android NOTICE file for the third-party code. 11 be used to generate an Android NOTICE file for the third-party code.
12 12
13 It makes use of src/tools/licenses.py and the README.chromium files on which 13 It makes use of src/tools/licenses.py and the README.chromium files on which
14 it depends. It also makes use of a data file, third_party_files_whitelist.txt, 14 it depends. It also makes use of a data file, third_party_files_whitelist.txt,
15 which whitelists indicidual files which contain third-party code but which 15 which whitelists indicidual files which contain third-party code but which
16 aren't in a third-party directory with a README.chromium file. 16 aren't in a third-party directory with a README.chromium file.
17 """ 17 """
18 18
19 import glob 19 import glob
20 import imp 20 import imp
21 import json
21 import multiprocessing 22 import multiprocessing
22 import optparse 23 import optparse
23 import os 24 import os
24 import re 25 import re
25 import sys 26 import sys
26 import textwrap 27 import textwrap
27 28
28 29
29 REPOSITORY_ROOT = os.path.abspath(os.path.join( 30 REPOSITORY_ROOT = os.path.abspath(os.path.join(
30 os.path.dirname(__file__), '..', '..')) 31 os.path.dirname(__file__), '..', '..'))
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 '\n'.join(sorted(unknown)) 155 '\n'.join(sorted(unknown))
155 if missing: 156 if missing:
156 print 'The following files are whitelisted, but do not exist.\n%s' % \ 157 print 'The following files are whitelisted, but do not exist.\n%s' % \
157 '\n'.join(sorted(missing)) 158 '\n'.join(sorted(missing))
158 if stale: 159 if stale:
159 print 'The following files are whitelisted unnecessarily. You must ' \ 160 print 'The following files are whitelisted unnecessarily. You must ' \
160 'remove the following files from the whitelist.\n%s' % \ 161 'remove the following files from the whitelist.\n%s' % \
161 '\n'.join(sorted(stale)) 162 '\n'.join(sorted(stale))
162 163
163 if unknown: 164 if unknown:
164 return ScanResult.Errors 165 code = ScanResult.Errors
165 elif stale or missing: 166 elif stale or missing:
166 return ScanResult.Warnings 167 code = ScanResult.Warnings
167 else: 168 else:
168 return ScanResult.Ok 169 code = ScanResult.Ok
170
171 problem_paths = sorted(set(unknown + missing + stale))
mnaganov (inactive) 2015/02/17 11:27:09 How exactly will this list be used? Will any human
mnaganov (inactive) 2015/02/17 11:28:35 Looked at the bug -- if it is only for scripts tha
Paweł Hajdan Jr. 2015/02/17 14:09:36 Yes, JSON is for machine-readable processing. Con
172 return (code, problem_paths)
169 173
170 174
171 def _ReadFile(full_path, mode='rU'): 175 def _ReadFile(full_path, mode='rU'):
172 """Reads a file from disk. This emulates presubmit InputApi.ReadFile func. 176 """Reads a file from disk. This emulates presubmit InputApi.ReadFile func.
173 Args: 177 Args:
174 full_path: The path of the file to read. 178 full_path: The path of the file to read.
175 Returns: 179 Returns:
176 The contents of the file as a string. 180 The contents of the file as a string.
177 """ 181 """
178 182
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 that all non third-party code doesn't contain external copyrighted code. 238 that all non third-party code doesn't contain external copyrighted code.
235 Returns: 239 Returns:
236 ScanResult.Ok if everything is in order; 240 ScanResult.Ok if everything is in order;
237 ScanResult.Warnings if there are non-fatal problems (e.g. stale whitelist 241 ScanResult.Warnings if there are non-fatal problems (e.g. stale whitelist
238 entries) 242 entries)
239 ScanResult.Errors otherwise. 243 ScanResult.Errors otherwise.
240 """ 244 """
241 245
242 third_party_dirs = _FindThirdPartyDirs() 246 third_party_dirs = _FindThirdPartyDirs()
243 247
248 problem_paths = []
249
244 # First, check designated third-party directories using src/tools/licenses.py. 250 # First, check designated third-party directories using src/tools/licenses.py.
245 all_licenses_valid = True 251 all_licenses_valid = True
246 for path in sorted(third_party_dirs): 252 for path in sorted(third_party_dirs):
247 try: 253 try:
248 licenses.ParseDir(path, REPOSITORY_ROOT) 254 licenses.ParseDir(path, REPOSITORY_ROOT)
249 except licenses.LicenseError, e: 255 except licenses.LicenseError, e:
250 if not (path in known_issues.KNOWN_ISSUES): 256 if not (path in known_issues.KNOWN_ISSUES):
251 print 'Got LicenseError "%s" while scanning %s' % (e, path) 257 print 'Got LicenseError "%s" while scanning %s' % (e, path)
258 problem_paths.append(path)
252 all_licenses_valid = False 259 all_licenses_valid = False
253 260
254 # Second, check for non-standard license text. 261 # Second, check for non-standard license text.
255 whitelisted_files = copyright_scanner.LoadWhitelistedFilesList(InputApi()) 262 whitelisted_files = copyright_scanner.LoadWhitelistedFilesList(InputApi())
256 licenses_check = _CheckLicenseHeaders(third_party_dirs, whitelisted_files) 263 licenses_check, more_problem_paths = _CheckLicenseHeaders(
264 third_party_dirs, whitelisted_files)
257 265
258 return licenses_check if all_licenses_valid else ScanResult.Errors 266 problem_paths.extend(more_problem_paths)
267
268 return (licenses_check if all_licenses_valid else ScanResult.Errors,
269 problem_paths)
259 270
260 271
261 class TemplateEntryGenerator(object): 272 class TemplateEntryGenerator(object):
262 def __init__(self): 273 def __init__(self):
263 self._generate_licenses_file_list_only = False 274 self._generate_licenses_file_list_only = False
264 self._toc_index = 0 275 self._toc_index = 0
265 276
266 def SetGenerateLicensesFileListOnly(self, generate_licenses_file_list_only): 277 def SetGenerateLicensesFileListOnly(self, generate_licenses_file_list_only):
267 self._generate_licenses_file_list_only = generate_licenses_file_list_only 278 self._generate_licenses_file_list_only = generate_licenses_file_list_only
268 279
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 354
344 def main(): 355 def main():
345 class FormatterWithNewLines(optparse.IndentedHelpFormatter): 356 class FormatterWithNewLines(optparse.IndentedHelpFormatter):
346 def format_description(self, description): 357 def format_description(self, description):
347 paras = description.split('\n') 358 paras = description.split('\n')
348 formatted_paras = [textwrap.fill(para, self.width) for para in paras] 359 formatted_paras = [textwrap.fill(para, self.width) for para in paras]
349 return '\n'.join(formatted_paras) + '\n' 360 return '\n'.join(formatted_paras) + '\n'
350 361
351 parser = optparse.OptionParser(formatter=FormatterWithNewLines(), 362 parser = optparse.OptionParser(formatter=FormatterWithNewLines(),
352 usage='%prog [options]') 363 usage='%prog [options]')
364 parser.add_option('--json', help='Path to JSON output file')
353 parser.description = (__doc__ + 365 parser.description = (__doc__ +
354 '\nCommands:\n' 366 '\nCommands:\n'
355 ' scan Check licenses.\n' 367 ' scan Check licenses.\n'
356 ' notice_deps Generate the list of dependencies for ' 368 ' notice_deps Generate the list of dependencies for '
357 'Android NOTICE file.\n' 369 'Android NOTICE file.\n'
358 ' notice [file] Generate Android NOTICE file on ' 370 ' notice [file] Generate Android NOTICE file on '
359 'stdout or into |file|.\n' 371 'stdout or into |file|.\n'
360 ' incompatible_directories Scan for incompatibly' 372 ' incompatible_directories Scan for incompatibly'
361 ' licensed directories.\n' 373 ' licensed directories.\n'
362 ' all_incompatible_directories Scan for incompatibly' 374 ' all_incompatible_directories Scan for incompatibly'
363 ' licensed directories (even those in' 375 ' licensed directories (even those in'
364 ' known_issues.py).\n' 376 ' known_issues.py).\n'
365 ' display_copyrights Display autorship on the files' 377 ' display_copyrights Display autorship on the files'
366 ' using names provided via stdin.\n') 378 ' using names provided via stdin.\n')
367 (_, args) = parser.parse_args() 379 (options, args) = parser.parse_args()
368 if len(args) < 1: 380 if len(args) < 1:
369 parser.print_help() 381 parser.print_help()
370 return ScanResult.Errors 382 return ScanResult.Errors
371 383
372 if args[0] == 'scan': 384 if args[0] == 'scan':
373 scan_result = _Scan() 385 scan_result, problem_paths = _Scan()
374 if scan_result == ScanResult.Ok: 386 if scan_result == ScanResult.Ok:
375 print 'OK!' 387 print 'OK!'
388 if options.json:
389 with open(options.json, 'w') as f:
390 json.dump(problem_paths, f)
376 return scan_result 391 return scan_result
377 elif args[0] == 'notice_deps': 392 elif args[0] == 'notice_deps':
378 # 'set' is used to eliminate duplicate references to the same license file. 393 # 'set' is used to eliminate duplicate references to the same license file.
379 print ' '.join( 394 print ' '.join(
380 sorted(set(GenerateNoticeFile(generate_licenses_file_list_only=True)))) 395 sorted(set(GenerateNoticeFile(generate_licenses_file_list_only=True))))
381 return ScanResult.Ok 396 return ScanResult.Ok
382 elif args[0] == 'notice': 397 elif args[0] == 'notice':
383 notice_file_contents = GenerateNoticeFile() 398 notice_file_contents = GenerateNoticeFile()
384 if len(args) == 1: 399 if len(args) == 1:
385 print notice_file_contents 400 print notice_file_contents
386 else: 401 else:
387 with open(args[1], 'w') as output_file: 402 with open(args[1], 'w') as output_file:
388 output_file.write(notice_file_contents) 403 output_file.write(notice_file_contents)
389 return ScanResult.Ok 404 return ScanResult.Ok
390 elif args[0] == 'incompatible_directories': 405 elif args[0] == 'incompatible_directories':
391 return _ProcessIncompatibleResult(GetUnknownIncompatibleDirectories()) 406 return _ProcessIncompatibleResult(GetUnknownIncompatibleDirectories())
392 elif args[0] == 'all_incompatible_directories': 407 elif args[0] == 'all_incompatible_directories':
393 return _ProcessIncompatibleResult(GetIncompatibleDirectories()) 408 return _ProcessIncompatibleResult(GetIncompatibleDirectories())
394 elif args[0] == 'display_copyrights': 409 elif args[0] == 'display_copyrights':
395 files = sys.stdin.read().splitlines() 410 files = sys.stdin.read().splitlines()
396 for f, c in \ 411 for f, c in \
397 zip(files, copyright_scanner.FindCopyrights(InputApi(), '.', files)): 412 zip(files, copyright_scanner.FindCopyrights(InputApi(), '.', files)):
398 print f, '\t', ' / '.join(sorted(c)) 413 print f, '\t', ' / '.join(sorted(c))
399 return ScanResult.Ok 414 return ScanResult.Ok
400 parser.print_help() 415 parser.print_help()
401 return ScanResult.Errors 416 return ScanResult.Errors
402 417
403 if __name__ == '__main__': 418 if __name__ == '__main__':
404 sys.exit(main()) 419 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | testing/buildbot/chromium.linux.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698