Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: add stdenv passthru chapter #315909

Merged
merged 4 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
4 changes: 2 additions & 2 deletions doc/build-helpers/fetchers.chapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ If `pname` and `version` are specified, `fetchurl` will use those values and wil
_Default value:_ `{}`.

`passthru` (Attribute Set; _optional_)
: Specifies any extra [passthru](#var-stdenv-passthru) attributes for the derivation returned by `fetchurl`.
: Specifies any extra [passthru](#chap-passthru) attributes for the derivation returned by `fetchurl`.
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved
Note that `fetchurl` defines [passthru attributes of its own](#ssec-pkgs-fetchers-fetchurl-passthru-outputs).
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved
Attributes specified in `passthru` can override the default attributes returned by `fetchurl`.

Expand All @@ -387,7 +387,7 @@ If `pname` and `version` are specified, `fetchurl` will use those values and wil

### Passthru outputs {#ssec-pkgs-fetchers-fetchurl-passthru-outputs}

`fetchurl` also defines its own [`passthru`](#var-stdenv-passthru) attributes:
`fetchurl` also defines its own [`passthru`](#chap-passthru) attributes:

`url` (String)

Expand Down
6 changes: 3 additions & 3 deletions doc/build-helpers/images/dockertools.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ Similarly, if you encounter errors similar to `Error_Protocol ("certificate has

### Passthru outputs {#ssec-pkgs-dockerTools-buildImage-passthru-outputs}

`buildImage` defines a few [`passthru`](#var-stdenv-passthru) attributes:
`buildImage` defines a few [`passthru`](#chap-passthru) attributes:

`buildArgs` (Attribute Set)

Expand Down Expand Up @@ -576,13 +576,13 @@ This allows the function to produce reproducible images.

`passthru` (Attribute Set; _optional_)

: Use this to pass any attributes as [passthru](#var-stdenv-passthru) for the resulting derivation.
: Use this to pass any attributes as [passthru](#chap-passthru) for the resulting derivation.
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved

_Default value:_ `{}`

### Passthru outputs {#ssec-pkgs-dockerTools-streamLayeredImage-passthru-outputs}

`streamLayeredImage` also defines its own [`passthru`](#var-stdenv-passthru) attributes:
`streamLayeredImage` also defines its own [`passthru`](#chap-passthru) attributes:

`imageTag` (String)

Expand Down
1 change: 1 addition & 0 deletions doc/stdenv.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
```{=include=} chapters
stdenv/stdenv.chapter.md
stdenv/meta.chapter.md
stdenv/passthru.chapter.md
stdenv/multiple-output.chapter.md
stdenv/cross-compilation.chapter.md
stdenv/platform-notes.chapter.md
Expand Down
101 changes: 0 additions & 101 deletions doc/stdenv/meta.chapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,107 +110,6 @@ Some packages use this to automatically detect the maximum set of features with
For example, `systemd` [requires dynamic linking](https://github.com/systemd/systemd/issues/20600#issuecomment-912338965), and [has a `meta.badPlatforms` setting](https://github.com/NixOS/nixpkgs/blob/b03ac42b0734da3e7be9bf8d94433a5195734b19/pkgs/os-specific/linux/systemd/default.nix#L752) similar to the one above.
Packages which can be built with or without `systemd` support will use `lib.meta.availableOn` to detect whether or not `systemd` is available on the [`hostPlatform`](#ssec-cross-platform-parameters) for which they are being built; if it is not available (e.g. due to a statically-linked host platform like `pkgsStatic`) this support will be disabled by default.

### `tests` {#var-meta-tests}

::: {.warning}
This attribute is special in that it is not actually under the `meta` attribute set but rather under the `passthru` attribute set. This is due to how `meta` attributes work, and the fact that they are supposed to contain only metadata, not derivations.
:::

An attribute set with tests as values. A test is a derivation that builds when the test passes and fails to build otherwise.

You can run these tests with:

```ShellSession
$ cd path/to/nixpkgs
$ nix-build -A your-package.tests
```

Note that Hydra and [`nixpkgs-review`](https://github.com/Mic92/nixpkgs-review) don't build these derivations by default, and that ([`@ofborg`](https://github.com/NixOS/ofborg)) only builds them when evaluating PRs for that particular package (or when manually instructed).

#### Package tests {#var-meta-tests-packages}

Tests that are part of the source package are often executed in the `installCheckPhase`. This phase is also suitable for performing a `--version` test for packages that support such flag. Here's an example:

```nix
# Say the package is git
stdenv.mkDerivation(finalAttrs: {
pname = "git";
version = "...";
# ...

doInstallCheck = true;
installCheckPhase = ''
runHook preInstallCheck

echo checking if 'git --version' mentions ${finalAttrs.version}
$out/bin/git --version | grep ${finalAttrs.version}

runHook postInstallCheck
'';
# ...
})
```

Most programs distributed by Nixpkgs support such a `--version` flag, and it can help give confidence that the package at least got compiled properly. However, tests that are slightly non trivial will better fit into `passthru.tests`, because:

* `passthru.tests` tests the 'real' package, independently from the environment in which it was built
* We can run and debug a `passthru.tests` independently, after the package was built (useful if it takes a long time).
* `installCheckPhase` adds overhead to each build

It is also possible to still use `passthru.tests` to test the version, with [testVersion](#tester-testVersion).

For more on how to write and run package tests, see [`pkgs/README.md`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md#package-tests).

#### NixOS tests {#var-meta-tests-nixos}

The NixOS tests are available as `nixosTests` in parameters of derivations. For instance, the OpenSMTPD derivation includes lines similar to:

```nix
{ /* ... , */ nixosTests }:
{
# ...
passthru.tests = {
basic-functionality-and-dovecot-integration = nixosTests.opensmtpd;
};
}
```

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 to inject the correct package without
relying on non-local definitions, even in the presence of `overrideAttrs`.
Here that's `finalAttrs.finalPackage`, 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 (finalAttrs: {
# ...
passthru.tests.example = callPackage ./example.nix { my-package = finalAttrs.finalPackage; };
})
```

```nix
# my-package/example.nix
{ runCommand, lib, my-package, ... }:
runCommand "my-package-test" {
nativeBuildInputs = [ my-package ];
src = lib.sources.sourcesByRegex ./. [ ".*.in" ".*.expected" ];
} ''
my-package --help
my-package <example.in >example.actual
diff -U3 --color=auto example.expected example.actual
mkdir $out
''
```


### `timeout` {#var-meta-timeout}

A timeout (in seconds) for building the derivation. If the derivation takes longer than this time to build, Hydra will fail it due to breaking the timeout. However, all computers do not have the same computing power, hence some builders may decide to apply a multiplicative factor to this value. When filling this value in, try to keep it approximately consistent with other values already present in `nixpkgs`.
Expand Down
157 changes: 157 additions & 0 deletions doc/stdenv/passthru.chapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# Passthru-attributes {#chap-passthru}
[]{#var-stdenv-passthru} []{#special-variables} <!-- legacy anchors -->

As opposed to most other `mkDerivation` input attributes, `passthru` is not passed to the derivation's [`builder` executable](https://nixos.org/manual/nix/stable/expressions/derivations.html#attr-builder).
Changing it will not trigger a rebuild – it is "passed through".
Its value can be accessed as if it was set inside a derivation.

::: {.note}
`passthru` attributes follow no particular schema, but there are a few [conventional patterns](#sec-common-passthru-attributes).
:::

:::{.example #ex-accessing-passthru}

## Setting and accessing `passthru` attributes

```nix
{ stdenv, fetchGit }:
let
hello = stdenv.mkDerivation {
pname = "hello";
src = fetchGit { /* ... */ };

passthru = {
foo = "bar";
baz = {
value1 = 4;
value2 = 5;
};
};
};
in
hello.baz.value1
```

```
4
```
:::

## Common `passthru`-attributes {#sec-common-passthru-attributes}

Many `passthru` attributes are situational, so this section only lists recurring patterns.
They fall in one of these categories:

- Global conventions, which are applied almost universally in Nixpkgs.

Generally these don't entail any special support built into the derivation they belong to.
Common examples of this type are [`passthru.tests`](#var-passthru-tests) and [`passthru.updateScript`](#var-passthru-updateScript).

- Conventions for adding extra functionality to a derivation.

These tend to entail support from the derivation or the `passthru` attribute in question.
Common examples of this type are `passthru.optional-dependencies`, `passthru.withPlugins`, and `passthru.withPackages`.
All of those allow associating the package with a set of components built for that specific package, such as when building Python runtime environments using (`python.withPackages`)[#python.withpackages-function].

Attributes that apply only to particular [build helpers](#part-builders) or [language ecosystems](#chap-language-support) are documented there.

### `passthru.tests` {#var-passthru-tests}
[]{#var-meta-tests} <!-- legacy anchor -->

An attribute set with tests as values.
A test is a derivation that builds when the test passes and fails to build otherwise.

Run these tests with:

```ShellSession
$ cd path/to/nixpkgs
$ nix-build -A your-package.tests
```

:::{.note}
The Nixpkgs systems for continuous integration [Hydra](https://hydra.nixos.org/) and [`nixpkgs-review`](https://github.com/Mic92/nixpkgs-review) don't build these derivations by default, and ([`@ofborg`](https://github.com/NixOS/ofborg)) only builds them when evaluating pull requests for that particular package, or when manually instructed.
:::

#### Package tests {#var-passthru-tests-packages}
[]{#var-meta-tests-packages} <!-- legacy anchor -->

Tests that are part of the source package, if they run quickly, are typically executed in the [`installCheckPhase`](#var-stdenv-phases).
This phase is also suitable for performing a `--version` test for packages that support such flag.
Most programs distributed by Nixpkgs support such a `--version` flag, and successfully calling the program with that flag indicates that the package at least got compiled properly.

:::{.example #ex-checking-build-installCheckPhase}

## Checking builds with `installCheckPhase`

When building `git`, a rudimentary test for successful compilation would be running `git --version`:

```nix
stdenv.mkDerivation (finalAttrs: {
pname = "git";
version = "1.2.3";
# ...
doInstallCheck = true;
installCheckPhase = ''
runHook preInstallCheck
echo checking if 'git --version' mentions ${finalAttrs.version}
$out/bin/git --version | grep ${finalAttrs.version}
runHook postInstallCheck
'';
# ...
})
```
:::

However, tests that are non-trivial will better fit into `passthru.tests` because they:

- Access the package as consumers would, independently from the environment in which it was built
- Can be run and debugged without rebuilding the package, which is useful if that takes a long time
- Don't add overhad to each build, as opposed to `installCheckPhase`

It is also possible to use `passthru.tests` to test the version with [`testVersion`](#tester-testVersion).

<!-- NOTE(@fricklerhandwerk): one may argue whether that testing guide should rather be in the user's manual -->
For more on how to write and run package tests for Nixpkgs, see the [testing section in the package contributor guide](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md#package-tests).

#### NixOS tests {#var-passthru-tests-nixos}
[]{#var-meta-tests-nixos} <!-- legacy anchor -->

Tests written for NixOS are available as the `nixosTests` argument to package recipes.
For instance, the [OpenSMTPD derivation](https://search.nixos.org/packages?show=opensmtpd) includes lines similar to:

```nix
{ nixosTests, ... }:
{
# ...
passthru.tests = {
basic-functionality-and-dovecot-integration = nixosTests.opensmtpd;
};
}
```

NixOS tests run in a virtual machine (VM), so they are slower than regular package tests.
For more information see the NixOS manual on [NixOS module tests](https://nixos.org/manual/nixos/stable/#sec-nixos-tests).

### `passthru.updateScript` {#var-passthru-updateScript}
<!-- legacy anchors -->
[]{#var-passthru-updateScript-command}
[]{#var-passthru-updateScript-set-command}
[]{#var-passthru-updateScript-set-attrPath}
[]{#var-passthru-updateScript-set-supportedFeatures}
[]{#var-passthru-updateScript-env-UPDATE_NIX_NAME}
[]{#var-passthru-updateScript-env-UPDATE_NIX_PNAME}
[]{#var-passthru-updateScript-env-UPDATE_NIX_OLD_VERSION}
[]{#var-passthru-updateScript-env-UPDATE_NIX_ATTR_PATH}
[]{#var-passthru-updateScript-execution}
[]{#var-passthru-updateScript-supported-features}
[]{#var-passthru-updateScript-commit}
[]{#var-passthru-updateScript-commit-attrPath}
[]{#var-passthru-updateScript-commit-oldVersion}
[]{#var-passthru-updateScript-commit-newVersion}
[]{#var-passthru-updateScript-commit-files}
[]{#var-passthru-updateScript-commit-commitBody}
[]{#var-passthru-updateScript-commit-commitMessage}
[]{#var-passthru-updateScript-example-commit}

Nixpkgs tries to automatically update all packages that have an `passthru.updateScript` attribute.
See the [section on automatic package updates in the package contributor guide](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md#automatic-package-updates) for details.
Loading