Managing dotfiles
Because there is no place like $HOME
In this post, we will see how we can easily manage our personal
configuration files - a.k.a. dotfiles.
Yeah dotfiles, named after there common ~/.my_config
form, you know,
all of those small configuration files lying across our $HOME.
Because there is no place like $HOME
Because we are spending so much time on our machine, be it for work or for fun (both at the same time if you are lucky), we love to tweak our environment to our taste and needs. Change the UX, create some aliases, use some dark theme and what not, most if not all of these are saved in some configuration files somewhere. And since we spent so much time making a home for ourselves, wouldn’t it be great if we could quickly set it up again on a different computer? Change the house but keep the furniture and decorations? This is precisely what we are going to set up here.
Picking a dotfiles manager
Looking on the web for a dotfiles manager, you may find many of them - see a whole list of them here. Most of them work off the same principles, being a small set of utils to help manage our dotfiles. Management includes most importantly versioning, often through git and the installation of the files to their correct location as they are more than often expected to be found at a given path. You may want to give a look at the aforementioned list of managers and pick one that best answers your needs and expectations. Note that many are interchangeable.
In this post we settled using homeshick
.
There are two main reasons for this choice.
Firstly, it is entirely written in bash, making it usable virtually anywhere.
Secondly, it ‘installs’ dotfiles on our system using symlinks rather than
hard copies. The files thus exist in a single place.
Some other nice features includes, being git-based, being cli-based,
supporting multi dotfiles repos.
It has to be noted tho that the project is not in a really active
development and not very feature rich compared to other solutions.
It is a thin-layer that does the job.
Alright so how do we get started?
Building our castle
homeshick
relies around the concept of castles which are nothing
more than git repositories.
A castle contains all of our dotfiles which are organized with the same
layout as our home directory.
But before building our castle, we need to install the appropriate tool.
To install homeshick
, nothing easier, we simply clone its repository
in our home:
git clone https://github.com/andsens/homeshick.git $HOME/.homesick/repos/homeshick
And we are done. Now to use it, we only have to source it,
e.g. directly in our .bashrc
,
echo "source ~/.homesick/repos/homeshick/homeshick.sh" >> ~/.bashrc
We can also source its tab completion tool to ease our life,
echo "source ~/.homesick/repos/homeshick/completions/homeshick-completion.bash" >> ~/.bashrc
Alright, we are done with the installation, let us start creating the said castle.
First we create a new local git repo through homeshick
cli tool,
$ homeshick generate dotfiles
This creates an empty castle named ‘dotfiles’ in
~/.homesick/repos/dotfiles/
.
To populate our castle with a dotfile, we make use of the ’track’ command:
homeshick track {castle} {dotfile}
To track our first file, say e.g. .bashrc
, we simply issue,
homeshick track dotfiles ~/.bashrc
The command copies the file in our castle at
~/.homesick/repos/dotfiles/home/.bashrc
and replaces the original file
with a symlink to the copy.
Now all we have to do is to commit our change and save our castle online,
To move to our local repository, we enter,
$ homeshick cd dotfiles
and we can now use the usual git commands,
git add .
git commit -m 'add .bashrc'
Let us save our castle online, e.g. on GitHub,
git remote add origin git@github.com:user/dotfiles.git
git push -u origin master
We may now repeat this operation for each and every configuration file we would like to save. With our castle safely backed up online, we will now see how we can quickly set up our environment on a new machine.
Quickly setting up a new machine
Whether you bought a new computer or nuked your old hardware with a
fresh new distro, you will now witness the true power of homeshick
.
To install our cosy environment on a fresh distro, all we have to do is,
Install
homeshick
git clone https://github.com/andsens/homeshick.git $HOME/.homesick/repos/homeshick source ~/.homesick/repos/homeshick/homeshick.sh
Import our castle
homeshick clone git@github.com:user/dotfiles.git
Let
homeshick
works its magichomeshick link dotfiles
Voila! Home sweet home.
Of course this post is only a quick overview of a given dotfiles manager.
I won’t detail here all of its options and features
and let you discover them for yourself in its wiki.
As mentioned previously many dotfiles managers rely on a git repository and the
same layout as homeshick
so you can get started with it and later move to
another one which better fits your needs.
At this point you may be wondering if this is really worth it given that you probably install a fresh distro every 2 years or so and completely change hardware even less frequently. Well, fellow developer, aren’t you using containers? If not, you definitely should consider it and check this other post where I detail a development workflow for ROS in LXD.
Disposable tiny home
If you are like me, trying your best to keep a tidy laptop while
messing around with plenty of different software toys,
then you may have had one of these days during which you spawn several containers.
Containers in which we don’t have our sweet bash aliases;
on our very own machine!
But thanks to homeshick
we can now start up a fresh
container and have it mimic $HOME
in a matter of seconds!
Let me demonstrate it for you with a LXD container,
lxc launch ubuntu:20.04 tmp-20-04
lxc profile add castle tmp-20-04
lxc ubuntu tmp-20-04
Ahhh, what a cozy tiny disposable home!
That seemed too easy to you? Alright I confess, I used some of my own aliases here. But isn’t it what this whole post is about? Note that the above 3 lines really boils down to,
$ lxc launch ubuntu:20.04 tmp-20-04
$ lxc exec tmp-20-04 -- sudo --login --user ubuntu
...
$ git clone https://github.com/andsens/homeshick.git $HOME/.homesick/repos/homeshick
$ source ~/.homesick/repos/homeshick/homeshick.sh
$ homeshick clone git@github.com:user/dotfiles.git
$ homeshick link dotfiles
With this example,
I hope that I managed to offer you a glimpse at the power of homeshick
(and more generally of dotfiles managers),
especially when coupled to a containerized workflow.
Before closing this post, let me give you one last tip.
Because we made our containerized workflow rather seamless with our
host, it can be easy to lose track of which shell is in a container and which
is not. To differentiate them, add the following to your .bashrc
:
function prompt_lxc_header()
{
if [ -e /dev/lxd/sock ]; then
echo "[LXC] ";
fi
}
PS1='$(prompt_lxc_header)'$PS1
When used in a container, a shell prompt in the said container will now look something like:
[LXC] ubuntu@tmp-20-04:~$
No more confusion 👍