Skip to content

Example of cross-cutting concern in a single flake-module. #1

@vic

Description

@vic

Hey @mightyiam, thanks for creating the dendritic pattern and this repo dedicated to it.

I'm thinking on adding a bit more of documentation about why this pattern is useful, perhaps some code, not intended to be actually used, but more on the lines of an example of cross-cutting concerns (or a feature) across different nix module classes, and how the dendritic approach allows grouping these different module classes by their single purpose.

I was thinking something along these lines (pseudo-code not tested):

# /modules/features/example.nix
{ inputs, lib, config, ... }:
let

  #  a custom package is defined (suppose this package has some os-level requirement, like firewall rules or any other os config requirement)
  perSystem = { pkgs, ...}: {
      packages.example = pkgs.mkDerivation {
         src = inputs.example-program-src; 
     };
  };

  #   - nixos, darwin modules provide os-level configurations 
  flake.modules.nixos."feature/example" = {
       # a nixos systemd unit or some other os-level conf
  };

  flake.modules.darwin."feature/example" = {
       # a darwin launch agent or some other os-level conf
  };

  #  - homeManager module that adds the package to an user environment and ~/.config for it to work
  flake.modules.homeManager."feature/example" = {pkgs, ...}: {
     # things like shell-aliases, shell-completion and other home-level behaviour for this feature.
     home.packages = [ inputs.self.packages.${pkgs.system}.example ];
     home.file.".config/example/settings".text = "port = ${conf.port}";
  };

  conf = config.features.example;
  opts.feature.example.enable = lib.mkEnableOption "Example feature";
  opts.feature.example.port = lib.mkOption {
     type = lib.types.port;
     default = 12345;
  };

in 
{
  options = opts;
  config = lib.mkIf conf.enable  { inherit flake perSystem; };
}

of course it does not have to be about firewall rules, any other os-level example should work, I want to illustrate how the flake-parts module can expose an option that enables (and exposes functionality) across os/home/flake levels.

any input on this idea is more than welcome :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions