hercules-ci / flake-parts

❄️ Simplify Nix Flakes with the module system
https://flake.parts
MIT License
699 stars 38 forks source link

Declaring per-system functions as flake outputs #220

Open endgame opened 3 months ago

endgame commented 3 months ago

I ported nix-freeze-tree to flake-parts. It exports a function for freezing a derivation as a tree of fixed-output derivations and uses a native program to do this. Because I can't assign to lib in perSystem, I am forced to declare these functions in flake and use flake-utils' eachSystem to generate this function. Is there a better way to either:

  1. Emit per-system functions by setting them in perSystem, or
  2. Call an equivalent to eachSystem without having to go through flake-utils?

https://git.sr.ht/~jack/nix-freeze-tree/tree/343fd80a67db6f55cacc1961f60bbac91d96bbb6/item/flake.nix#L27-52 is what I am currently doing.

roberth commented 3 months ago
  1. Emit per-system functions by setting them in perSystem, or

Can be done by defining flake.lib.something using the withSystem module argument.

Example:

{ lib, withSystem, ... }: {
  perSystem = mkPerSystemOption {
    options.lib = mkOption { type = raw; internal = true; };
    config.lib.freeze = <...>;
  };

  flake.lib.freeze = drv:
    withSystem drv.system ({ config, ... }:
      config.lib.freeze drv
    );
}
  1. Call an equivalent to eachSystem without having to go through flake-utils?

You could define lib using perSystem, similar to how flake-parts does it for other attributes. The formatter.nix is a reasonable template for this, if you omit perInput, because the format of lib isn't standardized for arbitrary flakes. I'm not a big fan of doing it this way, because system attributes are bothersome.

(3?)

You could expose a flake-parts module that adds your library as a module argument. That way it can use the user pkgs, which can be something fancy, like a cross compiled package set.