blob: e7b8dd365f2c81dc8ebdea50679c01183603562b [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)?',
7 'Apache( Version)? 2(\.0)?',
8 '(New )?([23]-Clause )?BSD( [23]-Clause)?( with advertising clause)?',
9 'L?GPL ?v?2(\.[01])?( or later)?',
10 'MIT(/X11)?(-like)?',
11 'MPL 1\.1 ?/ ?GPL 2(\.0)? ?/ ?LGPL 2\.1',
12 'MPL 2(\.0)?',
13 'Microsoft Limited Public License',
14 'Microsoft Permissive License',
15 'Public Domain',
16 'Python',
17 'SGI Free Software License B',
18 'University of Illinois\/NCSA Open Source',
19 'X11',
20]
21
22def LicenseIsCompatibleWithAndroid(input_api, license):
23 regex = '^(%s)$' % '|'.join(ANDROID_WHITELISTED_LICENSES)
24 tokens = \
25 [x.strip() for x in input_api.re.split(' and |,', license) if len(x) > 0]
26 has_compatible_license = False
27 for token in tokens:
28 if input_api.re.match(regex, token, input_api.re.IGNORECASE):
29 has_compatible_license = True
30 break
31 return has_compatible_license
32
[email protected]99f1a482011-04-12 00:11:2333def _CheckThirdPartyReadmesUpdated(input_api, output_api):
34 """
35 Checks to make sure that README.chromium files are properly updated
davidben88ace3f2015-11-19 17:09:5036 when dependencies in third_party are modified.
[email protected]99f1a482011-04-12 00:11:2337 """
38 readmes = []
39 files = []
40 errors = []
41 for f in input_api.AffectedFiles():
[email protected]e5dd62f2013-07-31 16:50:2842 local_path = f.LocalPath()
43 if input_api.os_path.dirname(local_path) == 'third_party':
44 continue
Primiano Tuccic2aa2ce2d2015-09-23 16:39:2945 if (local_path.startswith('third_party' + input_api.os_path.sep) and
46 not local_path.startswith('third_party' + input_api.os_path.sep +
davidben88ace3f2015-11-19 17:09:5047 'WebKit' + input_api.os_path.sep) and
48 not local_path.startswith('third_party' + input_api.os_path.sep +
danakjb1423c52015-11-25 22:10:1349 'mojo' + input_api.os_path.sep) and
50 not local_path.startswith('third_party' + input_api.os_path.sep +
davidben88ace3f2015-11-19 17:09:5051 'boringssl' + input_api.os_path.sep)):
[email protected]99f1a482011-04-12 00:11:2352 files.append(f)
[email protected]e5dd62f2013-07-31 16:50:2853 if local_path.endswith("README.chromium"):
[email protected]99f1a482011-04-12 00:11:2354 readmes.append(f)
55 if files and not readmes:
56 errors.append(output_api.PresubmitPromptWarning(
57 'When updating or adding third party code the appropriate\n'
58 '\'README.chromium\' file should also be updated with the correct\n'
59 'version and package information.', files))
60 if not readmes:
61 return errors
62
63 name_pattern = input_api.re.compile(
[email protected]31eac5b2012-08-01 15:50:2964 r'^Name: [a-zA-Z0-9_\-\. \(\)]+\r?$',
[email protected]99f1a482011-04-12 00:11:2365 input_api.re.IGNORECASE | input_api.re.MULTILINE)
66 shortname_pattern = input_api.re.compile(
67 r'^Short Name: [a-zA-Z0-9_\-\.]+\r?$',
68 input_api.re.IGNORECASE | input_api.re.MULTILINE)
69 version_pattern = input_api.re.compile(
[email protected]0fcbfe482011-04-29 17:52:3970 r'^Version: [a-zA-Z0-9_\-\.:]+\r?$',
[email protected]99f1a482011-04-12 00:11:2371 input_api.re.IGNORECASE | input_api.re.MULTILINE)
72 release_pattern = input_api.re.compile(
[email protected]fd00e492014-02-10 12:44:0973 r'^Security Critical: (yes|no)\r?$',
[email protected]31eac5b2012-08-01 15:50:2974 input_api.re.IGNORECASE | input_api.re.MULTILINE)
75 license_pattern = input_api.re.compile(
[email protected]fd00e492014-02-10 12:44:0976 r'^License: (.+)\r?$',
77 input_api.re.IGNORECASE | input_api.re.MULTILINE)
78 license_android_compatible_pattern = input_api.re.compile(
79 r'^License Android Compatible: (yes|no)\r?$',
[email protected]99f1a482011-04-12 00:11:2380 input_api.re.IGNORECASE | input_api.re.MULTILINE)
81
82 for f in readmes:
[email protected]e5dd62f2013-07-31 16:50:2883 if 'D' in f.Action():
84 _IgnoreIfDeleting(input_api, output_api, f, errors)
85 continue
86
[email protected]99f1a482011-04-12 00:11:2387 contents = input_api.ReadFile(f)
88 if (not shortname_pattern.search(contents)
89 and not name_pattern.search(contents)):
90 errors.append(output_api.PresubmitError(
91 'Third party README files should contain either a \'Short Name\' or\n'
92 'a \'Name\' which is the name under which the package is\n'
93 'distributed. Check README.chromium.template for details.',
94 [f]))
95 if not version_pattern.search(contents):
96 errors.append(output_api.PresubmitError(
97 'Third party README files should contain a \'Version\' field.\n'
98 'If the package is not versioned or the version is not known\n'
99 'list the version as \'unknown\'.\n'
100 'Check README.chromium.template for details.',
101 [f]))
102 if not release_pattern.search(contents):
103 errors.append(output_api.PresubmitError(
104 'Third party README files should contain a \'Security Critical\'\n'
105 'field. This field specifies whether the package is built with\n'
106 'Chromium. Check README.chromium.template for details.',
107 [f]))
[email protected]fd00e492014-02-10 12:44:09108 license_match = license_pattern.search(contents)
109 if not license_match:
[email protected]31eac5b2012-08-01 15:50:29110 errors.append(output_api.PresubmitError(
111 'Third party README files should contain a \'License\' field.\n'
112 'This field specifies the license used by the package. Check\n'
113 'README.chromium.template for details.',
114 [f]))
[email protected]fd00e492014-02-10 12:44:09115 elif not LicenseIsCompatibleWithAndroid(input_api, license_match.group(1)) \
116 and not license_android_compatible_pattern.search(contents):
117 errors.append(output_api.PresubmitPromptWarning(
118 'Cannot determine whether specified license is compatible with\n' +
119 'the Android licensing requirements. Please check that the license\n' +
120 'name is spelled according to third_party/PRESUBMIT.py. Please see\n' +
121 'README.chromium.template for details.',
122 [f]))
[email protected]99f1a482011-04-12 00:11:23123 return errors
124
125
[email protected]e5dd62f2013-07-31 16:50:28126def _IgnoreIfDeleting(input_api, output_api, affected_file, errors):
127 third_party_dir = input_api.os_path.dirname(affected_file.LocalPath())
128 for f in input_api.AffectedFiles():
129 if f.LocalPath().startswith(third_party_dir):
130 if 'D' not in f.Action():
131 errors.append(output_api.PresubmitError(
132 'Third party README should only be removed when the whole\n'
133 'directory is being removed.\n', [f, affected_file]))
134
135
[email protected]99f1a482011-04-12 00:11:23136def CheckChangeOnUpload(input_api, output_api):
137 results = []
138 results.extend(_CheckThirdPartyReadmesUpdated(input_api, output_api))
139 return results