From fdc6c91e0835518a9598e30425eba478899b801f Mon Sep 17 00:00:00 2001 From: Marcel Robitaille Date: Sat, 12 Dec 2020 00:41:05 -0500 Subject: [PATCH] Add dotfile-specific `ignore_missing` option --- dotdrop/cfg_yaml.py | 1 + dotdrop/dotdrop.py | 4 +++- dotdrop/dotfile.py | 4 +++- dotdrop/updater.py | 40 +++++++++++++++++++++------------------- 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/dotdrop/cfg_yaml.py b/dotdrop/cfg_yaml.py index 16461c5..9b14b12 100644 --- a/dotdrop/cfg_yaml.py +++ b/dotdrop/cfg_yaml.py @@ -59,6 +59,7 @@ class CfgYaml: key_dotfile_noempty = 'ignoreempty' key_dotfile_template = 'template' key_dotfile_chmod = 'chmod' + key_dotfile_ignore_missing = 'ignore_missing_in_dotdrop' # profile key_profile_dotfiles = 'dotfiles' diff --git a/dotdrop/dotdrop.py b/dotdrop/dotdrop.py index 49c79e0..0d0f346 100644 --- a/dotdrop/dotdrop.py +++ b/dotdrop/dotdrop.py @@ -93,13 +93,15 @@ def _dotfile_compare(o, dotfile, tmp): returns True if same """ t = _get_templater(o) + ignore_missing_in_dotdrop = o.ignore_missing_in_dotdrop or \ + dotfile.ignore_missing_in_dotdrop inst = Installer(create=o.create, backup=o.backup, dry=o.dry, base=o.dotpath, workdir=o.workdir, debug=o.debug, backup_suffix=o.install_backup_suffix, diff_cmd=o.diff_command) comp = Comparator(diff_cmd=o.diff_command, debug=o.debug, - ignore_missing_in_dotdrop=o.ignore_missing_in_dotdrop) + ignore_missing_in_dotdrop=ignore_missing_in_dotdrop) # add dotfile variables newvars = dotfile.get_dotfile_variables() diff --git a/dotdrop/dotfile.py b/dotdrop/dotfile.py index 9c96434..21a6557 100644 --- a/dotdrop/dotfile.py +++ b/dotdrop/dotfile.py @@ -22,7 +22,8 @@ class Dotfile(DictParser): actions=[], trans_r=None, trans_w=None, link=LinkTypes.NOLINK, noempty=False, cmpignore=[], upignore=[], - instignore=[], template=True, chmod=None): + instignore=[], template=True, chmod=None, + ignore_missing_in_dotdrop=False): """ constructor @key: dotfile key @@ -52,6 +53,7 @@ class Dotfile(DictParser): self.instignore = instignore self.template = template self.chmod = chmod + self.ignore_missing_in_dotdrop = ignore_missing_in_dotdrop if self.link != LinkTypes.NOLINK and \ ( diff --git a/dotdrop/updater.py b/dotdrop/updater.py index 0a36c2b..8bdd185 100644 --- a/dotdrop/updater.py +++ b/dotdrop/updater.py @@ -108,7 +108,7 @@ class Updater: self.log.err(msg.format(dtpath)) return False - if self._ignore([path, dtpath]): + if self._ignore([path, dtpath], dotfile): self.log.sub('\"{}\" ignored'.format(dotfile.key)) return True # apply write transformation if any @@ -122,9 +122,9 @@ class Updater: # handle the pointed file if os.path.isdir(new_path): - ret = self._handle_dir(new_path, dtpath) + ret = self._handle_dir(new_path, dtpath, dotfile) else: - ret = self._handle_file(new_path, dtpath) + ret = self._handle_file(new_path, dtpath, dotfile) if fsmode != dfmode: # mirror rights @@ -205,9 +205,9 @@ class Updater: except OSError as e: self.log.err(e) - def _handle_file(self, path, dtpath, compare=True): + def _handle_file(self, path, dtpath, dotfile, compare=True): """sync path (deployed file) and dtpath (dotdrop dotfile path)""" - if self._ignore([path, dtpath]): + if self._ignore([path, dtpath], dotfile): self.log.sub('\"{}\" ignored'.format(dtpath)) return True if self.debug: @@ -245,29 +245,29 @@ class Updater: return False return True - def _handle_dir(self, path, dtpath): + def _handle_dir(self, path, dtpath, dotfile): """sync path (deployed dir) and dtpath (dotdrop dir path)""" if self.debug: self.log.dbg('handle update for dir {} to {}'.format(path, dtpath)) # paths must be absolute (no tildes) path = os.path.expanduser(path) dtpath = os.path.expanduser(dtpath) - if self._ignore([path, dtpath]): + if self._ignore([path, dtpath], dotfile): self.log.sub('\"{}\" ignored'.format(dtpath)) return True # find the differences diff = filecmp.dircmp(path, dtpath, ignore=None) # handle directories diff - ret = self._merge_dirs(diff) + ret = self._merge_dirs(diff, dotfile) self._mirror_rights(path, dtpath) return ret - def _merge_dirs(self, diff): + def _merge_dirs(self, diff, dotfile): """Synchronize directories recursively.""" left, right = diff.left, diff.right if self.debug: self.log.dbg('sync dir {} to {}'.format(left, right)) - if self._ignore([left, right]): + if self._ignore([left, right], dotfile): return True # create dirs that don't exist in dotdrop @@ -278,7 +278,7 @@ class Updater: continue # match to dotdrop dotpath new = os.path.join(right, toadd) - if self._ignore([exist, new]): + if self._ignore([exist, new], dotfile): self.log.sub('\"{}\" ignored'.format(exist)) continue if self.dry: @@ -311,7 +311,7 @@ class Updater: if not os.path.isdir(old): # ignore files for now continue - if self._ignore([old]): + if self._ignore([old], dotfile): continue if self.dry: self.log.dry('would rm -r {}'.format(old)) @@ -331,14 +331,14 @@ class Updater: for f in fdiff: fleft = os.path.join(left, f) fright = os.path.join(right, f) - if self._ignore([fleft, fright]): + if self._ignore([fleft, fright], dotfile): continue if self.dry: self.log.dry('would cp {} {}'.format(fleft, fright)) continue if self.debug: self.log.dbg('cp {} {}'.format(fleft, fright)) - self._handle_file(fleft, fright, compare=False) + self._handle_file(fleft, fright, dotfile, compare=False) # copy files that don't exist in dotdrop for toadd in diff.left_only: @@ -347,7 +347,7 @@ class Updater: # ignore dirs, done above continue new = os.path.join(right, toadd) - if self._ignore([exist, new]): + if self._ignore([exist, new], dotfile): continue if self.dry: self.log.dry('would cp {} {}'.format(exist, new)) @@ -366,7 +366,7 @@ class Updater: if os.path.isdir(new): # ignore dirs, done above continue - if self._ignore([new]): + if self._ignore([new], dotfile): continue if self.dry: self.log.dry('would rm {}'.format(new)) @@ -385,7 +385,7 @@ class Updater: # Recursively decent into common subdirectories. for subdir in diff.subdirs.values(): - self._merge_dirs(subdir) + self._merge_dirs(subdir, dotfile) # Nothing more to do here. return True @@ -404,10 +404,12 @@ class Updater: return False return True - def _ignore(self, paths): + def _ignore(self, paths, dotfile): + ignore_missing_in_dotdrop = self.ignore_missing_in_dotdrop or \ + dotfile.ignore_missing_in_dotdrop if must_ignore( paths, self.ignores, debug=self.debug, - ignore_missing_in_dotdrop=self.ignore_missing_in_dotdrop, + ignore_missing_in_dotdrop=ignore_missing_in_dotdrop, ): if self.debug: self.log.dbg('ignoring update for {}'.format(paths))