From 2303303eea5fa98fcc6fa665a904dd1d2f094ecb Mon Sep 17 00:00:00 2001 From: dein0s Date: Wed, 22 Mar 2017 13:22:10 +0300 Subject: [PATCH 1/2] added force option for clean plugin; added tests --- plugins/clean.py | 32 +++++++++++++++++++++-------- test/tests/clean-outside-force.bash | 18 ++++++++++++++++ test/tests/defaults.bash | 27 +++++++++++++++++++++++- 3 files changed, 68 insertions(+), 9 deletions(-) create mode 100644 test/tests/clean-outside-force.bash diff --git a/plugins/clean.py b/plugins/clean.py index dbd11af..549f4db 100644 --- a/plugins/clean.py +++ b/plugins/clean.py @@ -17,18 +17,22 @@ class Clean(dotbot.Plugin): def _process_clean(self, targets): success = True - for target in targets: - success &= self._clean(target) + defaults = self._context.defaults().get(self._directive, {}) + force = defaults.get('force', False) + for target in self._dispatch_targets(targets): + if isinstance(targets, dict): + force = targets[target].get('force', force) + success &= self._clean(target, force) if success: self._log.info('All targets have been cleaned') else: self._log.error('Some targets were not successfully cleaned') return success - def _clean(self, target): + def _clean(self, target, force): ''' - Cleans all the broken symbolic links in target that point to - a subdirectory of the base directory. + Cleans all the broken symbolic links in target if that point to + a subdirectory of the base directory or forced to clean. ''' if not os.path.isdir(os.path.expanduser(target)): self._log.debug('Ignoring nonexistent directory %s' % target) @@ -36,12 +40,24 @@ class Clean(dotbot.Plugin): for item in os.listdir(os.path.expanduser(target)): path = os.path.join(os.path.expanduser(target), item) if not os.path.exists(path) and os.path.islink(path): - if self._in_directory(path, self._context.base_directory()): - self._log.lowinfo('Removing invalid link %s -> %s' % - (path, os.path.join(os.path.dirname(path), os.readlink(path)))) + points_at = os.path.join(os.path.dirname(path), os.readlink(path)) + if self._in_directory(path, self._context.base_directory()) or force: + self._log.lowinfo('Removing invalid link %s -> %s' % (path, points_at)) os.remove(path) + else: + self._log.lowinfo('Link %s -> %s not removed (force=%s). '\ + 'You can remove it manually.' % (path, points_at, force)) return True + def _dispatch_targets(self, targets): + ''' + Returns list of targets to process. + ''' + if isinstance(targets, list): + return targets + if isinstance(targets, dict): + return targets.keys() + def _in_directory(self, path, directory): ''' Returns true if the path is in the directory. diff --git a/test/tests/clean-outside-force.bash b/test/tests/clean-outside-force.bash new file mode 100644 index 0000000..16a740d --- /dev/null +++ b/test/tests/clean-outside-force.bash @@ -0,0 +1,18 @@ +test_description='clean forced to remove files linking outside dotfiles directory' +. '../test-lib.bash' + +test_expect_success 'setup' ' +ln -s /nowhere ~/.g +' + +test_expect_success 'run' ' +run_dotbot < ${DOTFILES}/f && echo "grape" > ~/f && -ln -s ~/f ~/.f +ln -s ~/f ~/.f && +ln -s /nowhere ~/.g ' test_expect_failure 'run-fail' ' @@ -32,3 +33,27 @@ EOF test_expect_success 'test' ' grep "apple" ~/.f ' + +test_expect_success 'run-fail' ' +run_dotbot < Date: Sun, 26 Mar 2017 18:10:05 +0300 Subject: [PATCH 2/2] removed unnecessary _dispatch_targets method; fixed docstring; fixed `not removed` message --- plugins/clean.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/plugins/clean.py b/plugins/clean.py index 549f4db..7e6cba1 100644 --- a/plugins/clean.py +++ b/plugins/clean.py @@ -19,7 +19,7 @@ class Clean(dotbot.Plugin): success = True defaults = self._context.defaults().get(self._directive, {}) force = defaults.get('force', False) - for target in self._dispatch_targets(targets): + for target in targets: if isinstance(targets, dict): force = targets[target].get('force', force) success &= self._clean(target, force) @@ -31,8 +31,8 @@ class Clean(dotbot.Plugin): def _clean(self, target, force): ''' - Cleans all the broken symbolic links in target if that point to - a subdirectory of the base directory or forced to clean. + Cleans all the broken symbolic links in target if they point to + a subdirectory of the base directory or if forced to clean. ''' if not os.path.isdir(os.path.expanduser(target)): self._log.debug('Ignoring nonexistent directory %s' % target) @@ -45,19 +45,9 @@ class Clean(dotbot.Plugin): self._log.lowinfo('Removing invalid link %s -> %s' % (path, points_at)) os.remove(path) else: - self._log.lowinfo('Link %s -> %s not removed (force=%s). '\ - 'You can remove it manually.' % (path, points_at, force)) + self._log.lowinfo('Link %s -> %s not removed.' % (path, points_at)) return True - def _dispatch_targets(self, targets): - ''' - Returns list of targets to process. - ''' - if isinstance(targets, list): - return targets - if isinstance(targets, dict): - return targets.keys() - def _in_directory(self, path, directory): ''' Returns true if the path is in the directory.