this post was submitted on 25 May 2024
10 points (100.0% liked)

Nix / NixOS

1738 readers
1 users here now

Main links

Videos

founded 1 year ago
MODERATORS
 

My solution:

let

  nixFilesInDirectory = directory:
    (
      map (file: "${directory}/${file}")
      (
        builtins.filter
          (
            nodeName:
              (builtins.isList (builtins.match ".+\.nix$" nodeName)) &&
              # checking that it is NOT a directory by seeing
              # if the node name forcefully used as a directory is an invalid path
              (!builtins.pathExists "${directory}/${nodeName}/.")
          )
          (builtins.attrNames (builtins.readDir directory))
      )
    );

  nixFilesInDirectories = directoryList:
    (
      builtins.concatMap
        (directory: nixFilesInDirectory directory)
        (directoryList)
    );
  # ...
in {
  imports = nixFilesInDirectories ([
      "${./programs}"
      "${./programs/terminal-niceties}"
  ]);
  # ...
}

snippet from the full source code: quazar-omega/home-manager-config (L5-L26)

credits:


I'm trying out Nix Home Manager and learning its features little by little.
I've been trying to split my app configurations into their own files now and saw that many do the following:

  1. Make a directory containing all the app specific configurations:
programs/
└── helix.nix
  1. Make a catch-all file default.nix that selectively imports the files inside:
programs/
├── default.nix
└── helix.nix

Content:

{
  imports = [
    ./helix.nix
  ];
}
  1. Import the directory (picking up the default.nix) within the home-manager configuration:
{
  # some stuff...
  imports = [
    ./programs
  ];
 # some other stuff...
}

I'd like to avoid having to write each and every file I'll create into the imports of default.nix, that kinda defeats the point of separating it if I'll have to specify everything anyway, so is there a way to do so? I haven't found different ways to do this in various Nix discussions.


Example I'm looking at: https://github.com/fufexan/dotfiles/blob/main/home/terminal/default.nix

My own repository: https://codeberg.org/quazar-omega/home-manager-config

you are viewing a single comment's thread
view the rest of the comments
[–] [email protected] 3 points 5 months ago (1 children)

Oh, right, monoids! Yes, you understand correctly.

A monoid is a collection of objects that has some sort of addition and zero. (Depending on your maths background, it might equivalently have some sort of multiplication and unit.) Addition must be associative, and addition with zero must not have any effect. Monoids let us think of a system as built from a sequence of operations; each operation adds to the system, preparing its state incrementally.

Sometimes monoids are commutative, which means that the order of additions is irrelevant to the result. Commutative monoids let us think of a system as built from a collection of operations without worrying about the order in which those operations are applied.

NixOS modules (and HM modules, etc.) are commutative monoids. The zero is {}. The module system lets options declare their own monoids which ride along, like my example of allowedTCPPorts. Because we can combine sets of port numbers (with set union) and get more sets, we can factor a set of ports into many smaller subsets and put each one in their own file. Here's my shortest module, for an internal Docker registry, docker-registry.nix:

{
  networking.firewall.allowedTCPPorts = [ 5000 ];
  services.dockerRegistry = {
    enable = true;
    enableGarbageCollect = true;
  };
}
[–] [email protected] 2 points 5 months ago

I don't have much of a math background, but that makes a lot of sense when talking about the application here! I like the explanation