Change function ZipDelete to use Python module zipinfo instead of command 'zip'.
'zip' is a host command, and it can not be provided as a dependency when some release tools are used in Bazel rules.
Test: atest --host releasetools_test
Bug: 243748589
Change-Id: Ie5f42eadbd316ccd018b19194c466a908971af82
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index bbdff6e..e7fd204 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -2868,30 +2868,32 @@
def ZipDelete(zip_filename, entries, force=False):
"""Deletes entries from a ZIP file.
- Since deleting entries from a ZIP file is not supported, it shells out to
- 'zip -d'.
-
Args:
zip_filename: The name of the ZIP file.
entries: The name of the entry, or the list of names to be deleted.
-
- Raises:
- AssertionError: In case of non-zero return from 'zip'.
"""
if isinstance(entries, str):
entries = [entries]
# If list is empty, nothing to do
if not entries:
return
- if force:
- cmd = ["zip", "-q", "-d", zip_filename] + entries
- else:
- cmd = ["zip", "-d", zip_filename] + entries
- if force:
- p = Run(cmd)
- p.wait()
- else:
- RunAndCheckOutput(cmd)
+
+ with zipfile.ZipFile(zip_filename, 'r') as zin:
+ if not force and len(set(zin.namelist()).intersection(entries)) == 0:
+ raise ExternalError(
+ "Failed to delete zip entries, name not matched: %s" % entries)
+
+ fd, new_zipfile = tempfile.mkstemp(dir=os.path.dirname(zip_filename))
+ os.close(fd)
+
+ with zipfile.ZipFile(new_zipfile, 'w') as zout:
+ for item in zin.infolist():
+ if item.filename in entries:
+ continue
+ buffer = zin.read(item.filename)
+ zout.writestr(item, buffer)
+
+ os.replace(new_zipfile, zip_filename)
def ZipClose(zip_file):