aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/android/aar_resources_extractor.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/android/aar_resources_extractor.py')
-rw-r--r--tools/android/aar_resources_extractor.py46
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():