Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 # 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 ANDROID_WHITELISTED_LICENSES = [ | |
| 6 'Apache( Version)? 2(\.0)?', | |
| 7 '(New )?([23]-Clause )?BSD( [23]-Clause)?( with advertising clause)?', | |
| 8 'L?GPL ?v?2(\.[01])?( or later)?', | |
| 9 'MIT(/X11)?(-like)?', | |
| 10 'MPL 1\.1 ?/ ?GPL 2(\.0)? ?/ ?LGPL 2\.1', | |
| 11 'MPL 2(\.0)?', | |
| 12 'Microsoft Limited Public License', | |
| 13 'Microsoft Permissive License', | |
| 14 'Public Domain', | |
| 15 'Python', | |
| 16 'SGI Free Software License B', | |
| 17 'University of Illinois\/NCSA Open Source', | |
| 18 'X11', | |
| 19 ] | |
| 20 | |
| 21 def LicenseIsCompatibleWithAndroid(input_api, license): | |
| 22 regex = '^(%s)$' % '|'.join(ANDROID_WHITELISTED_LICENSES) | |
| 23 tokens = \ | |
| 24 [x.strip() for x in input_api.re.split(' and |,', license) if len(x) > 0] | |
| 25 has_compatible_license = False | |
| 26 for token in tokens: | |
| 27 if input_api.re.match(regex, token, input_api.re.IGNORECASE): | |
| 28 has_compatible_license = True | |
| 29 break | |
| 30 return has_compatible_license | |
| 31 | |
| 5 def _CheckThirdPartyReadmesUpdated(input_api, output_api): | 32 def _CheckThirdPartyReadmesUpdated(input_api, output_api): |
| 6 """ | 33 """ |
| 7 Checks to make sure that README.chromium files are properly updated | 34 Checks to make sure that README.chromium files are properly updated |
| 8 when dependancies in third_party are modified. | 35 when dependancies in third_party are modified. |
| 9 """ | 36 """ |
| 10 readmes = [] | 37 readmes = [] |
| 11 files = [] | 38 files = [] |
| 12 errors = [] | 39 errors = [] |
| 13 for f in input_api.AffectedFiles(): | 40 for f in input_api.AffectedFiles(): |
| 14 local_path = f.LocalPath() | 41 local_path = f.LocalPath() |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 32 shortname_pattern = input_api.re.compile( | 59 shortname_pattern = input_api.re.compile( |
| 33 r'^Short Name: [a-zA-Z0-9_\-\.]+\r?$', | 60 r'^Short Name: [a-zA-Z0-9_\-\.]+\r?$', |
| 34 input_api.re.IGNORECASE | input_api.re.MULTILINE) | 61 input_api.re.IGNORECASE | input_api.re.MULTILINE) |
| 35 version_pattern = input_api.re.compile( | 62 version_pattern = input_api.re.compile( |
| 36 r'^Version: [a-zA-Z0-9_\-\.:]+\r?$', | 63 r'^Version: [a-zA-Z0-9_\-\.:]+\r?$', |
| 37 input_api.re.IGNORECASE | input_api.re.MULTILINE) | 64 input_api.re.IGNORECASE | input_api.re.MULTILINE) |
| 38 release_pattern = input_api.re.compile( | 65 release_pattern = input_api.re.compile( |
| 39 r'^Security Critical: (yes)|(no)\r?$', | 66 r'^Security Critical: (yes)|(no)\r?$', |
| 40 input_api.re.IGNORECASE | input_api.re.MULTILINE) | 67 input_api.re.IGNORECASE | input_api.re.MULTILINE) |
| 41 license_pattern = input_api.re.compile( | 68 license_pattern = input_api.re.compile( |
| 42 r'^License: .+\r?$', | 69 r'^License: (.+)\r?$', |
| 70 input_api.re.IGNORECASE | input_api.re.MULTILINE) | |
| 71 license_android_compatible_pattern = input_api.re.compile( | |
| 72 r'^License Android Compatible: (yes)|(no)\r?$', | |
| 43 input_api.re.IGNORECASE | input_api.re.MULTILINE) | 73 input_api.re.IGNORECASE | input_api.re.MULTILINE) |
| 44 | 74 |
| 45 for f in readmes: | 75 for f in readmes: |
| 46 if 'D' in f.Action(): | 76 if 'D' in f.Action(): |
| 47 _IgnoreIfDeleting(input_api, output_api, f, errors) | 77 _IgnoreIfDeleting(input_api, output_api, f, errors) |
| 48 continue | 78 continue |
| 49 | 79 |
| 50 contents = input_api.ReadFile(f) | 80 contents = input_api.ReadFile(f) |
| 51 if (not shortname_pattern.search(contents) | 81 if (not shortname_pattern.search(contents) |
| 52 and not name_pattern.search(contents)): | 82 and not name_pattern.search(contents)): |
| 53 errors.append(output_api.PresubmitError( | 83 errors.append(output_api.PresubmitError( |
| 54 'Third party README files should contain either a \'Short Name\' or\n' | 84 'Third party README files should contain either a \'Short Name\' or\n' |
| 55 'a \'Name\' which is the name under which the package is\n' | 85 'a \'Name\' which is the name under which the package is\n' |
| 56 'distributed. Check README.chromium.template for details.', | 86 'distributed. Check README.chromium.template for details.', |
| 57 [f])) | 87 [f])) |
| 58 if not version_pattern.search(contents): | 88 if not version_pattern.search(contents): |
| 59 errors.append(output_api.PresubmitError( | 89 errors.append(output_api.PresubmitError( |
| 60 'Third party README files should contain a \'Version\' field.\n' | 90 'Third party README files should contain a \'Version\' field.\n' |
| 61 'If the package is not versioned or the version is not known\n' | 91 'If the package is not versioned or the version is not known\n' |
| 62 'list the version as \'unknown\'.\n' | 92 'list the version as \'unknown\'.\n' |
| 63 'Check README.chromium.template for details.', | 93 'Check README.chromium.template for details.', |
| 64 [f])) | 94 [f])) |
| 65 if not release_pattern.search(contents): | 95 if not release_pattern.search(contents): |
| 66 errors.append(output_api.PresubmitError( | 96 errors.append(output_api.PresubmitError( |
| 67 'Third party README files should contain a \'Security Critical\'\n' | 97 'Third party README files should contain a \'Security Critical\'\n' |
| 68 'field. This field specifies whether the package is built with\n' | 98 'field. This field specifies whether the package is built with\n' |
| 69 'Chromium. Check README.chromium.template for details.', | 99 'Chromium. Check README.chromium.template for details.', |
| 70 [f])) | 100 [f])) |
| 71 if not license_pattern.search(contents): | 101 license_match = license_pattern.search(contents) |
| 102 if not license_match: | |
| 72 errors.append(output_api.PresubmitError( | 103 errors.append(output_api.PresubmitError( |
| 73 'Third party README files should contain a \'License\' field.\n' | 104 'Third party README files should contain a \'License\' field.\n' |
| 74 'This field specifies the license used by the package. Check\n' | 105 'This field specifies the license used by the package. Check\n' |
| 75 'README.chromium.template for details.', | 106 'README.chromium.template for details.', |
| 76 [f])) | 107 [f])) |
| 108 elif not LicenseIsCompatibleWithAndroid(input_api, license_match.group(1)) \ | |
| 109 and not license_android_compatible_pattern.search(contents): | |
| 110 errors.append(output_api.PresubmitError( | |
| 111 'The license specified does not seem to be allowed in\n' + | |
|
mkosiba (inactive)
2014/01/31 17:47:38
I guess this should be something like
'Cannot det
mnaganov (inactive)
2014/02/03 10:00:26
Yes, you are right. Fixed the text.
Also, I have
mkosiba (inactive)
2014/02/03 10:30:55
Makes sense. I guess that once I add the other bit
| |
| 112 'the Android tree. Please check that the license name is spelled\n' + | |
| 113 'according to third_party/PRESUBMIT.py. Please see\n' + | |
| 114 'README.chromium.template for details.', | |
| 115 [f])) | |
| 77 return errors | 116 return errors |
| 78 | 117 |
| 79 | 118 |
| 80 def _IgnoreIfDeleting(input_api, output_api, affected_file, errors): | 119 def _IgnoreIfDeleting(input_api, output_api, affected_file, errors): |
| 81 third_party_dir = input_api.os_path.dirname(affected_file.LocalPath()) | 120 third_party_dir = input_api.os_path.dirname(affected_file.LocalPath()) |
| 82 for f in input_api.AffectedFiles(): | 121 for f in input_api.AffectedFiles(): |
| 83 if f.LocalPath().startswith(third_party_dir): | 122 if f.LocalPath().startswith(third_party_dir): |
| 84 if 'D' not in f.Action(): | 123 if 'D' not in f.Action(): |
| 85 errors.append(output_api.PresubmitError( | 124 errors.append(output_api.PresubmitError( |
| 86 'Third party README should only be removed when the whole\n' | 125 'Third party README should only be removed when the whole\n' |
| 87 'directory is being removed.\n', [f, affected_file])) | 126 'directory is being removed.\n', [f, affected_file])) |
| 88 | 127 |
| 89 | 128 |
| 90 def CheckChangeOnUpload(input_api, output_api): | 129 def CheckChangeOnUpload(input_api, output_api): |
| 91 results = [] | 130 results = [] |
| 92 results.extend(_CheckThirdPartyReadmesUpdated(input_api, output_api)) | 131 results.extend(_CheckThirdPartyReadmesUpdated(input_api, output_api)) |
| 93 return results | 132 return results |
| OLD | NEW |