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):