mirror of
https://github.com/deadc0de6/dotdrop.git
synced 2026-02-16 22:34:10 +00:00
Add support for soft links
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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():
|
||||||
|
|||||||
@@ -66,6 +66,9 @@ def install(opts, conf):
|
|||||||
diff=opts['installdiff'])
|
diff=opts['installdiff'])
|
||||||
installed = []
|
installed = []
|
||||||
for dotfile in dotfiles:
|
for dotfile in dotfiles:
|
||||||
|
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)
|
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)))
|
||||||
|
|||||||
@@ -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 []
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
Reference in New Issue
Block a user