Dotfiles management with dotdrop

Managing dotfiles is a pain, especially when working on multiple hosts (your host at home, your host in the office, your cloud VMs, etc), I was therefore looking for a solution that would allow me to save my dotfiles and manage them easily.

If you don't know what this is about, dotfiles are all those configuration files you keep in your $HOME usually in a hidden file (starting with a dot, therefore dotfile).

There exist several smart solutions on how to save your dotfiles, here are some solutions I almost adopted:

Check the page Github does dotfiles for more tools on dotfiles.

Those solutions are awesome but didn't exactly match what I needed. Here are some of the requirements I had:

  • I want my dotfiles to be versioned (preferably with git).
  • I want to store each dotfile only once (no multiple repositories, no duplicate, ...).
  • I want to be able to easily compare my local version with the stored one.
  • I want my management tool to handle multiple profiles (for different hosts: home, desktop, VM, ...).
  • I want different versions of same dotfile to be generated depending on where I want it deployed.

Most of the tools out there are designed for people using either a single host or the same set of dotfiles on all their hosts. One exception is ConMan which is a nice tools that uses M4 macro processor to generate the dotfiles. I found the idea really interesting but was missing the possibility to compare the local dotfiles with the ones stored. Moreover I wanted to code something ;-)

I thus decided to implement my own tool to manage my dotfiles. I went for Python3 and needed a templating engine to parse and generate different versions of the same files based on macros. This led me to jinja2, a well recognized templating engine for python.

The resulting tool is dotdrop ! Dotdrop's goal is to help you manage your dotfiles by storing them once and deploying them on different hosts the way you want them to be.

Dotdrop keeps all its configs in a config file (config.yaml) where all the different dotfiles are listed as well as the profiles where they should be deployed. It thus gives the ability to have different sets of dotfiles on different hosts. For example you would install all your dotfiles on your home laptop but would have only a subset for your vserver (a stripped down version of vimrc for example along with some other basic dotfiles: tmux, etc). Also it leverages the power of jinja2 by allowing to template your dotfiles such that the same stored dotfile could be generated differently depending on where it is to be installed.

It has nice features like the ability to import your dotfiles automatically and to compare the dotfiles you have currently on your host with the ones stored on dotdrop; such that if you change your dotfiles from your desktop, you are able to see what has changed and how you need to update it on dotdrop to reflect what you want.

Let's take an example: you want to manage the following two files using dotdrop:

  • $HOME/.xinitrc: it is to be deployed on both your home and your office host but with two different versions of the file.
  • $HOME/.vimrc: it only needs to be deployed on your home host.

A template for jinja2 needs to be set up for .xinitrc such that different versions of that file are installed using dotdrop (no worry it's straight forward and doesn't need much to be efficient):

#!/bin/bash

# load Xresources
userresources=$HOME/.Xresources
if [ -f "$userresources" ]; then
      xrdb -merge "$userresources" &
fi

# launch the wm
{%@@ if profile == "home" @@%}
exec awesome
{%@@ elif profile == "office" @@%}
exec bspwm
{%@@ endif @@%}

When the above dotfile is deployed it will result in two different file depending if you are running it from the home profile or the office one (see the if branch above). Jinja2 templating engine will choose the right branch and drop the rest such that the resulting file is a clean dotfile.

Moreover using the config file you are able to specify what needs to be installed with which profile:

config:
  backup: true
  create: true
  dotpath: dotfiles
dotfiles:
  f_xinitrc:
    dst: ~/.xinitrc
    src: xinitrc
  f_vimrc:
    dst: ~/.vimrc
    src: vimrc
profiles:
  home:
  - f_xinitrc
  - f_vimrc
  office:
  - f_xinitrc

Hope this tool will be useful to some. If you have issues using it or want to contribute, feel free to do a PR or create an issue on dotdrop's page on github.

Link to the project on github: dotdrop

Happy ricing !