Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(155)

Side by Side Diff: components/cronet/tools/api_static_checks.py

Issue 2544043002: [Cronet] Enforce Cronet API never modified, only grown (Closed)
Patch Set: fix Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright 2016 The Chromium Authors. All rights reserved. 2 # Copyright 2016 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 """api_static_checks.py - Check Cronet implementation does not call through 6 """api_static_checks.py - Enforce Cronet API requirements."""
7 API classes.
8 """
9 7
10 import argparse 8 import argparse
11 import os 9 import os
12 import re 10 import re
13 import shutil 11 import shutil
14 import sys 12 import sys
15 import tempfile 13 import tempfile
16 14
15 import update_api
16
17 REPOSITORY_ROOT = os.path.abspath(os.path.join( 17 REPOSITORY_ROOT = os.path.abspath(os.path.join(
18 os.path.dirname(__file__), '..', '..', '..')) 18 os.path.dirname(__file__), '..', '..', '..'))
19 19
20 sys.path.append(os.path.join(REPOSITORY_ROOT, 'build/android/gyp/util')) 20 sys.path.append(os.path.join(REPOSITORY_ROOT, 'build/android/gyp/util'))
21 import build_utils 21 import build_utils
22 22
23 # These regular expressions catch the beginning of lines that declar classes and 23 # These regular expressions catch the beginning of lines that declar classes and
24 # methods. The first group returned by a match is the class or method name. 24 # methods. The first group returned by a match is the class or method name.
25 CLASS_RE = re.compile(r'.*class ([^ ]*) .*{') 25 from update_api import CLASS_RE
26 METHOD_RE = re.compile(r'.* ([^ ]*)\(.*\);') 26 METHOD_RE = re.compile(r'.* ([^ ]*)\(.*\);')
27 27
28 # Allowed exceptions. Adding anything to this list is dangerous and should be 28 # Allowed exceptions. Adding anything to this list is dangerous and should be
29 # avoided if possible. For now these exceptions are for APIs that existed in 29 # avoided if possible. For now these exceptions are for APIs that existed in
30 # the first version of Cronet and will be supported forever. 30 # the first version of Cronet and will be supported forever.
31 # TODO(pauljensen): Remove these. 31 # TODO(pauljensen): Remove these.
32 ALLOWED_EXCEPTIONS = [ 32 ALLOWED_EXCEPTIONS = [
33 'org.chromium.net.impl.CronetEngineBuilderImpl/build ->' 33 'org.chromium.net.impl.CronetEngineBuilderImpl/build ->'
34 ' org/chromium/net/ExperimentalCronetEngine/getVersionString', 34 ' org/chromium/net/ExperimentalCronetEngine/getVersionString',
35 'org.chromium.net.urlconnection.CronetFixedModeOutputStream$UploadDataProviderI' 35 'org.chromium.net.urlconnection.CronetFixedModeOutputStream$UploadDataProviderI'
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 # Ignore VersionSafe calls 86 # Ignore VersionSafe calls
87 if 'VersionSafeCallbacks' in caller_class: 87 if 'VersionSafeCallbacks' in caller_class:
88 continue 88 continue
89 bad_call = '%s/%s -> %s/%s' % (caller_class, caller_method, 89 bad_call = '%s/%s -> %s/%s' % (caller_class, caller_method,
90 callee_class, callee_method) 90 callee_class, callee_method)
91 if bad_call in ALLOWED_EXCEPTIONS: 91 if bad_call in ALLOWED_EXCEPTIONS:
92 continue 92 continue
93 bad_calls += [bad_call] 93 bad_calls += [bad_call]
94 94
95 95
96 def main(args): 96 def check_api_calls(opts):
97 # Returns True if no calls through API classes in implementation. 97 # Returns True if no calls through API classes in implementation.
98 98
99 parser = argparse.ArgumentParser(
100 description='Check modules do not contain ARM Neon instructions.')
101 parser.add_argument('--api_jar',
102 help='Path to API jar (i.e. cronet_api.jar)',
103 required=True,
104 metavar='path/to/cronet_api.jar')
105 parser.add_argument('--impl_jar',
106 help='Path to implementation jar '
107 '(i.e. cronet_impl_native_java.jar)',
108 required=True,
109 metavar='path/to/cronet_impl_native_java.jar',
110 action='append')
111 parser.add_argument('--stamp', help='Path to touch on success.')
112 opts = parser.parse_args(args)
113
114 temp_dir = tempfile.mkdtemp() 99 temp_dir = tempfile.mkdtemp()
115 100
116 # Extract API class files from jar 101 # Extract API class files from jar
117 jar_cmd = ['jar', 'xf', os.path.abspath(opts.api_jar)] 102 jar_cmd = ['jar', 'xf', os.path.abspath(opts.api_jar)]
118 build_utils.CheckOutput(jar_cmd, cwd=temp_dir) 103 build_utils.CheckOutput(jar_cmd, cwd=temp_dir)
119 shutil.rmtree(os.path.join(temp_dir, 'META-INF')) 104 shutil.rmtree(os.path.join(temp_dir, 'META-INF'))
120 105
121 # Collect names of API classes 106 # Collect names of API classes
122 api_classes = [] 107 api_classes = []
123 for root, _, filenames in os.walk(temp_dir): 108 for root, _, filenames in os.walk(temp_dir):
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 find_api_calls(dump, api_classes, api_calls) 140 find_api_calls(dump, api_classes, api_calls)
156 141
157 shutil.rmtree(temp_dir) 142 shutil.rmtree(temp_dir)
158 143
159 if api_calls: 144 if api_calls:
160 print 'ERROR: Found the following calls from implementation classes through' 145 print 'ERROR: Found the following calls from implementation classes through'
161 print ' API classes. These could fail if older API is used that' 146 print ' API classes. These could fail if older API is used that'
162 print ' does not contain newer methods. Please call through a' 147 print ' does not contain newer methods. Please call through a'
163 print ' wrapper class from VersionSafeCallbacks.' 148 print ' wrapper class from VersionSafeCallbacks.'
164 print '\n'.join(api_calls) 149 print '\n'.join(api_calls)
165
166 if not api_calls and opts.stamp:
167 build_utils.Touch(opts.stamp)
168 return not api_calls 150 return not api_calls
169 151
170 152
153 def check_api_version(opts):
154 if update_api.check_up_to_date(opts.api_jar):
155 return True
156 print 'ERROR: API file out of date. Please run this command:'
157 print ' components/cronet/tools/update_api.py --api_jar %s' % (
158 os.path.abspath(opts.api_jar))
159 return False
160
161
162 def main(args):
163 parser = argparse.ArgumentParser(
164 description='Enforce Cronet API requirements.')
165 parser.add_argument('--api_jar',
166 help='Path to API jar (i.e. cronet_api.jar)',
167 required=True,
168 metavar='path/to/cronet_api.jar')
169 parser.add_argument('--impl_jar',
170 help='Path to implementation jar '
171 '(i.e. cronet_impl_native_java.jar)',
172 required=True,
173 metavar='path/to/cronet_impl_native_java.jar',
174 action='append')
175 parser.add_argument('--stamp', help='Path to touch on success.')
176 opts = parser.parse_args(args)
177
178 ret = True
179 ret = check_api_calls(opts) and ret
180 ret = check_api_version(opts) and ret
181 if ret and opts.stamp:
182 build_utils.Touch(opts.stamp)
183 return ret
184
185
171 if __name__ == '__main__': 186 if __name__ == '__main__':
172 sys.exit(0 if main(sys.argv[1:]) != 0 else -1) 187 sys.exit(0 if main(sys.argv[1:]) != 0 else -1)
173 188
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698