How to Dotfiles
This chapter walks you through the typical bois workflow of managing a few dotfiles that are shared between some hosts.
It won’t go into too much detail, the idea is to get a feel for what working with bois looks like in practice.
Every topic that is touched in this guide also has its own chapter with more detailed documentation.
Note
The How to System Provisioning chapter covers the same workflow, but for provisioning your system.
Now let’s get to it. Let’s assume you have a laptop with whose hostname is milo, and you would like to manage your configuration files in ~/.config.
User mode
By default, bois determines its run mode from the user that calls it.
When run as a normal non-root user, it operates in user mode:
- Files are deployed to
~/.config. - No packages can be installed (yet).
- Service managers are run in user mode (e.g.
systemctlis called with--user)
Creating the bois directory
Everything bois manages lives in a single directory, the bois directory.
Let’s create this directory at a location where bois automatically discovers it (e.g. ~/.config/bois or ~/.config/dotfiles):
bois init ~/.config/bois
cd ~/.config/bois
Note
If you’d rather put it somewhere else, check out the Bois Config chapter.
All paths from here on are relative to this directory.
After running bois init, you’ll end up with this structure:
📁 traits/
│ 📂 base/
│ │ └ base.yml
📂 hosts/
│ 📂 milo/
│ │ milo.yml
│ │ └ vars.yml
└ bois.yml
The host’s config file lives inside the host’s directory at hosts/milo/milo.yml.
The important part for now is hosts/milo/.
Everything inside it (except the milo.yml config file and the vars.yml special file) is configuration that will be deployed for this host only.
Your first managed file
Let’s put a config file you already have under bois’ control like, for example, your alacritty config:
mkdir hosts/milo/alacritty
cp ~/.config/alacritty/alacritty.toml hosts/milo/alacritty/
That’s all there is to it.
Since you’re running as a normal user, bois runs in user mode and deploys to ~/.config by default (the target_directory).
Files in a host directory mirror their path relative to that target directory:
hosts/milo/alacritty/alacritty.toml will be deployed to ~/.config/alacritty/alacritty.toml.
Plan and deploy
bois plan is a dry-run that shows everything a deployment would do, without touching your system:
bois plan
Since we just copied the file, the source and the deployed file are identical and there’s nothing to do.
bois only ever touches things that actually changed.
So let’s change something!
Open hosts/milo/alacritty/alacritty.toml in the bois directory and tweak a value, for example the font size.
bois plan now shows a diff of exactly what would change on your system.
If you’re happy with it, apply the change:
bois deploy
That’s the basic workflow you’ll be using most of the time.
I.e. edit some files in the bois directory → bois plan → bois deploy
Safety features
In case some deployed (and thereby managed) file is edited on your host directly, it won’t just be overwritten.
bois compares the actual state of each managed file against the previous state from the last deployment.
If any changes are detected, bois warns you about non-adopted changes and only overwrites those changes if you explicitly say so:
These changes will be overwritten. Are you sure that's okay?
Nothing gets overwritten without you being notified about it. If you want to keep those changes, simply abort, adopt the changes into your bois directory and rerun the deployment.
Sharing config between hosts with traits
So far, everything lives in hosts/milo/ and is exclusive to your laptop.
But it would be nice to also have that alacritty config on your desktop.
That’s what traits are for: A trait is basically a bundle of configuration that any host can opt into.
The template generated by bois init already created a trait called base, and the generated hosts/milo/milo.yml already enables it:
# hosts/milo/milo.yml
traits:
- base
To move the alacritty config to the trait, simply run:
mv hosts/milo/alacritty traits/base/alacritty
If you were to now run bois init, nothing would change as milo opted into the base trait and as such, the file is still part of the configuration that’s active for milo.
Now, setting up configuration for your desktop with the name cleo boils down to:
- Adding a
hosts/cleo.yml, which also opts into thebasetrait. Sincecleobrings no files of its own (yet), a stand-alone config file without a host directory is all it needs:traits: - base - Cloning your bois directory on
cleoto a well-known path (e.g.~/.config/boisor~/.config/dotfiles). - Running
bois deploy.
Check the Trait Config chapter for everything else traits can do.
Removing files
To stop managing a file, just delete it from the bois directory.
The next bois deploy will notice the removal and delete the deployed file from your system.
Important
Directories will never be removed as long as they still contain files.
Also, directories aren’t removed by default. For that you have to set the following in your host/trait config:
cleanup:
directories: true
Managing hidden files
Some tools insist on dotfiles like ~/.bashrc, which are annoying to work with inside the bois directory, due to them being hidden.
To address this, files can carry their own configuration in a bois_config block inside the file itself. Most file format’s native comment syntaxes are supported:
hosts/milo/bashrc:
# bois_config
# target_path: ~/
# rename: .bashrc
# bois_config
alias ls='ls --color=auto'
target_path overrides the target directory, and rename adds that dot back to the filename, so that the file is deployed to ~/.bashrc.
The config block is also stripped during deployment.
Check out the File Configuration chapter to learn more and see all available options.
Templating
Sooner or later, shared configs may need small per-host adjustments, such as a bigger font size on a small laptop screen. For those cases, any file can be turned into a minijinja (Jinja2-style) template.
To enable templating, the bois_config block has a template parameter.
For example, the shared alacritty config from earlier could looks something like this:
# traits/base/alacritty/alacritty.toml
# bois_config
# template: true
# bois_config
[font]
{% if host == "milo" %}
size = 14
{% else %}
size = 11
{% endif %}
There are quite a few pre-set global variables and you can also define your own variables in the host’s vars.yml or use secrets from your password manager.
The delimiters {{/}}, {#/#} and {%/%} can also be individually overwritten so that they don’t interfere with your configuration file format.
See the Templating chapter for more information.
User service
In user mode, bois can also manage enabled services, such as systemd user services.
This is done via the services configuration in either a host config, a trait config or a dir.yml and look like this:
# hosts/milo/milo.yml
services:
systemd:
- ssh-agent
Important
By default, services are only enabled, not started.
Once this entry is removed from the host configuration, the ssh-agent service will be stopped and disabled.
For detailed info, check out the Service Management chapter.
I hope this gives you a good idea what you can do with bois :)