DavHau / drv-parts

Configure packages like NixOS systems
MIT License
154 stars 6 forks source link

feat(pkg-func): prefix options with name of pkg-func #19

Closed DavHau closed 1 year ago

DavHau commented 1 year ago

This changes the basic layout of drv-parts package options. Options specific to a packaging interface like mkDerivation are now prefixed with mkDerivation.. For example config.buildInputs moves to config.mkDerivation.buildInputs.

Pros:

  1. Implementation-wise this feels a lot cleaner as it's always clear which interface an option belongs to. Before this change, it was required to specify argsForward to signal which top-level args are relevant for the final derivation call. Some of the top-level args like deps or flags should not be passed to the final derivation.
  2. Extensibility: Adding interfaces ontop of mkDerivation like buildPythonPackage feels cleaner now, as additional options can be prefixed with buildPythonPackage., and are not adding to the already large mkDerivation space.
  3. The generated documentation now has the options sorted by interface. A user who already knows how mkDerivation works, but wants to see the options specific to buildRustCrate, can now find those easily.

Cons:

  1. Increased verbosity, as all package options now need to be prefixed
  2. Implementation details are leaking into the UI. Imagine a user who starts blank and has no idea about what mkDerivation or builtins.derivation is. For this user the separation of options into categories seems arbitrary. The goal of a perfect packaging abstraction should be that a user doesn't need to understand anything about the internals behind it. So is it really a good idea to let these internal package function categories surface?

@phaer @hsjobeki This will be relevant for work on dream2nix

@roberth Please let me know if you think this change is a bad idea for some reason.

roberth commented 1 year ago

I think this is understood, but for context, I consider the possibility of "backend functions" to be specific to drv-parts and not necessarily part of a good first-principles module-based implementation of derivations; something that would be upstreamed into Nixpkgs. drv-parts can make a pragmatic choice in this regard, to make the "experimentation for Nixpkgs" aspect a bit more practical. Having real world applications of such a solution is valuable even if it's not the final architecture. What's your view on this?

With that out of the way, I think this separation aligns with the separation we ought to have between the "derivation" and "package attrset" aspects of a package.

In a final architecture that's perhaps suitable for becoming the next generation solution for Nixpkgs, I would think of these "namespaces":

Coming back to this PR, it seems to move in a similar direction. It does not achieve the separation of concerns or ability to replace parts of what's traditionally stdenv.mkDerivation, but that's not currently possible without heavy refactoring in nixpkgs anyway. So while it's not the final thing (as if that's even a sensible expectation), I think this is a move in the right direction!

DavHau commented 1 year ago

This raises awareness that the package function backends are just a concept for compatibility and not necessarily part of the final solution for nixpkgs.

Having real world applications of such a solution is valuable even if it's not the final architecture. What's your view on this?

I fully agree with this. The milestone I'm working towards right now is using drv-parts to solve some of dream2nix' problems and thereby getting some real world usage. I think that the solution has to embody compromises like using existing package functions to keep complexity manageable.

Though, I want to make sure that these compromises are kept as separate modules, so that at any time they could be replaced with other modules, more suitable for a native nixpkgs solution. Considering this, it becomes more clear now, that moving mkDerivation specific attributes out of the top-level is a move towards the right direction.

Apart from these compatibility modules, I'd like to steer the design as much as possible towards whats needed for the final solution. Therefore your input is very much appreciated.

I think what you describe as public is what drv-parts currently puts in final.package. Maybe I should just rename it to public as it's shorter.

I'll keep the derivation.* and derivation.stdenv idea in mind.

DavHau commented 1 year ago

renamed final.package -> public via https://github.com/DavHau/drv-parts/commit/4aa24c2acdc45e16a24cd53031c74a58197cc0db

Also now setting public.name and public.version instead of mkDerivation.[name|version] is enforced. via https://github.com/DavHau/drv-parts/commit/eac0970515bccba908c4bbea57911fd36e51c1a2. The mkDerivation's pname+version are automatically inherited from public.