blob: 12011a53b5b2873db7ba6f640819bf8eb599b1af [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
Dan Harringtonb60e1aa2019-11-20 08:48:545import os
6
[email protected]fd00e492014-02-10 12:44:097ANDROID_WHITELISTED_LICENSES = [
8 'A(pple )?PSL 2(\.0)?',
Peter Wend340c5e2018-07-26 20:55:399 'Android Software Development Kit License',
Andrew Grieved1f9db42019-11-13 16:50:5810 'Apache( License)?,?( Version)? 2(\.0)?',
[email protected]fd00e492014-02-10 12:44:0911 '(New )?([23]-Clause )?BSD( [23]-Clause)?( with advertising clause)?',
Andrew Grieved1f9db42019-11-13 16:50:5812 'GNU Lesser Public License',
Peter Wenee303ae2018-09-12 19:41:3713 'L?GPL ?v?2(\.[01])?( or later)?( with the classpath exception)?',
Andrew Grieved1f9db42019-11-13 16:50:5814 '(The )?MIT(/X11)?(-like)?( License)?',
[email protected]fd00e492014-02-10 12:44:0915 'MPL 1\.1 ?/ ?GPL 2(\.0)? ?/ ?LGPL 2\.1',
16 'MPL 2(\.0)?',
17 'Microsoft Limited Public License',
18 'Microsoft Permissive License',
19 'Public Domain',
20 'Python',
21 'SGI Free Software License B',
22 'University of Illinois\/NCSA Open Source',
23 'X11',
Corentin Wallez955059ff2018-10-21 10:47:3924 'Zlib',
[email protected]fd00e492014-02-10 12:44:0925]
26
27def LicenseIsCompatibleWithAndroid(input_api, license):
28 regex = '^(%s)$' % '|'.join(ANDROID_WHITELISTED_LICENSES)
29 tokens = \
30 [x.strip() for x in input_api.re.split(' and |,', license) if len(x) > 0]
31 has_compatible_license = False
32 for token in tokens:
33 if input_api.re.match(regex, token, input_api.re.IGNORECASE):
34 has_compatible_license = True
35 break
36 return has_compatible_license
37
[email protected]99f1a482011-04-12 00:11:2338def _CheckThirdPartyReadmesUpdated(input_api, output_api):
39 """
40 Checks to make sure that README.chromium files are properly updated
davidben88ace3f2015-11-19 17:09:5041 when dependencies in third_party are modified.
[email protected]99f1a482011-04-12 00:11:2342 """
43 readmes = []
44 files = []
45 errors = []
46 for f in input_api.AffectedFiles():
[email protected]e5dd62f2013-07-31 16:50:2847 local_path = f.LocalPath()
48 if input_api.os_path.dirname(local_path) == 'third_party':
49 continue
Primiano Tuccic2aa2ce2d2015-09-23 16:39:2950 if (local_path.startswith('third_party' + input_api.os_path.sep) and
51 not local_path.startswith('third_party' + input_api.os_path.sep +
Kent Tamurae9b3a9ec2017-08-31 02:20:1952 'blink' + input_api.os_path.sep) and
53 not local_path.startswith('third_party' + input_api.os_path.sep +
Dominic Mazzonib3228412018-05-22 23:29:3754 'boringssl' + input_api.os_path.sep) and
55 not local_path.startswith('third_party' + input_api.os_path.sep +
Dominic Mazzonib3228412018-05-22 23:29:3756 'closure_compiler' + input_api.os_path.sep +
57 'externs' + input_api.os_path.sep) and
58 not local_path.startswith('third_party' + input_api.os_path.sep +
59 'closure_compiler' + input_api.os_path.sep +
Alex Cooper26d47ce2019-04-25 19:51:4460 'interfaces' + input_api.os_path.sep) and
61 not local_path.startswith('third_party' + input_api.os_path.sep +
Peter Kasting8ea44bb2020-07-11 20:36:0162 'feed_library' + input_api.os_path.sep) and
Dan Harrington4bb752422019-11-21 19:30:3863 not local_path.startswith('third_party' + input_api.os_path.sep +
Peter Kasting8ea44bb2020-07-11 20:36:0164 'mojo' + input_api.os_path.sep) and
65 not local_path.startswith('third_party' + input_api.os_path.sep +
66 'webxr_test_pages' + input_api.os_path.sep)):
[email protected]99f1a482011-04-12 00:11:2367 files.append(f)
[email protected]e5dd62f2013-07-31 16:50:2868 if local_path.endswith("README.chromium"):
[email protected]99f1a482011-04-12 00:11:2369 readmes.append(f)
70 if files and not readmes:
71 errors.append(output_api.PresubmitPromptWarning(
72 'When updating or adding third party code the appropriate\n'
73 '\'README.chromium\' file should also be updated with the correct\n'
74 'version and package information.', files))
75 if not readmes:
76 return errors
77
78 name_pattern = input_api.re.compile(
[email protected]31eac5b2012-08-01 15:50:2979 r'^Name: [a-zA-Z0-9_\-\. \(\)]+\r?$',
[email protected]99f1a482011-04-12 00:11:2380 input_api.re.IGNORECASE | input_api.re.MULTILINE)
81 shortname_pattern = input_api.re.compile(
82 r'^Short Name: [a-zA-Z0-9_\-\.]+\r?$',
83 input_api.re.IGNORECASE | input_api.re.MULTILINE)
84 version_pattern = input_api.re.compile(
Andrew Grieved1f9db42019-11-13 16:50:5885 r'^Version: [a-zA-Z0-9_\-\+\.:]+\r?$',
[email protected]99f1a482011-04-12 00:11:2386 input_api.re.IGNORECASE | input_api.re.MULTILINE)
87 release_pattern = input_api.re.compile(
[email protected]fd00e492014-02-10 12:44:0988 r'^Security Critical: (yes|no)\r?$',
[email protected]31eac5b2012-08-01 15:50:2989 input_api.re.IGNORECASE | input_api.re.MULTILINE)
90 license_pattern = input_api.re.compile(
[email protected]fd00e492014-02-10 12:44:0991 r'^License: (.+)\r?$',
92 input_api.re.IGNORECASE | input_api.re.MULTILINE)
Andrew Grieved1f9db42019-11-13 16:50:5893 not_shipped_pattern = input_api.re.compile(
94 r'^License File: NOT_SHIPPED\r?$',
95 input_api.re.IGNORECASE | input_api.re.MULTILINE)
[email protected]fd00e492014-02-10 12:44:0996 license_android_compatible_pattern = input_api.re.compile(
97 r'^License Android Compatible: (yes|no)\r?$',
[email protected]99f1a482011-04-12 00:11:2398 input_api.re.IGNORECASE | input_api.re.MULTILINE)
99
100 for f in readmes:
[email protected]e5dd62f2013-07-31 16:50:28101 if 'D' in f.Action():
102 _IgnoreIfDeleting(input_api, output_api, f, errors)
103 continue
104
[email protected]99f1a482011-04-12 00:11:23105 contents = input_api.ReadFile(f)
106 if (not shortname_pattern.search(contents)
107 and not name_pattern.search(contents)):
108 errors.append(output_api.PresubmitError(
109 'Third party README files should contain either a \'Short Name\' or\n'
110 'a \'Name\' which is the name under which the package is\n'
111 'distributed. Check README.chromium.template for details.',
112 [f]))
113 if not version_pattern.search(contents):
114 errors.append(output_api.PresubmitError(
115 'Third party README files should contain a \'Version\' field.\n'
116 'If the package is not versioned or the version is not known\n'
117 'list the version as \'unknown\'.\n'
118 'Check README.chromium.template for details.',
119 [f]))
120 if not release_pattern.search(contents):
121 errors.append(output_api.PresubmitError(
122 'Third party README files should contain a \'Security Critical\'\n'
123 'field. This field specifies whether the package is built with\n'
124 'Chromium. Check README.chromium.template for details.',
125 [f]))
[email protected]fd00e492014-02-10 12:44:09126 license_match = license_pattern.search(contents)
127 if not license_match:
[email protected]31eac5b2012-08-01 15:50:29128 errors.append(output_api.PresubmitError(
129 'Third party README files should contain a \'License\' field.\n'
130 'This field specifies the license used by the package. Check\n'
131 'README.chromium.template for details.',
132 [f]))
Andrew Grieved1f9db42019-11-13 16:50:58133 not_shipped_match = not_shipped_pattern.search(contents)
134 android_compatible_match = (
135 license_android_compatible_pattern.search(contents))
Justin DeWitt09be99352020-07-07 18:18:19136 if (not not_shipped_match and not android_compatible_match and
Andrew Grieved1f9db42019-11-13 16:50:58137 not LicenseIsCompatibleWithAndroid(input_api, license_match.group(1))):
[email protected]fd00e492014-02-10 12:44:09138 errors.append(output_api.PresubmitPromptWarning(
139 'Cannot determine whether specified license is compatible with\n' +
140 'the Android licensing requirements. Please check that the license\n' +
141 'name is spelled according to third_party/PRESUBMIT.py. Please see\n' +
142 'README.chromium.template for details.',
143 [f]))
[email protected]99f1a482011-04-12 00:11:23144 return errors
145
146
[email protected]e5dd62f2013-07-31 16:50:28147def _IgnoreIfDeleting(input_api, output_api, affected_file, errors):
Dan Harringtonb60e1aa2019-11-20 08:48:54148 third_party_dir = input_api.os_path.dirname(affected_file.LocalPath()) + \
149 os.path.sep
[email protected]e5dd62f2013-07-31 16:50:28150 for f in input_api.AffectedFiles():
151 if f.LocalPath().startswith(third_party_dir):
152 if 'D' not in f.Action():
153 errors.append(output_api.PresubmitError(
154 'Third party README should only be removed when the whole\n'
155 'directory is being removed.\n', [f, affected_file]))
156
157
[email protected]99f1a482011-04-12 00:11:23158def CheckChangeOnUpload(input_api, output_api):
159 results = []
160 results.extend(_CheckThirdPartyReadmesUpdated(input_api, output_api))
161 return results