Only check root files for conflicts

This commit is contained in:
Ellwood Zwovic
2017-07-12 15:03:12 -07:00
parent 7d7be711d3
commit 4df177e397

View File

@@ -137,6 +137,9 @@ def _install(pipe_to_blender, pkgpath: pathlib.Path, dest: pathlib.Path):
"""Extracts/moves package at `pkgpath` to `dest`""" """Extracts/moves package at `pkgpath` to `dest`"""
import zipfile import zipfile
log = logging.getLogger('%s.install' % __name__)
log.debug("Starting installation")
pipe_to_blender.send(Progress(0.0)) pipe_to_blender.send(Progress(0.0))
if not pkgpath.is_file(): if not pkgpath.is_file():
@@ -155,13 +158,27 @@ def _install(pipe_to_blender, pkgpath: pathlib.Path, dest: pathlib.Path):
# check to see if the file is in compressed format (.zip) # check to see if the file is in compressed format (.zip)
if zipfile.is_zipfile(pkgpath): if zipfile.is_zipfile(pkgpath):
log.debug("Package is zipfile")
try: try:
file_to_extract = zipfile.ZipFile(str(pkgpath), 'r') file_to_extract = zipfile.ZipFile(str(pkgpath), 'r')
except Exception as err: except Exception as err:
# TODO HACK: see if it makes sense to make a single InstallError class which inherits from both Exception and SubprocError
# It sounds weird, but it could avoid the need for duplication here; create a new InstallError with the right message,
# then send it to blender and also raise it.
pipe_to_blender.send(InstallError("Failed to read zip file: %s" % err)) pipe_to_blender.send(InstallError("Failed to read zip file: %s" % err))
raise InstallException from err raise InstallException from err
conflicts = [f for f in file_to_extract.namelist() if (dest / f).exists()] def root_files(filelist: list) -> list:
"""Some string parsing to get a list of the root contents of a zip from its namelist"""
rootlist = []
for f in filelist:
# Get all names which have no path separators (root level files)
# or have a single path separator at the end (root level directories).
if len(f.rstrip('/').split('/')) == 1:
rootlist.append(f)
return rootlist
conflicts = [f for f in root_files(file_to_extract.namelist()) if (dest / f).exists()]
if len(conflicts) > 0: if len(conflicts) > 0:
# TODO: handle this better than just dumping a list of all files # TODO: handle this better than just dumping a list of all files
pipe_to_blender.send(FileConflictError("Installation would overwrite: %s" % conflicts, conflicts)) pipe_to_blender.send(FileConflictError("Installation would overwrite: %s" % conflicts, conflicts))
@@ -174,6 +191,7 @@ def _install(pipe_to_blender, pkgpath: pathlib.Path, dest: pathlib.Path):
raise InstallException from err raise InstallException from err
else: else:
log.debug("Package is pyfile")
dest_file = (dest / pkgpath.name) dest_file = (dest / pkgpath.name)
if dest_file.exists(): if dest_file.exists():
@@ -190,6 +208,7 @@ def _install(pipe_to_blender, pkgpath: pathlib.Path, dest: pathlib.Path):
try: try:
pkgpath.unlink() pkgpath.unlink()
log.debug("Removed cached package: %s", pkgpath)
except Exception as err: except Exception as err:
pipe_to_blender.send(SubprocWarning("Failed to remove package from cache: %s" % err)) pipe_to_blender.send(SubprocWarning("Failed to remove package from cache: %s" % err))
raise InstallException from err raise InstallException from err