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

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

Issue 22870021: [Android] Makes GYP changes for EMMA coverage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Reverts accidental change in common.gypi, moves emma_device_jar to gyp Created 7 years, 4 months 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/gyp/dex.py ('k') | build/android/instr_action.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 #
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
5 # found in the LICENSE file.
6
7 """Instruments classes and jar files.
8
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
11 call one of the instrument commands, or the copy command.
12
13 Possible commands are:
14 - instrument_jar: Accepts a jar and instruments it using emma.jar.
15 - instrument_classes: Accepts a directory contains java classes and instruments
16 it using emma.jar.
17 - copy: Triggered instead of an instrumentation command when we don't have EMMA
18 coverage enabled. This allows us to make this a required step without
19 necessarily instrumenting on every build.
20 """
21
22 import collections
23 import json
24 import os
25 import shutil
26 import sys
27 import tempfile
28
29 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir))
30 from pylib.utils import command_option_parser
31
32 from util import build_utils
33
34
35 def _AddCommonOptions(option_parser):
36 """Adds common options to |option_parser|."""
37 option_parser.add_option('--input-path',
38 help=('Path to input file(s). Either the classes '
39 'directory, or the path to a jar.'))
40 option_parser.add_option('--output-path',
41 help=('Path to output final file(s) to. Either the '
42 'final classes directory, or the directory in '
43 'which to place the instrumented/copied jar.'))
44 option_parser.add_option('--stamp', help='Path to touch when done.')
45
46
47 def _AddInstrumentOptions(option_parser):
48 """Adds options related to instrumentation to |option_parser|."""
49 _AddCommonOptions(option_parser)
50 option_parser.add_option('--coverage-file',
51 help='File to create with coverage metadata')
52 option_parser.add_option('--sources-file',
53 help='File to create with the list of sources.')
54 option_parser.add_option('--sources',
55 help='Space separated list of sources.')
56 option_parser.add_option('--src-root',
57 help='Root of the src repository.')
58 option_parser.add_option('--emma-jar',
59 help='Path to emma.jar.')
60
61
62 def _RunCopyCommand(command, options, args, option_parser):
63 """Just copies the jar from input to output locations.
64
65 Args:
66 command: String indicating the command that was received to trigger
67 this function.
68 options: optparse options dictionary.
69 args: List of extra args from optparse.
70 option_parser: optparse.OptionParser object.
71
72 Returns:
73 An exit code.
74 """
75 if not (options.input_path and options.output_path):
76 option_parser.error('All arguments are required.')
77
78 if os.path.isdir(options.input_path):
79 shutil.rmtree(options.output_path, ignore_errors=True)
80 shutil.copytree(options.input_path, options.output_path)
81 else:
82 shutil.copy(options.input_path, options.output_path)
83
84 if options.stamp:
85 build_utils.Touch(options.stamp)
86
87
88 def _CreateSourcesFile(sources_string, sources_file, src_root):
89 """Adds all normalized source directories to |sources_file|.
90
91 Args:
92 sources_string: String generated from gyp containing the list of sources.
93 sources_file: File into which to write the JSON list of sources.
94 src_root: Root which sources added to the file should be relative to.
95
96 Returns:
97 An exit code.
98 """
99 src_root = os.path.abspath(src_root)
100 sources = build_utils.ParseGypList(sources_string)
101 relative_sources = []
102 for s in sources:
103 abs_source = os.path.abspath(s)
104 if abs_source[:len(src_root)] != src_root:
105 print ('Error: found source directory not under repository root: %s %s'
106 % (abs_source, src_root))
107 return 1
108 rel_source = os.path.relpath(abs_source, src_root)
109
110 relative_sources.append(rel_source)
111
112 with open(sources_file, 'w') as f:
113 json.dump(relative_sources, f)
114
115
116 def _RunInstrumentCommand(command, options, args, option_parser):
117 """Instruments the classes/jar files using EMMA.
118
119 Args:
120 command: 'instrument_jar' or 'instrument_classes'. This distinguishes
121 whether we copy the output from the created lib/ directory, or classes/
122 directory.
123 options: optparse options dictionary.
124 args: List of extra args from optparse.
125 option_parser: optparse.OptionParser object.
126
127 Returns:
128 An exit code.
129 """
130 if not (options.input_path and options.output_path and
131 options.coverage_file and options.sources_file and options.sources and
132 options.src_root and options.emma_jar):
133 option_parser.error('All arguments are required.')
134
135 temp_dir = tempfile.mkdtemp()
136 try:
137 # TODO(gkanwar): Add '-ix' option to filter out useless classes.
138 build_utils.CheckCallDie(['java', '-cp', options.emma_jar,
139 'emma', 'instr',
140 '-ip', options.input_path,
141 '-d', temp_dir,
142 '-out', options.coverage_file,
143 '-m', 'fullcopy'], suppress_output=True)
144
145 if command == 'instrument_jar':
146 for jar in os.listdir(os.path.join(temp_dir, 'lib')):
147 shutil.copy(os.path.join(temp_dir, 'lib', jar),
148 options.output_path)
149 else: # 'instrument_classes'
150 if os.path.isdir(options.output_path):
151 shutil.rmtree(options.output_path, ignore_errors=True)
152 shutil.copytree(os.path.join(temp_dir, 'classes'),
153 options.output_path)
154 finally:
155 shutil.rmtree(temp_dir)
156
157 _CreateSourcesFile(options.sources, options.sources_file, options.src_root)
158
159 if options.stamp:
160 build_utils.Touch(options.stamp)
161
162 return 0
163
164
165 CommandFunctionTuple = collections.namedtuple(
166 'CommandFunctionTuple', ['add_options_func', 'run_command_func'])
167 VALID_COMMANDS = {
168 'copy': CommandFunctionTuple(_AddCommonOptions,
169 _RunCopyCommand),
170 'instrument_jar': CommandFunctionTuple(_AddInstrumentOptions,
171 _RunInstrumentCommand),
172 'instrument_classes': CommandFunctionTuple(_AddInstrumentOptions,
173 _RunInstrumentCommand),
174 }
175
176
177 def main(argv):
178 option_parser = command_option_parser.CommandOptionParser(
179 commands_dict=VALID_COMMANDS)
180 command_option_parser.ParseAndExecute(option_parser)
181
182
183 if __name__ == '__main__':
184 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « build/android/gyp/dex.py ('k') | build/android/instr_action.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698