Setting up your development environment can be a lengthy ordeal. We have tools, configurations, installed software, preferred keybindings, and so many little details you come to ignore most of the time. This is probably most true for Linux users, but still holds for other systems. Our value comes from our ability to be productive at the keyboard and it can be frustrating when things aren't setup properly. How we maintain our environments is a deeply personal endeavor and you probably don't hear much about it on the internet because there's not one true way to handle it. This post is about how I handle it for my stystems.
If I had all the time in the world, I'd probably put my entire system under some sort of version control. Maybe it'd be with nix or guix. These projects aim to provide programming constructs for installing and maintaining dependencies in ways that are controlled and unified. In principle these are how I think of the needs of my system. I need repeatable, scriptable, maintainable, predictable, and consistent environments that can evolve and grow with me. Who wouldn't want all that?
Heck, I've even tried managing my system with Ansible. It worked mostly. Well, as long as I could stick to my guns and try to only use the Ansible playbooks for system management. Inevitably, something would force me to the path of least resistance. I could just download the latest Zoom
.deb package or I could write a script to get the latest version and then install that. The latter has the benefit of always being at the latest without any manual intervention. I wouldn't need to re-install it manually next time I set up a new system.
Maybe it's out of laziness, but maybe its just accepting insurmountable defeat to the chaotic fragmentation of the Linux application ecosystem, I just had to go the other direction. Instead of fixing everything to my favorite fonts and colors, I just accept the system defaults. Instead of tweaking to the height of productive minimalism, I just install VSCode. Instead of Arch or some other DIY distroy, I just stick with mainstream Ubuntu. Then it's compromises all the way down.
It's sad, but it's kind of a relief too. I'd rather deal with the occasional gnome crash on a monthly basis than have to troubleshoot why my dwm setup no longer works with my current GPU. The whole point of all of this is to see my system as an evolving growing thing, but if the tools routinely fail to keep up with the hardware I need to use, then I cannot rely on those tools.
Minimal Dotfiles in Git
The main things we need to track are:
- ssh keys, particularly to github/gitlab
- installer script
- config files
- systemd timers/units for background tasks
- assets like desktop backgrounds
It's not a bunch and it's mostly aesthetic, but it's stuff I find valuable to have around. We track everything in git, so it's kind of up to you to add/remove whatever you want across your development environments. I like collecting pleasing desktop backgrounds that rotate regularly. It makes me happy, so it's part of my setup.
I took my strategy from this article by Atlassian. I'm not going to rewrite it, but the gist is that you're basically creating a git repository of the files and directories that you want to track in your home directory. That's really simple. They use a bare repository and some fancy shell aliasing to make it more convenient to manage, but you're only using git. You don't have to learn new tools or languages.
Here's how I do a fresh install:
git clone --bare https://gitlab.com/petersooley/dots.git ~/.dots alias dots='/usr/bin/git --git-dir=$HOME/.dots/ --work-tree=$HOME' dots config --local status.showUntrackedFiles no dots checkout dots remote set-url origin email@example.com:petersooley/dots.git ./install.sh cd .ssh make unlock
- Clone my config files into
~/.dots. This is the bare repo that tracks changes to the files I want to track.
- Make a shell alias called "dots" so that instead of using
git commit -m "..."I use
dots commit -m "..."when working with tracked config files. This is overkill. I don't have any other git repos in my home directory. There's no need to worry about overlapping or conflicting repos. But, hey, it's fun to imagine I have a specialized tool that manages my configs. Note that this just makes a temporary alias. The permanent alias is stored in my shell configs (also tracked).
- I configure git to not tell me about untracked files for which there will be a lot. Home directories, no matter what I do, become a junkyard of configs, app states, and other files that I don't care about. This is a really nice way to handle it.
- I update the git remote URL to the SSH variation so that I can authenticate changes back to gitlab using standard SSH keys.
- I run the installer file which is just a basic shell script with a few convenience functions. Again, this only gets me started, but isn't an attempt to provide everything I might need to use. You can see the full thing here.
- Then I unlock my SSH keys. These were encrypted for storage in git. This is actually really pleasant. Now I can track keys somewhere central without worrying about losing them if my machine fails. To see how this works, check out the makefile here. (Hot tip: makefiles are a great way to provide shortcuts to long, obscure, or complex commands that are hard to remember.)
That's it! In summary, we lowered our expectations and then did the bare minimum to get to a working system. 😏
Bonus: Rotating Backgrounds
Okay, so if you explored my dotfiles, you'll have seen this line in my installer script:
systemctl enable --user --now ~/.config/systemd/user/bg-changer.timer
This starts and enables a systemd timer for changing my desktop backgrounds on a regular interval. It's a trivial task, but leaning on gnome shell extensions for this functionality has been surprisingly difficult with the seemingly transient nature of gnome extension management.
Here is what those systemd files look like:
# ~/.config/systemd/user/bg-changer.service [Unit] Description="Background Changer" [Service] ExecStart=/home/peter/bin/bg-changer.sh
# ~/.config/systemd/user/bg-changer.timer [Unit] Description="Timer to change backgrounds" [Timer] OnCalendar=weekly Unit=bg-changer.service [Install] WantedBy=default.target
And the shell script that gets called every week:
# Changes the desktop background to a random file in the ~/.config/backgrounds directory ls ~/.config/backgrounds | sort -R | tail -n 1 | while read file; do gsettings set org.gnome.desktop.background picture-uri "file:///home/peter/.config/backgrounds/$file" done
It works like a charm.