1
0
mirror of https://github.com/deadc0de6/dotdrop.git synced 2026-02-16 23:09:11 +00:00

Add support for soft links

This commit is contained in:
moyiz
2017-05-03 11:00:52 +03:00
parent d40ea36187
commit c4aab509f7
5 changed files with 50 additions and 5 deletions

View File

@@ -177,11 +177,12 @@ the following entries:
* `dotpath`: path to the folder containing the dotfiles to be managed * `dotpath`: path to the folder containing the dotfiles to be managed
by dotdrop (absolute path or relative to the config file location) by dotdrop (absolute path or relative to the config file location)
* **dotfiles** entry: a list of dotfiles in the form * **dotfiles** entry: a list of dotfiles in the form
* When `link` is true, dotdrop will create a link instead of copying. Template generation (as in [template](#template)) is not supported when `link` is true.
``` ```
<dotfile-key-name>: <dotfile-key-name>:
dst: <where-this-file-is-deployed> dst: <where-this-file-is-deployed>
src: <filename-within-the-dotpath> src: <filename-within-the-dotpath>
link: <true|false> # Optional
``` ```
* **profiles** entry: a list of profiles with a sublist * **profiles** entry: a list of profiles with a sublist

View File

@@ -62,8 +62,8 @@ class Cfg:
for k, v in self.content[self.key_dotfiles].items(): for k, v in self.content[self.key_dotfiles].items():
src = v[self.key_dotfiles_src] src = v[self.key_dotfiles_src]
dst = v[self.key_dotfiles_dst] dst = v[self.key_dotfiles_dst]
link = v[self.key_dotfiles_link] if self.key_dotfiles_link in v link = v[self.key_dotfiles_link] if self.key_dotfiles_link \
else False in v else False
self.dotfiles[k] = Dotfile(k, dst, src, link) self.dotfiles[k] = Dotfile(k, dst, src, link)
# contains a list of dotfiles defined for each profile # contains a list of dotfiles defined for each profile
for k, v in self.profiles.items(): for k, v in self.profiles.items():

View File

@@ -66,7 +66,10 @@ def install(opts, conf):
diff=opts['installdiff']) diff=opts['installdiff'])
installed = [] installed = []
for dotfile in dotfiles: for dotfile in dotfiles:
r = inst.install(t, opts['profile'], dotfile.src, dotfile.dst) if hasattr(dotfile, "link") and dotfile.link:
r = inst.link(dotfile.src, dotfile.dst)
else:
r = inst.install(t, opts['profile'], dotfile.src, dotfile.dst)
installed.extend(r) installed.extend(r)
LOG.log('\n%u dotfile(s) installed.' % (len(installed))) LOG.log('\n%u dotfile(s) installed.' % (len(installed)))
return True return True

View File

@@ -32,6 +32,32 @@ class Installer:
return self._handle_dir(templater, profile, src, dst) return self._handle_dir(templater, profile, src, dst)
return self._handle_file(templater, profile, src, dst) return self._handle_file(templater, profile, src, dst)
def link(self, src, dst):
'''Sets src as the link target of dst'''
src = os.path.join(self.base, os.path.expanduser(src))
dst = os.path.join(self.base, os.path.expanduser(dst))
if os.path.exists(dst):
if os.path.realpath(dst) == os.path.realpath(src):
self.log.sub('ignoring "{}", link exists'.format(dst))
return []
if self.dry:
self.log.dry('would remove {} and link it to {}'
.format(dst, src))
return []
if self.safe and not self.log.ask('Remove "{}" for link creation?'
.format(dst)):
self.log.warn('ignoring "{}", link was not created'
.format(dst))
return []
utils.remove(dst)
if self.dry:
self.log.dry('would link {} to {}'.format(dst, src))
return []
os.symlink(src, dst)
self.log.sub('linked %s to %s' % (dst, src))
# Follows original developer's behavior
return [(src, dst)]
def _handle_file(self, templater, profile, src, dst): def _handle_file(self, templater, profile, src, dst):
'''Install a file using templater for "profile"''' '''Install a file using templater for "profile"'''
content = templater.generate(src, profile) content = templater.generate(src, profile)
@@ -47,7 +73,7 @@ class Installer:
self.log.sub('ignoring \"%s\", same content' % (dst)) self.log.sub('ignoring \"%s\", same content' % (dst))
return [] return []
if ret == 0: if ret == 0:
if not self.quiet: if not self.quiet and not self.dry:
self.log.sub('copied %s to %s' % (src, dst)) self.log.sub('copied %s to %s' % (src, dst))
return [(src, dst)] return [(src, dst)]
return [] return []

View File

@@ -6,7 +6,10 @@ utilities
import subprocess import subprocess
import tempfile import tempfile
import os
from logger import Logger from logger import Logger
from shutil import rmtree
LOG = Logger() LOG = Logger()
@@ -29,3 +32,15 @@ def diff(src, dst, log=False, raw=True):
def get_tmpdir(): def get_tmpdir():
return tempfile.mkdtemp(prefix='dotdrop-') return tempfile.mkdtemp(prefix='dotdrop-')
def remove(path):
''' Remove a file / directory / symlink '''
if not os.path.exists(path):
raise Exception("ERROR in remove: File not found: {}".format(path))
if os.path.islink(path) or os.path.isfile(path):
os.unlink(path)
elif os.path.isdir(path):
rmtree(path)
else:
raise Exception("Unsupported file type for deletion: {}".format(path))