blob: 52fcc7114cbfe810e7d783f8ffbdf1c6e7c332ff [file] [log] [blame]
[email protected]99f1a482011-04-12 00:11:231# Copyright (c) 2011 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
[email protected]fd00e492014-02-10 12:44:095ANDROID_WHITELISTED_LICENSES = [
6 'A(pple )?PSL 2(\.0)?',
Peter Wend340c5e2018-07-26 20:55:397 'Android Software Development Kit License',
[email protected]fd00e492014-02-10 12:44:098 'Apache( Version)? 2(\.0)?',
9 '(New )?([23]-Clause )?BSD( [23]-Clause)?( with advertising clause)?',
Peter Wenee303ae2018-09-12 19:41:3710 'L?GPL ?v?2(\.[01])?( or later)?( with the classpath exception)?',
[email protected]fd00e492014-02-10 12:44:0911 'MIT(/X11)?(-like)?',
12 'MPL 1\.1 ?/ ?GPL 2(\.0)? ?/ ?LGPL 2\.1',
13 'MPL 2(\.0)?',
14 'Microsoft Limited Public License',
15 'Microsoft Permissive License',
16 'Public Domain',
17 'Python',
18 'SGI Free Software License B',
19 'University of Illinois\/NCSA Open Source',
20 'X11',
Corentin Wallez955059ff2018-10-21 10:47:3921 'Zlib',
[email protected]fd00e492014-02-10 12:44:0922]
23
24def LicenseIsCompatibleWithAndroid(input_api, license):
25 regex = '^(%s)$' % '|'.join(ANDROID_WHITELISTED_LICENSES)
26 tokens = \
27 [x.strip() for x in input_api.re.split(' and |,', license) if len(x) > 0]
28 has_compatible_license = False
29 for token in tokens:
30 if input_api.re.match(regex, token, input_api.re.IGNORECASE):
31 has_compatible_license = True
32 break
33 return has_compatible_license
34
[email protected]99f1a482011-04-12 00:11:2335def _CheckThirdPartyReadmesUpdated(input_api, output_api):
36 """
37 Checks to make sure that README.chromium files are properly updated
davidben88ace3f2015-11-19 17:09:5038 when dependencies in third_party are modified.
[email protected]99f1a482011-04-12 00:11:2339 """
40 readmes = []
41 files = []
42 errors = []
43 for f in input_api.AffectedFiles():
[email protected]e5dd62f2013-07-31 16:50:2844 local_path = f.LocalPath()
45 if input_api.os_path.dirname(local_path) == 'third_party':
46 continue
Primiano Tuccic2aa2ce2d2015-09-23 16:39:2947 if (local_path.startswith('third_party' + input_api.os_path.sep) and
48 not local_path.startswith('third_party' + input_api.os_path.sep +
davidben88ace3f2015-11-19 17:09:5049 'WebKit' + input_api.os_path.sep) and
50 not local_path.startswith('third_party' + input_api.os_path.sep +
Kent Tamurae9b3a9ec2017-08-31 02:20:1951 'blink' + input_api.os_path.sep) and
52 not local_path.startswith('third_party' + input_api.os_path.sep +
danakjb1423c52015-11-25 22:10:1353 'mojo' + input_api.os_path.sep) and
54 not local_path.startswith('third_party' + input_api.os_path.sep +
Dominic Mazzonib3228412018-05-22 23:29:3755 'boringssl' + input_api.os_path.sep) and
56 not local_path.startswith('third_party' + input_api.os_path.sep +
57 'closure_compiler' + input_api.os_path.sep +
58 'externs' + input_api.os_path.sep) and
59 not local_path.startswith('third_party' + input_api.os_path.sep +
60 'closure_compiler' + input_api.os_path.sep +
Alex Cooper26d47ce2019-04-25 19:51:4461 'interfaces' + input_api.os_path.sep) and
62 not local_path.startswith('third_party' + input_api.os_path.sep +
63 'webxr_test_pages' + input_api.os_path.sep)):
[email protected]99f1a482011-04-12 00:11:2364 files.append(f)
[email protected]e5dd62f2013-07-31 16:50:2865 if local_path.endswith("README.chromium"):
[email protected]99f1a482011-04-12 00:11:2366 readmes.append(f)
67 if files and not readmes:
68 errors.append(output_api.PresubmitPromptWarning(
69 'When updating or adding third party code the appropriate\n'
70 '\'README.chromium\' file should also be updated with the correct\n'
71 'version and package information.', files))
72 if not readmes:
73 return errors
74
75 name_pattern = input_api.re.compile(
[email protected]31eac5b2012-08-01 15:50:2976 r'^Name: [a-zA-Z0-9_\-\. \(\)]+\r?$',
[email protected]99f1a482011-04-12 00:11:2377 input_api.re.IGNORECASE | input_api.re.MULTILINE)
78 shortname_pattern = input_api.re.compile(
79 r'^Short Name: [a-zA-Z0-9_\-\.]+\r?$',
80 input_api.re.IGNORECASE | input_api.re.MULTILINE)
81 version_pattern = input_api.re.compile(
[email protected]0fcbfe482011-04-29 17:52:3982 r'^Version: [a-zA-Z0-9_\-\.:]+\r?$',
[email protected]99f1a482011-04-12 00:11:2383 input_api.re.IGNORECASE | input_api.re.MULTILINE)
84 release_pattern = input_api.re.compile(
[email protected]fd00e492014-02-10 12:44:0985 r'^Security Critical: (yes|no)\r?$',
[email protected]31eac5b2012-08-01 15:50:2986 input_api.re.IGNORECASE | input_api.re.MULTILINE)
87 license_pattern = input_api.re.compile(
[email protected]fd00e492014-02-10 12:44:0988 r'^License: (.+)\r?$',
89 input_api.re.IGNORECASE | input_api.re.MULTILINE)
90 license_android_compatible_pattern = input_api.re.compile(
91 r'^License Android Compatible: (yes|no)\r?$',
[email protected]99f1a482011-04-12 00:11:2392 input_api.re.IGNORECASE | input_api.re.MULTILINE)
93
94 for f in readmes:
[email protected]e5dd62f2013-07-31 16:50:2895 if 'D' in f.Action():
96 _IgnoreIfDeleting(input_api, output_api, f, errors)
97 continue
98
[email protected]99f1a482011-04-12 00:11:2399 contents = input_api.ReadFile(f)
100 if (not shortname_pattern.search(contents)
101 and not name_pattern.search(contents)):
102 errors.append(output_api.PresubmitError(
103 'Third party README files should contain either a \'Short Name\' or\n'
104 'a \'Name\' which is the name under which the package is\n'
105 'distributed. Check README.chromium.template for details.',
106 [f]))
107 if not version_pattern.search(contents):
108 errors.append(output_api.PresubmitError(
109 'Third party README files should contain a \'Version\' field.\n'
110 'If the package is not versioned or the version is not known\n'
111 'list the version as \'unknown\'.\n'
112 'Check README.chromium.template for details.',
113 [f]))
114 if not release_pattern.search(contents):
115 errors.append(output_api.PresubmitError(
116 'Third party README files should contain a \'Security Critical\'\n'
117 'field. This field specifies whether the package is built with\n'
118 'Chromium. Check README.chromium.template for details.',
119 [f]))
[email protected]fd00e492014-02-10 12:44:09120 license_match = license_pattern.search(contents)
121 if not license_match:
[email protected]31eac5b2012-08-01 15:50:29122 errors.append(output_api.PresubmitError(
123 'Third party README files should contain a \'License\' field.\n'
124 'This field specifies the license used by the package. Check\n'
125 'README.chromium.template for details.',
126 [f]))
[email protected]fd00e492014-02-10 12:44:09127 elif not LicenseIsCompatibleWithAndroid(input_api, license_match.group(1)) \
128 and not license_android_compatible_pattern.search(contents):
129 errors.append(output_api.PresubmitPromptWarning(
130 'Cannot determine whether specified license is compatible with\n' +
131 'the Android licensing requirements. Please check that the license\n' +
132 'name is spelled according to third_party/PRESUBMIT.py. Please see\n' +
133 'README.chromium.template for details.',
134 [f]))
[email protected]99f1a482011-04-12 00:11:23135 return errors
136
137
[email protected]e5dd62f2013-07-31 16:50:28138def _IgnoreIfDeleting(input_api, output_api, affected_file, errors):
139 third_party_dir = input_api.os_path.dirname(affected_file.LocalPath())
140 for f in input_api.AffectedFiles():
141 if f.LocalPath().startswith(third_party_dir):
142 if 'D' not in f.Action():
143 errors.append(output_api.PresubmitError(
144 'Third party README should only be removed when the whole\n'
145 'directory is being removed.\n', [f, affected_file]))
146
147
[email protected]99f1a482011-04-12 00:11:23148def CheckChangeOnUpload(input_api, output_api):
149 results = []
150 results.extend(_CheckThirdPartyReadmesUpdated(input_api, output_api))
151 return results