blob: cb27a3040ea395f69407979b9c1ad707cab6e56d [file] [log] [blame]
Tamas Kenez19a3b8a2017-05-29 23:08:48 +02001#!/usr/bin/env python
2# Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
3# for details. All rights reserved. Use of this source code is governed by a
4# BSD-style license that can be found in the LICENSE file.
5
6# Take a file where each line is a tab-separated list of arguments for DX (or
Søren Gjessea99636c2019-11-28 14:00:26 +01007# D8) and create a self-contained directory with all the input files
Tamas Kenez19a3b8a2017-05-29 23:08:48 +02008# and a script which replays the same DX invocations as the original list.
9#
10# Usage:
11#
12# create_dx_replay.py <dx-args-script> <output-dir>
13#
14# The <dx-args-script> is a text file where each line contains tab-separated
Søren Gjessea99636c2019-11-28 14:00:26 +010015# arguments for a DX (D8) call.
Tamas Kenez19a3b8a2017-05-29 23:08:48 +020016# The script 'tools/test_android_cts.py' can log DX invocations during an AOSP
17# build to such a file. Use 'test_android_cts.py --tool=d8 --d8log=<file> ...'.
18
19from __future__ import print_function
20from os.path import join, isdir, exists, basename
21from os import rmdir
22from shutil import copy2
23import argparse
24import os
25import stat
26import sys
27
28import utils
29
30IN_SUBDIR = 'in' # subdirectory for the local copy of the input files
Søren Gjessea99636c2019-11-28 14:00:26 +010031OUT_SUBDIR = 'out' # subdirectory prefix for the output of DX
Tamas Kenez19a3b8a2017-05-29 23:08:48 +020032REPLAY_SCRIPT_NAME = 'replay_script.py'
33
34# This function will be called with arguments of the original DX invocation. It
35# copies the original input files into the local input directory and replaces
36# the references in orig_args to the local input files.
37# Returns the new line to be appended to the replay script.
38def process_line(out_dir, input_counter, orig_args):
39 args = []
40 inputs = []
41 for arg in orig_args:
42 if arg.startswith('--output='):
43 continue # nothing to do, just skip this arg
44 if arg.startswith('--'):
45 args.append(arg)
46 else:
47 # 'arg' is the path of an input file: copy arg to local dir with
48 # a new, unique name
49 if isdir(arg):
50 raise IOError("Adding directories ('{}') to the replay script is not"
51 " implemented.".format(arg))
52 elif not exists(arg):
Søren Gjessea99636c2019-11-28 14:00:26 +010053 print("The input file to DX does not exist: '{}'.".format(arg))
Tamas Kenez19a3b8a2017-05-29 23:08:48 +020054
55 input_file = '{}_{}'.format(input_counter, basename(arg))
56
57 copy2(arg, join(out_dir, join(IN_SUBDIR, input_file)))
58 inputs.append(input_file)
59
60 return 'call_dx({}, {}, {})\n'.format(input_counter, args, inputs)
61
62
63def parse_arguments():
64 parser = argparse.ArgumentParser(
65 description = 'Creates a self-contained directory for playing back a '
Søren Gjessea99636c2019-11-28 14:00:26 +010066 ' sequence of DX calls.')
Tamas Kenez19a3b8a2017-05-29 23:08:48 +020067 parser.add_argument('dx_call_log',
68 help = 'File containing tab-separated arguments for a DX call on each'
69 ' line.')
70 parser.add_argument('output_dir',
71 help = 'Target path the create the self-contained directory at.')
72 return parser.parse_args()
73
74def Main():
75 args = parse_arguments()
76
77 if isdir(args.output_dir):
78 rmdir(args.output_dir) # make sure to write only to empty out dir
79
80 utils.makedirs_if_needed(join(args.output_dir, IN_SUBDIR))
81
82 # create the first lines of the replay script
83 replay_script = \
84"""#!/usr/bin/env python
85import os
86import shutil
87import subprocess
88import sys
89
90SCRIPT_DIR = os.path.abspath(os.path.normpath(os.path.join(__file__, '..')))
91IN_SUBDIR = '{}'
92OUT_SUBDIR = '{}'
93
94def call_dx(input_counter, args, inputs):
95 out_dir = os.path.join(SCRIPT_DIR, OUT_SUBDIR, str(input_counter))
96 if not os.path.isdir(out_dir):
97 os.makedirs(out_dir)
98 full_inputs = [os.path.join(SCRIPT_DIR, IN_SUBDIR, i) for i in inputs]
99 subprocess.check_call(sys.argv[1:] + args + ['--output=' + out_dir]
100 + full_inputs)
101
102if len(sys.argv) < 2:
103 raise IOError('Usage: create_dx_replay.py <dx-command>'
104 ' # can be multiple args')
105abs_out_dir = os.path.join(SCRIPT_DIR, OUT_SUBDIR)
106if os.path.isdir(abs_out_dir):
107 shutil.rmtree(abs_out_dir)
108
109""".format(IN_SUBDIR, OUT_SUBDIR)
110
111 with open(args.dx_call_log) as f:
112 lines = f.read().splitlines()
113
114 input_counter = 1
115 for line in lines:
116 replay_script += \
117 process_line(args.output_dir, input_counter, line.split('\t'))
118 input_counter += 1
119
120 script_file = join(args.output_dir, REPLAY_SCRIPT_NAME)
121 with open(script_file, 'w') as f:
122 f.write(replay_script)
123
124 # chmod +x for script_file
125 st = os.stat(script_file)
126 os.chmod(script_file, st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
127
128if __name__ == '__main__':
129 sys.exit(Main())