blob: 501451658f71ffb68796d3cd52bcc8101e8de9bb [file] [log] [blame]
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001#!/usr/bin/env python
2#
3# Copyright (C) 2019 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may not
6# use this file except in compliance with the License. You may obtain a copy of
7# the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations under
15# the License.
16
17"""
18This script merges two partial target files packages (one of which contains
19system files, and the other contains non-system files) together, producing a
20complete target files package that can be used to generate an OTA package.
21
22Usage: merge_target_files.py [args]
23
24 --system-target-files system-target-files-zip-archive
25 The input target files package containing system bits. This is a zip
26 archive.
27
Daniel Norman2c99c5b2019-03-07 13:01:48 -080028 --system-item-list system-item-list-file
29 The optional path to a newline-separated config file that replaces the
30 contents of default_system_item_list if provided.
31
32 --system-misc-info-keys system-misc-info-keys-file
33 The optional path to a newline-separated config file that replaces the
34 contents of default_system_misc_info_keys if provided.
35
Bill Peckhame9eb5f92019-02-01 15:52:10 -080036 --other-target-files other-target-files-zip-archive
37 The input target files package containing other bits. This is a zip
38 archive.
39
Daniel Norman2c99c5b2019-03-07 13:01:48 -080040 --other-item-list other-item-list-file
41 The optional path to a newline-separated config file that replaces the
42 contents of default_other_item_list if provided.
43
Bill Peckhame9eb5f92019-02-01 15:52:10 -080044 --output-target-files output-target-files-package
45 The output merged target files package. Also a zip archive.
46"""
47
48from __future__ import print_function
49
Bill Peckhame9eb5f92019-02-01 15:52:10 -080050import fnmatch
51import logging
52import os
53import sys
54import zipfile
55
56import common
57import add_img_to_target_files
58
59logger = logging.getLogger(__name__)
60OPTIONS = common.OPTIONS
61OPTIONS.verbose = True
Bill Peckhamf753e152019-02-19 18:02:46 -080062OPTIONS.system_target_files = None
Daniel Norman2c99c5b2019-03-07 13:01:48 -080063OPTIONS.system_item_list = None
64OPTIONS.system_misc_info_keys = None
Bill Peckhamf753e152019-02-19 18:02:46 -080065OPTIONS.other_target_files = None
Daniel Norman2c99c5b2019-03-07 13:01:48 -080066OPTIONS.other_item_list = None
Bill Peckhamf753e152019-02-19 18:02:46 -080067OPTIONS.output_target_files = None
68OPTIONS.keep_tmp = False
Bill Peckhame9eb5f92019-02-01 15:52:10 -080069
Daniel Norman2c99c5b2019-03-07 13:01:48 -080070# default_system_item_list is a list of items to extract from the partial
Bill Peckhame9eb5f92019-02-01 15:52:10 -080071# system target files package as is, meaning these items will land in the
72# output target files package exactly as they appear in the input partial
73# system target files package.
74
Daniel Norman2c99c5b2019-03-07 13:01:48 -080075default_system_item_list = [
Bill Peckhame9eb5f92019-02-01 15:52:10 -080076 'META/apkcerts.txt',
77 'META/filesystem_config.txt',
78 'META/root_filesystem_config.txt',
79 'META/system_manifest.xml',
80 'META/system_matrix.xml',
81 'META/update_engine_config.txt',
82 'PRODUCT/*',
83 'ROOT/*',
84 'SYSTEM/*',
85]
86
87# system_extract_special_item_list is a list of items to extract from the
88# partial system target files package that need some special processing, such
89# as some sort of combination with items from the partial other target files
90# package.
91
92system_extract_special_item_list = [
93 'META/*',
94]
95
Daniel Norman2c99c5b2019-03-07 13:01:48 -080096# default_system_misc_info_keys is a list of keys to obtain from the system instance of
Bill Peckhame9eb5f92019-02-01 15:52:10 -080097# META/misc_info.txt. The remaining keys from the other instance.
98
Daniel Norman2c99c5b2019-03-07 13:01:48 -080099default_system_misc_info_keys = [
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800100 'avb_system_hashtree_enable',
101 'avb_system_add_hashtree_footer_args',
102 'avb_system_key_path',
103 'avb_system_algorithm',
104 'avb_system_rollback_index_location',
105 'avb_product_hashtree_enable',
106 'avb_product_add_hashtree_footer_args',
107 'avb_product_services_hashtree_enable',
108 'avb_product_services_add_hashtree_footer_args',
109 'system_root_image',
110 'root_dir',
111 'ab_update',
112 'default_system_dev_certificate',
113 'system_size',
114]
115
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800116# default_other_item_list is a list of items to extract from the partial
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800117# other target files package as is, meaning these items will land in the output
118# target files package exactly as they appear in the input partial other target
119# files package.
120
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800121default_other_item_list = [
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800122 'META/boot_filesystem_config.txt',
123 'META/otakeys.txt',
124 'META/releasetools.py',
125 'META/vendor_filesystem_config.txt',
126 'META/vendor_manifest.xml',
127 'META/vendor_matrix.xml',
128 'BOOT/*',
129 'DATA/*',
130 'ODM/*',
131 'OTA/android-info.txt',
132 'PREBUILT_IMAGES/*',
133 'RADIO/*',
134 'VENDOR/*',
135]
136
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800137# other_extract_special_item_list is a list of items to extract from the
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800138# partial other target files package that need some special processing, such as
139# some sort of combination with items from the partial system target files
140# package.
141
142other_extract_special_item_list = [
143 'META/*',
144]
145
146
147def extract_items(target_files, target_files_temp_dir, extract_item_list):
148 """Extract items from target files to temporary directory.
149
150 This function extracts from the specified target files zip archive into the
151 specified temporary directory, the items specified in the extract item list.
152
153 Args:
154 target_files: The target files zip archive from which to extract items.
155
156 target_files_temp_dir: The temporary directory where the extracted items
157 will land.
158
159 extract_item_list: A list of items to extract.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800160 """
161
162 logger.info('extracting from %s', target_files)
163
164 # Filter the extract_item_list to remove any items that do not exist in the
165 # zip file. Otherwise, the extraction step will fail.
166
167 with zipfile.ZipFile(
168 target_files,
169 'r',
170 allowZip64=True) as target_files_zipfile:
171 target_files_namelist = target_files_zipfile.namelist()
172
173 filtered_extract_item_list = []
174 for pattern in extract_item_list:
175 matching_namelist = fnmatch.filter(target_files_namelist, pattern)
176 if not matching_namelist:
177 logger.warning('no match for %s', pattern)
178 else:
179 filtered_extract_item_list.append(pattern)
180
Bill Peckham8ff3fbd2019-02-22 10:57:43 -0800181 # Extract from target_files into target_files_temp_dir the
182 # filtered_extract_item_list.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800183
Bill Peckham8ff3fbd2019-02-22 10:57:43 -0800184 common.UnzipToDir(
185 target_files,
186 target_files_temp_dir,
187 filtered_extract_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800188
189
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800190def read_config_list(config_file_path):
191 """Reads a config file into a list of strings.
192
193 Expects the file to be newline-separated.
194
195 Args:
196 config_file_path: The path to the config file to open and read.
197 """
198 with open(config_file_path) as config_file:
199 return config_file.read().splitlines()
200
201
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800202def process_ab_partitions_txt(
203 system_target_files_temp_dir,
204 other_target_files_temp_dir,
205 output_target_files_temp_dir):
206 """Perform special processing for META/ab_partitions.txt
207
208 This function merges the contents of the META/ab_partitions.txt files from
209 the system directory and the other directory, placing the merged result in
210 the output directory. The precondition in that the files are already
211 extracted. The post condition is that the output META/ab_partitions.txt
212 contains the merged content. The format for each ab_partitions.txt a one
213 partition name per line. The output file contains the union of the parition
214 names.
215
216 Args:
217 system_target_files_temp_dir: The name of a directory containing the
218 special items extracted from the system target files package.
219
220 other_target_files_temp_dir: The name of a directory containing the
221 special items extracted from the other target files package.
222
223 output_target_files_temp_dir: The name of a directory that will be used
224 to create the output target files package after all the special cases
225 are processed.
226 """
227
228 system_ab_partitions_txt = os.path.join(
229 system_target_files_temp_dir, 'META', 'ab_partitions.txt')
230
231 other_ab_partitions_txt = os.path.join(
232 other_target_files_temp_dir, 'META', 'ab_partitions.txt')
233
234 with open(system_ab_partitions_txt) as f:
235 system_ab_partitions = f.read().splitlines()
236
237 with open(other_ab_partitions_txt) as f:
238 other_ab_partitions = f.read().splitlines()
239
240 output_ab_partitions = set(system_ab_partitions + other_ab_partitions)
241
242 output_ab_partitions_txt = os.path.join(
243 output_target_files_temp_dir, 'META', 'ab_partitions.txt')
244
245 with open(output_ab_partitions_txt, 'w') as output:
246 for partition in sorted(output_ab_partitions):
247 output.write('%s\n' % partition)
248
249
250def process_misc_info_txt(
251 system_target_files_temp_dir,
252 other_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800253 output_target_files_temp_dir,
254 system_misc_info_keys):
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800255 """Perform special processing for META/misc_info.txt
256
257 This function merges the contents of the META/misc_info.txt files from the
258 system directory and the other directory, placing the merged result in the
259 output directory. The precondition in that the files are already extracted.
260 The post condition is that the output META/misc_info.txt contains the merged
261 content.
262
263 Args:
264 system_target_files_temp_dir: The name of a directory containing the
265 special items extracted from the system target files package.
266
267 other_target_files_temp_dir: The name of a directory containing the
268 special items extracted from the other target files package.
269
270 output_target_files_temp_dir: The name of a directory that will be used
271 to create the output target files package after all the special cases
272 are processed.
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800273
274 system_misc_info_keys: A list of keys to obtain from the system instance
275 of META/misc_info.txt. The remaining keys from the other instance.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800276 """
277
278 def read_helper(d):
279 misc_info_txt = os.path.join(d, 'META', 'misc_info.txt')
280 with open(misc_info_txt) as f:
281 return list(f.read().splitlines())
282
283 system_info_dict = common.LoadDictionaryFromLines(
284 read_helper(system_target_files_temp_dir))
285
286 # We take most of the misc info from the other target files.
287
288 merged_info_dict = common.LoadDictionaryFromLines(
289 read_helper(other_target_files_temp_dir))
290
291 # Replace certain values in merged_info_dict with values from
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800292 # system_info_dict.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800293
294 for key in system_misc_info_keys:
295 merged_info_dict[key] = system_info_dict[key]
296
297 output_misc_info_txt = os.path.join(
298 output_target_files_temp_dir,
299 'META', 'misc_info.txt')
300
301 sorted_keys = sorted(merged_info_dict.keys())
302
303 with open(output_misc_info_txt, 'w') as output:
304 for key in sorted_keys:
305 output.write('{}={}\n'.format(key, merged_info_dict[key]))
306
307
308def process_file_contexts_bin(temp_dir, output_target_files_temp_dir):
309 """Perform special processing for META/file_contexts.bin.
310
311 This function combines plat_file_contexts and vendor_file_contexts, which are
312 expected to already be extracted in temp_dir, to produce a merged
313 file_contexts.bin that will land in temp_dir at META/file_contexts.bin.
314
315 Args:
316 temp_dir: The name of a scratch directory that this function can use for
317 intermediate files generated during processing.
318
319 output_target_files_temp_dir: The name of the working directory that must
320 already contain plat_file_contexts and vendor_file_contexts (in the
321 appropriate sub directories), and to which META/file_contexts.bin will be
322 written.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800323 """
324
325 # To create a merged file_contexts.bin file, we use the system and vendor
326 # file contexts files as input, the m4 tool to combine them, the sorting tool
327 # to sort, and finally the sefcontext_compile tool to generate the final
328 # output. We currently omit a checkfc step since the files had been checked
329 # as part of the build.
330
331 # The m4 step concatenates the two input files contexts files. Since m4
332 # writes to stdout, we receive that into an array of bytes, and then write it
333 # to a file.
334
335 # Collect the file contexts that we're going to combine from SYSTEM, VENDOR,
336 # PRODUCT, and ODM. We require SYSTEM and VENDOR, but others are optional.
337
338 file_contexts_list = []
339
340 for partition in ['SYSTEM', 'VENDOR', 'PRODUCT', 'ODM']:
341 prefix = 'plat' if partition == 'SYSTEM' else partition.lower()
342
343 file_contexts = os.path.join(
344 output_target_files_temp_dir,
345 partition, 'etc', 'selinux', prefix + '_file_contexts')
346
347 mandatory = partition in ['SYSTEM', 'VENDOR']
348
349 if mandatory or os.path.isfile(file_contexts):
350 file_contexts_list.append(file_contexts)
351 else:
352 logger.warning('file not found: %s', file_contexts)
353
354 command = ['m4', '--fatal-warnings', '-s'] + file_contexts_list
355
356 merged_content = common.RunAndCheckOutput(command, verbose=False)
357
358 merged_file_contexts_txt = os.path.join(temp_dir, 'merged_file_contexts.txt')
359
360 with open(merged_file_contexts_txt, 'wb') as f:
361 f.write(merged_content)
362
363 # The sort step sorts the concatenated file.
364
365 sorted_file_contexts_txt = os.path.join(temp_dir, 'sorted_file_contexts.txt')
366 command = ['fc_sort', merged_file_contexts_txt, sorted_file_contexts_txt]
Bill Peckham889b0c62019-02-21 18:53:37 -0800367 common.RunAndWait(command, verbose=True)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800368
369 # Finally, the compile step creates the final META/file_contexts.bin.
370
371 file_contexts_bin = os.path.join(
372 output_target_files_temp_dir,
373 'META', 'file_contexts.bin')
374
375 command = [
376 'sefcontext_compile',
377 '-o', file_contexts_bin,
378 sorted_file_contexts_txt,
379 ]
380
Bill Peckham889b0c62019-02-21 18:53:37 -0800381 common.RunAndWait(command, verbose=True)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800382
383
384def process_special_cases(
385 temp_dir,
386 system_target_files_temp_dir,
387 other_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800388 output_target_files_temp_dir,
389 system_misc_info_keys):
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800390 """Perform special-case processing for certain target files items.
391
392 Certain files in the output target files package require special-case
393 processing. This function performs all that special-case processing.
394
395 Args:
396 temp_dir: The name of a scratch directory that this function can use for
397 intermediate files generated during processing.
398
399 system_target_files_temp_dir: The name of a directory containing the
400 special items extracted from the system target files package.
401
402 other_target_files_temp_dir: The name of a directory containing the
403 special items extracted from the other target files package.
404
405 output_target_files_temp_dir: The name of a directory that will be used
406 to create the output target files package after all the special cases
407 are processed.
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800408
409 system_misc_info_keys: A list of keys to obtain from the system instance
410 of META/misc_info.txt. The remaining keys from the other instance.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800411 """
412
413 process_ab_partitions_txt(
414 system_target_files_temp_dir=system_target_files_temp_dir,
415 other_target_files_temp_dir=other_target_files_temp_dir,
416 output_target_files_temp_dir=output_target_files_temp_dir)
417
418 process_misc_info_txt(
419 system_target_files_temp_dir=system_target_files_temp_dir,
420 other_target_files_temp_dir=other_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800421 output_target_files_temp_dir=output_target_files_temp_dir,
422 system_misc_info_keys=system_misc_info_keys)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800423
Bill Peckham889b0c62019-02-21 18:53:37 -0800424 process_file_contexts_bin(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800425 temp_dir=temp_dir,
426 output_target_files_temp_dir=output_target_files_temp_dir)
427
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800428
429def merge_target_files(
430 temp_dir,
431 system_target_files,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800432 system_item_list,
433 system_misc_info_keys,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800434 other_target_files,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800435 other_item_list,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800436 output_target_files):
437 """Merge two target files packages together.
438
439 This function takes system and other target files packages as input, performs
440 various file extractions, special case processing, and finally creates a
441 merged zip archive as output.
442
443 Args:
444 temp_dir: The name of a directory we use when we extract items from the
445 input target files packages, and also a scratch directory that we use for
446 temporary files.
447
448 system_target_files: The name of the zip archive containing the system
449 partial target files package.
450
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800451 system_item_list: The list of items to extract from the partial system
452 target files package as is, meaning these items will land in the output
453 target files package exactly as they appear in the input partial system
454 target files package.
455
456 system_misc_info_keys: The list of keys to obtain from the system instance
457 of META/misc_info.txt. The remaining keys from the other instance.
458
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800459 other_target_files: The name of the zip archive containing the other
460 partial target files package.
461
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800462 other_item_list: The list of items to extract from the partial other
463 target files package as is, meaning these items will land in the output
464 target files package exactly as they appear in the input partial other
465 target files package.
466
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800467 output_target_files: The name of the output zip archive target files
468 package created by merging system and other.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800469 """
470
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800471 logger.info(
472 'starting: merge system %s and other %s into output %s',
473 system_target_files,
474 other_target_files,
475 output_target_files)
476
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800477 # Create directory names that we'll use when we extract files from system,
478 # and other, and for zipping the final output.
479
480 system_target_files_temp_dir = os.path.join(temp_dir, 'system')
481 other_target_files_temp_dir = os.path.join(temp_dir, 'other')
482 output_target_files_temp_dir = os.path.join(temp_dir, 'output')
483
484 # Extract "as is" items from the input system partial target files package.
485 # We extract them directly into the output temporary directory since the
486 # items do not need special case processing.
487
Bill Peckham889b0c62019-02-21 18:53:37 -0800488 extract_items(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800489 target_files=system_target_files,
490 target_files_temp_dir=output_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800491 extract_item_list=system_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800492
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800493 # Extract "as is" items from the input other partial target files package. We
494 # extract them directly into the output temporary directory since the items
495 # do not need special case processing.
496
Bill Peckham889b0c62019-02-21 18:53:37 -0800497 extract_items(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800498 target_files=other_target_files,
499 target_files_temp_dir=output_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800500 extract_item_list=other_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800501
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800502 # Extract "special" items from the input system partial target files package.
503 # We extract these items to different directory since they require special
504 # processing before they will end up in the output directory.
505
Bill Peckham889b0c62019-02-21 18:53:37 -0800506 extract_items(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800507 target_files=system_target_files,
508 target_files_temp_dir=system_target_files_temp_dir,
509 extract_item_list=system_extract_special_item_list)
510
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800511 # Extract "special" items from the input other partial target files package.
512 # We extract these items to different directory since they require special
513 # processing before they will end up in the output directory.
514
Bill Peckham889b0c62019-02-21 18:53:37 -0800515 extract_items(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800516 target_files=other_target_files,
517 target_files_temp_dir=other_target_files_temp_dir,
518 extract_item_list=other_extract_special_item_list)
519
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800520 # Now that the temporary directories contain all the extracted files, perform
521 # special case processing on any items that need it. After this function
522 # completes successfully, all the files we need to create the output target
523 # files package are in place.
524
Bill Peckham889b0c62019-02-21 18:53:37 -0800525 process_special_cases(
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800526 temp_dir=temp_dir,
527 system_target_files_temp_dir=system_target_files_temp_dir,
528 other_target_files_temp_dir=other_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800529 output_target_files_temp_dir=output_target_files_temp_dir,
530 system_misc_info_keys=system_misc_info_keys)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800531
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800532 # Regenerate IMAGES in the temporary directory.
533
534 add_img_args = [
535 '--verbose',
536 output_target_files_temp_dir,
537 ]
538
539 add_img_to_target_files.main(add_img_args)
540
541 # Finally, create the output target files zip archive.
542
543 output_zip = os.path.abspath(output_target_files)
544 output_target_files_list = os.path.join(temp_dir, 'output.list')
545 output_target_files_meta_dir = os.path.join(
546 output_target_files_temp_dir, 'META')
547
548 command = [
549 'find',
550 output_target_files_meta_dir,
551 ]
552 # TODO(bpeckham): sort this to be more like build.
553 meta_content = common.RunAndCheckOutput(command, verbose=False)
554 command = [
555 'find',
556 output_target_files_temp_dir,
557 '-path',
558 output_target_files_meta_dir,
559 '-prune',
560 '-o',
561 '-print'
562 ]
563 # TODO(bpeckham): sort this to be more like build.
564 other_content = common.RunAndCheckOutput(command, verbose=False)
565
566 with open(output_target_files_list, 'wb') as f:
567 f.write(meta_content)
568 f.write(other_content)
569
570 command = [
Bill Peckhamf753e152019-02-19 18:02:46 -0800571 'soong_zip',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800572 '-d',
573 '-o', output_zip,
574 '-C', output_target_files_temp_dir,
575 '-l', output_target_files_list,
576 ]
577 logger.info('creating %s', output_target_files)
Bill Peckham889b0c62019-02-21 18:53:37 -0800578 common.RunAndWait(command, verbose=True)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800579
580
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800581def call_func_with_temp_dir(func, keep_tmp):
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800582 """Manage the creation and cleanup of the temporary directory.
583
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800584 This function calls the given function after first creating a temporary
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800585 directory. It also cleans up the temporary directory.
586
587 Args:
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800588 func: The function to call. Should accept one parameter, the path to
589 the temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800590
591 keep_tmp: Keep the temporary directory after processing is complete.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800592 """
593
594 # Create a temporary directory. This will serve as the parent of directories
595 # we use when we extract items from the input target files packages, and also
596 # a scratch directory that we use for temporary files.
597
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800598 temp_dir = common.MakeTempDir(prefix='merge_target_files_')
599
600 try:
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800601 func(temp_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800602 except:
603 raise
604 finally:
605 if keep_tmp:
606 logger.info('keeping %s', temp_dir)
607 else:
608 common.Cleanup()
609
610
611def main():
612 """The main function.
613
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800614 Process command line arguments, then call merge_target_files to
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800615 perform the heavy lifting.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800616 """
617
618 common.InitLogging()
619
Bill Peckhamf753e152019-02-19 18:02:46 -0800620 def option_handler(o, a):
621 if o == '--system-target-files':
622 OPTIONS.system_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800623 elif o == '--system-item-list':
624 OPTIONS.system_item_list = a
625 elif o == '--system-misc-info-keys':
626 OPTIONS.system_misc_info_keys = a
Bill Peckhamf753e152019-02-19 18:02:46 -0800627 elif o == '--other-target-files':
628 OPTIONS.other_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800629 elif o == '--other-item-list':
630 OPTIONS.other_item_list = a
Bill Peckhamf753e152019-02-19 18:02:46 -0800631 elif o == '--output-target-files':
632 OPTIONS.output_target_files = a
633 elif o == '--keep_tmp':
634 OPTIONS.keep_tmp = True
635 else:
636 return False
637 return True
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800638
Bill Peckhamf753e152019-02-19 18:02:46 -0800639 args = common.ParseOptions(
640 sys.argv[1:], __doc__,
641 extra_long_opts=[
642 'system-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800643 'system-item-list=',
644 'system-misc-info-keys=',
Bill Peckhamf753e152019-02-19 18:02:46 -0800645 'other-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800646 'other-item-list=',
Bill Peckhamf753e152019-02-19 18:02:46 -0800647 'output-target-files=',
648 "keep_tmp",
649 ],
650 extra_option_handler=option_handler)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800651
Bill Peckham889b0c62019-02-21 18:53:37 -0800652 if (len(args) != 0 or
Bill Peckhamf753e152019-02-19 18:02:46 -0800653 OPTIONS.system_target_files is None or
654 OPTIONS.other_target_files is None or
655 OPTIONS.output_target_files is None):
656 common.Usage(__doc__)
Bill Peckham889b0c62019-02-21 18:53:37 -0800657 sys.exit(1)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800658
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800659 if OPTIONS.system_item_list:
660 system_item_list = read_config_list(OPTIONS.system_item_list)
661 else:
662 system_item_list = default_system_item_list
663
664 if OPTIONS.system_misc_info_keys:
665 system_misc_info_keys = read_config_list(OPTIONS.system_misc_info_keys)
666 else:
667 system_misc_info_keys = default_system_misc_info_keys
668
669 if OPTIONS.other_item_list:
670 other_item_list = read_config_list(OPTIONS.other_item_list)
671 else:
672 other_item_list = default_other_item_list
673
674 call_func_with_temp_dir(
675 lambda temp_dir: merge_target_files(
676 temp_dir=temp_dir,
677 system_target_files=OPTIONS.system_target_files,
678 system_item_list=system_item_list,
679 system_misc_info_keys=system_misc_info_keys,
680 other_target_files=OPTIONS.other_target_files,
681 other_item_list=other_item_list,
682 output_target_files=OPTIONS.output_target_files),
683 OPTIONS.keep_tmp)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800684
685
686if __name__ == '__main__':
Bill Peckham889b0c62019-02-21 18:53:37 -0800687 main()