blob: 2fa85b63a82d4ae720d35354e76eb4600a901590 [file] [log] [blame]
Laszlo Csomord456fca2017-08-10 10:21:53 +02001# pylint: disable=g-direct-third-party-import
Adam Michael67d736b2016-10-06 21:31:57 +00002# Copyright 2016 The Bazel Authors. All rights reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
Adam Michael97cc5be2016-10-25 21:25:20 +000016"""A tool for extracting all jar files from an AAR.
Adam Michael67d736b2016-10-06 21:31:57 +000017
Adam Michael97cc5be2016-10-25 21:25:20 +000018An AAR may contain JARs at /classes.jar and /libs/*.jar. This tool extracts all
19of the jars and creates a param file for singlejar to merge them into one jar.
Adam Michael67d736b2016-10-06 21:31:57 +000020"""
21
Laszlo Csomor567e9ab2017-09-27 10:13:43 -040022import os
Adam Michael97cc5be2016-10-25 21:25:20 +000023import re
Adam Michael67d736b2016-10-06 21:31:57 +000024import sys
25import zipfile
26
Laszlo Csomor567e9ab2017-09-27 10:13:43 -040027from tools.android import junction
Adam Michael67d736b2016-10-06 21:31:57 +000028from third_party.py import gflags
29
30FLAGS = gflags.FLAGS
31
Adam Michael97cc5be2016-10-25 21:25:20 +000032gflags.DEFINE_string("input_aar", None, "Input AAR")
33gflags.MarkFlagAsRequired("input_aar")
34gflags.DEFINE_string(
35 "output_singlejar_param_file", None, "Output parameter file for singlejar")
36gflags.MarkFlagAsRequired("output_singlejar_param_file")
37gflags.DEFINE_string("output_dir", None, "Output directory to extract jars in")
Adam Michael67d736b2016-10-06 21:31:57 +000038gflags.MarkFlagAsRequired("output_dir")
39
40
Laszlo Csomor567e9ab2017-09-27 10:13:43 -040041def ExtractEmbeddedJars(aar,
42 singlejar_param_file,
43 output_dir,
44 output_dir_orig=None):
45 if not output_dir_orig:
46 output_dir_orig = output_dir
Adam Michael97cc5be2016-10-25 21:25:20 +000047 jar_pattern = re.compile("^(classes|libs/.+)\\.jar$")
Googler246ee562017-12-19 11:04:21 -080048 singlejar_param_file.write(b"--exclude_build_data\n")
Adam Michael97cc5be2016-10-25 21:25:20 +000049 for name in aar.namelist():
50 if jar_pattern.match(name):
Googler246ee562017-12-19 11:04:21 -080051 singlejar_param_file.write(b"--sources\n")
Laszlo Csomor567e9ab2017-09-27 10:13:43 -040052 # output_dir may be a temporary junction, so write the original
53 # (unshortened) path to the params file
Googler246ee562017-12-19 11:04:21 -080054 singlejar_param_file.write(
55 (output_dir_orig + "/" + name + "\n").encode("utf-8"))
Adam Michael97cc5be2016-10-25 21:25:20 +000056 aar.extract(name, output_dir)
Adam Michael67d736b2016-10-06 21:31:57 +000057
58
Laszlo Csomor567e9ab2017-09-27 10:13:43 -040059def _Main(input_aar,
60 output_singlejar_param_file,
61 output_dir,
62 output_dir_orig=None):
63 if not output_dir_orig:
64 output_dir_orig = output_dir
65 with zipfile.ZipFile(input_aar, "r") as aar:
Googler246ee562017-12-19 11:04:21 -080066 with open(output_singlejar_param_file, "wb") as singlejar_param_file:
Laszlo Csomor567e9ab2017-09-27 10:13:43 -040067 ExtractEmbeddedJars(aar, singlejar_param_file, output_dir,
68 output_dir_orig)
69
70
Adam Michael67d736b2016-10-06 21:31:57 +000071def main():
Laszlo Csomor567e9ab2017-09-27 10:13:43 -040072 if os.name == "nt":
73 # Shorten paths unconditionally, because the extracted paths in
74 # ExtractEmbeddedJars (which we cannot yet predict, because they depend on
75 # the names of the Zip entries) may be longer than MAX_PATH.
76 aar_long = os.path.abspath(FLAGS.input_aar)
77 params_long = os.path.abspath(FLAGS.output_singlejar_param_file)
78 out_long = os.path.abspath(FLAGS.output_dir)
79 with junction.TempJunction(os.path.dirname(aar_long)) as aar_junc:
80 with junction.TempJunction(os.path.dirname(params_long)) as params_junc:
81 with junction.TempJunction(os.path.dirname(out_long)) as out_junc:
82 _Main(
83 os.path.join(aar_junc, os.path.basename(aar_long)),
84 os.path.join(params_junc, os.path.basename(params_long)),
85 os.path.join(out_junc, os.path.basename(out_long)),
86 FLAGS.output_dir)
87 else:
88 _Main(FLAGS.input_aar, FLAGS.output_singlejar_param_file, FLAGS.output_dir)
89
Adam Michael67d736b2016-10-06 21:31:57 +000090
91if __name__ == "__main__":
92 FLAGS(sys.argv)
93 main()