| # pylint: disable=g-direct-third-party-import |
| # Copyright 2016 The Bazel Authors. All rights reserved. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| """A tool for extracting all jar files from an AAR. |
| |
| An AAR may contain JARs at /classes.jar and /libs/*.jar. This tool extracts all |
| of the jars and creates a param file for singlejar to merge them into one jar. |
| """ |
| |
| import os |
| import re |
| import sys |
| import zipfile |
| |
| # Do not edit this line. Copybara replaces it with PY2 migration helper. |
| from absl import app |
| from absl import flags |
| |
| from tools.android import junction |
| |
| FLAGS = flags.FLAGS |
| |
| flags.DEFINE_string("input_aar", None, "Input AAR") |
| flags.mark_flag_as_required("input_aar") |
| flags.DEFINE_string("output_singlejar_param_file", None, |
| "Output parameter file for singlejar") |
| flags.mark_flag_as_required("output_singlejar_param_file") |
| flags.DEFINE_string("output_dir", None, "Output directory to extract jars in") |
| flags.mark_flag_as_required("output_dir") |
| |
| |
| def ExtractEmbeddedJars(aar, |
| singlejar_param_file, |
| output_dir, |
| output_dir_orig=None): |
| if not output_dir_orig: |
| output_dir_orig = output_dir |
| jar_pattern = re.compile("^(classes|libs/.+)\\.jar$") |
| singlejar_param_file.write(b"--exclude_build_data\n") |
| for name in aar.namelist(): |
| if jar_pattern.match(name): |
| singlejar_param_file.write(b"--sources\n") |
| # output_dir may be a temporary junction, so write the original |
| # (unshortened) path to the params file |
| singlejar_param_file.write( |
| (output_dir_orig + "/" + name + "\n").encode("utf-8")) |
| aar.extract(name, output_dir) |
| |
| |
| def _Main(input_aar, |
| output_singlejar_param_file, |
| output_dir, |
| output_dir_orig=None): |
| if not output_dir_orig: |
| output_dir_orig = output_dir |
| with zipfile.ZipFile(input_aar, "r") as aar: |
| with open(output_singlejar_param_file, "wb") as singlejar_param_file: |
| ExtractEmbeddedJars(aar, singlejar_param_file, output_dir, |
| output_dir_orig) |
| |
| |
| def main(unused_argv): |
| if os.name == "nt": |
| # Shorten paths unconditionally, because the extracted paths in |
| # ExtractEmbeddedJars (which we cannot yet predict, because they depend on |
| # the names of the Zip entries) may be longer than MAX_PATH. |
| aar_long = os.path.abspath(FLAGS.input_aar) |
| params_long = os.path.abspath(FLAGS.output_singlejar_param_file) |
| out_long = os.path.abspath(FLAGS.output_dir) |
| with junction.TempJunction(os.path.dirname(aar_long)) as aar_junc: |
| with junction.TempJunction(os.path.dirname(params_long)) as params_junc: |
| with junction.TempJunction(os.path.dirname(out_long)) as out_junc: |
| _Main( |
| os.path.join(aar_junc, os.path.basename(aar_long)), |
| os.path.join(params_junc, os.path.basename(params_long)), |
| os.path.join(out_junc, os.path.basename(out_long)), |
| FLAGS.output_dir) |
| else: |
| _Main(FLAGS.input_aar, FLAGS.output_singlejar_param_file, FLAGS.output_dir) |
| |
| |
| if __name__ == "__main__": |
| FLAGS(sys.argv) |
| app.run(main) |