Skip to content

Commit

Permalink
Make layers overridable
Browse files Browse the repository at this point in the history
This also makes the old `mkPackageWithDeps` style the default, and
improves error reporting a bit.
  • Loading branch information
roberth committed Jan 14, 2025
1 parent b3edddd commit 715fbfa
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 7 deletions.
69 changes: 63 additions & 6 deletions pkgs/build-support/package/make-package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ let
deps = old.deps // f old.deps;
});

# FIXME: Use `toExtension f`?
# TODO: Support legacy attrs like passthru?
overrideAttrs = f:
this.extend (this: old:
let
Expand Down Expand Up @@ -115,7 +117,7 @@ let
// outputs;
};

layers.withDeps = f: this: old:
layers.withDeps = f: externalArgs: this: old:
let
fargs = lib.functionArgs f;
spy = lib.setFunctionArgs
Expand All @@ -127,11 +129,25 @@ let
true)
fargs);
# TODO: make callPackage a parameter?
values = (callPackage spy { }).args;
values = (callPackage spy externalArgs).args;
old2 = old // {
deps = old.deps or {} // values;
inherit values;
};
r = f (lib.mapAttrs (name: value: this.deps.${name}) fargs);
r =
f
(lib.mapAttrs
(name: hasDefault:
builtins.addErrorContext
"while evaluating the package function argument `${name}`"
(externalArgs.${name} or (
this.deps.${name} or (
throw "Dependency ${name} went missing from the package internal `deps` attribute. Did you forget to preserve previous deps? Write e.g. `deps = prev.deps // { ... }`"
)
))
)
fargs
);
r' = if lib.isList r then lib.composeManyExtensions r else r;
in
old2 //
Expand All @@ -143,13 +159,54 @@ let
# TODO: layers.pkg-config
# TODO: layers.<some language>

mkPackage = f: lib.encapsulate (lib.extends f baseLayer);
mkPackageWithDeps = f: mkPackage (layers.withDeps f);
layers.noop = _this: _old: { };

mkPackageWith = {
/* these are not overridable by the layer implementations - not suited for `deps` */
externalDeps ? { inherit layers; }
}: f: lib.encapsulate (
this:
let baseLayer' = x: baseLayer x // {
/**
Extend the package layers with the given function.
*/
extend = f: this.extend (this: old: {
userLayer = lib.composeExtensions old.userLayer f;
});
};
in
# The root of the mkPackage fixpoint is responsible for managing the deps,
# and combining the layers (without adding an extra fixpoint).
# Virtually all package logic happens in userLayer.
{
userLayer = final: prev:
this.externalDeps.layers.withDeps
f
(this.externalDeps // {
# Package attributes
inherit final prev;
# Dependencies
/**
Override the package dependencies that are not overridable by the individual layer implementations,
Notably, the `layers` attribute.
*/
overrideExternalDeps = newDeps:
this.extend (this: old: {
externalDeps = old.externalDeps // newDeps;
});
})
final
prev;
inherit externalDeps;
package = lib.extends this.userLayer baseLayer' this.package;
inherit (this.package) public;
}
);
mkPackage = mkPackageWith {};
in
{
inherit
layers
mkPackage
mkPackageWithDeps
;
}
2 changes: 1 addition & 1 deletion pkgs/by-name/he/hello/package.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{ mkPackageWithDeps, layers }: mkPackageWithDeps ({ stdenv, fetchurl, testers, lib, callPackage, nixos }: [
{ mkPackage }: mkPackage ({ final, layers, stdenv, fetchurl, testers, nixos, callPackage, lib }: [
(layers.derivation { inherit stdenv; })
(this: old: {
name = "hello";
Expand Down

0 comments on commit 715fbfa

Please sign in to comment.