Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 |
| 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 imp | |
| 19 import optparse | 20 import optparse |
| 20 import os | 21 import os |
| 21 import re | 22 import re |
| 22 import subprocess | 23 import subprocess |
| 23 import sys | 24 import sys |
| 24 import textwrap | 25 import textwrap |
| 25 | 26 |
| 26 | 27 |
| 27 REPOSITORY_ROOT = os.path.abspath(os.path.join( | 28 REPOSITORY_ROOT = os.path.abspath(os.path.join( |
| 28 os.path.dirname(__file__), '..', '..')) | 29 os.path.dirname(__file__), '..', '..')) |
| 29 | 30 |
| 31 # Import third_party/PRESUBMIT.py via imp to avoid importing a random | |
| 32 # PRESUBMIT.py from $PATH, also make sure we don't generate a .pyc file. | |
| 33 sys.dont_write_bytecode = True | |
| 34 third_party = \ | |
| 35 imp.load_source('PRESUBMIT', \ | |
| 36 os.path.join(REPOSITORY_ROOT, 'third_party', 'PRESUBMIT.py')) | |
| 37 | |
| 30 sys.path.append(os.path.join(REPOSITORY_ROOT, 'tools')) | 38 sys.path.append(os.path.join(REPOSITORY_ROOT, 'tools')) |
| 31 import licenses | 39 import licenses |
| 32 | 40 |
| 33 import known_issues | 41 import known_issues |
| 34 | 42 |
| 43 class InputApi(object): | |
| 44 def __init__(self): | |
| 45 self.re = re | |
|
mkosiba (inactive)
2014/01/31 17:47:38
could you explain why this is needed? PRESUBMIT.py
mnaganov (inactive)
2014/02/03 10:00:26
No -- in fact, PRESUBMIT scripts don't import anyt
mkosiba (inactive)
2014/02/03 10:30:55
ah, thanks for that. I got confused by the import
| |
| 46 | |
| 35 def GetIncompatibleDirectories(): | 47 def GetIncompatibleDirectories(): |
| 36 """Gets a list of third-party directories which use licenses incompatible | 48 """Gets a list of third-party directories which use licenses incompatible |
| 37 with Android. This is used by the snapshot tool and the AOSP bot. | 49 with Android. This is used by the snapshot tool and the AOSP bot. |
| 38 Returns: | 50 Returns: |
| 39 A list of directories. | 51 A list of directories. |
| 40 """ | 52 """ |
| 41 | 53 |
| 42 whitelist = [ | |
| 43 'Apache( Version)? 2(\.0)?', | |
| 44 '(New )?([23]-Clause )?BSD( [23]-Clause)?( with advertising clause)?', | |
| 45 'L?GPL ?v?2(\.[01])?( or later)?', | |
| 46 'MIT(/X11)?(-like)?', | |
| 47 'MPL 1\.1 ?/ ?GPL 2(\.0)? ?/ ?LGPL 2\.1', | |
| 48 'MPL 2(\.0)?', | |
| 49 'Microsoft Limited Public License', | |
| 50 'Microsoft Permissive License', | |
| 51 'Public Domain', | |
| 52 'Python', | |
| 53 'SGI Free Software License B', | |
| 54 'University of Illinois\/NCSA Open Source', | |
| 55 'X11', | |
| 56 ] | |
| 57 regex = '^(%s)$' % '|'.join(whitelist) | |
| 58 result = [] | 54 result = [] |
| 59 for directory in _FindThirdPartyDirs(): | 55 for directory in _FindThirdPartyDirs(): |
| 60 if directory in known_issues.KNOWN_ISSUES: | 56 if directory in known_issues.KNOWN_ISSUES: |
| 61 result.append(directory) | 57 result.append(directory) |
| 62 continue | 58 continue |
| 63 try: | 59 try: |
| 64 metadata = licenses.ParseDir(directory, REPOSITORY_ROOT, | 60 metadata = licenses.ParseDir(directory, REPOSITORY_ROOT, |
| 65 require_license_file=False) | 61 require_license_file=False) |
| 66 except licenses.LicenseError as e: | 62 except licenses.LicenseError as e: |
| 67 print 'Got LicenseError while scanning ' + directory | 63 print 'Got LicenseError while scanning ' + directory |
| 68 raise | 64 raise |
| 69 if metadata.get('License Android Compatible', 'no').upper() == 'YES': | 65 if metadata.get('License Android Compatible', 'no').upper() == 'YES': |
| 70 continue | 66 continue |
| 71 license = re.split(' [Ll]icenses?$', metadata['License'])[0] | 67 license = re.split(' [Ll]icenses?$', metadata['License'])[0] |
| 72 tokens = [x.strip() for x in re.split(' and |,', license) if len(x) > 0] | 68 if not third_party.LicenseIsCompatibleWithAndroid(InputApi(), license): |
| 73 for token in tokens: | 69 result.append(directory) |
| 74 if not re.match(regex, token, re.IGNORECASE): | |
| 75 result.append(directory) | |
| 76 break | |
| 77 return result | 70 return result |
| 78 | 71 |
| 79 class ScanResult(object): | 72 class ScanResult(object): |
| 80 Ok, Warnings, Errors = range(3) | 73 Ok, Warnings, Errors = range(3) |
| 81 | 74 |
| 82 def _CheckLicenseHeaders(excluded_dirs_list, whitelisted_files): | 75 def _CheckLicenseHeaders(excluded_dirs_list, whitelisted_files): |
| 83 """Checks that all files which are not in a listed third-party directory, | 76 """Checks that all files which are not in a listed third-party directory, |
| 84 and which do not use the standard Chromium license, are whitelisted. | 77 and which do not use the standard Chromium license, are whitelisted. |
| 85 Args: | 78 Args: |
| 86 excluded_dirs_list: The list of directories to exclude from scanning. | 79 excluded_dirs_list: The list of directories to exclude from scanning. |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 306 print ("Incompatibly licensed directories found:" + | 299 print ("Incompatibly licensed directories found:" + |
| 307 "\n".join(incompatible_directories)) | 300 "\n".join(incompatible_directories)) |
| 308 return ScanResult.Errors | 301 return ScanResult.Errors |
| 309 return ScanResult.Ok | 302 return ScanResult.Ok |
| 310 | 303 |
| 311 parser.print_help() | 304 parser.print_help() |
| 312 return ScanResult.Errors | 305 return ScanResult.Errors |
| 313 | 306 |
| 314 if __name__ == '__main__': | 307 if __name__ == '__main__': |
| 315 sys.exit(main()) | 308 sys.exit(main()) |
| OLD | NEW |