diff --git a/dotdrop/dotdrop.py b/dotdrop/dotdrop.py index b09a50a..9f60592 100644 --- a/dotdrop/dotdrop.py +++ b/dotdrop/dotdrop.py @@ -169,11 +169,13 @@ def _dotfile_compare(opts, dotfile, tmp): if tmpsrc: tmpsrc = os.path.join(opts.dotpath, tmpsrc) if os.path.exists(tmpsrc): - removepath(tmpsrc, LOG) + # ignore error + removepath(tmpsrc, logger=LOG) # clean tmp template dotfile if any if insttmp and os.path.exists(insttmp): - removepath(insttmp, LOG) + # ignore error + removepath(insttmp, logger=LOG) if diff != '': # print diff results @@ -258,7 +260,8 @@ def _dotfile_install(opts, dotfile, tmpdir=None): if tmp: tmp = os.path.join(opts.dotpath, tmp) if os.path.exists(tmp): - removepath(tmp, LOG) + # ignore error + removepath(tmp, logger=LOG) # check result of installation if ret: @@ -322,6 +325,7 @@ def cmd_install(opts): for root, _, files in os.walk(opts.workdir): for file in files: fpath = os.path.join(root, file) + # ignore error removepath(fpath, logger=LOG) # execute profile pre-action @@ -721,7 +725,7 @@ def cmd_remove(opts): # remove dotfile from dotpath dtpath = os.path.join(opts.dotpath, dotfile.src) - removepath(dtpath, LOG) + removepath(dtpath, logger=LOG) # remove empty directory parent = os.path.dirname(dtpath) # remove any empty parent up to dotpath @@ -730,7 +734,8 @@ def cmd_remove(opts): msg = f'Remove empty dir \"{parent}\"' if opts.safe and not LOG.ask(msg): break - removepath(parent, LOG) + if not removepath(parent, logger=LOG): + LOG.warn(f'unable to remove {parent}') parent = os.path.dirname(parent) removed.append(dotfile) @@ -833,7 +838,8 @@ def apply_install_trans(dotpath, dotfile, templater, debug=False): msg += f'failed for {dotfile.key}' LOG.err(msg) if new_src and os.path.exists(new_src): - removepath(new_src, LOG) + # ignore error + removepath(new_src, logger=LOG) return None return new_src @@ -873,7 +879,8 @@ def _exec_command(opts): tmp = get_tmpdir() ret = cmd_compare(opts, tmp) # clean tmp directory - removepath(tmp, LOG) + # ignore any error + removepath(tmp, logger=LOG) elif opts.cmd_import: # import dotfile(s) diff --git a/dotdrop/importer.py b/dotdrop/importer.py index 602598f..5d91484 100644 --- a/dotdrop/importer.py +++ b/dotdrop/importer.py @@ -328,6 +328,7 @@ class Importer: msg = f'transformation \"{trans.key}\" failed for {path}' self.log.err(msg) if os.path.exists(tmp): + # ignore error removepath(tmp, logger=self.log) return None return tmp diff --git a/dotdrop/installer.py b/dotdrop/installer.py index 0e96c41..be3c238 100644 --- a/dotdrop/installer.py +++ b/dotdrop/installer.py @@ -700,8 +700,9 @@ class Installer: if self.safe: if not self.log.ask(f'remove unmanaged \"{path}\"'): return - self.log.dbg(f'removing not managed: {path}') - removepath(path, logger=self.log) + self.log.dbg(f'removing unmanaged file \"{path}\"') + if not removepath(path, logger=self.log): + self.log.warn('unable to remove {path}') @classmethod def _write_content_to_file(cls, content, src, dst): @@ -825,6 +826,7 @@ class Installer: if ret: self.log.dbg('content differ') if content: + # ignore error removepath(tmp) return ret @@ -841,6 +843,7 @@ class Installer: diff = diffit(modified=src, original=dst, diff_cmd=self.diff_cmd) if tmp: + # ignore error removepath(tmp, logger=self.log) if diff: diff --git a/dotdrop/uninstaller.py b/dotdrop/uninstaller.py index de5e2dd..c33c99f 100644 --- a/dotdrop/uninstaller.py +++ b/dotdrop/uninstaller.py @@ -99,7 +99,7 @@ class Uninstaller: def _remove_path(self, path): """remove a file""" try: - removepath(path, self.log) + removepath(path) except OSError as exc: err = f'removing \"{path}\" failed: {exc}' return False, err diff --git a/dotdrop/updater.py b/dotdrop/updater.py index 8ceeb39..e482237 100644 --- a/dotdrop/updater.py +++ b/dotdrop/updater.py @@ -151,6 +151,7 @@ class Updater: # clean temporary files if new_path != deployed_path and os.path.exists(new_path): + # ignore error removepath(new_path, logger=self.log) return ret @@ -167,6 +168,7 @@ class Updater: if not trans.transform(path, tmp, templater=self.templater, debug=self.debug): if os.path.exists(tmp): + # ignore error removepath(tmp, logger=self.log) err = f'transformation \"{trans.key}\" failed for {dotfile.key}' self.log.err(err) @@ -259,6 +261,7 @@ class Updater: def _handle_dir(self, deployed_path, local_path, dotfile, ignores): """sync path (local dir) and local_path (dotdrop dir path)""" + ret = True self.log.dbg(f'handle update for dir {deployed_path} to {local_path}') # get absolute paths @@ -282,7 +285,11 @@ class Updater: self.log.dbg(f'rm -r {path}') if not self._confirm_rm_r(path): continue - removepath(path, logger=self.log) + if not removepath(path, logger=self.log): + msg = f'unable to remove {path}, do manually' + self.log.warn(msg) + ret = False + continue self.log.sub(f'\"{path}\" removed') ignore_missing_in_dotdrop = self.ignore_missing_in_dotdrop or \ @@ -306,6 +313,7 @@ class Updater: msg = f'{srcpath} update right only failed' msg += f', do manually: {exc}' self.log.warn(msg) + ret = False continue self.log.sub(f'\"{dstpath}\" updated') @@ -332,10 +340,10 @@ class Updater: except IOError as exc: msg = f'{srcpath} update common failed, do manually: {exc}' self.log.warn(msg) + ret = False continue self.log.sub(f'\"{dstpath}\" content updated') - - return True + return ret def _overwrite(self, src, dst): """ask for overwritting""" diff --git a/dotdrop/utils.py b/dotdrop/utils.py index f83c64c..1dc01ae 100644 --- a/dotdrop/utils.py +++ b/dotdrop/utils.py @@ -153,26 +153,24 @@ def get_unique_tmp_name(): return os.path.join(tmpdir, unique) -def removepath(path, logger=None): +def removepath(path, logger=None): # TODO """ remove a file/directory/symlink - if logger is defined, OSError are catched - and printed to logger.warn instead of being forwarded - as OSError + raises OSError in case of error + unless logger is defined. + + When logger is defined, a logger.warn + is printed and a boolean returned """ if not path: - return + return True if not os.path.lexists(path): - err = f'File not found: {path}' - if logger: - logger.warn(err) - return - raise OSError(err) + return True if os.path.normpath(os.path.expanduser(path)) in NOREMOVE: err = f'Dotdrop refuses to remove {path}' if logger: logger.warn(err) - return + return False LOG.err(err) raise OSError(err) if logger: @@ -189,8 +187,9 @@ def removepath(path, logger=None): err = str(exc) if logger: logger.warn(err) - return + return False raise OSError(err) from exc + return True def samefile(path1, path2):