OLD | NEW |
---|---|
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 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 """Gathers information about APKs.""" | 5 """Gathers information about APKs.""" |
6 | 6 |
7 import collections | 7 import collections |
8 import logging | |
8 import os | 9 import os |
10 import pickle | |
9 import re | 11 import re |
10 | 12 |
11 import cmd_helper | 13 import cmd_helper |
12 | 14 |
15 # If you change the cached output of proguard, increment this number | |
16 PICKLE_FORMAT_VERSION = 1 | |
13 | 17 |
14 def GetPackageNameForApk(apk_path): | 18 def GetPackageNameForApk(apk_path): |
15 """Returns the package name of the apk file.""" | 19 """Returns the package name of the apk file.""" |
16 aapt_output = cmd_helper.GetCmdOutput( | 20 aapt_output = cmd_helper.GetCmdOutput( |
17 ['aapt', 'dump', 'badging', apk_path]).split('\n') | 21 ['aapt', 'dump', 'badging', apk_path]).split('\n') |
18 package_name_re = re.compile(r'package: .*name=\'(\S*)\'') | 22 package_name_re = re.compile(r'package: .*name=\'(\S*)\'') |
19 for line in aapt_output: | 23 for line in aapt_output: |
20 m = package_name_re.match(line) | 24 m = package_name_re.match(line) |
21 if m: | 25 if m: |
22 return m.group(1) | 26 return m.group(1) |
(...skipping 20 matching lines...) Expand all Loading... | |
43 raise Exception('%s not found, please build it' % apk_path) | 47 raise Exception('%s not found, please build it' % apk_path) |
44 self._apk_path = apk_path | 48 self._apk_path = apk_path |
45 if not os.path.exists(jar_path): | 49 if not os.path.exists(jar_path): |
46 raise Exception('%s not found, please build it' % jar_path) | 50 raise Exception('%s not found, please build it' % jar_path) |
47 self._jar_path = jar_path | 51 self._jar_path = jar_path |
48 self._annotation_map = collections.defaultdict(list) | 52 self._annotation_map = collections.defaultdict(list) |
49 self._test_methods = [] | 53 self._test_methods = [] |
50 self._Initialize() | 54 self._Initialize() |
51 | 55 |
52 def _Initialize(self): | 56 def _Initialize(self): |
57 pickle_name = self._jar_path + "-proguard.pickle" | |
frankf
2012/11/22 03:03:48
single quotes here and below.
Yaron
2012/11/26 18:26:15
Done.
| |
58 if os.path.exists(pickle_name) and (os.stat(pickle_name).st_mtime > | |
59 os.stat(self._jar_path).st_mtime): | |
frankf
2012/11/22 03:03:48
os.path.getmtime() is slightly preferred.
Yaron
2012/11/26 18:26:15
Done.
| |
60 logging.info("Loading cached proguard output from %s", pickle_name) | |
bulach
2012/11/22 13:51:20
see below, probably best as:
try:
with open(pick
Yaron
2012/11/26 18:26:15
Done.
| |
61 unpickler = pickle.Unpickler(open(pickle_name)) | |
62 if PICKLE_FORMAT_VERSION == unpickler.load(): | |
bulach
2012/11/22 13:51:20
prefer to pickle one dict, see below..
Yaron
2012/11/26 18:26:15
Done.
| |
63 self._annotation_map = unpickler.load() | |
64 self._test_methods = unpickler.load() | |
65 return | |
66 else: | |
67 logging.warning("PICKLE_FORMAT_VERSION has changed, ignoring cache") | |
frankf
2012/11/22 03:03:48
Can you put this in a finally block with above lin
Yaron
2012/11/26 18:26:15
Done.
| |
68 | |
53 proguard_output = cmd_helper.GetCmdOutput([self._PROGUARD_PATH, | 69 proguard_output = cmd_helper.GetCmdOutput([self._PROGUARD_PATH, |
54 '-injars', self._jar_path, | 70 '-injars', self._jar_path, |
55 '-dontshrink', | 71 '-dontshrink', |
56 '-dontoptimize', | 72 '-dontoptimize', |
57 '-dontobfuscate', | 73 '-dontobfuscate', |
58 '-dontpreverify', | 74 '-dontpreverify', |
59 '-dump', | 75 '-dump', |
60 ]).split('\n') | 76 ]).split('\n') |
61 clazz = None | 77 clazz = None |
62 method = None | 78 method = None |
(...skipping 28 matching lines...) Expand all Loading... | |
91 if m: | 107 if m: |
92 has_value = True | 108 has_value = True |
93 else: | 109 else: |
94 m = self._PROGUARD_ANNOTATION_VALUE_RE.match(line) | 110 m = self._PROGUARD_ANNOTATION_VALUE_RE.match(line) |
95 if m: | 111 if m: |
96 value = m.group(1) | 112 value = m.group(1) |
97 self._annotation_map[qualified_method].append( | 113 self._annotation_map[qualified_method].append( |
98 annotation + ':' + value) | 114 annotation + ':' + value) |
99 has_value = False | 115 has_value = False |
100 | 116 |
117 logging.info("Storing proguard output to %s", pickle_name) | |
118 pickler = pickle.Pickler(open(pickle_name, 'w')) | |
bulach
2012/11/22 13:51:20
pickle.dumps with a dict works better, no need for
Yaron
2012/11/26 18:26:15
Done.
| |
119 pickler.dump(PICKLE_FORMAT_VERSION) | |
120 pickler.dump(self._annotation_map) | |
121 pickler.dump(self._test_methods) | |
122 | |
101 def _GetAnnotationMap(self): | 123 def _GetAnnotationMap(self): |
102 return self._annotation_map | 124 return self._annotation_map |
103 | 125 |
104 def _IsTestMethod(self, test): | 126 def _IsTestMethod(self, test): |
105 class_name, method = test.split('#') | 127 class_name, method = test.split('#') |
106 return class_name.endswith('Test') and method.startswith('test') | 128 return class_name.endswith('Test') and method.startswith('test') |
107 | 129 |
108 def GetApkPath(self): | 130 def GetApkPath(self): |
109 return self._apk_path | 131 return self._apk_path |
110 | 132 |
(...skipping 29 matching lines...) Expand all Loading... | |
140 if self._IsTestMethod(test) and self._AnnotationsMatchFilters( | 162 if self._IsTestMethod(test) and self._AnnotationsMatchFilters( |
141 annotation_filter_list, annotations)] | 163 annotation_filter_list, annotations)] |
142 | 164 |
143 def GetTestMethods(self): | 165 def GetTestMethods(self): |
144 """Returns a list of all test methods in this apk as Class#testMethod.""" | 166 """Returns a list of all test methods in this apk as Class#testMethod.""" |
145 return self._test_methods | 167 return self._test_methods |
146 | 168 |
147 @staticmethod | 169 @staticmethod |
148 def IsPythonDrivenTest(test): | 170 def IsPythonDrivenTest(test): |
149 return 'pythonDrivenTests' in test | 171 return 'pythonDrivenTests' in test |
OLD | NEW |