drv-parts
drv-parts copied to clipboard
Problems with `deps`
After collecting some experience using drv-parts in dream2nix, there are some observations with the current deps
pattern that I'd like to discuss and find a solution for:
Observation 1: clashing names
Package can have clashing names. For example there can be a python package shadowing the name of a dependency from nixpkgs.
Observation 2: mixed concerns
Dependencies of very different concerns are currently mixed under deps.
, for example:
- nix library dependencies
- build dependencies (packages)
- other builders (like pkgs.writeText)
- stdenv
Observation 3: untyped
Due to the multi use described above, deps
currently cannot be strictly typed.
It would be hard to apply a generic transformation on all dependencies (example: change stdenv for all deps), as not all dependencies are packages.
Observation 4: current deps
aren't modules
In a lang2nix auto-generated dependency tree we'd like our dependencies to be modules, and we'd like to have a standard way of handling such dependencies, which is currently missing.
Since deps
currently is a freeform module we could declare the type of some attributes to be a drv-parts submodule, but it feels odd mixing modules with arbitrary other types.
Ideas
It seems to me that we might want to categorize dependencies somehow. Dependencies can be different things, and have different capabilities.
Idea 1: Extra layer of nesting
Re-define deps
to allow one extra layer of nesting, so it can be used like this:
{
deps.generic = {nixpkgs, ...}: {
inherit (nixpkgs) hello;
python = nixpkgs.python310;
}
# language specific dependencies
# allow the module maintainer to define the type of deps.python
deps.python = {...}: {
requests = ...;
hello = ...;
};
# separate library deps
deps.lib = ...
}
Idea 2: offer only a type or helper
Do not change/extend deps
, but offer a pre-defined type or helper via drv-parts, so module maintainers can easily create new options similar to deps
, like for example pythonDeps
or nodejsDeps
. This allows to assign a custom type to each dependency group which is useful.
Idea 3: Prefix the attribute names of individual dependencies
Example:
{
deps = {nixpkgs, ...}: {
inherit (nixpkgs) hello;
python = nixpkgs.python310;
# python deps
python_hello = ...;
python_requests = ...;
# nodejs deps
nodejs_hello = ...;
}
}
I don't really like Idea 3.
Conclusion
Using Idea 2 seems like to most straight forward way to go as of now as it doesn't require changing drv-parts. Still I'm wondering if we should implement a more sophisticated way of dealing with module dependencies and how such a solution would look like.
@roberth @phaer
Aliasing is another concern. For instance if you've encountered pkg-config dependencies, you could use pkgs.defaultPkgConfigPackages
to resolve those, but that makes overriding hard if you're also using the same dependency directly from pkgs
in another related place.
I don't want to say it, but maybe we need some kind of solver. In the end, functions are almost mutation and fixpoints lead to little more than inheritance. Programming concepts; not the most declarative things.