diff options
Diffstat (limited to 'tools/android/aar_resources_extractor.py')
-rw-r--r-- | tools/android/aar_resources_extractor.py | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/tools/android/aar_resources_extractor.py b/tools/android/aar_resources_extractor.py index eb0d432027..61f9f4d397 100644 --- a/tools/android/aar_resources_extractor.py +++ b/tools/android/aar_resources_extractor.py @@ -40,23 +40,49 @@ gflags.MarkFlagAsRequired("output_res_dir") def ExtractResources(aar, output_res_dir): """Extract resource from an `aar` file to the `output_res_dir` directory.""" aar_contains_no_resources = True - output_res_dir_abs = os.path.normpath( - os.path.join(os.getcwd(), output_res_dir)) + output_res_dir_abs = os.path.abspath(output_res_dir) for name in aar.namelist(): if name.startswith("res/"): - fullpath = os.path.normpath(os.path.join(output_res_dir_abs, name)) - if os.name == "nt" and len(fullpath) >= 260: # MAX_PATH in <windows.h> - with junction.TempJunction(os.path.dirname(fullpath)) as juncpath: - shortpath = os.path.join(juncpath, os.path.basename(fullpath)) - aar.extract(name, shortpath) + if os.name == "nt": + fullpath = os.path.normpath(os.path.join(output_res_dir_abs, name)) + if name[-1] == "/": + # The zip entry is a directory. Create a junction to it, which also + # takes care of creating the directory and all of its parents in a + # longpath-safe manner. + # We must pretend to have extracted this directory, even if it's + # empty, therefore we mustn't rely on creating it as a parent + # directory of a subsequently extracted zip entry (because there may + # be no such subsequent entry). + with junction.TempJunction(fullpath.rstrip("/")) as juncpath: + pass + else: + # The zip entry is a file. Create a junction to its parent directory, + # then open the compressed entry as a file object, so we can extract + # the data even if the extracted file's path would be too long. + # The tradeoff is that we lose the permission bits of the compressed + # file, but Unix permissions don't mean much on Windows anyway. + with junction.TempJunction(os.path.dirname(fullpath)) as juncpath: + extracted_path = os.path.join(juncpath, os.path.basename(fullpath)) + with aar.open(name) as src_fd: + with open(extracted_path, "wb") as dest_fd: + dest_fd.write(src_fd.read()) else: aar.extract(name, output_res_dir) aar_contains_no_resources = False + if aar_contains_no_resources: empty_xml_filename = output_res_dir + "/res/values/empty.xml" - os.makedirs(os.path.dirname(empty_xml_filename)) - with open(empty_xml_filename, "wb") as empty_xml: - empty_xml.write("<resources/>") + if os.name == "nt": + # Create a junction to the parent directory, because its path might be too + # long. Creating the junction also creates all parent directories. + with junction.TempJunction(os.path.dirname(empty_xml_filename)) as junc: + xmlpath = os.path.join(junc, os.path.basename(empty_xml_filename)) + with open(xmlpath, "wb") as empty_xml: + empty_xml.write("<resources/>") + else: + os.makedirs(os.path.dirname(empty_xml_filename)) + with open(empty_xml_filename, "wb") as empty_xml: + empty_xml.write("<resources/>") def main(): |