Table of Contents
Introduction
After about 1 year, I came back to Nix as one of my main tools for my workflow. In case, you can see my entire macOS configuration, written in Nix, here.
After having to change MacBook devices twice during the end of the last year, I really missed Nix on my daily usage, where I need to setup my config every time, instead of just running a command. That’s why I’m using Nix again after some period without it.
Now, I reached a specific scenario last week, where I need to write a specific overlay for a tool. In my case, beanprice. I’m using beancount, as my daily-driven tool to track my finances, and I’d like to track the value of my stocks in an easier way, instead of having to manually adding it everytime.
Doing some search, I discovered that the beancount’s brewfile didn’t install this binary for me. After trying the
nixpkgs
version of this binary, I discovered another thing: with that version, it comes with the bean-price
binary, but it comes with an old version, where it didn’t contain a specific module to fetch some of the stock
prices that I’d like to fetch (more specifically, the alphavantage source).
For that reason, it seems to be a good argument to have an overlay for that. That’s what I did, and was my first
time writing an overlay from scratch.
Writing the Module File
The overlays on Nix are a kind of function, it gives for us the ability to provide some overriding some specific configurations for a given module, package or anything else that your creativity let you think about.
In my case, what should I be doing? Writing a new overlay that would add a new package called bean-price
into all Python
packages modules. For that, I used this Python section as my reference to do that.
That’s the output of what I did:
What we’re doing here? We’re calling the buildPythonPackage
function accordingly to the Python interpreter. And will run four steps,
accordingly to this documentation here: buildPhase
, installPhase
, postFixup
and installCheck
.
With that, we will be able to build and have our own binary of a given package, that, in case, we’re fetching all those
informations based on the src
with the fetchPypi
function.
Finally, we had this overlay done, now, we need to let both nixpkgs
and home-manager
know about that.
Consuming the Overlays
In my opinion, as a good pattern for that, I like to have the overlay being “exported” on a main file.
For my config, I wrote a overlays/default.nix
that does it for me:
Now, what I’m doing is: getting all my overrides related to python and overriding it on pythonPackagesExtensions
.
Which basically override it for every Python extension (python3
, python
, python39
, python312
, etc).
Now, we just need to add it on the imported nixpkgs
and on home-manager
, to guarantee that everything is good.
From another post that I wrote last year, where I teach how to install Nix + nix-darwin + home-manager on macOS. My flake.nix
config was like that:
flake.nix
config without overlays
Now, we will need to adjust it in two parts to guarantee that everything is good:
With that, you will be able to add both overlays to nixpkgs
side, so you can add the overlays
at a system-level, for NixOS, nix-darwin, or any place you’re using it. And, inheriting overlays
at the nixpkgsConfig
at L16, will let you use the overlay in home-manager
level.
Now, in your home-manager config, you can do something like that:
Solving Conflicts on Overlays
One issue that I had on this bean-price
overlay is, as I said, the nixpkgs
version of the beancount
adds the bean-price
binary. So, both packages are conflicting to decide which of the binaries should
be chosen.
The first solution that I saw, was adding a meta.priority = 10;
on the overlay. But haven’t success, it
still getting the outdated version of the bean-price
binary. In that case, I did a different approach:
I added an overlay to beancount
package too, where add a step on postInstall
that just remove
the binary related to /bin/bean-price
. With that, everything works as expected.
DISCLAIMER!
I didn’t find any other way to solve this issue. Everyone that knows a better, elegant approach to do it, feel free to reach me out. I would really like to have a better way to solve this.
Also, if I find something, I come back to this post and update it accordingly to what I find.
Conclusion
This is just a brief tour around how you can approach to write your first overlay. And a good introduction to understand how useful is Nix at all, you can do a lot of things or extend things that you already had as you want. It’s a powerful tool in the right hands.