From e04ad54c6ca8fb218fb058795290c36c084e96f0 Mon Sep 17 00:00:00 2001 From: Ziirish Date: Thu, 31 May 2018 22:33:57 +0200 Subject: [PATCH] adding support for pre/post actions --- README.md | 43 +++++++++++++++++++++++++++++++++++++++++++ dotdrop/config.py | 30 ++++++++++++++++++++++++++---- dotdrop/dotdrop.py | 28 ++++++++++++++++++++-------- dotdrop/dotfile.py | 2 +- 4 files changed, 90 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 767dae7..949f64b 100644 --- a/README.md +++ b/README.md @@ -290,6 +290,49 @@ Thus when `f_vimrc` is installed, the command `vim +VundleClean! +VundleInstall +VundleInstall! +qall` will be executed. + +Sometimes, you may even want to execute some action prior deploying a dotfile. +Let's take another example with +[vim-plug](https://github.com/junegunn/vim-plug): + +```yaml +actions: + pre: + vim-plug-install: test -e ~/.vim/autoload/plug.vim || (mkdir -p ~/.vim/autoload; curl + -fLo ~/.vim/autoload/plug.vim https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim) + vim-plug: vim +PlugInstall +qall +config: + backup: true + create: true + dotpath: dotfiles +dotfiles: + f_vimrc: + dst: ~/.vimrc + src: vimrc + actions: + - vim-plug-install + - vim-plug +profiles: + home: + dotfiles: + - f_vimrc +``` + +This way, we make sure [vim-plug](https://github.com/junegunn/vim-plug) +is installed prior deploying the `~/.vimrc` dotfile. + + +Note: You can also define `post` actions like this: + +```yaml +actions: + post: + some-action: echo "Hello, World!" >/tmp/log +``` + +If you don't specify neither `post` or `pre`, actions will be executed +after dotfiles deployment (which is equivalent to `post`). + ## Use transformations Transformation actions are used to transform a dotfile before it is diff --git a/dotdrop/config.py b/dotdrop/config.py index 13eae00..ca265fd 100644 --- a/dotdrop/config.py +++ b/dotdrop/config.py @@ -25,6 +25,8 @@ class Cfg: # key actions key_actions = 'actions' + key_actions_pre = 'pre' + key_actions_post = 'post' # key transformations key_trans = 'trans' @@ -101,12 +103,26 @@ class Cfg: def _parse_actions(self, actions, entries): """ parse actions specified for an element """ - res = [] + res = { + self.key_actions_pre: [], + self.key_actions_post: [], + 'actions': [] + } for entry in entries: - if entry not in actions.keys(): + key = 'actions' + action = None + if self.key_actions_pre in actions and entry in actions[self.key_actions_pre]: + key = self.key_actions_pre + action = actions[self.key_actions_pre][entry] + elif self.key_actions_post in actions and entry in actions[self.key_actions_post]: + key = self.key_actions_post + action = actions[self.key_actions_post][entry] + elif entry not in actions.keys(): self.log.warn('unknown action \"{}\"'.format(entry)) continue - res.append(actions[entry]) + else: + action = actions[entry] + res[key].append(action) return res def _complete_configs(self): @@ -124,7 +140,13 @@ class Cfg: if self.key_actions in self.content: if self.content[self.key_actions] is not None: for k, v in self.content[self.key_actions].items(): - self.actions[k] = Action(k, v) + if k in [self.key_actions_pre, self.key_actions_post]: + for k2, v2 in self.content[self.key_actions][k].items(): + if k not in self.actions: + self.actions[k] = {} + self.actions[k][k2] = Action(k2, v2) + else: + self.actions[k] = Action(k, v) # parse all transformations if self.key_trans in self.content: diff --git a/dotdrop/dotdrop.py b/dotdrop/dotdrop.py index e939468..e708953 100644 --- a/dotdrop/dotdrop.py +++ b/dotdrop/dotdrop.py @@ -87,16 +87,20 @@ def install(opts, conf): diff=opts['installdiff'], debug=opts['debug']) installed = [] for dotfile in dotfiles: + if dotfile.actions and Cfg.key_actions_pre in dotfile.actions: + for action in dotfile.actions[Cfg.key_actions_pre]: + LOG.dbg('executing pre action {}'.format(action)) + action.execute() LOG.dbg('installing {}'.format(dotfile)) if hasattr(dotfile, 'link') and dotfile.link: r = inst.link(dotfile.src, dotfile.dst) else: src = dotfile.src tmp = None - if dotfile.trans: + if 'actions' in dotfile.trans and dotfile.trans['actions']: tmp = '{}.{}'.format(src, TRANS_SUFFIX) err = False - for trans in dotfile.trans: + for trans in dotfile.trans['actions']: LOG.dbg('executing transformation {}'.format(trans)) s = os.path.join(opts['dotpath'], src) temp = os.path.join(opts['dotpath'], tmp) @@ -115,11 +119,19 @@ def install(opts, conf): tmp = os.path.join(opts['dotpath'], tmp) if os.path.exists(tmp): remove(tmp) - if len(r) > 0 and len(dotfile.actions) > 0: - # execute action - for action in dotfile.actions: - LOG.dbg('executing action {}'.format(action)) - action.execute() + if len(r) > 0: + if 'actions' in dotfile.actions: + actions = dotfile.actions['actions'] + # execute action + for action in actions: + LOG.dbg('executing action {}'.format(action)) + action.execute() + if Cfg.key_actions_post in dotfile.actions: + actions = dotfile.actions[Cfg.key_actions_post] + # execute action + for action in actions: + LOG.dbg('executing post action {}'.format(action)) + action.execute() installed.extend(r) LOG.log('\n{} dotfile(s) installed.'.format(len(installed))) return True @@ -155,7 +167,7 @@ def compare(opts, conf, tmp, focus=None): for dotfile in selected: LOG.dbg('comparing {}'.format(dotfile)) - if dotfile.trans: + if 'actions' in dotfile.trans and dotfile.trans['actions']: msg = 'ignore {} as it uses transformation(s)' LOG.log(msg.format(dotfile.key)) continue diff --git a/dotdrop/dotfile.py b/dotdrop/dotfile.py index 85e2e69..09b8eef 100644 --- a/dotdrop/dotfile.py +++ b/dotdrop/dotfile.py @@ -8,7 +8,7 @@ represents a dotfile in dotdrop class Dotfile: def __init__(self, key, dst, src, - actions=[], trans=[], link=False): + actions={}, trans={}, link=False): # key of dotfile in the config self.key = key # where to install this dotfile