hacker / welder / mechanic / carpenter / photographer / musician / writer / teacher / student

Musings of an Earth-bound carbon-based life form.

# There's no place like ~

For some of us who use more than one machine on a daily basis there is a certain amount of friction that we routinely encounter. For starters, there is the question of “which machine am I even on?” that we often solve using customized shell prompts or other visual cues. Then, there is the follow-up question of “does the tool I want to use exist on this particular machine?”. Even if the answer is “yes”, it doesn’t mean that it is configured the same way, or with the correct variation, etc. This problem is largely solved by using some tool that manages your configuration files (sometimes referred to as “dotfiles”), of which there are many. The simple fact that there are so many tools like this tells you that it is not an uncommon problem amongst users; each one functions in a slightly different way that mean some users prefer it to the alternatives (for me, currently, this is chezmoi).

### Dotfiles are not programs

This solves a certain set of problems, namely the job of getting your configuration files synchronized between machines (usually with the help of source control like GitHub). However, the configurations themselves are sometimes only valid for a given version of a program, with some specific set of features, which is outside of the purview of a dotfile management tool. And rightly so, the job of these tools is to help you keep your configuration safe and reproducible should you have to move to a new machine or clone your configuration.

However, this does not solve the underlying problem, one of consistent user environments, only provides us with ways to make it a bit less painful. Given the right set of constructs, one can cobble together something resembling a consistent user environment through scripting and other hacks (as I have with chezmoi in combination with brew and miniforge) but it’s definitely a bit fragile and requires a certain discipline to ensure that you only edit your configuration files through the tooling and only install new packages through your home-baked bootstrapping scripts.

### In which something Rube Goldberg would be proud of is born

edit_dotfiles takes a list of files, invokes chezmoi edit on each of them in turn, and then adds them to git with a simple commit message. Running commit invokes a pre-commit hook that does two things: generates my chezmoi data file (with my per-machine / per-environment config data such as e-mail address) and then runs chezmoi apply. chezmoi apply in turn uses the config data and the templates to render the actual dotfiles on my system and then invokes any run_ scripts in the repository. One of these will run homebrew bundle which will install any homebrew packages that are missing. And, because these happen in a pre-commit hook, if they fail then the changes won’t get committed (and therefore not pushed)

So the flow looks something like this:

## Making it work

function edit_dotfiles() {
if (( $# == 0 )) then echo usage: edit_dotfiles path ...; fi for i; do chezmoi edit$i
echo "Committing changes to $i..." ( cd$HOME/.local/share/chezmoi && git add . && git commit -m "Update to $i") ( cd$HOME/.local/share/chezmoi && git push origin main)
done
}