diff options
author | Anish Athalye <me@anishathalye.com> | 2014-06-08 11:30:10 -0700 |
---|---|---|
committer | Anish Athalye <me@anishathalye.com> | 2014-06-08 11:32:45 -0700 |
commit | abb825048b348e3892902fa92df1edacd3dd248f (patch) | |
tree | 204149781376e1bea4a0e776b410e5ae94dc9343 /dotbot | |
parent | 24f49603c8aeb7161ad83ff792dfa63baadb7362 (diff) |
Add Cleaner executor
Diffstat (limited to 'dotbot')
-rw-r--r-- | dotbot/executor/__init__.py | 1 | ||||
-rw-r--r-- | dotbot/executor/cleaner.py | 49 |
2 files changed, 50 insertions, 0 deletions
diff --git a/dotbot/executor/__init__.py b/dotbot/executor/__init__.py index 1762f78..d87ca4b 100644 --- a/dotbot/executor/__init__.py +++ b/dotbot/executor/__init__.py @@ -1,3 +1,4 @@ from .executor import Executor from .linker import Linker +from .cleaner import Cleaner from .commandrunner import CommandRunner diff --git a/dotbot/executor/cleaner.py b/dotbot/executor/cleaner.py new file mode 100644 index 0000000..59b9259 --- /dev/null +++ b/dotbot/executor/cleaner.py @@ -0,0 +1,49 @@ +import os +from . import Executor + +class Cleaner(Executor): + ''' + Cleans broken symbolic links. + ''' + + _directive = 'clean' + + def can_handle(self, directive): + return directive == self._directive + + def handle(self, directive, data): + if directive != self._directive: + raise ValueError('Cleaner cannot handle directive %s' % directive) + return self._process_clean(data) + + def _process_clean(self, targets): + success = True + for target in targets: + success &= self._clean(target) + if success: + self._log.info('All targets have been cleaned') + else: + self._log.error('Some targets were not succesfully cleaned') + return success + + def _clean(self, target): + ''' + Cleans all the broken symbolic links in target that point to + a subdirectory of the base directory. + ''' + 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._base_directory): + self._log.lowinfo('Removing invalid link %s -> %s' % + (path, os.path.join(os.path.dirname(path), os.readlink(path)))) + os.remove(path) + return True + + def _in_directory(self, path, directory): + ''' + Returns true if the path is in the directory. + ''' + directory = os.path.join(os.path.realpath(directory), '') + path = os.path.realpath(path) + return os.path.commonprefix([path, directory]) == directory |