Providing helper functions in and for a module

Some (of my) module options would benefit greatly from helper functions for defining option values. An example would be populating services.jupyterub.kernels, which can get quite verbose if you include things like wrapping in an FHS env or custom virtualenv management. Sure, types.submodule exists, but such a submodule is rather suitable for perfectly similar structures with just different values. Instead, something like this would be helpful:

{ pkgs, config, lib, ... }: {
  services.jupyterhub.kernels = {
    python3 = mkIpykernelWith { displayName="..."; systemPackages = [...]; ...};
    python3FHS = mkSelfManagedIpykernelInFHS { venDir="$HOME/.venv"; ... };
  };
}

Now how would I provide these helper functions mkIpykernelWith and mkSelfManagedIpykernelInFHS? These are specific to the jupyterhub module, so are no good fit for the general lib. Can one add a kind of lib overlay in a module that only gets activated if the module is enabled with enable=true?

config.lib?

Description

This option allows modules to define helper functions, constants, etc.
2 Likes

Thanks, just what I was looking for! :blush:

Just for the record (as config.lib’s documentation is… sparse…):

{ pkgs, config, lib, ... }: {
  options.myservice.enable = lib.mkEnableOption "my service";
  config = lib.mkIf config.myservice.enable {
    # Use this helper elsewhere with `config.lib.myservice.helper 1 2`
    #   πŸ‘‡πŸ‘‡πŸ‘‡πŸ‘‡     config.lib is an attrset of attrsets, so you must add one level, e.g. your service name
    lib.myservice.helper = a: b: a + b;
  };
}
3 Likes