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

Side by Side Diff: build/android/gyp/emma_instr.py

Issue 1448223004: Refactor emma_instr.py in preparation for porting EMMA GYP rules to GN (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month 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
« no previous file with comments | « build/android/emma_instr_action.gypi ('k') | build/java.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # 2 #
3 # Copyright 2013 The Chromium Authors. All rights reserved. 3 # Copyright 2013 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 """Instruments classes and jar files. 7 """Instruments classes and jar files.
8 8
9 This script corresponds to the 'emma_instr' action in the java build process. 9 This script corresponds to the 'emma_instr' action in the java build process.
10 Depending on whether emma_instrument is set, the 'emma_instr' action will either 10 Depending on whether emma_instrument is set, the 'emma_instr' action will either
(...skipping 14 matching lines...) Expand all
25 import tempfile 25 import tempfile
26 26
27 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir)) 27 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir))
28 from pylib.utils import command_option_parser 28 from pylib.utils import command_option_parser
29 29
30 from util import build_utils 30 from util import build_utils
31 31
32 32
33 def _AddCommonOptions(option_parser): 33 def _AddCommonOptions(option_parser):
34 """Adds common options to |option_parser|.""" 34 """Adds common options to |option_parser|."""
35 build_utils.AddDepfileOption(option_parser)
35 option_parser.add_option('--input-path', 36 option_parser.add_option('--input-path',
36 help=('Path to input file(s). Either the classes ' 37 help=('Path to input file(s). Either the classes '
37 'directory, or the path to a jar.')) 38 'directory, or the path to a jar.'))
38 option_parser.add_option('--output-path', 39 option_parser.add_option('--output-path',
39 help=('Path to output final file(s) to. Either the ' 40 help=('Path to output final file(s) to. Either the '
40 'final classes directory, or the directory in ' 41 'final classes directory, or the directory in '
41 'which to place the instrumented/copied jar.')) 42 'which to place the instrumented/copied jar.'))
42 option_parser.add_option('--stamp', help='Path to touch when done.') 43 option_parser.add_option('--stamp', help='Path to touch when done.')
43 option_parser.add_option('--coverage-file', 44 option_parser.add_option('--coverage-file',
44 help='File to create with coverage metadata.') 45 help='File to create with coverage metadata.')
45 option_parser.add_option('--sources-file', 46 option_parser.add_option('--sources-list-file',
46 help='File to create with the list of sources.') 47 help='File to create with the list of sources.')
47 48
48 49
49 def _AddInstrumentOptions(option_parser): 50 def _AddInstrumentOptions(option_parser):
50 """Adds options related to instrumentation to |option_parser|.""" 51 """Adds options related to instrumentation to |option_parser|."""
51 _AddCommonOptions(option_parser) 52 _AddCommonOptions(option_parser)
52 option_parser.add_option('--sources', 53 option_parser.add_option('--source-dirs',
53 help='Space separated list of sources.') 54 help='Space separated list of source directories. '
55 'source-files should not be specified if '
56 'source-dirs is specified')
57 option_parser.add_option('--source-files',
58 help='Space separated list of source files. '
59 'source-dirs should not be specified if '
60 'source-files is specified')
54 option_parser.add_option('--src-root', 61 option_parser.add_option('--src-root',
55 help='Root of the src repository.') 62 help='Root of the src repository.')
56 option_parser.add_option('--emma-jar', 63 option_parser.add_option('--emma-jar',
57 help='Path to emma.jar.') 64 help='Path to emma.jar.')
58 option_parser.add_option( 65 option_parser.add_option(
59 '--filter-string', default='', 66 '--filter-string', default='',
60 help=('Filter string consisting of a list of inclusion/exclusion ' 67 help=('Filter string consisting of a list of inclusion/exclusion '
61 'patterns separated with whitespace and/or comma.')) 68 'patterns separated with whitespace and/or comma.'))
62 69
63 70
64 def _RunCopyCommand(_command, options, _, option_parser): 71 def _RunCopyCommand(_command, options, _, option_parser):
65 """Copies the jar from input to output locations. 72 """Copies the jar from input to output locations.
66 73
67 Also removes any old coverage/sources file. 74 Also removes any old coverage/sources file.
68 75
69 Args: 76 Args:
70 command: String indicating the command that was received to trigger 77 command: String indicating the command that was received to trigger
71 this function. 78 this function.
72 options: optparse options dictionary. 79 options: optparse options dictionary.
73 args: List of extra args from optparse. 80 args: List of extra args from optparse.
74 option_parser: optparse.OptionParser object. 81 option_parser: optparse.OptionParser object.
75 82
76 Returns: 83 Returns:
77 An exit code. 84 An exit code.
78 """ 85 """
79 if not (options.input_path and options.output_path and 86 if not (options.input_path and options.output_path and
80 options.coverage_file and options.sources_file): 87 options.coverage_file and options.sources_list_file):
81 option_parser.error('All arguments are required.') 88 option_parser.error('All arguments are required.')
82 89
83 coverage_file = os.path.join(os.path.dirname(options.output_path), 90 if os.path.exists(options.coverage_file):
84 options.coverage_file) 91 os.remove(options.coverage_file)
85 sources_file = os.path.join(os.path.dirname(options.output_path), 92 if os.path.exists(options.sources_list_file):
86 options.sources_file) 93 os.remove(options.sources_list_file)
87 if os.path.exists(coverage_file):
88 os.remove(coverage_file)
89 if os.path.exists(sources_file):
90 os.remove(sources_file)
91 94
92 shutil.copy(options.input_path, options.output_path) 95 shutil.copy(options.input_path, options.output_path)
93 96
94 if options.stamp: 97 if options.stamp:
95 build_utils.Touch(options.stamp) 98 build_utils.Touch(options.stamp)
96 99
100 if options.depfile:
101 build_utils.WriteDepfile(options.depfile,
102 build_utils.GetPythonDependencies())
97 103
98 def _CreateSourcesFile(sources_string, sources_file, src_root): 104
99 """Adds all normalized source directories to |sources_file|. 105 def _GetSourceDirsFromSourceFiles(source_files_string):
106 """Returns list of directories for the files in |source_files_string|.
100 107
101 Args: 108 Args:
102 sources_string: String generated from gyp containing the list of sources. 109 source_files_string: String generated from GN or GYP containing the list
103 sources_file: File into which to write the JSON list of sources. 110 of source files.
111
112 Returns:
113 List of source directories.
114 """
115 source_files = build_utils.ParseGypList(source_files_string)
116 source_dirs = set()
agrieve 2015/11/18 15:30:46 nit: More concise: return list(set(os.path.dirname
pkotwicz 2015/11/18 15:59:28 It might be because I am relatively new to Python,
agrieve 2015/11/18 16:06:18 In general, List comprehensions are preferred when
pkotwicz 2015/11/18 17:03:02 According to the Google style guide, "List compreh
117 for source_file in source_files:
118 source_dirs.add(os.path.dirname(source_file))
119 return list(source_dirs)
120
121
122 def _CreateSourcesListFile(source_dirs, sources_list_file, src_root):
123 """Adds all normalized source directories to |sources_list_file|.
124
125 Args:
126 source_dirs: List of source directories.
127 sources_list_file: File into which to write the JSON list of sources.
104 src_root: Root which sources added to the file should be relative to. 128 src_root: Root which sources added to the file should be relative to.
105 129
106 Returns: 130 Returns:
107 An exit code. 131 An exit code.
108 """ 132 """
109 src_root = os.path.abspath(src_root) 133 src_root = os.path.abspath(src_root)
110 sources = build_utils.ParseGypList(sources_string)
111 relative_sources = [] 134 relative_sources = []
112 for s in sources: 135 for s in source_dirs:
113 abs_source = os.path.abspath(s) 136 abs_source = os.path.abspath(s)
114 if abs_source[:len(src_root)] != src_root: 137 if abs_source[:len(src_root)] != src_root:
115 print ('Error: found source directory not under repository root: %s %s' 138 print ('Error: found source directory not under repository root: %s %s'
116 % (abs_source, src_root)) 139 % (abs_source, src_root))
117 return 1 140 return 1
118 rel_source = os.path.relpath(abs_source, src_root) 141 rel_source = os.path.relpath(abs_source, src_root)
119 142
120 relative_sources.append(rel_source) 143 relative_sources.append(rel_source)
121 144
122 with open(sources_file, 'w') as f: 145 with open(sources_list_file, 'w') as f:
123 json.dump(relative_sources, f) 146 json.dump(relative_sources, f)
124 147
125 148
126 def _RunInstrumentCommand(_command, options, _, option_parser): 149 def _RunInstrumentCommand(_command, options, _, option_parser):
127 """Instruments jar files using EMMA. 150 """Instruments jar files using EMMA.
128 151
129 Args: 152 Args:
130 command: String indicating the command that was received to trigger 153 command: String indicating the command that was received to trigger
131 this function. 154 this function.
132 options: optparse options dictionary. 155 options: optparse options dictionary.
133 args: List of extra args from optparse. 156 args: List of extra args from optparse.
134 option_parser: optparse.OptionParser object. 157 option_parser: optparse.OptionParser object.
135 158
136 Returns: 159 Returns:
137 An exit code. 160 An exit code.
138 """ 161 """
139 if not (options.input_path and options.output_path and 162 if not (options.input_path and options.output_path and
140 options.coverage_file and options.sources_file and options.sources and 163 options.coverage_file and options.sources_list_file and
164 (options.source_files or options.source_dirs) and
141 options.src_root and options.emma_jar): 165 options.src_root and options.emma_jar):
142 option_parser.error('All arguments are required.') 166 option_parser.error('All arguments are required.')
143 167
144 coverage_file = os.path.join(os.path.dirname(options.output_path), 168 if os.path.exists(options.coverage_file):
145 options.coverage_file) 169 os.remove(options.coverage_file)
146 sources_file = os.path.join(os.path.dirname(options.output_path),
147 options.sources_file)
148 if os.path.exists(coverage_file):
149 os.remove(coverage_file)
150 temp_dir = tempfile.mkdtemp() 170 temp_dir = tempfile.mkdtemp()
151 try: 171 try:
152 cmd = ['java', '-cp', options.emma_jar, 172 cmd = ['java', '-cp', options.emma_jar,
153 'emma', 'instr', 173 'emma', 'instr',
154 '-ip', options.input_path, 174 '-ip', options.input_path,
155 '-ix', options.filter_string, 175 '-ix', options.filter_string,
156 '-d', temp_dir, 176 '-d', temp_dir,
157 '-out', coverage_file, 177 '-out', options.coverage_file,
158 '-m', 'fullcopy'] 178 '-m', 'fullcopy']
159 build_utils.CheckOutput(cmd) 179 build_utils.CheckOutput(cmd)
160 180
161 for jar in os.listdir(os.path.join(temp_dir, 'lib')): 181 temp_jar_dir = os.path.join(temp_dir, 'lib')
162 shutil.copy(os.path.join(temp_dir, 'lib', jar), 182 jars = os.listdir(temp_jar_dir)
163 options.output_path) 183 if len(jars) != 1:
184 print('Error: multiple output files in: %s' % (temp_jar_dir))
agrieve 2015/11/18 15:30:46 you should raise an exception rather than explicit
pkotwicz 2015/11/18 15:59:28 This way of handling exceptions is consistent with
185 return 1
186
187 shutil.copy(os.path.join(temp_jar_dir, jars[0]), options.output_path)
164 finally: 188 finally:
165 shutil.rmtree(temp_dir) 189 shutil.rmtree(temp_dir)
166 190
167 _CreateSourcesFile(options.sources, sources_file, options.src_root) 191 source_dirs = []
agrieve 2015/11/18 15:30:46 no need to initialize since it's re-assigned in bo
192 if options.source_dirs:
193 source_dirs = build_utils.ParseGypList(options.source_dirs)
194 else:
195 source_dirs = _GetSourceDirsFromSourceFiles(options.source_files)
196 _CreateSourcesListFile(source_dirs, options.sources_list_file,
197 options.src_root)
agrieve 2015/11/18 15:30:46 nit: indent is off
pkotwicz 2015/11/18 15:59:28 I am confused. There is an '_' before the 'C" in _
168 198
169 if options.stamp: 199 if options.stamp:
170 build_utils.Touch(options.stamp) 200 build_utils.Touch(options.stamp)
171 201
202 if options.depfile:
203 build_utils.WriteDepfile(options.depfile,
204 build_utils.GetPythonDependencies())
205
172 return 0 206 return 0
173 207
174 208
175 CommandFunctionTuple = collections.namedtuple( 209 CommandFunctionTuple = collections.namedtuple(
176 'CommandFunctionTuple', ['add_options_func', 'run_command_func']) 210 'CommandFunctionTuple', ['add_options_func', 'run_command_func'])
177 VALID_COMMANDS = { 211 VALID_COMMANDS = {
178 'copy': CommandFunctionTuple(_AddCommonOptions, 212 'copy': CommandFunctionTuple(_AddCommonOptions,
179 _RunCopyCommand), 213 _RunCopyCommand),
180 'instrument_jar': CommandFunctionTuple(_AddInstrumentOptions, 214 'instrument_jar': CommandFunctionTuple(_AddInstrumentOptions,
181 _RunInstrumentCommand), 215 _RunInstrumentCommand),
182 } 216 }
183 217
184 218
185 def main(): 219 def main():
186 option_parser = command_option_parser.CommandOptionParser( 220 option_parser = command_option_parser.CommandOptionParser(
187 commands_dict=VALID_COMMANDS) 221 commands_dict=VALID_COMMANDS)
188 command_option_parser.ParseAndExecute(option_parser) 222 command_option_parser.ParseAndExecute(option_parser)
189 223
190 224
191 if __name__ == '__main__': 225 if __name__ == '__main__':
192 sys.exit(main()) 226 sys.exit(main())
OLDNEW
« no previous file with comments | « build/android/emma_instr_action.gypi ('k') | build/java.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698