Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions lib/customisation.nix
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,61 @@ rec {
}
else result);

/*
Apply arbitrary customization to an overridable attribute set and its overriding results.

This function apply the specified customization *modify*
to an [overridable](#chap-overrides) attribute set *overridable*
and update common attributes that perform overriding
to automatically re-apply the customization to future overriding results.

Attributes [`override`](#sec-pkg-override),
[`overrideAttributes`](#sec-pkg-overrideAttrs) and
[`overrideDerivation`](#sec-pkg-overrideDerivation) are chosen
to cover most of the use cases.

Example:
helloWithAns1 = lib.extendDerivation true { ans = 42; } pkgs.hello

helloWithAns1.ans
=> 42
(helloWithAns1.override { }).ans
=> error: attribute 'ans' missing

helloWithAns2 = lib.applyToOverridable (lib.extendDerivation true { ans = 42; }) pkgs.hello

helloWithAns2.ans
=> 42
(helloWithAns2.override { }).ans
=> 42

helloFive1 = lib.extendDerivation (2 + 2 == 5) { } pkgs.hello

helloFive1
=> error: assertion 'condition' failed
helloFive1.override { }
=> «derivation /nix/store/4f4rwzm6s707ify0yqgib2lckp4dw8as-hello-2.12.1.drv»

helloFive2 = lib.applyToOverridable (lib.extendDerivation (2 + 2 == 5) { }) pkgs.hello

helloFive2
=> error: assertion 'condition' failed
helloFive2.override { }
=> error: assertion 'condition' failed

Type:
applyToOverridable :: (AttrSet -> AttrSet) -> AttrSet -> AttrSet
*/
applyToOverridable = modify: overridable:
let
r = modify overridable;
in
r // {
${if r ? override then "override" else null} = lib.mirrorFunctionArgs r.override (fdrv: applyToOverridable modify (r.override fdrv));
${if r ? overrideAttrs then "overrideAttrs" else null} = fdrv: applyToOverridable modify (r.overrideAttrs fdrv);
${if r ? overrideDerivation then "overrideDerivation" else null} = fdrv: applyToOverridable modify (r.overrideDerivation fdrv);
};


/* Call the package function in the file `fn` with the required
arguments automatically. The function is called with the
Expand Down
1 change: 1 addition & 0 deletions lib/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ let
inherit (self.stringsWithDeps) textClosureList textClosureMap
noDepEntry fullDepEntry packEntry stringAfter;
inherit (self.customisation) overrideDerivation makeOverridable
applyToOverridable
callPackageWith callPackagesWith extendDerivation hydraJob
makeScope makeScopeWithSplicing makeScopeWithSplicing';
inherit (self.derivations) lazyDerivation;
Expand Down
8 changes: 5 additions & 3 deletions pkgs/development/compilers/cudatoolkit/stdenv.nix
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ let
};
assertCondition = true;
in
lib.extendDerivation
assertCondition
passthruExtra
lib.applyToOverridable
(lib.extendDerivation
assertCondition
passthruExtra
)
cudaStdenv

39 changes: 39 additions & 0 deletions pkgs/test/overriding.nix
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,43 @@ let
expr = ((stdenvNoCC.mkDerivation { pname = "hello-no-final-attrs"; }).overrideAttrs { pname = "hello-no-final-attrs-overridden"; }).pname == "hello-no-final-attrs-overridden";
expected = true;
})
({
name = "extendDerivation-passthru";
expr = helloWithAns.ans == 42;
expected = true;
})
]
++ getTestsApplyToOverridable { }
;

getTestsApplyToOverridable =
{ applyToOverridable ? lib.applyToOverridable
, fname ? "applyToOverridable"
}:
let
helloWithAnsOverridable = applyToOverridable (lib.extendDerivation true { ans = 42; }) pkgs.hello;
in
[
({
name = fname + "-self";
expr = helloWithAnsOverridable.ans == 42;
expected = true;
})
({
name = fname + "-override";
expr = (helloWithAnsOverridable.override { stdenv = pkgs.clangStdenv; }).ans == 42;
expected = true;
})
({
name = fname + "-overrideAttrs";
expr = (helloWithAnsOverridable.overrideAttrs (previousAttrs: { FOO = "bar"; })).ans == 42;
expected = true;
})
({
name = fname + "-overrideDerivation";
expr = (helloWithAnsOverridable.overrideDerivation (previousDrv: { FOO = "bar"; })).ans == 42;
expected = true;
})
];

addEntangled = origOverrideAttrs: f:
Expand All @@ -55,6 +92,8 @@ let
overrides1 = example.overrideAttrs (_: super: { pname = "a-better-${super.pname}"; });

repeatedOverrides = overrides1.overrideAttrs (_: super: { pname = "${super.pname}-with-blackjack"; });

helloWithAns = lib.extendDerivation true { ans = 42; } pkgs.hello;
in

stdenvNoCC.mkDerivation {
Expand Down