summaryrefslogtreecommitdiff
path: root/dotbot/executor/linker.py
diff options
context:
space:
mode:
Diffstat (limited to 'dotbot/executor/linker.py')
-rw-r--r--dotbot/executor/linker.py142
1 files changed, 0 insertions, 142 deletions
diff --git a/dotbot/executor/linker.py b/dotbot/executor/linker.py
deleted file mode 100644
index 5c12ea0..0000000
--- a/dotbot/executor/linker.py
+++ /dev/null
@@ -1,142 +0,0 @@
-import os, shutil
-from . import Executor
-
-class Linker(Executor):
- '''
- Symbolically links dotfiles.
- '''
-
- _directive = 'link'
-
- def can_handle(self, directive):
- return directive == self._directive
-
- def handle(self, directive, data):
- if directive != self._directive:
- raise ValueError('Linker cannot handle directive %s' % directive)
- return self._process_links(data)
-
- def _process_links(self, links):
- success = True
- for destination, source in links.items():
- source = os.path.expandvars(source)
- destination = os.path.expandvars(destination)
- if isinstance(source, dict):
- # extended config
- path = source['path']
- force = source.get('force', False)
- relink = source.get('relink', False)
- create = source.get('create', False)
- if create:
- success &= self._create(destination)
- if force:
- success &= self._delete(path, destination, force=True)
- elif relink:
- success &= self._delete(path, destination, force=False)
- else:
- path = source
- success &= self._link(path, destination)
- if success:
- self._log.info('All links have been set up')
- else:
- self._log.error('Some links were not successfully set up')
- return success
-
- def _is_link(self, path):
- '''
- Returns true if the path is a symbolic link.
- '''
- return os.path.islink(os.path.expanduser(path))
-
- def _link_destination(self, path):
- '''
- Returns the absolute path to the destination of the symbolic link.
- '''
- path = os.path.expanduser(path)
- rel_dest = os.readlink(path)
- return os.path.join(os.path.dirname(path), rel_dest)
-
- def _exists(self, path):
- '''
- Returns true if the path exists.
- '''
- path = os.path.expanduser(path)
- return os.path.exists(path)
-
- def _create(self, path):
- success = True
- parent = os.path.abspath(os.path.join(os.path.expanduser(path), os.pardir))
- if not self._exists(parent):
- try:
- os.makedirs(parent)
- except OSError:
- self._log.warning('Failed to create directory %s' % parent)
- success = False
- else:
- self._log.lowinfo('Creating directory %s' % parent)
- return success
-
- def _delete(self, source, path, force):
- success = True
- source = os.path.join(self._base_directory, source)
- if ((self._is_link(path) and self._link_destination(path) != source) or
- (self._exists(path) and not self._is_link(path))):
- fullpath = os.path.expanduser(path)
- removed = False
- try:
- if os.path.islink(fullpath):
- os.unlink(fullpath)
- removed = True
- elif force:
- if os.path.isdir(fullpath):
- shutil.rmtree(fullpath)
- removed = True
- else:
- os.remove(fullpath)
- removed = True
- except OSError:
- self._log.warning('Failed to remove %s' % path)
- success = False
- else:
- if removed:
- self._log.lowinfo('Removing %s' % path)
- return success
-
- def _link(self, source, link_name):
- '''
- Links link_name to source.
-
- Returns true if successfully linked files.
- '''
- success = False
- source = os.path.join(self._base_directory, source)
- if (not self._exists(link_name) and self._is_link(link_name) and
- self._link_destination(link_name) != source):
- self._log.warning('Invalid link %s -> %s' %
- (link_name, self._link_destination(link_name)))
- elif not self._exists(link_name) and self._exists(source):
- try:
- os.symlink(source, os.path.expanduser(link_name))
- except OSError:
- self._log.warning('Linking failed %s -> %s' % (link_name, source))
- else:
- self._log.lowinfo('Creating link %s -> %s' % (link_name, source))
- success = True
- elif self._exists(link_name) and not self._is_link(link_name):
- self._log.warning(
- '%s already exists but is a regular file or directory' %
- link_name)
- elif self._is_link(link_name) and self._link_destination(link_name) != source:
- self._log.warning('Incorrect link %s -> %s' %
- (link_name, self._link_destination(link_name)))
- elif not self._exists(source):
- if self._is_link(link_name):
- self._log.warning('Nonexistent target %s -> %s' %
- (link_name, source))
- else:
- self._log.warning('Nonexistent target for %s : %s' %
- (link_name, source))
- else:
- self._log.lowinfo('Link exists %s -> %s' % (link_name, source))
- success = True
- return success