From 8895f9eceac4ad568bcca724c4dcf8faf5b865f4 Mon Sep 17 00:00:00 2001 From: Wei Li Date: Mon, 10 Oct 2022 17:13:17 -0700 Subject: [PATCH] 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 --- tools/releasetools/common.py | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py index bbdff6e50b..e7fd204aa3 100644 --- a/tools/releasetools/common.py +++ b/tools/releasetools/common.py @@ -2868,30 +2868,32 @@ def ZipWriteStr(zip_file, zinfo_or_arcname, data, perms=None, 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):