summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnish Athalye <me@anishathalye.com>2016-02-14 22:39:48 -0500
committerAnish Athalye <me@anishathalye.com>2016-02-14 23:06:52 -0500
commitdaf8d82e02c2bcc476932790fa25076631c4c312 (patch)
tree1413dbbb3e810618e127a17ac3843ee9a8be653c
parentc402396c58114640745dbba132856cfd8cd7f422 (diff)
Add functionality to create relative links
This commit adds an option to the extended configuration syntax for linking files and directories. Enabling the relative option makes it so that symbolic links are created with relative paths instead of absolute paths.
-rw-r--r--README.md15
-rw-r--r--plugins/link.py12
-rw-r--r--test/tests/link-relative.bash36
3 files changed, 53 insertions, 10 deletions
diff --git a/README.md b/README.md
index 00c654d..3ed74f5 100644
--- a/README.md
+++ b/README.md
@@ -83,7 +83,7 @@ The conventional name for the configuration file is `install.conf.yaml`.
- link:
~/.dotfiles: ''
~/.tmux.conf: tmux.conf
- ~/.vim: vim/
+ ~/.vim: vim
~/.vimrc: vimrc
- shell:
@@ -104,7 +104,7 @@ The conventional name for this file is `install.conf.json`.
"link": {
"~/.dotfiles": "",
"~/.tmux.conf": "tmux.conf",
- "~/.vim": "vim/",
+ "~/.vim": "vim",
"~/.vimrc": "vimrc"
}
},
@@ -147,7 +147,7 @@ files if necessary. Environment variables in paths are automatically expanded.
Link commands are specified as a dictionary mapping targets to source
locations. Source locations are specified relative to the base directory (that
-is specified when running the installer). Source directory names should contain
+is specified when running the installer). Directory names should *not* contain
a trailing "/" character.
Link commands support an (optional) extended configuration. In this type of
@@ -155,8 +155,9 @@ configuration, instead of specifying source locations directly, targets are
mapped to extended configuration dictionaries. These dictionaries map `path` to
the source path, specify `create` as `true` if the parent directory should be
created if necessary, specify `relink` as `true` if incorrect symbolic links
-should be automatically overwritten, and specify `force` as `true` if the file
-or directory should be forcibly linked.
+should be automatically overwritten, specify `force` as `true` if the file or
+directory should be forcibly linked, and specify `relative` as `true` if the
+symbolic link should have a relative path.
#### Example
@@ -164,8 +165,8 @@ or directory should be forcibly linked.
- link:
~/.config/terminator:
create: true
- path: config/terminator/
- ~/.vim: vim/
+ path: config/terminator
+ ~/.vim: vim
~/.vimrc:
relink: true
path: vimrc
diff --git a/plugins/link.py b/plugins/link.py
index 429158d..3bb5686 100644
--- a/plugins/link.py
+++ b/plugins/link.py
@@ -23,6 +23,7 @@ class Link(dotbot.Plugin):
if isinstance(source, dict):
# extended config
path = source['path']
+ relative = source.get('relative', False)
force = source.get('force', False)
relink = source.get('relink', False)
create = source.get('create', False)
@@ -33,8 +34,9 @@ class Link(dotbot.Plugin):
elif relink:
success &= self._delete(path, destination, force=False)
else:
+ relative = False
path = source
- success &= self._link(path, destination)
+ success &= self._link(path, destination, relative)
if success:
self._log.info('All links have been set up')
else:
@@ -101,7 +103,7 @@ class Link(dotbot.Plugin):
self._log.lowinfo('Removing %s' % path)
return success
- def _link(self, source, link_name):
+ def _link(self, source, link_name, relative):
'''
Links link_name to source.
@@ -115,7 +117,11 @@ class Link(dotbot.Plugin):
(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))
+ destination = os.path.expanduser(link_name)
+ if relative:
+ destination_dir = os.path.dirname(destination)
+ source = os.path.relpath(source, destination_dir)
+ os.symlink(source, destination)
except OSError:
self._log.warning('Linking failed %s -> %s' % (link_name, source))
else:
diff --git a/test/tests/link-relative.bash b/test/tests/link-relative.bash
new file mode 100644
index 0000000..ac55c17
--- /dev/null
+++ b/test/tests/link-relative.bash
@@ -0,0 +1,36 @@
+test_description='relative linking works'
+. '../test-lib.bash'
+
+test_expect_success 'setup' '
+echo "apple" > ${DOTFILES}/f &&
+mkdir ${DOTFILES}/d &&
+echo "grape" > ${DOTFILES}/d/e
+'
+
+test_expect_success 'run' '
+run_dotbot <<EOF
+- link:
+ ~/.f:
+ path: f
+ ~/.frel:
+ path: f
+ relative: true
+ ~/nested/.frel:
+ path: f
+ create: true
+ relative: true
+ ~/.d:
+ path: d
+ relative: true
+EOF
+'
+
+test_expect_success 'test' '
+grep "apple" ~/.f &&
+grep "apple" ~/.frel &&
+[[ "$(readlink ~/.f)" == "$(readlink -f dotfiles/f)" ]] &&
+[[ "$(readlink ~/.frel)" == "dotfiles/f" ]] &&
+[[ "$(readlink ~/nested/.frel)" == "../dotfiles/f" ]] &&
+grep "grape" ~/.d/e &&
+[[ "$(readlink ~/.d)" == "dotfiles/d" ]]
+'