Windows,Android: support long paths in tool //tools/android/aar_embedded_jars_extractor.py now supports long paths using the same junction-creating trick as aar_resources_extractor does. Fixes https://github.com/bazelbuild/bazel/issues/3808 Change-Id: I2db25b0536ac3a97f4a04191bc398eb236923a7c PiperOrigin-RevId: 170193093
diff --git a/tools/android/BUILD b/tools/android/BUILD index 340847e..302fa60 100644 --- a/tools/android/BUILD +++ b/tools/android/BUILD
@@ -123,7 +123,10 @@ py_binary( name = "aar_embedded_jars_extractor", srcs = ["aar_embedded_jars_extractor.py"], - deps = ["//third_party/py/gflags"], + deps = [ + ":junction_lib", + "//third_party/py/gflags", + ], ) py_test(
diff --git a/tools/android/BUILD.tools b/tools/android/BUILD.tools index 7110448..1a6a6d5 100644 --- a/tools/android/BUILD.tools +++ b/tools/android/BUILD.tools
@@ -183,7 +183,10 @@ py_binary( name = "aar_embedded_jars_extractor", srcs = ["aar_embedded_jars_extractor.py"], - deps = ["//third_party/py/gflags"], + deps = [ + ":junction_lib", + "//third_party/py/gflags", + ], ) py_binary(
diff --git a/tools/android/aar_embedded_jars_extractor.py b/tools/android/aar_embedded_jars_extractor.py index fcdc301..a46dd43b 100644 --- a/tools/android/aar_embedded_jars_extractor.py +++ b/tools/android/aar_embedded_jars_extractor.py
@@ -19,10 +19,12 @@ of the jars and creates a param file for singlejar to merge them into one jar. """ +import os import re import sys import zipfile +from tools.android import junction from third_party.py import gflags FLAGS = gflags.FLAGS @@ -36,20 +38,54 @@ gflags.MarkFlagAsRequired("output_dir") -def ExtractEmbeddedJars(aar, singlejar_param_file, 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("--exclude_build_data\n") for name in aar.namelist(): if jar_pattern.match(name): singlejar_param_file.write("--sources\n") - singlejar_param_file.write(output_dir + "/" + name + "\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") 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(): - with zipfile.ZipFile(FLAGS.input_aar, "r") as aar: - with open(FLAGS.output_singlejar_param_file, "wb") as singlejar_param_file: - ExtractEmbeddedJars(aar, singlejar_param_file, FLAGS.output_dir) + 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)