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 glob | 19 import glob |
| 20 import imp |
20 import optparse | 21 import optparse |
21 import os | 22 import os |
22 import re | 23 import re |
23 import subprocess | 24 import subprocess |
24 import sys | 25 import sys |
25 import textwrap | 26 import textwrap |
26 | 27 |
27 | 28 |
28 REPOSITORY_ROOT = os.path.abspath(os.path.join( | 29 REPOSITORY_ROOT = os.path.abspath(os.path.join( |
29 os.path.dirname(__file__), '..', '..')) | 30 os.path.dirname(__file__), '..', '..')) |
30 | 31 |
| 32 # Import third_party/PRESUBMIT.py via imp to avoid importing a random |
| 33 # PRESUBMIT.py from $PATH, also make sure we don't generate a .pyc file. |
| 34 sys.dont_write_bytecode = True |
| 35 third_party = \ |
| 36 imp.load_source('PRESUBMIT', \ |
| 37 os.path.join(REPOSITORY_ROOT, 'third_party', 'PRESUBMIT.py')) |
| 38 |
31 sys.path.append(os.path.join(REPOSITORY_ROOT, 'tools')) | 39 sys.path.append(os.path.join(REPOSITORY_ROOT, 'tools')) |
32 import licenses | 40 import licenses |
33 | 41 |
34 import known_issues | 42 import known_issues |
35 | 43 |
| 44 class InputApi(object): |
| 45 def __init__(self): |
| 46 self.re = re |
| 47 |
36 def GetIncompatibleDirectories(): | 48 def GetIncompatibleDirectories(): |
37 """Gets a list of third-party directories which use licenses incompatible | 49 """Gets a list of third-party directories which use licenses incompatible |
38 with Android. This is used by the snapshot tool. | 50 with Android. This is used by the snapshot tool. |
39 Returns: | 51 Returns: |
40 A list of directories. | 52 A list of directories. |
41 """ | 53 """ |
42 | 54 |
43 whitelist = [ | |
44 'A(pple )?PSL 2(\.0)?', | |
45 'Apache( Version)? 2(\.0)?', | |
46 '(New )?([23]-Clause )?BSD( [23]-Clause)?( with advertising clause)?', | |
47 'L?GPL ?v?2(\.[01])?( or later)?', | |
48 'MIT(/X11)?(-like)?', | |
49 'MPL 1\.1 ?/ ?GPL 2(\.0)? ?/ ?LGPL 2\.1', | |
50 'MPL 2(\.0)?', | |
51 'Microsoft Limited Public License', | |
52 'Microsoft Permissive License', | |
53 'Public Domain', | |
54 'Python', | |
55 'SGI Free Software License B', | |
56 'University of Illinois\/NCSA Open Source', | |
57 'X11', | |
58 ] | |
59 regex = '^(%s)$' % '|'.join(whitelist) | |
60 result = [] | 55 result = [] |
61 for directory in _FindThirdPartyDirs(): | 56 for directory in _FindThirdPartyDirs(): |
62 if directory in known_issues.KNOWN_ISSUES: | 57 if directory in known_issues.KNOWN_ISSUES: |
63 result.append(directory) | 58 result.append(directory) |
64 continue | 59 continue |
65 try: | 60 try: |
66 metadata = licenses.ParseDir(directory, REPOSITORY_ROOT, | 61 metadata = licenses.ParseDir(directory, REPOSITORY_ROOT, |
67 require_license_file=False) | 62 require_license_file=False) |
68 except licenses.LicenseError as e: | 63 except licenses.LicenseError as e: |
69 print 'Got LicenseError while scanning ' + directory | 64 print 'Got LicenseError while scanning ' + directory |
70 raise | 65 raise |
71 if metadata.get('License Android Compatible', 'no').upper() == 'YES': | 66 if metadata.get('License Android Compatible', 'no').upper() == 'YES': |
72 continue | 67 continue |
73 license = re.split(' [Ll]icenses?$', metadata['License'])[0] | 68 license = re.split(' [Ll]icenses?$', metadata['License'])[0] |
74 tokens = [x.strip() for x in re.split(' and |,', license) if len(x) > 0] | 69 if not third_party.LicenseIsCompatibleWithAndroid(InputApi(), license): |
75 for token in tokens: | 70 result.append(directory) |
76 if not re.match(regex, token, re.IGNORECASE): | |
77 result.append(directory) | |
78 break | |
79 return result | 71 return result |
80 | 72 |
81 def GetUnknownIncompatibleDirectories(): | 73 def GetUnknownIncompatibleDirectories(): |
82 """Gets a list of third-party directories which use licenses incompatible | 74 """Gets a list of third-party directories which use licenses incompatible |
83 with Android which are not present in the known_issues.py file. | 75 with Android which are not present in the known_issues.py file. |
84 This is used by the AOSP bot. | 76 This is used by the AOSP bot. |
85 Returns: | 77 Returns: |
86 A list of directories. | 78 A list of directories. |
87 """ | 79 """ |
88 incompatible_directories = frozenset(GetIncompatibleDirectories()) | 80 incompatible_directories = frozenset(GetIncompatibleDirectories()) |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 print ("Incompatibly licensed directories found:\n" + | 322 print ("Incompatibly licensed directories found:\n" + |
331 "\n".join(sorted(incompatible_directories))) | 323 "\n".join(sorted(incompatible_directories))) |
332 return ScanResult.Errors | 324 return ScanResult.Errors |
333 return ScanResult.Ok | 325 return ScanResult.Ok |
334 | 326 |
335 parser.print_help() | 327 parser.print_help() |
336 return ScanResult.Errors | 328 return ScanResult.Errors |
337 | 329 |
338 if __name__ == '__main__': | 330 if __name__ == '__main__': |
339 sys.exit(main()) | 331 sys.exit(main()) |
OLD | NEW |