From edc87576ce9de0929590a22c4a4064034c042963 Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Mon, 21 May 2018 18:11:28 +0200 Subject: [PATCH] Add --no-realpath-base switch to keep symbolic links in BASEDIR dotbot had a hardcoded behaviour that the BASEDIR was always passed to os.path.realpath which "returns the canonical path of the specified filename, eliminating any symbolic links encountered in the path". This might not always be desirable so this commit makes it configurable using a command line flag, `--no-realpath-base`. The use case where `--no-realpath-base` comes in handy is the following: You want to provide dotfiles in the Filesystem Hierarchy Standard under `/usr/local/share/ypid_dotfiles/`. Now you want to provide `.config/dotfiles` as a default in `/etc/skel`. When you now pre-configure `/etc/skel` by running dotbot in it set has HOME, dotfiles will refer to `/usr/local/share/ypid_dotfiles/` and not `/etc/skel/.config/dotfiles` which does not look nice. This is related to but not the same as the `relative` parameter used with link commands. --- dotbot/cli.py | 4 +++- dotbot/dispatcher.py | 12 +++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/dotbot/cli.py b/dotbot/cli.py index d77ab42..3ad5345 100644 --- a/dotbot/cli.py +++ b/dotbot/cli.py @@ -17,6 +17,8 @@ def add_options(parser): parser.add_argument('-d', '--base-directory', nargs=1, dest='base_directory', help='execute commands from within BASEDIR', metavar='BASEDIR', required=True) + parser.add_argument('-r', '--no-realpath-base', action='store_false', + dest='base_directory_real_path', help='Do not eliminate symbolic links encountered in BASEDIR') parser.add_argument('-c', '--config-file', nargs=1, dest='config_file', help='run commands given in CONFIGFILE', metavar='CONFIGFILE', required=True) @@ -58,7 +60,7 @@ def main(): tasks = read_config(options.config_file[0]) if not isinstance(tasks, list): raise ReadingError('Configuration file must be a list of tasks') - dispatcher = Dispatcher(options.base_directory[0]) + dispatcher = Dispatcher(options.base_directory[0], options.base_directory_real_path) success = dispatcher.dispatch(tasks) if success: log.info('\n==> All tasks executed successfully') diff --git a/dotbot/dispatcher.py b/dotbot/dispatcher.py index d1a4f95..c412b8d 100644 --- a/dotbot/dispatcher.py +++ b/dotbot/dispatcher.py @@ -4,14 +4,16 @@ from .messenger import Messenger from .context import Context class Dispatcher(object): - def __init__(self, base_directory): + def __init__(self, base_directory, base_directory_real_path): self._log = Messenger() - self._setup_context(base_directory) + self._setup_context(base_directory, base_directory_real_path) self._load_plugins() - def _setup_context(self, base_directory): - path = os.path.abspath(os.path.realpath( - os.path.expanduser(base_directory))) + def _setup_context(self, base_directory, base_directory_real_path): + path = os.path.abspath( + os.path.expanduser(base_directory)) + if base_directory_real_path: + path = os.path.realpath(path) if not os.path.exists(path): raise DispatchError('Nonexistent base directory') self._context = Context(path)