drv-parts

drv-parts Link to heading

This is experimental, use with care!

drv-parts replaces callPackage, override, overrideAttrs, ... as a mechanism for configuring packages. It makes package configuration feel similar to NixOS system configuration.

This is an implementation of ideas first drafted at DavHau/pkgs-modules.

It is recommended to use drv-parts through flake-parts (see examples/flake-parts).

There is also support for flake-less usage (see examples/no-flake).

Funding by NLNet Link to heading

drv-parts was funded as part of the dream2nix project through the NGI Assure Fund, a fund established by NLnet with financial support from the European Commission’s Next Generation Internet programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 957073. Applications are still open, you can apply today.

Why Modules? Link to heading

Declaring derivations as modules solves a number of issues. For more details on the problems, visit DavHau/pkgs-modules. Also I recommend watching @edolstra ’s talk about this topic.

Benefits Link to heading

No more override functions Link to heading

Changing options of packages in nixpkgs can require chaining different override functions like this:

{
  htop-mod = let
    htop-overridden = pkgs.htop.overrideAttrs (old: {
      pname = "htop-mod";
    });
  in
    htop-overridden.override (old: {
      sensorsSupport = false;
    });
}

… while doing the same using drv-parts looks like this:

{
  htop-mod = {
    imports = [./htop.nix];
    name = lib.mkForce "htop-mod";
    flags.sensorsSupport = false;
  };
}

See htop module definition here.

Type safety Link to heading

The following code in nixpkgs mkDerivation mysteriously skips the patches:

mkDerivation {
  # ...
  dontPatch = "false";
}

… while doing the same using drv-parts raises an informative type error:

A definition for option `[...].dontPatch' is not of type `boolean' [...]

Catch typos Link to heading

The following code in nixpkgs mkDerivation builds without openssl_3.

mkDerivation {
  # ...
  nativBuildInputs = [openssl_3];
}

… while doing the same using drv-parts raises an informative error:

The option `[...].nativBuildInputs' does not exist

Environment variables clearly defined Link to heading

drv-parts requires a clear distinction between known parameters and user-defined variables. Defining SOME_VARIABLE at the top-level, would raise:

The option `[...].SOME_VARIABLE' does not exist

Instead it has to be defined under env.:

{
  my-package = {
    # ...
    env.SOME_VARIABLE = "example";
  };
}

Package options documentation Link to heading

Documentation similar to search.nixos.org can be generated for packages declared via drv-parts.

This is not yet implemented.

Package blueprints Link to heading

With drv-parts, packages don’t need to be fully declared. Options can be left without defaults, requiring the consumer to complete the definition.

For example, this can be useful for lang2nix tools, where src and version are dynamically provided by a lock file parser.

Freedom of abstraction Link to heading

The nixos module system gives maintainers more freedom over how packages are split into modules. Separation of concerns can be implemented more easily. For example, the dependency tree of a package set can be factored out into a separate module, allowing for simpler modification.