From bff126ffbc49f1c1e08dc9c622081652a6a6e86d Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Fri, 18 Nov 2022 12:16:45 +0100 Subject: [PATCH 1/5] stdenv.mkDerivation: Make overrideAttrs overridable (cherry picked from commit 43c8b43f808f48fd5600afcad5503eaeaf6d71b7) --- pkgs/stdenv/generic/make-derivation.nix | 49 +++++++++++++------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix index 81fc31d67289ae0..b7030cab6ffdb73 100644 --- a/pkgs/stdenv/generic/make-derivation.nix +++ b/pkgs/stdenv/generic/make-derivation.nix @@ -18,33 +18,34 @@ let # separate lines, because Nix would only show the last line of the comment. # An infinite recursion here can be caused by having the attribute names of expression `e` in `.overrideAttrs(finalAttrs: previousAttrs: e)` depend on `finalAttrs`. Only the attribute values of `e` can depend on `finalAttrs`. - args = rattrs (args // { inherit finalPackage; }); + args = rattrs (args // { inherit finalPackage overrideAttrs; }); # ^^^^ - finalPackage = - mkDerivationSimple - (f0: - let - f = self: super: - # Convert f0 to an overlay. Legacy is: - # overrideAttrs (super: {}) - # We want to introduce self. We follow the convention of overlays: - # overrideAttrs (self: super: {}) - # Which means the first parameter can be either self or super. - # This is surprising, but far better than the confusion that would - # arise from flipping an overlay's parameters in some cases. - let x = f0 super; - in - if builtins.isFunction x - then - # Can't reuse `x`, because `self` comes first. - # Looks inefficient, but `f0 super` was a cheap thunk. - f0 self super - else x; + overrideAttrs = f0: + let + f = self: super: + # Convert f0 to an overlay. Legacy is: + # overrideAttrs (super: {}) + # We want to introduce self. We follow the convention of overlays: + # overrideAttrs (self: super: {}) + # Which means the first parameter can be either self or super. + # This is surprising, but far better than the confusion that would + # arise from flipping an overlay's parameters in some cases. + let x = f0 super; in - makeDerivationExtensible - (self: let super = rattrs self; in super // f self super)) - args; + if builtins.isFunction x + then + # Can't reuse `x`, because `self` comes first. + # Looks inefficient, but `f0 super` was a cheap thunk. + f0 self super + else x; + in + makeDerivationExtensible + (self: let super = rattrs self; in super // f self super); + + finalPackage = + mkDerivationSimple overrideAttrs args; + in finalPackage; # makeDerivationExtensibleConst == makeDerivationExtensible (_: attrs), From 5b2f597b116d56104d45c35587920323ed2a5666 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Sat, 19 Nov 2022 11:40:46 +0100 Subject: [PATCH 2/5] lib.extendDerivation: Fix interaction between output selection and overrideAttrs --- lib/customisation.nix | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/customisation.nix b/lib/customisation.nix index 101c9e62b9e6143..5b203552583b54f 100644 --- a/lib/customisation.nix +++ b/lib/customisation.nix @@ -213,7 +213,14 @@ rec { outputSpecified = true; drvPath = assert condition; drv.${outputName}.drvPath; outPath = assert condition; drv.${outputName}.outPath; - }; + } // + # TODO: give the derivation control over the outputs. + # `overrideAttrs` may not be the only attribute that needs + # updating when switching outputs. + lib.optionalAttrs (passthru?overrideAttrs) { + # TODO: also add overrideAttrs when overrideAttrs is not custom, e.g. when not splicing. + overrideAttrs = f: (passthru.overrideAttrs f).${outputName}; + }; }; outputsList = map outputToAttrListElement outputs; From b94fa2c25315d2086cb4c50716598ffa65363593 Mon Sep 17 00:00:00 2001 From: Artturin Date: Sun, 20 Nov 2022 16:19:15 +0200 Subject: [PATCH 3/5] python-packages-base: use extends instead of // // shouldn't be used when overrideAttrs is available here we can use extends instead of overrideAttrs for performance --- .../python/python-packages-base.nix | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/pkgs/development/interpreters/python/python-packages-base.nix b/pkgs/development/interpreters/python/python-packages-base.nix index 92b0a456b077942..738248a2cf04e93 100644 --- a/pkgs/development/interpreters/python/python-packages-base.nix +++ b/pkgs/development/interpreters/python/python-packages-base.nix @@ -16,17 +16,22 @@ let # This function introduces `overridePythonAttrs` and it overrides the call to `buildPythonPackage`. makeOverridablePythonPackage = f: origArgs: let - ff = f origArgs; - overrideWith = newArgs: origArgs // (if pkgs.lib.isFunction newArgs then newArgs origArgs else newArgs); + args = lib.fix (lib.extends + (_: previousAttrs: { + passthru = (previousAttrs.passthru or { }) // { + overridePythonAttrs = newArgs: makeOverridablePythonPackage f (overrideWith newArgs); + }; + }) + (_: origArgs)); + result = f args; + overrideWith = newArgs: args // (if pkgs.lib.isFunction newArgs then newArgs args else newArgs); in - if builtins.isAttrs ff then (ff // { + if builtins.isAttrs result then result + else if builtins.isFunction result then { overridePythonAttrs = newArgs: makeOverridablePythonPackage f (overrideWith newArgs); - }) - else if builtins.isFunction ff then { - overridePythonAttrs = newArgs: makeOverridablePythonPackage f (overrideWith newArgs); - __functor = self: ff; + __functor = self: result; } - else ff; + else result; buildPythonPackage = makeOverridablePythonPackage (lib.makeOverridable (callPackage ./mk-python-derivation.nix { inherit namePrefix; # We want Python libraries to be named like e.g. "python3.6-${name}" From 9c0ac5691c5c8e8902fe5a93599b07e3f21464aa Mon Sep 17 00:00:00 2001 From: Artturin Date: Fri, 20 Jan 2023 18:57:13 +0200 Subject: [PATCH 4/5] tests.overriding: init only outputs the first failing test atm --- pkgs/test/default.nix | 2 ++ pkgs/test/overriding.nix | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 pkgs/test/overriding.nix diff --git a/pkgs/test/default.nix b/pkgs/test/default.nix index 818001018b3ae11..445aa9a756780c4 100644 --- a/pkgs/test/default.nix +++ b/pkgs/test/default.nix @@ -59,6 +59,8 @@ with pkgs; nixos-functions = callPackage ./nixos-functions {}; + overriding = callPackage ./overriding.nix { }; + patch-shebangs = callPackage ./patch-shebangs {}; texlive = callPackage ./texlive {}; diff --git a/pkgs/test/overriding.nix b/pkgs/test/overriding.nix new file mode 100644 index 000000000000000..eab710af5afabd5 --- /dev/null +++ b/pkgs/test/overriding.nix @@ -0,0 +1,23 @@ +{ lib, pkgs, stdenvNoCC }: + +let + tests = + let + p = pkgs.python3Packages.xpybutil.overridePythonAttrs (_: { dontWrapPythonPrograms = true; }); + in + [ + ({ + name = "overridePythonAttrs"; + expr = !lib.hasInfix "wrapPythonPrograms" p.postFixup; + expected = true; + }) + ]; +in + +stdenvNoCC.mkDerivation { + name = "test-overriding"; + passthru = { inherit tests; }; + buildCommand = '' + touch $out + '' + lib.concatMapStringsSep "\n" (t: "([[ ${lib.boolToString t.expr} == ${lib.boolToString t.expected} ]] && echo '${t.name} success') || (echo '${t.name} fail' && exit 1)") tests; +} From a0f4e8746d15683d75e590b08334df7faf4c7621 Mon Sep 17 00:00:00 2001 From: Artturin Date: Sat, 28 Jan 2023 12:10:47 +0200 Subject: [PATCH 5/5] tests.overriding: add repeatedOverrides-pname, repeatedOverrides-entangled-pname from https://github.com/NixOS/nixpkgs/pull/201734#pullrequestreview-1185972282 --- pkgs/test/overriding.nix | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/pkgs/test/overriding.nix b/pkgs/test/overriding.nix index eab710af5afabd5..edc1b27cf4f1d2b 100644 --- a/pkgs/test/overriding.nix +++ b/pkgs/test/overriding.nix @@ -11,7 +11,40 @@ let expr = !lib.hasInfix "wrapPythonPrograms" p.postFixup; expected = true; }) + ({ + name = "repeatedOverrides-pname"; + expr = repeatedOverrides.pname == "a-better-hello-with-blackjack"; + expected = true; + }) + ({ + name = "repeatedOverrides-entangled-pname"; + expr = repeatedOverrides.entangled.pname == "a-better-figlet-with-blackjack"; + expected = true; + }) ]; + + addEntangled = origOverrideAttrs: f: + origOverrideAttrs ( + lib.composeExtensions f (self: super: { + passthru = super.passthru // { + entangled = super.passthru.entangled.overrideAttrs f; + overrideAttrs = addEntangled self.overrideAttrs; + }; + }) + ); + + entangle = pkg1: pkg2: pkg1.overrideAttrs (self: super: { + passthru = super.passthru // { + entangled = pkg2; + overrideAttrs = addEntangled self.overrideAttrs; + }; + }); + + example = entangle pkgs.hello pkgs.figlet; + + overrides1 = example.overrideAttrs (_: super: { pname = "a-better-${super.pname}"; }); + + repeatedOverrides = overrides1.overrideAttrs (_: super: { pname = "${super.pname}-with-blackjack"; }); in stdenvNoCC.mkDerivation {