1
0
Fork 0
mirror of synced 2024-12-22 06:01:07 -05:00

Add option to clean recursively

This commit is contained in:
Anish Athalye 2019-12-31 19:14:23 -05:00
parent 81f0d74955
commit e38e021ab3
3 changed files with 49 additions and 4 deletions

View file

@ -303,7 +303,9 @@ Clean commands are specified as an array of directories to be cleaned.
Clean commands support an extended configuration syntax. In this type of
configuration, commands are specified as directory paths mapping to options. If
the `force` option is set to `true`, dead links are removed even if they don't
point to a file inside the dotfiles directory.
point to a file inside the dotfiles directory. If `recursive` is set to `true`,
the directory is traversed recursively (not recommended for `~` because it will
be slow).
#### Example
@ -311,8 +313,10 @@ point to a file inside the dotfiles directory.
- clean: ['~']
- clean:
~/.config:
~/:
force: true
~/.config:
recursive: true
```
### Defaults

View file

@ -20,16 +20,18 @@ class Clean(dotbot.Plugin):
defaults = self._context.defaults().get(self._directive, {})
for target in targets:
force = defaults.get('force', False)
recursive = defaults.get('recursive', False)
if isinstance(targets, dict) and isinstance(targets[target], dict):
force = targets[target].get('force', force)
success &= self._clean(target, force)
recursive = targets[target].get('recursive', recursive)
success &= self._clean(target, force, recursive)
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, force):
def _clean(self, target, force, recursive):
'''
Cleans all the broken symbolic links in target if they point to
a subdirectory of the base directory or if forced to clean.
@ -39,6 +41,11 @@ class Clean(dotbot.Plugin):
return True
for item in os.listdir(os.path.expandvars(os.path.expanduser(target))):
path = os.path.join(os.path.expandvars(os.path.expanduser(target)), item)
if recursive and os.path.isdir(path):
# isdir implies not islink -- we don't want to descend into
# symlinked directories. okay to do a recursive call here
# because depth should be fairly limited
self._clean(path, force, recursive)
if not os.path.exists(path) and os.path.islink(path):
points_at = os.path.join(os.path.dirname(path), os.readlink(path))
if self._in_directory(path, self._context.base_directory()) or force:

View file

@ -0,0 +1,34 @@
test_description='clean removes recursively'
. '../test-lib.bash'
test_expect_success 'setup' '
mkdir -p ~/a/b
ln -s /nowhere ~/c
ln -s /nowhere ~/a/d
ln -s /nowhere ~/a/b/e
'
test_expect_success 'run' '
run_dotbot <<EOF
- clean:
~/:
force: true
EOF
'
test_expect_success 'test' '
! test -h ~/c && test -h ~/a/d && test -h ~/a/b/e
'
test_expect_success 'run 2' '
run_dotbot <<EOF
- clean:
~/:
force: true
recursive: true
EOF
'
test_expect_success 'test 2' '
! test -h ~/a/d && ! test -h ~/a/b/e
'