What's the best way to add my own utility functions?

Over the process of building my configuration for several different hosts, and now fooling with NixOps, I’ve built up a collection of helpful utility functions.

The problem is, I haven’t found a good way to make them accessible in any sort of global way. I’d like to be able to add them to lib, say in lib.<my-namespace>.someUtilFunc. That doesn’t seem to be possible…any kind of assignment to lib fails.

I end up just doing:

let
  my-lib = import ../path/to/my-lib.nix
in { ... }

…in every file where I need the utils. That’s kind of annoying, and seems clumsy. Or, I just end up rewriting the same functions in several different places.

Is there a way to do what I’d like and just add them to lib somehow?

(It just occurred to me that I could import my-lib early on, and pass it around as a sister arg to lib…that also seems a bit awkward, though).

Use an overlay that does lib = super.lib // { my-namespace = import funcs.nix; }

2 Likes

I’m not personally familiar with the nuance of its usage, but you might also look at existing uses of extends and makeExtensible within nixpkgs:

I’m only passingly aware of it after seeing Henrik’s usage here:

Perfect, that helps! I’ll give it a shot. Thanks!

I tried putting this in my overlay, but I get an error:

# overlays/default.nix
 lib = super.lib // { pinpox = import ../utils; };
# utils/default.nix
{ pkgs, ... }:
{
  renderMustache = name: template: data:
    pkgs.stdenv.mkDerivation {
      name = "${name}";
      nativeBuildInpts = [ pkgs.mustache-go ];
      passAsFile = [ "jsonData" ];
      jsonData = builtins.toJSON data;
      phases = [ "buildPhase" "installPhase" ];
      buildPhase = ''
        ${pkgs.mustache-go}/bin/mustache $jsonDataPath ${template} > rendered_file
      '';
      installPhase = ''
        cp rendered_file $out
      '';
    };
  }
error: attribute 'pinpox' missing

       at /nix/store/kr41f702jaw14vzqz8q5pk5d7qaw8nj5-source/modules/default-desktop/default.nix:156:18:

          155|
          156|           text = lib.pinpox.renderMustache "nixcolors.lua" ./nixcolors.lua.mustache vars.colors;
             |                  ^
          157|

Could you clarify how to do this? How do I access my functions?

How do you use your overlays/default nix and what is its full content?

I pushed my current state to a new brach to clarify.

This is my overlay

I’m trying to add this function to lib, if possible with a custom namespace:

To test it, I’m trying to call it here but get the error pasted above:

The function itself works, using it like this works:

But I want to have all functions in ./utils available everywhere without importing it every time

Where are you loading/importing/applying the overlay?

Here:

I found a workaround that works, but would prefer to have this in an overlay still if possible, so I can use it everywhere nixos/home.nix at 301ada9b0ec3d2ba7d4b28047a2269f1306ed567 · pinpox/nixos · GitHub

In the commit matching that flake.nix the lib doesn’t exist at all in the overlay… Or am I misreading your config?

Sorry, wrong branch: Here: nixos/flake.nix at d4cd25ba4955a0fa05ccee4aaaac4d896c09bc7a · pinpox/nixos · GitHub

The way you do it makes pinpox a function taking an attrset with at least the pkgs attribute.

PS: in flakes I’d just provide a lib-output, specific to self.