summary refs log tree commit diff
diff options
context:
space:
mode:
authorArtturi <Artturin@artturin.com>2023-02-03 12:49:08 +0200
committerGitHub <noreply@github.com>2023-02-03 12:49:08 +0200
commitdcc7df7fe6e74ac3b2895a1f2c6873b00278c83a (patch)
treee102e2eb4f76c7c884cb05763f425584e5f8a7f4
parent931f54ceff33e3dce7edd0b853e36e7444294419 (diff)
parenta0f4e8746d15683d75e590b08334df7faf4c7621 (diff)
downloadnixpkgs-dcc7df7fe6e74ac3b2895a1f2c6873b00278c83a.tar
nixpkgs-dcc7df7fe6e74ac3b2895a1f2c6873b00278c83a.tar.gz
nixpkgs-dcc7df7fe6e74ac3b2895a1f2c6873b00278c83a.tar.bz2
nixpkgs-dcc7df7fe6e74ac3b2895a1f2c6873b00278c83a.tar.lz
nixpkgs-dcc7df7fe6e74ac3b2895a1f2c6873b00278c83a.tar.xz
nixpkgs-dcc7df7fe6e74ac3b2895a1f2c6873b00278c83a.tar.zst
nixpkgs-dcc7df7fe6e74ac3b2895a1f2c6873b00278c83a.zip
Merge pull request #211685 from Artturin/splicingstuff1-split
-rw-r--r--lib/customisation.nix9
-rw-r--r--pkgs/development/interpreters/python/python-packages-base.nix21
-rw-r--r--pkgs/stdenv/generic/make-derivation.nix49
-rw-r--r--pkgs/test/default.nix2
-rw-r--r--pkgs/test/overriding.nix56
5 files changed, 104 insertions, 33 deletions
diff --git a/lib/customisation.nix b/lib/customisation.nix
index 42d711cf5fb..cb3a4b56115 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;
diff --git a/pkgs/development/interpreters/python/python-packages-base.nix b/pkgs/development/interpreters/python/python-packages-base.nix
index d5b02223fd6..de38fb13632 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}"
diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix
index c53eed3dfa1..5d272d9eb0c 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),
diff --git a/pkgs/test/default.nix b/pkgs/test/default.nix
index 39039c5950e..71d065179d1 100644
--- a/pkgs/test/default.nix
+++ b/pkgs/test/default.nix
@@ -61,6 +61,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 00000000000..edc1b27cf4f
--- /dev/null
+++ b/pkgs/test/overriding.nix
@@ -0,0 +1,56 @@
+{ lib, pkgs, stdenvNoCC }:
+
+let
+  tests =
+    let
+      p = pkgs.python3Packages.xpybutil.overridePythonAttrs (_: { dontWrapPythonPrograms = true; });
+    in
+    [
+      ({
+        name = "overridePythonAttrs";
+        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 {
+  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;
+}