Use finalAttrs instead of self for mkDerivation "overlay"

main
Robert Hensing 3 years ago
parent 41b3688ba1
commit d629ba27d9
  1. 13
      doc/stdenv/meta.chapter.md
  2. 20
      doc/stdenv/stdenv.chapter.md
  3. 8
      pkgs/applications/misc/hello/default.nix

@ -176,18 +176,21 @@ The NixOS tests are available as `nixosTests` in parameters of derivations. For
NixOS tests run in a VM, so they are slower than regular package tests. For more information see [NixOS module tests](https://nixos.org/manual/nixos/stable/#sec-nixos-tests).
Alternatively, you can specify other derivations as tests. You can make use of
the optional parameter (here: `self`) to inject the correct package without
relying on non-local definitions, even in the presence of `overrideAttrs`. This
means `(mypkg.overrideAttrs f).passthru.tests` will be as expected, as long as the
the optional parameter to inject the correct package without
relying on non-local definitions, even in the presence of `overrideAttrs`.
Here that's `finalAttrs.public`, but you could choose a different name if
`finalAttrs` already exists in your scope.
`(mypkg.overrideAttrs f).passthru.tests` will be as expected, as long as the
definition of `tests` does not rely on the original `mypkg` or overrides it in
all places.
```nix
# my-package/default.nix
{ stdenv, callPackage }:
stdenv.mkDerivation (self: {
stdenv.mkDerivation (finalAttrs: {
# ...
passthru.tests.example = callPackage ./example.nix { my-package = self.public; }
passthru.tests.example = callPackage ./example.nix { my-package = finalAttrs.public; }
})
```

@ -322,21 +322,21 @@ For information about how to run the updates, execute `nix-shell maintainers/scr
If you pass a function to `mkDerivation`, it will receive as its argument the final arguments, considering use of `overrideAttrs`. For example:
```nix
mkDerivation (self: {
mkDerivation (finalAttrs: {
pname = "hello";
withFeature = true;
configureFlags =
lib.optionals self.withFeature ["--with-feature"];
lib.optionals finalAttrs.withFeature ["--with-feature"];
})
```
Note that this does not use the `rec` keyword to reuse `withFeature` in `configureFlags`.
The `rec` keyword works at the syntax level and is unaware of overriding.
Instead, the definition references `self`, allowing users to change `withFeature`
Instead, the definition references `finalAttrs`, allowing users to change `withFeature`
consistently with `overrideAttrs`.
`self` also contains the attribute `public`, which represents the final package,
`finalAttrs` also contains the attribute `public`, which represents the final package,
including the output paths, etc.
Let's look at a more elaborate example to understand the differences between
@ -345,30 +345,30 @@ various bindings:
```nix
# `pkg` is the _original_ definition (for illustration purposes)
let pkg =
mkDerivation (self: { # self is the final package
mkDerivation (finalAttrs: {
# ...
# An example attribute
packages = [];
# `passthru.tests` is a commonly defined attribute.
passthru.tests.simple = f self.public;
passthru.tests.simple = f finalAttrs.public;
# An example of an attribute containing a function
passthru.appendPackages = packages':
self.public.overrideAttrs (newSelf: super: {
finalAttrs.public.overrideAttrs (newSelf: super: {
packages = super.packages ++ packages';
});
# For illustration purposes; referenced as
# `(pkg.overrideAttrs(x)).self` etc in the text below.
passthru.self = self;
# `(pkg.overrideAttrs(x)).finalAttrs` etc in the text below.
passthru.finalAttrs = finalAttrs;
passthru.original = pkg;
});
in pkg
```
Unlike the `pkg` binding in the above example, the `self` parameter always references the final attributes. For instance `(pkg.overrideAttrs(x)).self.public` is identical to `pkg.overrideAttrs(x)`, whereas `(pkg.overrideAttrs(x)).original` is the same as `pkg`.
Unlike the `pkg` binding in the above example, the `finalAttrs` parameter always references the final attributes. For instance `(pkg.overrideAttrs(x)).finalAttrs.public` is identical to `pkg.overrideAttrs(x)`, whereas `(pkg.overrideAttrs(x)).original` is the same as the original `pkg`.
See also the section about [`passthru.tests`](#var-meta-tests).

@ -7,12 +7,12 @@
, hello
}:
stdenv.mkDerivation (self: {
stdenv.mkDerivation (finalAttrs: {
pname = "hello";
version = "2.12";
src = fetchurl {
url = "mirror://gnu/hello/${self.pname}-${self.version}.tar.gz";
url = "mirror://gnu/hello/${finalAttrs.pname}-${finalAttrs.version}.tar.gz";
sha256 = "1ayhp9v4m4rdhjmnl2bq3cibrbqqkgjbl3s7yk2nhlh8vj3ay16g";
};
@ -28,7 +28,7 @@ stdenv.mkDerivation (self: {
(nixos { environment.noXlibs = true; }).pkgs.hello;
};
passthru.tests.run = callPackage ./test.nix { hello = self.public; };
passthru.tests.run = callPackage ./test.nix { hello = finalAttrs.public; };
meta = with lib; {
description = "A program that produces a familiar, friendly greeting";
@ -37,7 +37,7 @@ stdenv.mkDerivation (self: {
It is fully customizable.
'';
homepage = "https://www.gnu.org/software/hello/manual/";
changelog = "https://git.savannah.gnu.org/cgit/hello.git/plain/NEWS?h=v${self.version}";
changelog = "https://git.savannah.gnu.org/cgit/hello.git/plain/NEWS?h=v${finalAttrs.version}";
license = licenses.gpl3Plus;
maintainers = [ maintainers.eelco ];
platforms = platforms.all;

Loading…
Cancel
Save