diff --git a/README.md b/README.md index 5c79337..b8896dc 100644 --- a/README.md +++ b/README.md @@ -104,14 +104,19 @@ a trailing "/" character. Link commands support an (optional) extended configuration. In this type of configuration, instead of specifying source locations directly, targets are mapped to extended configuration dictionaries. These dictionaries map "path" to -the source path, and specify "force" as true if the file or directory should be -forcibly linked. +the source path, specify "create" as true if the parent directory should be +created if necessary, and specify "force" as true if the file or directory +should be forcibly linked. ##### Example ```json { "link": { + "~/.config/terminator": { + "path": "config/terminator/", + "create": true + }, "~/.vimrc": "vimrc", "~/.vim": "vim/", "~/.zshrc": { diff --git a/dotbot/executor/linker.py b/dotbot/executor/linker.py index 2d14ecc..c3d6dc5 100644 --- a/dotbot/executor/linker.py +++ b/dotbot/executor/linker.py @@ -23,6 +23,9 @@ class Linker(Executor): # extended config path = source['path'] force = source.get('force', False) + create = source.get('create', False) + if create: + success &= self._create(destination) if force: success &= self._delete(destination) else: @@ -55,6 +58,19 @@ class Linker(Executor): path = os.path.expanduser(path) return os.path.exists(path) + def _create(self, path): + success = True + parent = os.path.abspath(os.path.join(os.path.expanduser(path), os.pardir)) + if not self._exists(parent): + try: + os.makedirs(parent) + except OSError: + self._log.warning('Failed to create directory %s' % parent) + success = False + else: + self._log.lowinfo('Creating directory %s' % parent) + return success + def _delete(self, path): success = True if self._exists(path) and not self._is_link(path):