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.
This commit is contained in:
parent
c402396c58
commit
daf8d82e02
3 changed files with 53 additions and 10 deletions
15
README.md
15
README.md
|
@ -83,7 +83,7 @@ The conventional name for the configuration file is `install.conf.yaml`.
|
||||||
- link:
|
- link:
|
||||||
~/.dotfiles: ''
|
~/.dotfiles: ''
|
||||||
~/.tmux.conf: tmux.conf
|
~/.tmux.conf: tmux.conf
|
||||||
~/.vim: vim/
|
~/.vim: vim
|
||||||
~/.vimrc: vimrc
|
~/.vimrc: vimrc
|
||||||
|
|
||||||
- shell:
|
- shell:
|
||||||
|
@ -104,7 +104,7 @@ The conventional name for this file is `install.conf.json`.
|
||||||
"link": {
|
"link": {
|
||||||
"~/.dotfiles": "",
|
"~/.dotfiles": "",
|
||||||
"~/.tmux.conf": "tmux.conf",
|
"~/.tmux.conf": "tmux.conf",
|
||||||
"~/.vim": "vim/",
|
"~/.vim": "vim",
|
||||||
"~/.vimrc": "vimrc"
|
"~/.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
|
Link commands are specified as a dictionary mapping targets to source
|
||||||
locations. Source locations are specified relative to the base directory (that
|
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.
|
a trailing "/" character.
|
||||||
|
|
||||||
Link commands support an (optional) extended configuration. In this type of
|
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
|
mapped to extended configuration dictionaries. These dictionaries map `path` to
|
||||||
the source path, specify `create` as `true` if the parent directory should be
|
the source path, specify `create` as `true` if the parent directory should be
|
||||||
created if necessary, specify `relink` as `true` if incorrect symbolic links
|
created if necessary, specify `relink` as `true` if incorrect symbolic links
|
||||||
should be automatically overwritten, and specify `force` as `true` if the file
|
should be automatically overwritten, specify `force` as `true` if the file or
|
||||||
or directory should be forcibly linked.
|
directory should be forcibly linked, and specify `relative` as `true` if the
|
||||||
|
symbolic link should have a relative path.
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
|
|
||||||
|
@ -164,8 +165,8 @@ or directory should be forcibly linked.
|
||||||
- link:
|
- link:
|
||||||
~/.config/terminator:
|
~/.config/terminator:
|
||||||
create: true
|
create: true
|
||||||
path: config/terminator/
|
path: config/terminator
|
||||||
~/.vim: vim/
|
~/.vim: vim
|
||||||
~/.vimrc:
|
~/.vimrc:
|
||||||
relink: true
|
relink: true
|
||||||
path: vimrc
|
path: vimrc
|
||||||
|
|
|
@ -23,6 +23,7 @@ class Link(dotbot.Plugin):
|
||||||
if isinstance(source, dict):
|
if isinstance(source, dict):
|
||||||
# extended config
|
# extended config
|
||||||
path = source['path']
|
path = source['path']
|
||||||
|
relative = source.get('relative', False)
|
||||||
force = source.get('force', False)
|
force = source.get('force', False)
|
||||||
relink = source.get('relink', False)
|
relink = source.get('relink', False)
|
||||||
create = source.get('create', False)
|
create = source.get('create', False)
|
||||||
|
@ -33,8 +34,9 @@ class Link(dotbot.Plugin):
|
||||||
elif relink:
|
elif relink:
|
||||||
success &= self._delete(path, destination, force=False)
|
success &= self._delete(path, destination, force=False)
|
||||||
else:
|
else:
|
||||||
|
relative = False
|
||||||
path = source
|
path = source
|
||||||
success &= self._link(path, destination)
|
success &= self._link(path, destination, relative)
|
||||||
if success:
|
if success:
|
||||||
self._log.info('All links have been set up')
|
self._log.info('All links have been set up')
|
||||||
else:
|
else:
|
||||||
|
@ -101,7 +103,7 @@ class Link(dotbot.Plugin):
|
||||||
self._log.lowinfo('Removing %s' % path)
|
self._log.lowinfo('Removing %s' % path)
|
||||||
return success
|
return success
|
||||||
|
|
||||||
def _link(self, source, link_name):
|
def _link(self, source, link_name, relative):
|
||||||
'''
|
'''
|
||||||
Links link_name to source.
|
Links link_name to source.
|
||||||
|
|
||||||
|
@ -115,7 +117,11 @@ class Link(dotbot.Plugin):
|
||||||
(link_name, self._link_destination(link_name)))
|
(link_name, self._link_destination(link_name)))
|
||||||
elif not self._exists(link_name) and self._exists(source):
|
elif not self._exists(link_name) and self._exists(source):
|
||||||
try:
|
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:
|
except OSError:
|
||||||
self._log.warning('Linking failed %s -> %s' % (link_name, source))
|
self._log.warning('Linking failed %s -> %s' % (link_name, source))
|
||||||
else:
|
else:
|
||||||
|
|
36
test/tests/link-relative.bash
Normal file
36
test/tests/link-relative.bash
Normal file
|
@ -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" ]]
|
||||||
|
'
|
Loading…
Reference in a new issue