From 5a0f6676d41a7291e89f5e32e09396490d71a800 Mon Sep 17 00:00:00 2001 From: Jesse Leite Date: Sun, 6 Oct 2019 01:13:51 -0400 Subject: [PATCH] Add 'create' directive to create directories --- README.md | 33 ++++++++++++++++++++---- dotbot/cli.py | 2 +- dotbot/plugins/__init__.py | 1 + dotbot/plugins/create.py | 53 ++++++++++++++++++++++++++++++++++++++ test/tests/create.bash | 23 +++++++++++++++++ 5 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 dotbot/plugins/create.py create mode 100644 test/tests/create.bash diff --git a/README.md b/README.md index c4d7ab8..f6d7dd7 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,10 @@ The conventional name for the configuration file is `install.conf.yaml`. ~/.vim: vim ~/.vimrc: vimrc +- create: + - ~/downloads + - ~/.vim/undo-history + - shell: - [git submodule update --init --recursive, Installing submodules] ``` @@ -119,9 +123,9 @@ Configuration Dotbot uses YAML or JSON-formatted configuration files to let you specify how to set up your dotfiles. Currently, Dotbot knows how to [link](#link) files and -folders, execute [shell](#shell) commands, and [clean](#clean) directories of -broken symbolic links. Dotbot also supports user [plugins](#plugins) for custom -commands. +folders, [create](#create) folders, execute [shell](#shell) commands, and +[clean](#clean) directories of broken symbolic links. Dotbot also supports user +[plugins](#plugins) for custom commands. **Ideally, bootstrap configurations should be idempotent. That is, the installer should be able to be run multiple times without causing any @@ -219,6 +223,25 @@ the following config files equivalent: relink: true ``` +### Create + +Create commands specify empty directories to be created. This can be useful +for scaffolding out folders or parent folder structure required for various +apps, plugins, shell commands, etc. + +#### Format + +Create commands are specified as an array of directories to be created. + +#### Example + +```yaml +- create: + - ~/projects + - ~/downloads + - ~/.vim/undo-history +``` + ### Shell Shell commands specify shell commands to be run. Shell commands are run in the @@ -243,8 +266,8 @@ command itself. ```yaml - shell: - - mkdir -p ~/src - - [mkdir -p ~/downloads, Creating downloads directory] + - chsh -s $(which zsh) + - [chsh -s $(which zsh), Making zsh the default shell] - command: read var && echo Your variable is $var stdin: true diff --git a/dotbot/cli.py b/dotbot/cli.py index fdc2a13..2680acf 100644 --- a/dotbot/cli.py +++ b/dotbot/cli.py @@ -56,7 +56,7 @@ def main(): log.use_color(False) plugin_directories = list(options.plugin_dirs) if not options.disable_built_in_plugins: - from .plugins import Clean, Link, Shell + from .plugins import Clean, Create, Link, Shell plugin_paths = [] for directory in plugin_directories: for plugin_path in glob.glob(os.path.join(directory, '*.py')): diff --git a/dotbot/plugins/__init__.py b/dotbot/plugins/__init__.py index 93bd981..f75bef5 100644 --- a/dotbot/plugins/__init__.py +++ b/dotbot/plugins/__init__.py @@ -1,3 +1,4 @@ from .clean import Clean +from .create import Create from .link import Link from .shell import Shell diff --git a/dotbot/plugins/create.py b/dotbot/plugins/create.py new file mode 100644 index 0000000..dc119da --- /dev/null +++ b/dotbot/plugins/create.py @@ -0,0 +1,53 @@ +import os +import glob +import shutil +import dotbot +import subprocess + + +class Create(dotbot.Plugin): + ''' + Create empty paths. + ''' + + _directive = 'create' + + def can_handle(self, directive): + return directive == self._directive + + def handle(self, directive, data): + if directive != self._directive: + raise ValueError('Create cannot handle directive %s' % directive) + return self._process_paths(data) + + def _process_paths(self, paths): + success = True + for path in paths: + path = os.path.expandvars(os.path.expanduser(path)) + success &= self._create(path) + if success: + self._log.info('All paths have been set up') + else: + self._log.error('Some paths were not successfully set up') + return success + + def _exists(self, path): + ''' + Returns true if the path exists. + ''' + path = os.path.expanduser(path) + return os.path.exists(path) + + def _create(self, path): + success = True + if not self._exists(path): + self._log.debug('Trying to create path %s' % path) + try: + self._log.lowinfo('Creating path %s' % path) + os.makedirs(path) + except OSError: + self._log.warning('Failed to create path %s' % path) + success = False + else: + self._log.lowinfo('Path exists %s' % path) + return success diff --git a/test/tests/create.bash b/test/tests/create.bash new file mode 100644 index 0000000..c5f084f --- /dev/null +++ b/test/tests/create.bash @@ -0,0 +1,23 @@ +test_description='create folders' +. '../test-lib.bash' + +test_expect_success 'run' ' +run_dotbot <