Merge branch 'NixOS:master' into master

This commit is contained in:
Clément DOUIN 2023-02-08 16:55:13 +01:00 committed by GitHub
commit 024c0dc1e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10976 changed files with 212239 additions and 164136 deletions

View File

@ -55,10 +55,13 @@ trim_trailing_whitespace = unset
[*.lock]
indent_size = unset
# trailing whitespace is an actual syntax element of classic Markdown/
# CommonMark to enforce a line break
# Although Markdown/CommonMark allows using two trailing spaces to denote
# a hard line break, we do not use that feature in nixpkgs since
# it forces the surrounding paragraph to become a <literallayout> which
# does not wrap reasonably.
# Instead of a hard line break, start a new paragraph by inserting a blank line.
[*.md]
trim_trailing_whitespace = unset
trim_trailing_whitespace = true
# binaries
[*.nib]

11
.github/CODEOWNERS vendored
View File

@ -28,6 +28,7 @@
/lib/cli.nix @edolstra @nbp @Profpatsch
/lib/debug.nix @edolstra @nbp @Profpatsch
/lib/asserts.nix @edolstra @nbp @Profpatsch
/lib/path.* @infinisil @fricklerhandwerk
# Nixpkgs Internals
/default.nix @nbp
@ -48,6 +49,10 @@
# Nixpkgs build-support
/pkgs/build-support/writers @lassulus @Profpatsch
# Nixpkgs make-disk-image
/doc/builders/images/makediskimage.section.md @raitobezarius
/nixos/lib/make-disk-image.nix @raitobezarius
# Nixpkgs documentation
/maintainers/scripts/db-to-md.sh @jtojnar @ryantm
/maintainers/scripts/doc @jtojnar @ryantm
@ -102,7 +107,7 @@
/pkgs/top-level/python-packages.nix @FRidh @jonringer
/pkgs/development/interpreters/python @FRidh
/pkgs/development/python-modules @FRidh @jonringer
/doc/languages-frameworks/python.section.md @FRidh
/doc/languages-frameworks/python.section.md @FRidh @mweinelt
/pkgs/development/tools/poetry2nix @adisbladis
/pkgs/development/interpreters/python/hooks @FRidh @jonringer
@ -129,7 +134,9 @@
/pkgs/development/ruby-modules @marsam
# Rust
/pkgs/development/compilers/rust @Mic92 @LnL7 @zowoq
/pkgs/development/compilers/rust @Mic92 @LnL7 @zowoq @winterqt @figsoda
/pkgs/build-support/rust @zowoq @winterqt @figsoda
/doc/languages-frameworks/rust.section.md @zowoq @winterqt @figsoda
# C compilers
/pkgs/development/compilers/gcc @matthewbauer

View File

@ -26,6 +26,7 @@ If applicable, add screenshots to help explain your problem.
Add any other context about the problem here.
### Notify maintainers
<!--
Please @ people who are in the `meta.maintainers` list of the offending package or module.
If in doubt, check `git blame` for whoever last touched something.

View File

@ -1,31 +1,36 @@
---
name: Build failure
about: Create a report to help us improve
title: ''
title: 'Build failure: PACKAGENAME'
labels: '0.kind: build failure'
assignees: ''
---
### Steps To Reproduce
Steps to reproduce the behavior:
1. build *X*
### Build log
```
log here if short otherwise a link to a gist
```
### Additional context
Add any other context about the problem here.
### Notify maintainers
<!--
Please @ people who are in the `meta.maintainers` list of the offending package or module.
If in doubt, check `git blame` for whoever last touched something.
-->
### Metadata
Please run `nix-shell -p nix-info --run "nix-info -m"` and paste the result.
```console

View File

@ -1,7 +1,7 @@
---
name: Missing or incorrect documentation
about: Help us improve the Nixpkgs and NixOS reference manuals
title: ''
title: 'Documentation: '
labels: '9.needs: documentation'
assignees: ''
@ -11,6 +11,10 @@ assignees: ''
<!-- describe your problem -->
## Proposal
<!-- propose a solution (optional) -->
## Checklist
<!-- make sure this issue is not redundant or obsolete -->
@ -26,7 +30,3 @@ assignees: ''
[open documentation issues]: https://github.com/NixOS/nixpkgs/issues?q=is%3Aissue+is%3Aopen+label%3A%229.needs%3A+documentation%22
[open documentation pull requests]: https://github.com/NixOS/nixpkgs/pulls?q=is%3Aopen+is%3Apr+label%3A%228.has%3A+documentation%22%2C%226.topic%3A+documentation%22
## Proposal
<!-- propose a solution -->

View File

@ -1,24 +1,17 @@
---
name: Out-of-date package reports
about: For packages that are out-of-date
title: ''
title: 'Update request: PACKAGENAME OLDVERSION → NEWVERSION'
labels: '9.needs: package (update)'
assignees: ''
---
###### Checklist
<!-- Note that these are hard requirements -->
<!--
You can use the "Go to file" functionality on GitHub to find the package
Then you can go to the history for this package
Find the latest "package_name: old_version -> new_version" commit
The "new_version" is the current version of the package
-->
- [ ] Checked the [nixpkgs master branch](https://github.com/NixOS/nixpkgs)
- Package name:
- Latest released version:
<!-- Search your package here: https://search.nixos.org/packages?channel=unstable -->
- Current version on the unstable channel:
- Current version on the stable/release channel:
<!--
Type the name of your package and try to find an open pull request for the package
If you find an open pull request, you can review it!
@ -26,23 +19,10 @@ There's a high chance that you'll have the new version right away while helping
-->
- [ ] Checked the [nixpkgs pull requests](https://github.com/NixOS/nixpkgs/pulls)
###### Project name
`nix search` name:
<!--
The current version can be found easily with the same process as above for checking the master branch
If an open PR is present for the package, take this version as the current one and link to the PR
-->
current version:
desired version:
**Notify maintainers**
###### Notify maintainers
<!--
Search your package here: https://search.nixos.org/packages?channel=unstable
If no maintainer is listed for your package, tag the person that last updated the package
-->
<!-- If the search.nixos.org result shows no maintainers, tag the person that last updated the package. -->
maintainers:
-----
###### Note for maintainers
Please tag this issue in your PR.
Note for maintainers: Please tag this issue in your PR.

View File

@ -1,14 +1,15 @@
---
name: Packaging requests
about: For packages that are missing
title: ''
title: 'Package request: PACKAGENAME'
labels: '0.kind: packaging request'
assignees: ''
---
**Project description**
_describe the project a little_
<!-- Describe the project a little: -->
**Metadata**

View File

@ -2,7 +2,7 @@
name: Unreproducible package
about: A package that does not produce a bit-by-bit reproducible result each time it is built
title: ''
labels: '0.kind: enhancement', '6.topic: reproducible builds'
labels: [ '0.kind: enhancement', '6.topic: reproducible builds' ]
assignees: ''
---

18
.github/labeler.yml vendored
View File

@ -19,6 +19,11 @@
- pkgs/build-support/emacs/**/*
- pkgs/top-level/emacs-packages.nix
"6.topic: Enlightenment DE":
- nixos/modules/services/x11/desktop-managers/enlightenment.nix
- pkgs/desktops/enlightenment/**/*
- pkgs/development/python-modules/python-efl/*
"6.topic: erlang":
- doc/languages-frameworks/beam.section.md
- pkgs/development/beam-modules/**/*
@ -65,6 +70,19 @@
- pkgs/development/lua-modules/**/*
- pkgs/top-level/lua-packages.nix
"6.topic: Lumina DE":
- nixos/modules/services/x11/desktop-managers/lumina.nix
- pkgs/desktops/lumina/**/*
"6.topic: LXQt":
- nixos/modules/services/x11/desktop-managers/lxqt.nix
- pkgs/desktops/lxqt/**/*
"6.topic: mate":
- nixos/modules/services/x11/desktop-managers/mate.nix
- nixos/tests/mate.nix
- pkgs/desktops/mate/**/*
"6.topic: nixos":
- nixos/**/*
- pkgs/os-specific/linux/nixos-rebuild/**/*

View File

@ -14,23 +14,19 @@ permissions:
jobs:
backport:
permissions:
contents: write # for zeebe-io/backport-action to create branch
pull-requests: write # for zeebe-io/backport-action to create PR to backport
contents: write # for korthout/backport-action to create branch
pull-requests: write # for korthout/backport-action to create PR to backport
name: Backport Pull Request
if: github.repository_owner == 'NixOS' && github.event.pull_request.merged == true && (github.event_name != 'labeled' || startsWith('backport', github.event.label.name))
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
# required to find all branches
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Create backport PRs
uses: zeebe-io/backport-action@v0.0.9
uses: korthout/backport-action@v1.1.0
with:
# Config README: https://github.com/zeebe-io/backport-action#backport-action
github_token: ${{ secrets.GITHUB_TOKEN }}
github_workspace: ${{ github.workspace }}
# Config README: https://github.com/korthout/backport-action#backport-action
pull_description: |-
Bot-based backport to `${target_branch}`, triggered by a label in #${pull_number}.

View File

@ -11,7 +11,7 @@ on:
jobs:
tests:
runs-on: ubuntu-latest
if: "github.repository_owner == 'NixOS' && !contains(github.event.pull_request.title, '[skip editorconfig]')"
if: "github.repository_owner == 'NixOS' && !contains(github.event.pull_request.title, '[skip treewide]')"
steps:
- name: Get list of changed files from PR
env:

View File

@ -16,7 +16,7 @@ permissions:
jobs:
labels:
runs-on: ubuntu-latest
if: github.repository_owner == 'NixOS'
if: "github.repository_owner == 'NixOS' && !contains(github.event.pull_request.title, '[skip treewide]')"
steps:
- uses: actions/labeler@v4
with:

View File

@ -38,10 +38,6 @@ jobs:
into: staging-next-22.11
- from: staging-next-22.11
into: staging-22.11
- from: release-22.05
into: staging-next-22.05
- from: staging-next-22.05
into: staging-22.05
name: ${{ matrix.pairs.from }} → ${{ matrix.pairs.into }}
steps:
- uses: actions/checkout@v3

View File

@ -11,8 +11,8 @@ permissions:
jobs:
tf-providers:
permissions:
contents: write # for peter-evans/create-pull-request to create branch
pull-requests: write # for peter-evans/create-pull-request to create a PR, for peter-evans/create-or-update-comment to create or update comment
contents: write # for peter-evans/create-pull-request to create branch
pull-requests: write # for peter-evans/create-pull-request to create a PR, for peter-evans/create-or-update-comment to create or update comment
if: github.repository_owner == 'NixOS' && github.ref == 'refs/heads/master' # ensure workflow_dispatch only runs on master
runs-on: ubuntu-latest
steps:
@ -25,6 +25,8 @@ jobs:
run: |
echo "title=terraform-providers: update $(date -u +"%Y-%m-%d")" >> $GITHUB_OUTPUT
- name: update terraform-providers
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config user.name "github-actions[bot]"

View File

@ -38,11 +38,14 @@ Below is a short excerpt of some points in there:
The old config generation system used impure shell scripts and could break in specific circumstances (see #1234).
* `meta.description` should:
* Be short, just one sentence.
* Be capitalized.
* Not start with the package name.
* Not have a period at the end.
* More generally, it should not refer to the package name.
* Not end with a period (or any punctuation for that matter).
* `meta.license` must be set and fit the upstream license.
* If there is no upstream license, `meta.license` should default to `lib.licenses.unfree`.
* If in doubt, try to contact the upstream developers for clarification.
* `meta.maintainers` must be set.
See the nixpkgs manual for more details on [standard meta-attributes](https://nixos.org/nixpkgs/manual/#sec-standard-meta-attributes).
@ -55,7 +58,7 @@ Package version upgrades usually allow for simpler commit messages, including at
Pull requests should not be squash merged in order to keep complete commit messages and GPG signatures intact and must not be when the change doesn't make sense as a single commit.
This means that, when addressing review comments in order to keep the pull request in an always mergeable status, you will sometimes need to rewrite your branch's history and then force-push it with `git push --force-with-lease`.
Useful git commands that can help a lot with this are `git commit --patch --amend` and `git rebase --interactive @~3`. For more details consult the git man pages.
Useful git commands that can help a lot with this are `git commit --patch --amend` and `git rebase --interactive`. For more details consult the git man pages or online resources like [git-rebase.io](https://git-rebase.io/) or [The Pro Git Book](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History).
## Rebasing between branches (i.e. from master to staging)

View File

@ -1,4 +1,4 @@
Copyright (c) 2003-2022 Eelco Dolstra and the Nixpkgs/NixOS contributors
Copyright (c) 2003-2023 Eelco Dolstra and the Nixpkgs/NixOS contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@ -11,7 +11,7 @@ pandoc_commonmark_enabled_extensions = +attributes+fenced_divs+footnotes+bracket
pandoc_flags = --extract-media=$(pandoc_media_dir) \
--lua-filter=$(PANDOC_LUA_FILTERS_DIR)/diagram-generator.lua \
--lua-filter=build-aux/pandoc-filters/myst-reader/roles.lua \
--lua-filter=build-aux/pandoc-filters/link-unix-man-references.lua \
--lua-filter=$(PANDOC_LINK_MANPAGES_FILTER) \
--lua-filter=build-aux/pandoc-filters/docbook-writer/rst-roles.lua \
--lua-filter=build-aux/pandoc-filters/docbook-writer/labelless-link-is-xref.lua \
-f commonmark$(pandoc_commonmark_enabled_extensions)+smart

View File

@ -0,0 +1,28 @@
{ pkgs ? import ../../.. {} }:
let
inherit (pkgs) lib;
manpageURLs = builtins.fromJSON (builtins.readFile (pkgs.path + "/doc/manpage-urls.json"));
in pkgs.writeText "link-manpages.lua" ''
--[[
Adds links to known man pages that aren't already in a link.
]]
local manpage_urls = {
${lib.concatStringsSep "\n" (lib.mapAttrsToList (man: url:
" [${builtins.toJSON man}] = ${builtins.toJSON url},") manpageURLs)}
}
traverse = 'topdown'
-- Returning false as the second value aborts processing of child elements.
function Link(elem)
return elem, false
end
function Code(elem)
local is_man_role = elem.classes:includes('interpreted-text') and elem.attributes['role'] == 'manpage'
if is_man_role and manpage_urls[elem.text] ~= nil then
return pandoc.Link(elem, manpage_urls[elem.text]), false
end
end
''

View File

@ -1,17 +0,0 @@
--[[
Turns a manpage reference into a link, when a mapping is defined below.
]]
local man_urls = {
["tmpfiles.d(5)"] = "https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html",
["nix.conf(5)"] = "https://nixos.org/manual/nix/stable/#sec-conf-file",
["systemd.time(7)"] = "https://www.freedesktop.org/software/systemd/man/systemd.time.html",
["systemd.timer(5)"] = "https://www.freedesktop.org/software/systemd/man/systemd.timer.html",
}
function Code(elem)
local is_man_role = elem.classes:includes('interpreted-text') and elem.attributes['role'] == 'manpage'
if is_man_role and man_urls[elem.text] ~= nil then
return pandoc.Link(elem, man_urls[elem.text])
end
end

View File

@ -17,9 +17,16 @@ function Inlines(inlines)
if correct_tags then
-- docutils supports alphanumeric strings separated by [-._:]
-- We are slightly more liberal for simplicity.
local role = first.text:match('^{([-._+:%w]+)}$')
if role ~= nil then
inlines:remove(i)
-- Allow preceding punctuation (eg '('), otherwise '({file}`...`)'
-- does not match. Also allow anything followed by a non-breaking space
-- since pandoc emits those after certain abbreviations (e.g. e.g.).
local prefix, role = first.text:match('^(.*){([-._+:%w]+)}$')
if role ~= nil and (prefix == '' or prefix:match("^.*[%p ]$") ~= nil) then
if prefix == '' then
inlines:remove(i)
else
first.text = prefix
end
second.attributes['role'] = role
second.classes:insert('interpreted-text')
end

View File

@ -163,3 +163,30 @@ or "hg"), `domain` and `fetchSubmodules`.
If `fetchSubmodules` is `true`, `fetchFromSourcehut` uses `fetchgit`
or `fetchhg` with `fetchSubmodules` or `fetchSubrepos` set to `true`,
respectively. Otherwise, the fetcher uses `fetchzip`.
## `requireFile` {#requirefile}
`requireFile` allows requesting files that cannot be fetched automatically, but whose content is known.
This is a useful last-resort workaround for license restrictions that prohibit redistribution, or for downloads that are only accessible after authenticating interactively in a browser.
If the requested file is present in the Nix store, the resulting derivation will not be built, because its expected output is already available.
Otherwise, the builder will run, but fail with a message explaining to the user how to provide the file. The following code, for example:
```
requireFile {
name = "jdk-${version}_linux-x64_bin.tar.gz";
url = "https://www.oracle.com/java/technologies/javase-jdk11-downloads.html";
sha256 = "94bd34f85ee38d3ef59e5289ec7450b9443b924c55625661fffe66b03f2c8de2";
}
```
results in this error message:
```
***
Unfortunately, we cannot download file jdk-11.0.10_linux-x64_bin.tar.gz automatically.
Please go to https://www.oracle.com/java/technologies/javase-jdk11-downloads.html to download it yourself, and add it to the Nix store
using either
nix-store --add-fixed sha256 jdk-11.0.10_linux-x64_bin.tar.gz
or
nix-prefetch-url --type sha256 file:///path/to/jdk-11.0.10_linux-x64_bin.tar.gz
***
```

View File

@ -10,4 +10,5 @@
<xi:include href="images/ocitools.section.xml" />
<xi:include href="images/snaptools.section.xml" />
<xi:include href="images/portableservice.section.xml" />
<xi:include href="images/makediskimage.section.xml" />
</chapter>

View File

@ -145,7 +145,7 @@ Create a Docker image with many of the store paths being on their own layer to i
`architecture` is _optional_ and used to specify the image architecture, this is useful for multi-architecture builds that don't need cross compiling. If not specified it will default to `hostPlatform`.
: Run-time configuration of the container. A full list of the options are available at in the [Docker Image Specification v1.2.0](https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions).
: Run-time configuration of the container. A full list of the options available is in the [Docker Image Specification v1.2.0](https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions).
*Default:* `{}`

View File

@ -0,0 +1,107 @@
# `<nixpkgs/nixos/lib/make-disk-image.nix>` {#sec-make-disk-image}
`<nixpkgs/nixos/lib/make-disk-image.nix>` is a function to create _disk images_ in multiple formats: raw, QCOW2 (QEMU), QCOW2-Compressed (compressed version), VDI (VirtualBox), VPC (VirtualPC).
This function can create images in two ways:
- using `cptofs` without any virtual machine to create a Nix store disk image,
- using a virtual machine to create a full NixOS installation.
When testing early-boot or lifecycle parts of NixOS such as a bootloader or multiple generations, it is necessary to opt for a full NixOS system installation.
Whereas for many web servers, applications, it is possible to work with a Nix store only disk image and is faster to build.
NixOS tests also use this function when preparing the VM. The `cptofs` method is used when `virtualisation.useBootLoader` is false (the default). Otherwise the second method is used.
## Features
For reference, read the function signature source code for documentation on arguments: <https://github.com/NixOS/nixpkgs/blob/master/nixos/lib/make-disk-image.nix>.
Features are separated in various sections depending on if you opt for a Nix-store only image or a full NixOS image.
### Common
- arbitrary NixOS configuration
- automatic or bound disk size: `diskSize` parameter, `additionalSpace` can be set when `diskSize` is `auto` to add a constant of disk space
- multiple partition table layouts: EFI, legacy, legacy + GPT, hybrid, none through `partitionTableType` parameter
- OVMF or EFI firmwares and variables templates can be customized
- root filesystem `fsType` can be customized to whatever `mkfs.${fsType}` exist during operations
- root filesystem label can be customized, defaults to `nix-store` if it's a Nix store image, otherwise `nixpkgs/nixos`
- arbitrary code can be executed after disk image was produced with `postVM`
- the current nixpkgs can be realized as a channel in the disk image, which will change the hash of the image when the sources are updated
- additional store paths can be provided through `additionalPaths`
### Full NixOS image
- arbitrary contents with permissions can be placed in the target filesystem using `contents`
- a `/etc/nixpkgs/nixos/configuration.nix` can be provided through `configFile`
- bootloaders are supported
- EFI variables can be mutated during image production and the result is exposed in `$out`
- boot partition size when partition table is `efi` or `hybrid`
### On bit-to-bit reproducibility
Images are **NOT** deterministic, please do not hesitate to try to fix this, source of determinisms are (not exhaustive) :
- bootloader installation have timestamps
- SQLite Nix store database contain registration times
- `/etc/shadow` is in a non-deterministic order
A `deterministic` flag is available for best efforts determinism.
## Usage
To produce a Nix-store only image:
```nix
let
pkgs = import <nixpkgs> {};
lib = pkgs.lib;
make-disk-image = import <nixpkgs/nixos/lib/make-disk-image.nix>;
in
make-disk-image {
inherit pkgs lib;
config = {};
additionalPaths = [ ];
format = "qcow2";
onlyNixStore = true;
partitionTableType = "none";
installBootLoader = false;
touchEFIVars = false;
diskSize = "auto";
additionalSpace = "0M"; # Defaults to 512M.
copyChannel = false;
}
```
Some arguments can be left out, they are shown explicitly for the sake of the example.
Building this derivation will provide a QCOW2 disk image containing only the Nix store and its registration information.
To produce a NixOS installation image disk with UEFI and bootloader installed:
```nix
let
pkgs = import <nixpkgs> {};
lib = pkgs.lib;
make-disk-image = import <nixpkgs/nixos/lib/make-disk-image.nix>;
evalConfig = import <nixpkgs/nixos/lib/eval-config.nix>;
in
make-disk-image {
inherit pkgs lib;
config = evalConfig {
modules = [
{
fileSystems."/" = { device = "/dev/vda"; fsType = "ext4"; autoFormat = true; };
boot.grub.device = "/dev/vda";
}
];
};
format = "qcow2";
onlyNixStore = false;
partitionTableType = "legacy+gpt";
installBootLoader = true;
touchEFIVars = true;
diskSize = "auto";
additionalSpace = "0M"; # Defaults to 512M.
copyChannel = false;
}
```

View File

@ -34,4 +34,4 @@ buildContainer {
- `mounts` specifies additional mount points chosen by the user. By default only a minimal set of necessary filesystems are mounted into the container (e.g procfs, cgroupfs)
- `readonly` makes the container\'s rootfs read-only if it is set to true. The default value is false `false`.
- `readonly` makes the container's rootfs read-only if it is set to true. The default value is false `false`.

View File

@ -4,7 +4,7 @@ The [Citrix Workspace App](https://www.citrix.com/products/workspace-app/) is a
## Basic usage {#sec-citrix-base}
The tarball archive needs to be downloaded manually, as the license agreements of the vendor for [Citrix Workspace](https://www.citrix.de/downloads/workspace-app/linux/workspace-app-for-linux-latest.html) needs to be accepted first. Then run `nix-prefetch-url file://$PWD/linuxx64-$version.tar.gz`. With the archive available in the store, the package can be built and installed with Nix.
The tarball archive needs to be downloaded manually, as the license agreements of the vendor for [Citrix Workspace](https://www.citrix.com/downloads/workspace-app/linux/workspace-app-for-linux-latest.html) needs to be accepted first. Then run `nix-prefetch-url file://$PWD/linuxx64-$version.tar.gz`. With the archive available in the store, the package can be built and installed with Nix.
## Citrix Self-service {#sec-citrix-selfservice}
@ -19,7 +19,7 @@ $ selfservice
## Custom certificates {#sec-citrix-custom-certs}
The `Citrix Workspace App` in `nixpkgs` trusts several certificates [from the Mozilla database](https://curl.haxx.se/docs/caextract.html) by default. However, several companies using Citrix might require their own corporate certificate. On distros with imperative packaging, these certs can be stored easily in [`$ICAROOT`](https://developer-docs.citrix.com/projects/receiver-for-linux-command-reference/en/13.7/), however this directory is a store path in `nixpkgs`. In order to work around this issue, the package provides a simple mechanism to add custom certificates without rebuilding the entire package using `symlinkJoin`:
The `Citrix Workspace App` in `nixpkgs` trusts several certificates [from the Mozilla database](https://curl.haxx.se/docs/caextract.html) by default. However, several companies using Citrix might require their own corporate certificate. On distros with imperative packaging, these certs can be stored easily in [`$ICAROOT`](https://citrix.github.io/receiver-for-linux-command-reference/), however this directory is a store path in `nixpkgs`. In order to work around this issue, the package provides a simple mechanism to add custom certificates without rebuilding the entire package using `symlinkJoin`:
```nix
with import <nixpkgs> { config.allowUnfree = true; };

View File

@ -4,7 +4,7 @@
## Compiling without AVX support {#compiling-without-avx-support}
Especially older CPUs don\'t support [AVX](https://en.wikipedia.org/wiki/Advanced_Vector_Extensions) (Advanced Vector Extensions) instructions that are used by DLib to optimize their algorithms.
Especially older CPUs don't support [AVX](https://en.wikipedia.org/wiki/Advanced_Vector_Extensions) (Advanced Vector Extensions) instructions that are used by DLib to optimize their algorithms.
On the affected hardware errors like `Illegal instruction` will occur. In those cases AVX support needs to be disabled:

View File

@ -4,7 +4,7 @@ This package is an ibus-based completion method to speed up typing.
## Activating the engine {#sec-ibus-typing-booster-activate}
IBus needs to be configured accordingly to activate `typing-booster`. The configuration depends on the desktop manager in use. For detailed instructions, please refer to the [upstream docs](https://mike-fabian.github.io/ibus-typing-booster/documentation.html).
IBus needs to be configured accordingly to activate `typing-booster`. The configuration depends on the desktop manager in use. For detailed instructions, please refer to the [upstream docs](https://mike-fabian.github.io/ibus-typing-booster/).
On NixOS, you need to explicitly enable `ibus` with given engines before customizing your desktop to use `typing-booster`. This can be achieved using the `ibus` module:

View File

@ -7,4 +7,5 @@
</para>
<xi:include href="special/fhs-environments.section.xml" />
<xi:include href="special/mkshell.section.xml" />
<xi:include href="special/darwin-builder.section.xml" />
</chapter>

View File

@ -0,0 +1,63 @@
# darwin.builder {#sec-darwin-builder}
`darwin.builder` provides a way to bootstrap a Linux builder on a macOS machine.
This requires macOS version 12.4 or later.
This also requires that port 22 on your machine is free (since Nix does not
permit specifying a non-default SSH port for builders).
You will also need to be a trusted user for your Nix installation. In other
words, your `/etc/nix/nix.conf` should have something like:
```
extra-trusted-users = <your username goes here>
```
To launch the builder, run the following flake:
```ShellSession
$ nix run nixpkgs#darwin.builder
```
That will prompt you to enter your `sudo` password:
```
+ sudo --reset-timestamp /nix/store/…-install-credentials.sh ./keys
Password:
```
… so that it can install a private key used to `ssh` into the build server.
After that the script will launch the virtual machine and automatically log you
in as the `builder` user:
```
<<< Welcome to NixOS 22.11.20220901.1bd8d11 (aarch64) - ttyAMA0 >>>
Run 'nixos-help' for the NixOS manual.
nixos login: builder (automatic login)
[builder@nixos:~]$
```
> Note: When you need to stop the VM, run `shutdown now` as the `builder` user.
To delegate builds to the remote builder, add the following options to your
`nix.conf` file:
```
# - Replace ${ARCH} with either aarch64 or x86_64 to match your host machine
# - Replace ${MAX_JOBS} with the maximum number of builds (pick 4 if you're not sure)
builders = ssh-ng://builder@localhost ${ARCH}-linux /etc/nix/builder_ed25519 ${MAX_JOBS} - - - c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUpCV2N4Yi9CbGFxdDFhdU90RStGOFFVV3JVb3RpQzVxQkorVXVFV2RWQ2Igcm9vdEBuaXhvcwo=
# Not strictly necessary, but this will reduce your disk utilization
builders-use-substitutes = true
```
… and then restart your Nix daemon to apply the change:
```ShellSession
$ sudo launchctl kickstart -k system/org.nixos.nix-daemon
```

View File

@ -1,6 +1,19 @@
# Testers {#chap-testers}
This chapter describes several testing builders which are available in the <literal>testers</literal> namespace.
## `hasPkgConfigModule` {#tester-hasPkgConfigModule}
Checks whether a package exposes a certain `pkg-config` module.
Example:
```nix
passthru.tests.pkg-config = testers.hasPkgConfigModule {
package = finalAttrs.finalPackage;
moduleName = "libfoo";
}
```
## `testVersion` {#tester-testVersion}
Checks the command output contains the specified version
@ -62,7 +75,7 @@ runCommand "example" {
'';
```
While `testBuildFailure` is designed to keep changes to the original builder's
While `testBuildFailure` is designed to keep changes to the original builder's
environment to a minimum, some small changes are inevitable.
- The file `$TMPDIR/testBuildFailure.log` is present. It should not be deleted.

View File

@ -204,13 +204,13 @@ The key words _must_, _must not_, _required_, _shall_, _shall not_, _should_, _s
In Nixpkgs, there are generally three different names associated with a package:
- The `name` attribute of the derivation (excluding the version part). This is what most users see, in particular when using `nix-env`.
- The `pname` attribute of the derivation. This is what most users see, in particular when using `nix-env`.
- The variable name used for the instantiated package in `all-packages.nix`, and when passing it as a dependency to other functions. Typically this is called the _package attribute name_. This is what Nix expression authors see. It can also be used when installing using `nix-env -iA`.
- The filename for (the directory containing) the Nix expression.
Most of the time, these are the same. For instance, the package `e2fsprogs` has a `name` attribute `"e2fsprogs-version"`, is bound to the variable name `e2fsprogs` in `all-packages.nix`, and the Nix expression is in `pkgs/os-specific/linux/e2fsprogs/default.nix`.
Most of the time, these are the same. For instance, the package `e2fsprogs` has a `pname` attribute `"e2fsprogs"`, is bound to the variable name `e2fsprogs` in `all-packages.nix`, and the Nix expression is in `pkgs/os-specific/linux/e2fsprogs/default.nix`.
There are a few naming guidelines:
@ -260,6 +260,10 @@ When in doubt, consider refactoring the `pkgs/` tree, e.g. creating new categori
- `development/tools/build-managers` (e.g. `gnumake`)
- **If its a _language server_:**
- `development/tools/language-servers` (e.g. `ccls` or `rnix-lsp`)
- **Else:**
- `development/tools/misc` (e.g. `binutils`)

View File

@ -27,7 +27,7 @@ If the build succeeds, the manual will be in `./result/share/doc/nixpkgs/manual.
As per [RFC 0072](https://github.com/NixOS/rfcs/pull/72), all new documentation content should be written in [CommonMark](https://commonmark.org/) Markdown dialect.
Additional syntax extensions are available, though not all extensions can be used in NixOS option documentation. The following extensions are currently used:
Additional syntax extensions are available, all of which can be used in NixOS option documentation. The following extensions are currently used:
- []{#ssec-contributing-markup-anchors}
Explicitly defined **anchors** on headings, to allow linking to sections. These should be always used, to ensure the anchors can be linked even when the heading text changes, and to prevent conflicts between [automatically assigned identifiers](https://github.com/jgm/commonmark-hs/blob/master/commonmark-extensions/test/auto_identifiers.md).
@ -38,6 +38,10 @@ Additional syntax extensions are available, though not all extensions can be use
## Syntax {#sec-contributing-markup}
```
::: {.note}
NixOS option documentation does not support headings in general.
:::
- []{#ssec-contributing-markup-anchors-inline}
**Inline anchors**, which allow linking arbitrary place in the text (e.g. individual list items, sentences…).
@ -53,7 +57,7 @@ Additional syntax extensions are available, though not all extensions can be use
This syntax is taken from [MyST](https://myst-parser.readthedocs.io/en/latest/using/syntax.html#targets-and-cross-referencing).
- []{#ssec-contributing-markup-inline-roles}
If you want to link to a man page, you can use `` {manpage}`nix.conf(5)` ``, which will turn into {manpage}`nix.conf(5)`. The references will turn into links when a mapping exists in {file}`doc/build-aux/pandoc-filters/link-unix-man-references.lua`.
If you want to link to a man page, you can use `` {manpage}`nix.conf(5)` ``, which will turn into {manpage}`nix.conf(5)`. The references will turn into links when a mapping exists in {file}`doc/manpage-urls.json`.
A few markups for other kinds of literals are also available:
@ -67,10 +71,6 @@ Additional syntax extensions are available, though not all extensions can be use
This syntax is taken from [MyST](https://myst-parser.readthedocs.io/en/latest/syntax/syntax.html#roles-an-in-line-extension-point). Though, the feature originates from [reStructuredText](https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html#role-manpage) with slightly different syntax.
::: {.note}
Inline roles are available for option documentation.
:::
- []{#ssec-contributing-markup-admonitions}
**Admonitions**, set off from the text to bring attention to something.
@ -96,10 +96,6 @@ Additional syntax extensions are available, though not all extensions can be use
- [`tip`](https://tdg.docbook.org/tdg/5.0/tip.html)
- [`warning`](https://tdg.docbook.org/tdg/5.0/warning.html)
::: {.note}
Admonitions are available for option documentation.
:::
- []{#ssec-contributing-markup-definition-lists}
[**Definition lists**](https://github.com/jgm/commonmark-hs/blob/master/commonmark-extensions/test/definition_lists.md), for defining a group of terms:

View File

@ -34,7 +34,7 @@ To add a package to Nixpkgs:
- Apache HTTPD: [`pkgs/servers/http/apache-httpd/2.4.nix`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/http/apache-httpd/2.4.nix). A bunch of optional features, variable substitutions in the configure flags, a post-install hook, and miscellaneous hackery.
- Thunderbird: [`pkgs/applications/networking/mailreaders/thunderbird/default.nix`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/networking/mailreaders/thunderbird/default.nix). Lots of dependencies.
- buildMozillaMach: [`pkgs/applications/networking/browser/firefox/common.nix`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/networking/browsers/firefox/common.nix). A reusable build function for Firefox, Thunderbird and Librewolf.
- JDiskReport, a Java utility: [`pkgs/tools/misc/jdiskreport/default.nix`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/misc/jdiskreport/default.nix). Nixpkgs doesnt have a decent `stdenv` for Java yet so this is pretty ad-hoc.

View File

@ -199,7 +199,7 @@ Its important to test any executables generated by a build when you change or
### Meets Nixpkgs contribution standards {#submitting-changes-contribution-standards}
The last checkbox is fits [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md). The contributing document has detailed information on standards the Nix community has for commit messages, reviews, licensing of contributions you make to the project, etc\... Everyone should read and understand the standards the community has for contributing before submitting a pull request.
The last checkbox is fits [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md). The contributing document has detailed information on standards the Nix community has for commit messages, reviews, licensing of contributions you make to the project, etc... Everyone should read and understand the standards the community has for contributing before submitting a pull request.
## Hotfixing pull requests {#submitting-changes-hotfixing-pull-requests}

View File

@ -1,6 +1,5 @@
{ pkgs ? (import ./.. { }), nixpkgs ? { }}:
let
lib = pkgs.lib;
doc-support = import ./doc-support { inherit pkgs nixpkgs; };
in pkgs.stdenv.mkDerivation {
name = "nixpkgs-manual";
@ -15,7 +14,7 @@ in pkgs.stdenv.mkDerivation {
xmlformat
];
src = lib.cleanSource ./.;
src = pkgs.nix-gitignore.gitignoreSource [] ./.;
postPatch = ''
ln -s ${doc-support} ./doc-support/result
@ -36,4 +35,5 @@ in pkgs.stdenv.mkDerivation {
# Environment variables
PANDOC_LUA_FILTERS_DIR = "${pkgs.pandoc-lua-filters}/share/pandoc/filters";
PANDOC_LINK_MANPAGES_FILTER = import build-aux/pandoc-filters/link-manpages.nix { inherit pkgs; };
}

View File

@ -3,8 +3,23 @@ let
inherit (pkgs) lib;
inherit (lib) hasPrefix removePrefix;
locationsXml = import ./lib-function-locations.nix { inherit pkgs nixpkgs; };
functionDocs = import ./lib-function-docs.nix { inherit locationsXml pkgs; };
libsets = [
{ name = "asserts"; description = "assertion functions"; }
{ name = "attrsets"; description = "attribute set functions"; }
{ name = "strings"; description = "string manipulation functions"; }
{ name = "versions"; description = "version string functions"; }
{ name = "trivial"; description = "miscellaneous functions"; }
{ name = "lists"; description = "list manipulation functions"; }
{ name = "debug"; description = "debugging functions"; }
{ name = "options"; description = "NixOS / nixpkgs option handling"; }
{ name = "path"; description = "path functions"; }
{ name = "filesystem"; description = "filesystem functions"; }
{ name = "sources"; description = "source filtering functions"; }
{ name = "cli"; description = "command-line serialization functions"; }
];
locationsXml = import ./lib-function-locations.nix { inherit pkgs nixpkgs libsets; };
functionDocs = import ./lib-function-docs.nix { inherit locationsXml pkgs libsets; };
version = pkgs.lib.version;
epub-xsl = pkgs.writeText "epub.xsl" ''

View File

@ -1,30 +1,36 @@
# Generates the documentation for library functions via nixdoc. To add
# another library function file to this list, the include list in the
# file `doc/functions/library.xml` must also be updated.
# Generates the documentation for library functions via nixdoc.
{ pkgs ? import ./.. {}, locationsXml }:
{ pkgs, locationsXml, libsets }:
with pkgs; stdenv.mkDerivation {
name = "nixpkgs-lib-docs";
src = ./../../lib;
src = ../../lib;
buildInputs = [ nixdoc ];
installPhase = ''
function docgen {
nixdoc -c "$1" -d "$2" -f "../lib/$1.nix" > "$out/$1.xml"
# TODO: wrap lib.$1 in <literal>, make nixdoc not escape it
if [[ -e "../lib/$1.nix" ]]; then
nixdoc -c "$1" -d "lib.$1: $2" -f "$1.nix" > "$out/$1.xml"
else
nixdoc -c "$1" -d "lib.$1: $2" -f "$1/default.nix" > "$out/$1.xml"
fi
echo "<xi:include href='$1.xml' />" >> "$out/index.xml"
}
mkdir -p $out
ln -s ${locationsXml} $out/locations.xml
mkdir -p "$out"
docgen asserts 'Assert functions'
docgen attrsets 'Attribute-set functions'
docgen strings 'String manipulation functions'
docgen trivial 'Miscellaneous functions'
docgen lists 'List manipulation functions'
docgen debug 'Debugging functions'
docgen options 'NixOS / nixpkgs option handling'
docgen filesystem 'Filesystem functions'
docgen sources 'Source filtering functions'
cat > "$out/index.xml" << 'EOF'
<?xml version="1.0" encoding="utf-8"?>
<root xmlns:xi="http://www.w3.org/2001/XInclude">
EOF
${lib.concatMapStrings ({ name, description }: ''
docgen ${name} ${lib.escapeShellArg description}
'') libsets}
echo "</root>" >> "$out/index.xml"
ln -s ${locationsXml} $out/locations.xml
'';
}

View File

@ -1,24 +1,24 @@
{ pkgs ? (import ./.. { }), nixpkgs ? { }}:
{ pkgs, nixpkgs ? { }, libsets }:
let
revision = pkgs.lib.trivial.revisionWithDefault (nixpkgs.revision or "master");
libDefPos = set:
builtins.map
(name: {
name = name;
libDefPos = prefix: set:
builtins.concatMap
(name: [{
name = builtins.concatStringsSep "." (prefix ++ [name]);
location = builtins.unsafeGetAttrPos name set;
})
(builtins.attrNames set);
}] ++ nixpkgsLib.optionals
(builtins.length prefix == 0 && builtins.isAttrs set.${name})
(libDefPos (prefix ++ [name]) set.${name})
) (builtins.attrNames set);
libset = toplib:
builtins.map
(subsetname: {
subsetname = subsetname;
functions = libDefPos toplib.${subsetname};
functions = libDefPos [] toplib.${subsetname};
})
(builtins.filter
(name: builtins.isAttrs toplib.${name})
(builtins.attrNames toplib));
(builtins.map (x: x.name) libsets);
nixpkgsLib = pkgs.lib;

View File

@ -11,6 +11,7 @@
<xsl:param name="html.script" select="'./highlightjs/highlight.pack.js ./highlightjs/loader.js'" />
<xsl:param name="xref.with.number.and.title" select="0" />
<xsl:param name="use.id.as.filename" select="1" />
<xsl:param name="generate.section.toc.level" select="1" />
<xsl:param name="toc.section.depth" select="0" />
<xsl:param name="admon.style" select="''" />
<xsl:param name="callout.graphics.extension" select="'.svg'" />

View File

@ -8,25 +8,7 @@
Nixpkgs provides a standard library at <varname>pkgs.lib</varname>, or through <code>import &lt;nixpkgs/lib&gt;</code>.
</para>
<!-- These docs are generated via nixdoc. To add another generated
library function file to this list, the file
`lib-function-docs.nix` must also be updated. -->
<xi:include href="./library/generated/asserts.xml" />
<xi:include href="./library/generated/attrsets.xml" />
<xi:include href="./library/generated/strings.xml" />
<xi:include href="./library/generated/trivial.xml" />
<xi:include href="./library/generated/lists.xml" />
<xi:include href="./library/generated/debug.xml" />
<xi:include href="./library/generated/options.xml" />
<xi:include href="./library/generated/filesystem.xml" />
<xi:include href="./library/generated/sources.xml" />
<!-- The index must have a root element to declare namespaces, but we
don't want to include it, so we select all of its children. -->
<xi:include href="./library/generated/index.xml" xpointer="xpointer(/root/*)" />
</section>

View File

@ -4,7 +4,7 @@
## Usage {#sec-pkgs-nix-gitignore-usage}
`pkgs.nix-gitignore` exports a number of functions, but you\'ll most likely need either `gitignoreSource` or `gitignoreSourcePure`. As their first argument, they both accept either 1. a file with gitignore lines or 2. a string with gitignore lines, or 3. a list of either of the two. They will be concatenated into a single big string.
`pkgs.nix-gitignore` exports a number of functions, but you'll most likely need either `gitignoreSource` or `gitignoreSourcePure`. As their first argument, they both accept either 1. a file with gitignore lines or 2. a string with gitignore lines, or 3. a list of either of the two. They will be concatenated into a single big string.
```nix
{ pkgs ? import <nixpkgs> {} }:
@ -30,7 +30,7 @@ gitignoreSourcePure = gitignoreFilterSourcePure (_: _: true);
gitignoreSource = gitignoreFilterSource (_: _: true);
```
Those filter functions accept the same arguments the `builtins.filterSource` function would pass to its filters, thus `fn: gitignoreFilterSourcePure fn ""` should be extensionally equivalent to `filterSource`. The file is blacklisted if it\'s blacklisted by either your filter or the gitignoreFilter.
Those filter functions accept the same arguments the `builtins.filterSource` function would pass to its filters, thus `fn: gitignoreFilterSourcePure fn ""` should be extensionally equivalent to `filterSource`. The file is blacklisted if it's blacklisted by either your filter or the gitignoreFilter.
If you want to make your own filter from scratch, you may use

View File

@ -9,7 +9,7 @@ stdenv.mkDerivation {
# ...
checkInputs = [
nativeCheckInputs = [
postgresql
postgresqlTestHook
];
@ -46,6 +46,12 @@ Bash-only variables:
- `postgresqlEnableTCP`: set to `1` to enable TCP listening. Flaky; not recommended.
- `postgresqlStartCommands`: defaults to `pg_ctl start`.
## Hooks {#sec-postgresqlTestHook-hooks}
A number of additional hooks are ran in postgresqlTestHook
- `postgresqlTestSetupPost`: ran after postgresql has been set up.
## TCP and the Nix sandbox {#sec-postgresqlTestHook-tcp}
`postgresqlEnableTCP` relies on network sandboxing, which is not available on macOS and some custom Nix installations, resulting in flaky tests.

View File

@ -13,6 +13,7 @@ with import <nixpkgs> {};
let
androidComposition = androidenv.composeAndroidPackages {
cmdLineToolsVersion = "8.0";
toolsVersion = "26.1.1";
platformToolsVersion = "30.0.5";
buildToolsVersions = [ "30.0.3" ];
@ -42,7 +43,10 @@ exceptions are the tools, platform-tools and build-tools sub packages.
The following parameters are supported:
* `toolsVersion`, specifies the version of the tools package to use
* `cmdLineToolsVersion `, specifies the version of the `cmdline-tools` package to use
* `toolsVersion`, specifies the version of the `tools` package. Notice `tools` is
obsolete, and currently only `26.1.1` is available, so there's not a lot of
options here, however, you can set it as `null` if you don't want it.
* `platformsToolsVersion` specifies the version of the `platform-tools` plugin
* `buildToolsVersions` specifies the versions of the `build-tools` plugins to
use.

View File

@ -128,7 +128,7 @@ You will need to run the build process once to fix the hash to correspond to you
###### FOD {#fixed-output-derivation}
A fixed output derivation will download mix dependencies from the internet. To ensure reproducibility, a hash will be supplied. Note that mix is relatively reproducible. An FOD generating a different hash on each run hasn't been observed (as opposed to npm where the chances are relatively high). See [elixir_ls](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/beam-modules/elixir_ls.nix) for a usage example of FOD.
A fixed output derivation will download mix dependencies from the internet. To ensure reproducibility, a hash will be supplied. Note that mix is relatively reproducible. An FOD generating a different hash on each run hasn't been observed (as opposed to npm where the chances are relatively high). See [elixir_ls](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/beam-modules/elixir-ls/default.nix) for a usage example of FOD.
Practical steps

View File

@ -28,13 +28,13 @@ mkShell {
packages = [
(with dotnetCorePackages; combinePackages [
sdk_3_1
sdk_5_0
sdk_6_0
])
];
}
```
This will produce a dotnet installation that has the dotnet 3.1, 3.0, and 2.1 sdk. The first sdk listed will have it's cli utility present in the resulting environment. Example info output:
This will produce a dotnet installation that has the dotnet 3.1 6.0 sdk. The first sdk listed will have it's cli utility present in the resulting environment. Example info output:
```ShellSession
$ dotnet --info
@ -120,7 +120,7 @@ in buildDotnetModule rec {
projectReferences = [ referencedProject ]; # `referencedProject` must contain `nupkg` in the folder structure.
dotnet-sdk = dotnetCorePackages.sdk_3_1;
dotnet-runtime = dotnetCorePackages.net_5_0;
dotnet-runtime = dotnetCorePackages.net_6_0;
executables = [ "foo" ]; # This wraps "$out/lib/$pname/foo" to `$out/bin/foo`.
executables = []; # Don't install any executables.

View File

@ -34,7 +34,7 @@ To allow software to use various virtual file systems, `gvfs` package can be als
### GdkPixbuf loaders {#ssec-gnome-gdk-pixbuf-loaders}
GTK applications typically use [GdkPixbuf](https://developer.gnome.org/gdk-pixbuf/stable/) to load images. But `gdk-pixbuf` package only supports basic bitmap formats like JPEG, PNG or TIFF, requiring to use third-party loader modules for other formats. This is especially painful since GTK itself includes SVG icons, which cannot be rendered without a loader provided by `librsvg`.
GTK applications typically use [GdkPixbuf](https://gitlab.gnome.org/GNOME/gdk-pixbuf/) to load images. But `gdk-pixbuf` package only supports basic bitmap formats like JPEG, PNG or TIFF, requiring to use third-party loader modules for other formats. This is especially painful since GTK itself includes SVG icons, which cannot be rendered without a loader provided by `librsvg`.
Unlike other libraries mentioned in this section, GdkPixbuf only supports a single value in its controlling environment variable `GDK_PIXBUF_MODULE_FILE`. It is supposed to point to a cache file containing information about the available loaders. Each loader package will contain a `lib/gdk-pixbuf-2.0/2.10.0/loaders.cache` file describing the default loaders in `gdk-pixbuf` package plus the loader contained in the package itself. If you want to use multiple third-party loaders, you will need to create your own cache file manually. Fortunately, this is pretty rare as [not many loaders exist](https://gitlab.gnome.org/federico/gdk-pixbuf-survey/blob/master/src/modules.md).
@ -70,7 +70,7 @@ Also make sure that `icon-theme.cache` is installed for each theme provided by t
### GTK Themes {#ssec-gnome-themes}
Previously, a GTK theme needed to be in `XDG_DATA_DIRS`. This is no longer necessary for most programs since GTK incorporated Adwaita theme. Some programs (for example, those designed for [elementary HIG](https://elementary.io/docs/human-interface-guidelines#human-interface-guidelines)) might require a special theme like `pantheon.elementary-gtk-theme`.
Previously, a GTK theme needed to be in `XDG_DATA_DIRS`. This is no longer necessary for most programs since GTK incorporated Adwaita theme. Some programs (for example, those designed for [elementary HIG](https://docs.elementary.io/hig)) might require a special theme like `pantheon.elementary-gtk-theme`.
### GObject introspection typelibs {#ssec-gnome-typelibs}

View File

@ -16,7 +16,8 @@ In the following is an example expression using `buildGoModule`, the following a
`vendorHash` can also be set to `null`.
In that case, rather than fetching the dependencies and vendoring them, the dependencies vendored in the source repo will be used.
To avoid updating this field when dependencies change, run `go mod vendor` in your source repo and set `vendorHash = null;`
To avoid updating this field when dependencies change, run `go mod vendor` in your source repo and set `vendorHash = null;`
To obtain the actual hash, set `vendorHash = lib.fakeSha256;` and run the build ([more details here](#sec-source-hashes)).
- `proxyVendor`: Fetches (go mod download) and proxies the vendor directory. This is useful if your code depends on c code and go mod tidy does not include the needed sources to build or if any dependency has case-insensitive conflicts which will produce platform dependant `vendorHash` checksums.

File diff suppressed because it is too large Load Diff

View File

@ -32,11 +32,13 @@
<xi:include href="octave.section.xml" />
<xi:include href="perl.section.xml" />
<xi:include href="php.section.xml" />
<xi:include href="pkg-config.section.xml" />
<xi:include href="python.section.xml" />
<xi:include href="qt.section.xml" />
<xi:include href="r.section.xml" />
<xi:include href="ruby.section.xml" />
<xi:include href="rust.section.xml" />
<xi:include href="swift.section.xml" />
<xi:include href="texlive.section.xml" />
<xi:include href="titanium.section.xml" />
<xi:include href="vim.section.xml" />

View File

@ -175,10 +175,11 @@ buildNpmPackage rec {
hash = "sha256-BR+ZGkBBfd0dSQqAvujsbgsEPFYw/ThrylxUbOksYxM=";
};
patches = [ ./remove-prepack-script.patch ];
npmDepsHash = "sha256-tuEfyePwlOy2/mOPdXbqJskO6IowvAP4DWg8xSZwbJw=";
# The prepack script runs the build script, which we'd rather do in the build phase.
npmPackFlags = [ "--ignore-scripts" ];
NODE_OPTIONS = "--openssl-legacy-provider";
meta = with lib; {

View File

@ -129,3 +129,8 @@ packaged libraries may still use the old spelling: maintainers are invited to
fix this when updating packages. Massive renaming is strongly discouraged as it
would be challenging to review, difficult to test, and will cause unnecessary
rebuild.
The build will automatically fail if two distinct versions of the same library
are added to `buildInputs` (which usually happens transitively because of
`propagatedBuildInputs`). Set `dontDetectOcamlConflicts` to true to disable this
behavior.

View File

@ -0,0 +1,51 @@
# pkg-config {#sec-pkg-config}
*pkg-config* is a unified interface for declaring and querying built C/C++ libraries.
Nixpkgs provides a couple of facilities for working with this tool.
## Writing packages providing pkg-config modules
Packages should set `meta.pkgConfigProvides` with the list of package config modules they provide.
They should also use `testers.testMetaPkgConfig` to check that the final built package matches that list.
Additionally, the [`validatePkgConfig` setup hook](https://nixos.org/manual/nixpkgs/stable/#validatepkgconfig), will do extra checks on to-be-installed pkg-config modules.
A good example of all these things is zlib:
```
{ pkg-config, testers, ... }:
stdenv.mkDerivation (finalAttrs: {
...
nativeBuildInputs = [ pkg-config validatePkgConfig ];
passthru.tests.pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage;
meta = {
...
pkgConfigModules = [ "zlib" ];
};
})
```
## Accessing packages via pkg-config module name
### Within Nixpkgs
A [setup hook](#setup-hook-pkg-config) is bundled in the `pkg-config` package to bring a derivation's declared build inputs into the environment.
This will populate environment variables like `PKG_CONFIG_PATH`, `PKG_CONFIG_PATH_FOR_BUILD`, and `PKG_CONFIG_PATH_HOST` based on:
- how `pkg-config` itself is depended upon
- how other dependencies are depended upon
For more details see the section on [specifying dependencies in general](#ssec-stdenv-dependencies).
Normal pkg-config commands to look up dependencies by name will then work with those environment variables defined by the hook.
### Externally
The `defaultPkgConfigPackages` package set is a set of aliases, named after the modules they provide.
This is meant to be used by language-to-nix integrations.
Hand-written packages should use the normal Nixpkgs attribute name instead.

View File

@ -58,7 +58,7 @@ with a nix-shell that has `numpy` and `toolz` in Python 3.9; then we will create
a re-usable environment in a single-file Python script; then we will create a
full Python environment for development with this same environment.
Philosphically, this should be familiar to users who are used to a `venv` style
Philosophically, this should be familiar to users who are used to a `venv` style
of development: individual projects create their own Python environments without
impacting the global environment or each other.
@ -436,7 +436,7 @@ arguments `buildInputs` and `propagatedBuildInputs` to specify dependencies. If
something is exclusively a build-time dependency, then the dependency should be
included in `buildInputs`, but if it is (also) a runtime dependency, then it
should be added to `propagatedBuildInputs`. Test dependencies are considered
build-time dependencies and passed to `checkInputs`.
build-time dependencies and passed to `nativeCheckInputs`.
The following example shows which arguments are given to `buildPythonPackage` in
order to build [`datashape`](https://github.com/blaze/datashape).
@ -453,7 +453,7 @@ buildPythonPackage rec {
hash = "sha256-FLLvdm1MllKrgTGC6Gb0k0deZeVYvtCCLji/B7uhong=";
};
checkInputs = [ pytest ];
nativeCheckInputs = [ pytest ];
propagatedBuildInputs = [ numpy multipledispatch python-dateutil ];
meta = with lib; {
@ -466,7 +466,7 @@ buildPythonPackage rec {
```
We can see several runtime dependencies, `numpy`, `multipledispatch`, and
`python-dateutil`. Furthermore, we have one `checkInputs`, i.e. `pytest`. `pytest` is a
`python-dateutil`. Furthermore, we have one `nativeCheckInputs`, i.e. `pytest`. `pytest` is a
test runner and is only used during the `checkPhase` and is therefore not added
to `propagatedBuildInputs`.
@ -569,8 +569,14 @@ Pytest is the most common test runner for python repositories. A trivial
test run would be:
```
checkInputs = [ pytest ];
checkPhase = "pytest";
nativeCheckInputs = [ pytest ];
checkPhase = ''
runHook preCheck
pytest
runHook postCheck
'';
```
However, many repositories' test suites do not translate well to nix's build
@ -579,10 +585,14 @@ sandbox, and will generally need many tests to be disabled.
To filter tests using pytest, one can do the following:
```
checkInputs = [ pytest ];
nativeCheckInputs = [ pytest ];
# avoid tests which need additional data or touch network
checkPhase = ''
runHook preCheck
pytest tests/ --ignore=tests/integration -k 'not download and not update'
runHook postCheck
'';
```
@ -608,7 +618,7 @@ when a package may need many items disabled to run the test suite.
Using the example above, the analogous `pytestCheckHook` usage would be:
```
checkInputs = [ pytestCheckHook ];
nativeCheckInputs = [ pytestCheckHook ];
# requires additional data
pytestFlagsArray = [ "tests/" "--ignore=tests/integration" ];
@ -734,17 +744,17 @@ work in any of the formats supported by `buildPythonPackage` currently,
with the exception of `other` (see `format` in
[`buildPythonPackage` parameters](#buildpythonpackage-parameters) for more details).
### Using unittestCheckHook {#using-unittestcheckhook}
#### Using unittestCheckHook {#using-unittestcheckhook}
`unittestCheckHook` is a hook which will substitute the setuptools `test` command for a `checkPhase` which runs `python -m unittest discover`:
```
checkInputs = [ unittestCheckHook ];
nativeCheckInputs = [ unittestCheckHook ];
unittestFlags = [ "-s" "tests" "-v" ];
unittestFlagsArray = [ "-s" "tests" "-v" ];
```
##### Using sphinxHook {#using-sphinxhook}
#### Using sphinxHook {#using-sphinxhook}
The `sphinxHook` is a helpful tool to build documentation and manpages
using the popular Sphinx documentation generator.
@ -996,7 +1006,7 @@ buildPythonPackage rec {
rm testing/test_argcomplete.py
'';
checkInputs = [ hypothesis ];
nativeCheckInputs = [ hypothesis ];
nativeBuildInputs = [ setuptools-scm ];
propagatedBuildInputs = [ attrs py setuptools six pluggy ];
@ -1018,7 +1028,7 @@ The `buildPythonPackage` mainly does four things:
* In the `installCheck` phase, `${python.interpreter} setup.py test` is run.
By default tests are run because `doCheck = true`. Test dependencies, like
e.g. the test runner, should be added to `checkInputs`.
e.g. the test runner, should be added to `nativeCheckInputs`.
By default `meta.platforms` is set to the same value
as the interpreter unless overridden otherwise.
@ -1072,7 +1082,7 @@ because their behaviour is different:
* `buildInputs ? []`: Build and/or run-time dependencies that need to be
compiled for the host machine. Typically non-Python libraries which are being
linked.
* `checkInputs ? []`: Dependencies needed for running the `checkPhase`. These
* `nativeCheckInputs ? []`: Dependencies needed for running the `checkPhase`. These
are added to `nativeBuildInputs` when `doCheck = true`. Items listed in
`tests_require` go here.
* `propagatedBuildInputs ? []`: Aside from propagating dependencies,
@ -1406,9 +1416,13 @@ example of such a situation is when `py.test` is used.
buildPythonPackage {
# ...
# assumes the tests are located in tests
checkInputs = [ pytest ];
nativeCheckInputs = [ pytest ];
checkPhase = ''
runHook preCheck
py.test -k 'not function_name and not other_function' tests
runHook postCheck
'';
}
```
@ -1754,7 +1768,7 @@ In a `setup.py` or `setup.cfg` it is common to declare dependencies:
* `setup_requires` corresponds to `nativeBuildInputs`
* `install_requires` corresponds to `propagatedBuildInputs`
* `tests_require` corresponds to `checkInputs`
* `tests_require` corresponds to `nativeCheckInputs`
## Contributing {#contributing}

View File

@ -2,14 +2,11 @@
Writing Nix expressions for Qt libraries and applications is largely similar as for other C++ software.
This section assumes some knowledge of the latter.
There are two problems that the Nixpkgs Qt infrastructure addresses,
which are not shared by other C++ software:
1. There are usually multiple supported versions of Qt in Nixpkgs.
All of a package's dependencies must be built with the same version of Qt.
This is similar to the version constraints imposed on interpreted languages like Python.
2. Qt makes extensive use of runtime dependency detection.
Runtime dependencies are made into build dependencies through wrappers.
The major caveat with Qt applications is that Qt uses a plugin system to load additional modules at runtime,
from a list of well-known locations. In Nixpkgs, we patch QtCore to instead use an environment variable,
and wrap Qt applications to set it to the right paths. This effectively makes the runtime dependencies
pure and explicit at build-time, at the cost of introducing an extra indirection.
## Nix expression for a Qt package (default.nix) {#qt-default-nix}
@ -95,66 +92,3 @@ stdenv.mkDerivation {
This means that scripts won't be automatically wrapped so you'll need to manually wrap them as previously mentioned.
An example of when you'd always need to do this is with Python applications that use PyQt.
:::
## Adding a library to Nixpkgs {#adding-a-library-to-nixpkgs}
Add Qt libraries to `qt5-packages.nix` to make them available for every
supported Qt version.
### Example adding a Qt library {#qt-library-all-packages-nix}
The following represents the contents of `qt5-packages.nix`.
```nix
{
# ...
mylib = callPackage ../path/to/mylib {};
# ...
}
```
Libraries are built with every available version of Qt.
Use the `meta.broken` attribute to disable the package for unsupported Qt versions:
```nix
{ stdenv, lib, qtbase }:
stdenv.mkDerivation {
# ...
# Disable this library with Qt < 5.9.0
meta.broken = lib.versionOlder qtbase.version "5.9.0";
}
```
## Adding an application to Nixpkgs {#adding-an-application-to-nixpkgs}
Add Qt applications to `qt5-packages.nix`. Add an alias to `all-packages.nix`
to select the Qt 5 version used for the application.
### Example adding a Qt application {#qt-application-all-packages-nix}
The following represents the contents of `qt5-packages.nix`.
```nix
{
# ...
myapp = callPackage ../path/to/myapp {};
# ...
}
```
The following represents the contents of `all-packages.nix`.
```nix
{
# ...
myapp = libsForQt5.myapp;
# ...
}
```

View File

@ -186,6 +186,23 @@ added. To find the correct hash, you can first use `lib.fakeSha256` or
`lib.fakeHash` as a stub hash. Building the package (and thus the
vendored dependencies) will then inform you of the correct hash.
For usage outside nixpkgs, `allowBuiltinFetchGit` could be used to
avoid having to specify `outputHashes`. For example:
```nix
rustPlatform.buildRustPackage rec {
pname = "myproject";
version = "1.0.0";
cargoLock = {
lockFile = ./Cargo.lock;
allowBuiltinFetchGit = true;
};
# ...
}
```
### Cargo features {#cargo-features}
You can disable default features using `buildNoDefaultFeatures`, and

View File

@ -0,0 +1,176 @@
# Swift {#swift}
The Swift compiler is provided by the `swift` package:
```sh
# Compile and link a simple executable.
nix-shell -p swift --run 'swiftc -' <<< 'print("Hello world!")'
# Run it!
./main
```
The `swift` package also provides the `swift` command, with some caveats:
- Swift Package Manager (SwiftPM) is packaged separately as `swiftpm`. If you
need functionality like `swift build`, `swift run`, `swift test`, you must
also add the `swiftpm` package to your closure.
- On Darwin, the `swift repl` command requires an Xcode installation. This is
because it uses the system LLDB debugserver, which has special entitlements.
## Module search paths {#ssec-swift-module-search-paths}
Like other toolchains in Nixpkgs, the Swift compiler executables are wrapped
to help Swift find your application's dependencies in the Nix store. These
wrappers scan the `buildInputs` of your package derivation for specific
directories where Swift modules are placed by convention, and automatically
add those directories to the Swift compiler search paths.
Swift follows different conventions depending on the platform. The wrappers
look for the following directories:
- On Darwin platforms: `lib/swift/macosx`
(If not targeting macOS, replace `macosx` with the Xcode platform name.)
- On other platforms: `lib/swift/linux/x86_64`
(Where `linux` and `x86_64` are from lowercase `uname -sm`.)
- For convenience, Nixpkgs also adds simply `lib/swift` to the search path.
This can save a bit of work packaging Swift modules, because many Nix builds
will produce output for just one target any way.
## Core libraries {#ssec-swift-core-libraries}
In addition to the standard library, the Swift toolchain contains some
additional 'core libraries' that, on Apple platforms, are normally distributed
as part of the OS or Xcode. These are packaged separately in Nixpkgs, and can
be found (for use in `buildInputs`) as:
- `swiftPackages.Dispatch`
- `swiftPackages.Foundation`
- `swiftPackages.XCTest`
## Packaging with SwiftPM {#ssec-swift-packaging-with-swiftpm}
Nixpkgs includes a small helper `swiftpm2nix` that can fetch your SwiftPM
dependencies for you, when you need to write a Nix expression to package your
application.
The first step is to run the generator:
```sh
cd /path/to/my/project
# Enter a Nix shell with the required tools.
nix-shell -p swift swiftpm swiftpm2nix
# First, make sure the workspace is up-to-date.
swift package resolve
# Now generate the Nix code.
swiftpm2nix
```
This produces some files in a directory `nix`, which will be part of your Nix
expression. The next step is to write that expression:
```nix
{ stdenv, swift, swiftpm, swiftpm2nix, fetchFromGitHub }:
let
# Pass the generated files to the helper.
generated = swiftpm2nix.helpers ./nix;
in
stdenv.mkDerivation rec {
pname = "myproject";
version = "0.0.0";
src = fetchFromGitHub {
owner = "nixos";
repo = pname;
rev = version;
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
# Including SwiftPM as a nativeBuildInput provides a buildPhase for you.
# This by default performs a release build using SwiftPM, essentially:
# swift build -c release
nativeBuildInputs = [ swift swiftpm ];
# The helper provides a configure snippet that will prepare all dependencies
# in the correct place, where SwiftPM expects them.
configurePhase = generated.configure;
installPhase = ''
# This is a special function that invokes swiftpm to find the location
# of the binaries it produced.
binPath="$(swiftpmBinPath)"
# Now perform any installation steps.
mkdir -p $out/bin
cp $binPath/myproject $out/bin/
'';
}
```
### Custom build flags {#ssec-swiftpm-custom-build-flags}
If you'd like to build a different configuration than `release`:
```nix
swiftpmBuildConfig = "debug";
```
It is also possible to provide additional flags to `swift build`:
```nix
swiftpmFlags = [ "--disable-dead-strip" ];
```
The default `buildPhase` already passes `-j` for parallel building.
If these two customization options are insufficient, simply provide your own
`buildPhase` that invokes `swift build`.
### Running tests {#ssec-swiftpm-running-tests}
Including `swiftpm` in your `nativeBuildInputs` also provides a default
`checkPhase`, but it must be enabled with:
```nix
doCheck = true;
```
This essentially runs: `swift test -c release`
### Patching dependencies {#ssec-swiftpm-patching-dependencies}
In some cases, it may be necessary to patch a SwiftPM dependency. SwiftPM
dependencies are located in `.build/checkouts`, but the `swiftpm2nix` helper
provides these as symlinks to read-only `/nix/store` paths. In order to patch
them, we need to make them writable.
A special function `swiftpmMakeMutable` is available to replace the symlink
with a writable copy:
```
configurePhase = generated.configure ++ ''
# Replace the dependency symlink with a writable copy.
swiftpmMakeMutable swift-crypto
# Now apply a patch.
patch -p1 -d .build/checkouts/swift-crypto -i ${./some-fix.patch}
'';
```
## Considerations for custom build tools {#ssec-swift-considerations-for-custom-build-tools}
### Linking the standard library {#ssec-swift-linking-the-standard-library}
The `swift` package has a separate `lib` output containing just the Swift
standard library, to prevent Swift applications needing a dependency on the
full Swift compiler at run-time. Linking with the Nixpkgs Swift toolchain
already ensures binaries correctly reference the `lib` output.
Sometimes, Swift is used only to compile part of a mixed codebase, and the
link step is manual. Custom build tools often locate the standard library
relative to the `swift` compiler executable, and while the result will work,
when this path ends up in the binary, it will have the Swift compiler as an
unintended dependency.
In this case, you should investigate how your build process discovers the
standard library, and override the path. The correct path will be something
like: `"${swift.swift.lib}/${swift.swiftModuleSubdir}"`

32
doc/manpage-urls.json Normal file
View File

@ -0,0 +1,32 @@
{
"gnunet.conf(5)": "https://docs.gnunet.org/users/configuration.html",
"mpd(1)": "https://mpd.readthedocs.io/en/latest/mpd.1.html",
"mpd.conf(5)": "https://mpd.readthedocs.io/en/latest/mpd.conf.5.html",
"nix.conf(5)": "https://nixos.org/manual/nix/stable/command-ref/conf-file.html",
"journald.conf(5)": "https://www.freedesktop.org/software/systemd/man/journald.conf.html",
"logind.conf(5)": "https://www.freedesktop.org/software/systemd/man/logind.conf.html",
"networkd.conf(5)": "https://www.freedesktop.org/software/systemd/man/networkd.conf.html",
"systemd.automount(5)": "https://www.freedesktop.org/software/systemd/man/systemd.automount.html",
"systemd.exec(5)": "https://www.freedesktop.org/software/systemd/man/systemd.exec.html",
"systemd.link(5)": "https://www.freedesktop.org/software/systemd/man/systemd.link.html",
"systemd.mount(5)": "https://www.freedesktop.org/software/systemd/man/systemd.mount.html",
"systemd.netdev(5)": "https://www.freedesktop.org/software/systemd/man/systemd.netdev.html",
"systemd.network(5)": "https://www.freedesktop.org/software/systemd/man/systemd.network.html",
"systemd.nspawn(5)": "https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html",
"systemd.path(5)": "https://www.freedesktop.org/software/systemd/man/systemd.path.html",
"systemd.resource-control(5)": "https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html",
"systemd.scope(5)": "https://www.freedesktop.org/software/systemd/man/systemd.scope.html",
"systemd.service(5)": "https://www.freedesktop.org/software/systemd/man/systemd.service.html",
"systemd.slice(5)": "https://www.freedesktop.org/software/systemd/man/systemd.slice.html",
"systemd.socket(5)": "https://www.freedesktop.org/software/systemd/man/systemd.socket.html",
"systemd.timer(5)": "https://www.freedesktop.org/software/systemd/man/systemd.timer.html",
"systemd.unit(5)": "https://www.freedesktop.org/software/systemd/man/systemd.unit.html",
"systemd-system.conf(5)": "https://www.freedesktop.org/software/systemd/man/systemd-system.conf.html",
"systemd-user.conf(5)": "https://www.freedesktop.org/software/systemd/man/systemd-user.conf.html",
"timesyncd.conf(5)": "https://www.freedesktop.org/software/systemd/man/timesyncd.conf.html",
"tmpfiles.d(5)": "https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html",
"systemd.time(7)": "https://www.freedesktop.org/software/systemd/man/systemd.time.html",
"systemd-fstab-generator(8)": "https://www.freedesktop.org/software/systemd/man/systemd-fstab-generator.html",
"systemd-networkd-wait-online.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-networkd-wait-online.service.html"
}

View File

@ -24,8 +24,8 @@ Packages, including the Nix packages collection, are distributed through
[channels](https://nixos.org/nix/manual/#sec-channels). The collection is
distributed for users of Nix on non-NixOS distributions through the channel
`nixpkgs`. Users of NixOS generally use one of the `nixos-*` channels, e.g.
`nixos-19.09`, which includes all packages and modules for the stable NixOS
19.09. Stable NixOS releases are generally only given
`nixos-22.11`, which includes all packages and modules for the stable NixOS
22.11. Stable NixOS releases are generally only given
security updates. More up to date packages and modules are available via the
`nixos-unstable` channel.
@ -43,4 +43,4 @@ The binaries are made available via a [binary cache](https://cache.nixos.org).
The current Nix expressions of the channels are available in the
[`nixpkgs`](https://github.com/NixOS/nixpkgs) repository in branches
that correspond to the channel names (e.g. `nixos-19.09-small`).
that correspond to the channel names (e.g. `nixos-22.11-small`).

View File

@ -150,7 +150,7 @@ depsBuildBuild = [ buildPackages.stdenv.cc ];
Add the following to your `mkDerivation` invocation.
```nix
doCheck = stdenv.hostPlatform == stdenv.buildPlatform;
doCheck = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
```
#### Package using Meson needs to run binaries for the host platform during build. {#cross-meson-runs-host-code}

View File

@ -66,7 +66,7 @@ For details, see [Licenses](#sec-meta-license).
### `maintainers` {#var-meta-maintainers}
A list of the maintainers of this Nix expression. Maintainers are defined in [`nixpkgs/maintainers/maintainer-list.nix`](https://github.com/NixOS/nixpkgs/blob/master/maintainers/maintainer-list.nix). There is no restriction to becoming a maintainer, just add yourself to that list in a separate commit titled “maintainers: add alice”, and reference maintainers with `maintainers = with lib.maintainers; [ alice bob ]`.
A list of the maintainers of this Nix expression. Maintainers are defined in [`nixpkgs/maintainers/maintainer-list.nix`](https://github.com/NixOS/nixpkgs/blob/master/maintainers/maintainer-list.nix). There is no restriction to becoming a maintainer, just add yourself to that list in a separate commit titled “maintainers: add alice” in the same pull request, and reference maintainers with `maintainers = with lib.maintainers; [ alice bob ]`.
### `mainProgram` {#var-meta-mainProgram}

View File

@ -253,7 +253,7 @@ The propagated equivalent of `depsTargetTarget`. This is prefixed for the same r
#### `NIX_DEBUG` {#var-stdenv-NIX_DEBUG}
A natural number indicating how much information to log. If set to 1 or higher, `stdenv` will print moderate debugging information during the build. In particular, the `gcc` and `ld` wrapper scripts will print out the complete command line passed to the wrapped tools. If set to 6 or higher, the `stdenv` setup script will be run with `set -x` tracing. If set to 7 or higher, the `gcc` and `ld` wrapper scripts will also be run with `set -x` tracing.
A number between 0 and 7 indicating how much information to log. If set to 1 or higher, `stdenv` will print moderate debugging information during the build. In particular, the `gcc` and `ld` wrapper scripts will print out the complete command line passed to the wrapped tools. If set to 6 or higher, the `stdenv` setup script will be run with `set -x` tracing. If set to 7 or higher, the `gcc` and `ld` wrapper scripts will also be run with `set -x` tracing.
### Attributes affecting build properties {#attributes-affecting-build-properties}
@ -626,7 +626,7 @@ Before and after running `make`, the hooks `preBuild` and `postBuild` are called
### The check phase {#ssec-check-phase}
The check phase checks whether the package was built correctly by running its test suite. The default `checkPhase` calls `make check`, but only if the `doCheck` variable is enabled.
The check phase checks whether the package was built correctly by running its test suite. The default `checkPhase` calls `make $checkTarget`, but only if the [`doCheck` variable](#var-stdenv-doCheck) is enabled.
#### Variables controlling the check phase {#variables-controlling-the-check-phase}
@ -646,7 +646,8 @@ See the [build phase](#var-stdenv-makeFlags) for details.
##### `checkTarget` {#var-stdenv-checkTarget}
The make target that runs the tests. Defaults to `check`.
The `make` target that runs the tests.
If unset, use `check` if it exists, otherwise `test`; if neither is found, do nothing.
##### `checkFlags` / `checkFlagsArray` {#var-stdenv-checkFlags}
@ -654,7 +655,11 @@ A list of strings passed as additional flags to `make`. Like `makeFlags` and `ma
##### `checkInputs` {#var-stdenv-checkInputs}
A list of dependencies used by the phase. This gets included in `nativeBuildInputs` when `doCheck` is set.
A list of host dependencies used by the phase, usually libraries linked into executables built during tests. This gets included in `buildInputs` when `doCheck` is set.
##### `nativeCheckInputs` {#var-stdenv-nativeCheckInputs}
A list of native dependencies used by the phase, notably tools needed on `$PATH`. This gets included in `nativeBuildInputs` when `doCheck` is set.
##### `preCheck` {#var-stdenv-preCheck}
@ -821,7 +826,11 @@ A list of strings passed as additional flags to `make`. Like `makeFlags` and `ma
##### `installCheckInputs` {#var-stdenv-installCheckInputs}
A list of dependencies used by the phase. This gets included in `nativeBuildInputs` when `doInstallCheck` is set.
A list of host dependencies used by the phase, usually libraries linked into executables built during tests. This gets included in `buildInputs` when `doInstallCheck` is set.
##### `nativeInstallCheckInputs` {#var-stdenv-nativeInstallCheckInputs}
A list of native dependencies used by the phase, notably tools needed on `$PATH`. This gets included in `nativeBuildInputs` when `doInstallCheck` is set.
##### `preInstallCheck` {#var-stdenv-preInstallCheck}
@ -837,6 +846,10 @@ The distribution phase is intended to produce a source distribution of the packa
#### Variables controlling the distribution phase {#variables-controlling-the-distribution-phase}
##### `doDist` {#var-stdenv-doDist}
If set, the distribution phase is executed.
##### `distTarget` {#var-stdenv-distTarget}
The make target that produces the distribution. Defaults to `dist`.
@ -990,6 +1003,32 @@ Convenience function for `makeWrapper` that replaces `<\executable\>` with a wra
If you will apply it multiple times, it will overwrite the wrapper file and you will end up with double wrapping, which should be avoided.
### `prependToVar` \<variableName\> \<elements...\> {#fun-prependToVar}
Prepend elements to a variable.
Example:
```shellSession
$ configureFlags="--disable-static"
$ prependToVar configureFlags --disable-dependency-tracking --enable-foo
$ echo $configureFlags
--disable-dependency-tracking --enable-foo --disable-static
```
### `appendToVar` \<variableName\> \<elements...\> {#fun-appendToVar}
Append elements to a variable.
Example:
```shellSession
$ configureFlags="--disable-static"
$ appendToVar configureFlags --disable-dependency-tracking --enable-foo
$ echo $configureFlags
--disable-static --disable-dependency-tracking --enable-foo
```
## Package setup hooks {#ssec-setup-hooks}
Nix itself considers a build-time dependency as merely something that should previously be built and accessible at build time—packages themselves are on their own to perform any additional setup. In most cases, that is fine, and the downstream derivation can deal with its own dependencies. But for a few common tasks, that would result in almost every package doing the same sort of setup work—depending not on the package itself, but entirely on which dependencies were used.

View File

@ -73,7 +73,7 @@ There are also two ways to try compiling a package which has been marked as unsu
}
```
The difference between a package being unsupported on some system and being broken is admittedly a bit fuzzy. If a program *ought* to work on a certain platform, but doesn't, the platform should be included in `meta.platforms`, but marked as broken with e.g. `meta.broken = !hostPlatform.isWindows`. Of course, this begs the question of what \"ought\" means exactly. That is left to the package maintainer.
The difference between a package being unsupported on some system and being broken is admittedly a bit fuzzy. If a program *ought* to work on a certain platform, but doesn't, the platform should be included in `meta.platforms`, but marked as broken with e.g. `meta.broken = !hostPlatform.isWindows`. Of course, this begs the question of what "ought" means exactly. That is left to the package maintainer.
## Installing unfree packages {#sec-allow-unfree}

View File

@ -63,7 +63,7 @@ You should prefer `overrideAttrs` in almost all cases, see its documentation for
:::
::: {.warning}
Do not use this function in Nixpkgs as it evaluates a Derivation before modifying it, which breaks package abstraction and removes error-checking of function arguments. In addition, this evaluation-per-function application incurs a performance penalty, which can become a problem if many overrides are used. It is only intended for ad-hoc customisation, such as in `~/.config/nixpkgs/config.nix`.
Do not use this function in Nixpkgs as it evaluates a derivation before modifying it, which breaks package abstraction. In addition, this evaluation-per-function application incurs a performance penalty, which can become a problem if many overrides are used. It is only intended for ad-hoc customisation, such as in `~/.config/nixpkgs/config.nix`.
:::
The function `overrideDerivation` creates a new derivation based on an existing one by overriding the original's attributes with the attribute set produced by the specified function. This function is available on all derivations defined using the `makeOverridable` function. Most standard derivation-producing functions, such as `stdenv.mkDerivation`, are defined using this function, which means most packages in the nixpkgs expression, `pkgs`, have this function.

View File

@ -16,6 +16,8 @@ rec {
Example:
x = { a = { b = 3; }; }
# ["a" "b"] is equivalent to x.a.b
# 6 is a default value to return if the path does not exist in attrset
attrByPath ["a" "b"] 6 x
=> 3
attrByPath ["z" "z"] 6 x
@ -23,6 +25,7 @@ rec {
Type:
attrByPath :: [String] -> Any -> AttrSet -> Any
*/
attrByPath =
# A list of strings representing the attribute path to return from `set`
@ -85,7 +88,7 @@ rec {
else { ${elemAt attrPath n} = atDepth (n + 1); };
in atDepth 0;
/* Like `attrByPath', but without a default value. If it doesn't find the
/* Like `attrByPath`, but without a default value. If it doesn't find the
path it will throw an error.
Example:
@ -96,7 +99,7 @@ rec {
=> error: cannot find attribute `z.z'
Type:
getAttrFromPath :: [String] -> AttrSet -> Value
getAttrFromPath :: [String] -> AttrSet -> Any
*/
getAttrFromPath =
# A list of strings representing the attribute path to get from `set`
@ -109,10 +112,7 @@ rec {
/* Map each attribute in the given set and merge them into a new attribute set.
Type:
concatMapAttrs ::
(String -> a -> AttrSet)
-> AttrSet
-> AttrSet
concatMapAttrs :: (String -> a -> AttrSet) -> AttrSet -> AttrSet
Example:
concatMapAttrs
@ -168,8 +168,7 @@ rec {
] { a.b.c = 0; }
=> { a = { b = { d = 1; }; }; x = { y = "xy"; }; }
Type:
updateManyAttrsByPath :: [AttrSet] -> AttrSet -> AttrSet
Type: updateManyAttrsByPath :: [{ path :: [String]; update :: (Any -> Any); }] -> AttrSet -> AttrSet
*/
updateManyAttrsByPath = let
# When recursing into attributes, instead of updating the `path` of each
@ -252,6 +251,7 @@ rec {
Example:
attrValues {c = 3; a = 1; b = 2;}
=> [1 2 3]
Type:
attrValues :: AttrSet -> [Any]
*/
@ -274,7 +274,7 @@ rec {
# The set to get the named attributes from
attrs: genAttrs names (name: attrs.${name});
/* Collect each attribute named `attr' from a list of attribute
/* Collect each attribute named `attr` from a list of attribute
sets. Sets that don't contain the named attribute are ignored.
Example:
@ -341,6 +341,7 @@ rec {
Type:
foldAttrs :: (Any -> Any -> Any) -> Any -> [AttrSets] -> Any
*/
foldAttrs =
# A function, given a value and a collector combines the two.
@ -356,8 +357,8 @@ rec {
) {} list_of_attrs;
/* Recursively collect sets that verify a given predicate named `pred'
from the set `attrs'. The recursion is stopped when the predicate is
/* Recursively collect sets that verify a given predicate named `pred`
from the set `attrs`. The recursion is stopped when the predicate is
verified.
Example:
@ -394,7 +395,7 @@ rec {
{ a = 2; b = 20; }
]
Type:
cartesianProductOfSets :: AttrSet -> [AttrSet]
cartesianProductOfSets :: AttrSet -> [AttrSet]
*/
cartesianProductOfSets =
# Attribute set with attributes that are lists of values
@ -413,7 +414,7 @@ rec {
=> { name = "some"; value = 6; }
Type:
nameValuePair :: String -> Any -> AttrSet
nameValuePair :: String -> Any -> { name :: String; value :: Any; }
*/
nameValuePair =
# Attribute name
@ -438,9 +439,9 @@ rec {
listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set)));
/* Like `mapAttrs', but allows the name of each attribute to be
/* Like `mapAttrs`, but allows the name of each attribute to be
changed in addition to the value. The applied function should
return both the new name and value as a `nameValuePair'.
return both the new name and value as a `nameValuePair`.
Example:
mapAttrs' (name: value: nameValuePair ("foo_" + name) ("bar-" + value))
@ -448,7 +449,7 @@ rec {
=> { foo_x = "bar-a"; foo_y = "bar-b"; }
Type:
mapAttrs' :: (String -> Any -> { name = String; value = Any }) -> AttrSet -> AttrSet
mapAttrs' :: (String -> Any -> { name :: String; value :: Any; }) -> AttrSet -> AttrSet
*/
mapAttrs' =
# A function, given an attribute's name and value, returns a new `nameValuePair`.
@ -478,9 +479,14 @@ rec {
map (name: f name attrs.${name}) (attrNames attrs);
/* Like `mapAttrs', except that it recursively applies itself to
attribute sets. Also, the first argument of the argument
function is a *list* of the names of the containing attributes.
/* Like `mapAttrs`, except that it recursively applies itself to
the *leaf* attributes of a potentially-nested attribute set:
the second argument of the function will never be an attrset.
Also, the first argument of the argument function is a *list*
of the attribute names that form the path to the leaf attribute.
For a function that gives you control over what counts as a leaf,
see `mapAttrsRecursiveCond`.
Example:
mapAttrsRecursive (path: value: concatStringsSep "-" (path ++ [value]))
@ -498,9 +504,9 @@ rec {
mapAttrsRecursiveCond (as: true) f set;
/* Like `mapAttrsRecursive', but it takes an additional predicate
/* Like `mapAttrsRecursive`, but it takes an additional predicate
function that tells it whether to recurse into an attribute
set. If it returns false, `mapAttrsRecursiveCond' does not
set. If it returns false, `mapAttrsRecursiveCond` does not
recurse, but does apply the map function. If it returns true, it
does recurse, and does not apply the map function.
@ -600,7 +606,7 @@ rec {
=> { }
Type:
optionalAttrs :: Bool -> AttrSet
optionalAttrs :: Bool -> AttrSet -> AttrSet
*/
optionalAttrs =
# Condition under which the `as` attribute set is returned.
@ -643,10 +649,10 @@ rec {
Example:
zipAttrsWith (name: values: values) [{a = "x";} {a = "y"; b = "z";}]
=> { a = ["x" "y"]; b = ["z"] }
=> { a = ["x" "y"]; b = ["z"]; }
Type:
zipAttrsWith :: (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet
zipAttrsWith :: (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet
*/
zipAttrsWith =
builtins.zipAttrsWith or (f: sets: zipAttrsWithNames (concatMap attrNames sets) f sets);
@ -654,11 +660,11 @@ rec {
/* Merge sets of attributes and combine each attribute value in to a list.
Like `lib.attrsets.zipAttrsWith' with `(name: values: values)' as the function.
Like `lib.attrsets.zipAttrsWith` with `(name: values: values)` as the function.
Example:
zipAttrs [{a = "x";} {a = "y"; b = "z";}]
=> { a = ["x" "y"]; b = ["z"] }
=> { a = ["x" "y"]; b = ["z"]; }
Type:
zipAttrs :: [ AttrSet ] -> AttrSet
@ -737,7 +743,7 @@ rec {
}
Type:
recursiveUpdate :: AttrSet -> AttrSet -> AttrSet
recursiveUpdate :: AttrSet -> AttrSet -> AttrSet
*/
recursiveUpdate =
# Left attribute set of the merge.
@ -795,6 +801,7 @@ rec {
/* Turns a list of strings into a human-readable description of those
strings represented as an attribute path. The result of this function is
not intended to be machine-readable.
Create a new attribute set with `value` set at the nested attribute location specified in `attrPath`.
Example:
showAttrPath [ "foo" "10" "bar" ]
@ -831,11 +838,11 @@ rec {
If the output does not exist, fallback to `.out` and then to the default.
Example:
getOutput pkgs.openssl
getBin pkgs.openssl
=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r"
Type:
getOutput :: Derivation -> String
getBin :: Derivation -> String
*/
getBin = getOutput "bin";
@ -844,11 +851,11 @@ rec {
If the output does not exist, fallback to `.out` and then to the default.
Example:
getOutput pkgs.openssl
getLib pkgs.openssl
=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-lib"
Type:
getOutput :: Derivation -> String
getLib :: Derivation -> String
*/
getLib = getOutput "lib";
@ -857,11 +864,11 @@ rec {
If the output does not exist, fallback to `.out` and then to the default.
Example:
getOutput pkgs.openssl
getDev pkgs.openssl
=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev"
Type:
getOutput :: Derivation -> String
getDev :: Derivation -> String
*/
getDev = getOutput "dev";
@ -870,15 +877,19 @@ rec {
If the output does not exist, fallback to `.out` and then to the default.
Example:
getOutput pkgs.openssl
getMan pkgs.openssl
=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-man"
Type:
getOutput :: Derivation -> String
getMan :: Derivation -> String
*/
getMan = getOutput "man";
/* Pick the outputs of packages to place in `buildInputs` */
/* Pick the outputs of packages to place in `buildInputs`
Type: chooseDevOutputs :: [Derivation] -> [String]
*/
chooseDevOutputs =
# List of packages to pick `dev` outputs from
drvs:
@ -900,6 +911,7 @@ rec {
Type:
recurseIntoAttrs :: AttrSet -> AttrSet
*/
recurseIntoAttrs =
# An attribute set to scan for derivations.
@ -909,7 +921,7 @@ rec {
/* Undo the effect of recurseIntoAttrs.
Type:
recurseIntoAttrs :: AttrSet -> AttrSet
dontRecurseIntoAttrs :: AttrSet -> AttrSet
*/
dontRecurseIntoAttrs =
# An attribute set to not scan for derivations.
@ -919,7 +931,10 @@ rec {
/* `unionOfDisjoint x y` is equal to `x // y // z` where the
attrnames in `z` are the intersection of the attrnames in `x` and
`y`, and all values `assert` with an error message. This
operator is commutative, unlike (//). */
operator is commutative, unlike (//).
Type: unionOfDisjoint :: AttrSet -> AttrSet -> AttrSet
*/
unionOfDisjoint = x: y:
let
intersection = builtins.intersectAttrs x y;
@ -930,9 +945,10 @@ rec {
in
(x // y) // mask;
# deprecated
# DEPRECATED
zipWithNames = zipAttrsWithNames;
# deprecated
# DEPRECATED
zip = builtins.trace
"lib.zip is deprecated, use lib.zipAttrsWith instead" zipAttrsWith;
}

View File

@ -3,13 +3,13 @@
rec {
/* `overrideDerivation drv f' takes a derivation (i.e., the result
of a call to the builtin function `derivation') and returns a new
/* `overrideDerivation drv f` takes a derivation (i.e., the result
of a call to the builtin function `derivation`) and returns a new
derivation in which the attributes of the original are overridden
according to the function `f'. The function `f' is called with
according to the function `f`. The function `f` is called with
the original derivation attributes.
`overrideDerivation' allows certain "ad-hoc" customisation
`overrideDerivation` allows certain "ad-hoc" customisation
scenarios (e.g. in ~/.config/nixpkgs/config.nix). For instance,
if you want to "patch" the derivation returned by a package
function in Nixpkgs to build another version than what the
@ -27,11 +27,19 @@ rec {
For another application, see build-support/vm, where this
function is used to build arbitrary derivations inside a QEMU
virtual machine.
Note that in order to preserve evaluation errors, the new derivation's
outPath depends on the old one's, which means that this function cannot
be used in circular situations when the old derivation also depends on the
new one.
You should in general prefer `drv.overrideAttrs` over this function;
see the nixpkgs manual for more information on overriding.
*/
overrideDerivation = drv: f:
let
newDrv = derivation (drv.drvAttrs // (f drv));
in lib.flip (extendDerivation true) newDrv (
in lib.flip (extendDerivation (builtins.seq drv.drvPath true)) newDrv (
{ meta = drv.meta or {};
passthru = if drv ? passthru then drv.passthru else {};
}
@ -96,10 +104,10 @@ rec {
else result;
/* Call the package function in the file `fn' with the required
/* Call the package function in the file `fn` with the required
arguments automatically. The function is called with the
arguments `args', but any missing arguments are obtained from
`autoArgs'. This function is intended to be partially
arguments `args`, but any missing arguments are obtained from
`autoArgs`. This function is intended to be partially
parameterised, e.g.,
callPackage = callPackageWith pkgs;
@ -108,9 +116,9 @@ rec {
libbar = callPackage ./bar.nix { };
};
If the `libbar' function expects an argument named `libfoo', it is
If the `libbar` function expects an argument named `libfoo`, it is
automatically passed as an argument. Overrides or missing
arguments can be supplied in `args', e.g.
arguments can be supplied in `args`, e.g.
libbar = callPackage ./bar.nix {
libfoo = null;
@ -244,16 +252,17 @@ rec {
outputsList = map makeOutput outputs;
drv' = (lib.head outputsList).value;
in lib.deepSeq drv' drv';
in if drv == null then null else
lib.deepSeq drv' drv';
/* Make a set of packages with a common scope. All packages called
with the provided `callPackage' will be evaluated with the same
with the provided `callPackage` will be evaluated with the same
arguments. Any package in the set may depend on any other. The
`overrideScope'` function allows subsequent modification of the package
set in a consistent way, i.e. all packages in the set will be
called with the overridden packages. The package sets may be
hierarchical: the packages in the set are called with the scope
provided by `newScope' and the set provides a `newScope' attribute
provided by `newScope` and the set provides a `newScope` attribute
which can form the parent scope for later package sets. */
makeScope = newScope: f:
let self = f self // {

View File

@ -1,7 +1,7 @@
/* Library of low-level helper functions for nix expressions.
*
* Please implement (mostly) exhaustive unit tests
* for new functions in `./tests.nix'.
* for new functions in `./tests.nix`.
*/
let
@ -27,7 +27,6 @@ let
maintainers = import ../maintainers/maintainer-list.nix;
teams = callLibs ../maintainers/team-list.nix;
meta = callLibs ./meta.nix;
sources = callLibs ./sources.nix;
versions = callLibs ./versions.nix;
# module system
@ -53,7 +52,9 @@ let
fetchers = callLibs ./fetchers.nix;
# Eval-time filesystem handling
path = callLibs ./path;
filesystem = callLibs ./filesystem.nix;
sources = callLibs ./sources.nix;
# back-compat aliases
platforms = self.systems.doubles;
@ -63,7 +64,7 @@ let
inherit (builtins) add addErrorContext attrNames concatLists
deepSeq elem elemAt filter genericClosure genList getAttr
hasAttr head isAttrs isBool isInt isList isString length
hasAttr head isAttrs isBool isInt isList isPath isString length
lessThan listToAttrs pathExists readFile replaceStrings seq
stringLength sub substring tail trace;
inherit (self.trivial) id const pipe concat or and bitAnd bitOr bitXor
@ -87,23 +88,25 @@ let
updateManyAttrsByPath;
inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1
concatMap flatten remove findSingle findFirst any all count
optional optionals toList range partition zipListsWith zipLists
optional optionals toList range replicate partition zipListsWith zipLists
reverseList listDfs toposort sort naturalSort compareLists take
drop sublist last init crossLists unique intersectLists
subtractLists mutuallyExclusive groupBy groupBy';
inherit (self.strings) concatStrings concatMapStrings concatImapStrings
intersperse concatStringsSep concatMapStringsSep
concatImapStringsSep makeSearchPath makeSearchPathOutput
concatImapStringsSep concatLines makeSearchPath makeSearchPathOutput
makeLibraryPath makeBinPath optionalString
hasInfix hasPrefix hasSuffix stringToCharacters stringAsChars escape
escapeShellArg escapeShellArgs isValidPosixName toShellVar toShellVars
escapeShellArg escapeShellArgs
isStorePath isStringLike
isValidPosixName toShellVar toShellVars
escapeRegex escapeXML replaceChars lowerChars
upperChars toLower toUpper addContextFrom splitString
removePrefix removeSuffix versionOlder versionAtLeast
getName getVersion
mesonOption mesonBool mesonEnable
nameFromURL enableFeature enableFeatureAs withFeature
withFeatureAs fixedWidthString fixedWidthNumber isStorePath
withFeatureAs fixedWidthString fixedWidthNumber
toInt toIntBase10 readPathsFromFile fileContents;
inherit (self.stringsWithDeps) textClosureList textClosureMap
noDepEntry fullDepEntry packEntry stringAfter;
@ -128,14 +131,15 @@ let
mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule
mkRenamedOptionModule mkRenamedOptionModuleWith
mkMergedOptionModule mkChangedOptionModule
mkAliasOptionModule mkDerivedConfig doRename;
mkAliasOptionModule mkDerivedConfig doRename
mkAliasOptionModuleMD;
inherit (self.options) isOption mkEnableOption mkSinkUndeclaredOptions
mergeDefaultOption mergeOneOption mergeEqualOption mergeUniqueOption
getValues getFiles
optionAttrSetToDocList optionAttrSetToDocList'
scrubOptionValue literalExpression literalExample literalDocBook
showOption showOptionWithDefLocs showFiles
unknownModule mkOption mkPackageOption
unknownModule mkOption mkPackageOption mkPackageOptionMD
mdDoc literalMD;
inherit (self.types) isType setType defaultTypeMerge defaultFunctor
isOptionType mkOptionType;

View File

@ -107,7 +107,7 @@ rec {
# Same as `makeExtensible` but the name of the extending attribute is
# customized.
makeExtensibleWithCustomName = extenderName: rattrs:
fix' rattrs // {
fix' (self: (rattrs self) // {
${extenderName} = f: makeExtensibleWithCustomName extenderName (extends f rattrs);
};
});
}

View File

@ -289,7 +289,9 @@ rec {
(This means fn is type Val -> String.) */
allowPrettyValues ? false,
/* If this option is true, the output is indented with newlines for attribute sets and lists */
multiline ? true
multiline ? true,
/* Initial indentation level */
indent ? ""
}:
let
go = indent: v: with builtins;
@ -348,7 +350,7 @@ rec {
};") v)
+ outroSpace + "}"
else abort "generators.toPretty: should never happen (v = ${v})";
in go "";
in go indent;
# PLIST handling
toPlist = {}: v: let

View File

@ -114,6 +114,16 @@ in mkLicense lset) ({
fullName = "Bitstream Vera Font License";
};
bitTorrent10 = {
spdxId = "BitTorrent-1.0";
fullName = " BitTorrent Open Source License v1.0";
};
bitTorrent11 = {
spdxId = "BitTorrent-1.1";
fullName = " BitTorrent Open Source License v1.1";
};
bola11 = {
url = "https://blitiri.com.ar/p/bola/";
fullName = "Buena Onda License Agreement 1.1";
@ -333,6 +343,13 @@ in mkLicense lset) ({
free = false;
};
ecl20 = {
fullName = "Educational Community License, Version 2.0";
url = "https://opensource.org/licenses/ECL-2.0";
shortName = "ECL 2.0";
spdxId = "ECL-2.0";
};
efl10 = {
spdxId = "EFL-1.0";
fullName = "Eiffel Forum License v1.0";
@ -558,6 +575,12 @@ in mkLicense lset) ({
redistributable = false;
};
fair = {
fullName = "Fair License";
spdxId = "Fair";
free = true;
};
issl = {
fullName = "Intel Simplified Software License";
url = "https://software.intel.com/en-us/license/intel-simplified-software-license";
@ -709,7 +732,12 @@ in mkLicense lset) ({
ncsa = {
spdxId = "NCSA";
fullName = "University of Illinois/NCSA Open Source License";
fullName = "University of Illinois/NCSA Open Source License";
};
nlpl = {
spdxId = "NLPL";
fullName = "No Limit Public License";
};
nposl3 = {
@ -842,6 +870,12 @@ in mkLicense lset) ({
fullName = "SGI Free Software License B v2.0";
};
# Gentoo seems to treat it as a license:
# https://gitweb.gentoo.org/repo/gentoo.git/tree/licenses/SGMLUG?id=7d999af4a47bf55e53e54713d98d145f935935c1
sgmlug = {
fullName = "SGML UG SGML Parser Materials license";
};
sleepycat = {
spdxId = "Sleepycat";
fullName = "Sleepycat License";

View File

@ -242,7 +242,7 @@ rec {
/* Return a singleton list or an empty list, depending on a boolean
value. Useful when building lists with optional elements
(e.g. `++ optional (system == "i686-linux") firefox').
(e.g. `++ optional (system == "i686-linux") firefox`).
Type: optional :: bool -> a -> [a]
@ -283,7 +283,7 @@ rec {
*/
toList = x: if isList x then x else [x];
/* Return a list of integers from `first' up to and including `last'.
/* Return a list of integers from `first` up to and including `last`.
Type: range :: int -> int -> [int]
@ -303,10 +303,22 @@ rec {
else
genList (n: first + n) (last - first + 1);
/* Return a list with `n` copies of an element.
Type: replicate :: int -> a -> [a]
Example:
replicate 3 "a"
=> [ "a" "a" "a" ]
replicate 2 true
=> [ true true ]
*/
replicate = n: elem: genList (_: elem) n;
/* Splits the elements of a list in two lists, `right` and
`wrong`, depending on the evaluation of a predicate.
Type: (a -> bool) -> [a] -> { right :: [a], wrong :: [a] }
Type: (a -> bool) -> [a] -> { right :: [a]; wrong :: [a]; }
Example:
partition (x: x > 2) [ 5 1 2 3 4 ]
@ -320,7 +332,7 @@ rec {
) { right = []; wrong = []; });
/* Splits the elements of a list into many lists, using the return value of a predicate.
Predicate should return a string which becomes keys of attrset `groupBy' returns.
Predicate should return a string which becomes keys of attrset `groupBy` returns.
`groupBy'` allows to customise the combining function and initial value
@ -374,7 +386,7 @@ rec {
/* Merges two lists of the same size together. If the sizes aren't the same
the merging stops at the shortest.
Type: zipLists :: [a] -> [b] -> [{ fst :: a, snd :: b}]
Type: zipLists :: [a] -> [b] -> [{ fst :: a; snd :: b; }]
Example:
zipLists [ 1 2 ] [ "a" "b" ]

View File

@ -27,7 +27,7 @@ rec {
setName = name: drv: drv // {inherit name;};
/* Like `setName', but takes the previous name as an argument.
/* Like `setName`, but takes the previous name as an argument.
Example:
updateName (oldName: oldName + "-experimental") somePkg
@ -76,7 +76,9 @@ rec {
1. (legacy) a system string.
2. (modern) a pattern for the platform `parsed` field.
2. (modern) a pattern for the entire platform structure (see `lib.systems.inspect.platformPatterns`).
3. (modern) a pattern for the platform `parsed` field (see `lib.systems.inspect.patterns`).
We can inject these into a pattern for the whole of a structured platform,
and then match that.
@ -85,6 +87,8 @@ rec {
pattern =
if builtins.isString elem
then { system = elem; }
else if elem?parsed
then elem
else { parsed = elem; };
in lib.matchAttrs pattern platform;
@ -92,12 +96,13 @@ rec {
A package is available on a platform if both
1. One of `meta.platforms` pattern matches the given platform.
1. One of `meta.platforms` pattern matches the given
platform, or `meta.platforms` is not present.
2. None of `meta.badPlatforms` pattern matches the given platform.
*/
availableOn = platform: pkg:
lib.any (platformMatch platform) pkg.meta.platforms &&
((!pkg?meta.platforms) || lib.any (platformMatch platform) pkg.meta.platforms) &&
lib.all (elem: !platformMatch platform elem) (pkg.meta.badPlatforms or []);
/* Get the corresponding attribute in lib.licenses

View File

@ -157,6 +157,11 @@ rec {
${if prefix == []
then null # unset => visible
else "internal"} = true;
# TODO: hidden during the markdown transition to not expose downstream
# users of the docs infra to markdown if they're not ready for it.
# we don't make this visible conditionally because it can impact
# performance (https://github.com/NixOS/nixpkgs/pull/208407#issuecomment-1368246192)
visible = false;
# TODO: Change the type of this option to a submodule with a
# freeformType, so that individual arguments can be documented
# separately
@ -1110,6 +1115,15 @@ rec {
use = id;
};
/* Transitional version of mkAliasOptionModule that uses MD docs. */
mkAliasOptionModuleMD = from: to: doRename {
inherit from to;
visible = true;
warn = false;
use = id;
markdown = true;
};
/* mkDerivedConfig : Option a -> (a -> Definition b) -> Definition b
Create config definitions with the same priority as the definition of another option.
@ -1130,7 +1144,7 @@ rec {
(opt.highestPrio or defaultOverridePriority)
(f opt.value);
doRename = { from, to, visible, warn, use, withPriority ? true }:
doRename = { from, to, visible, warn, use, withPriority ? true, markdown ? false }:
{ config, options, ... }:
let
fromOpt = getAttrFromPath from options;
@ -1141,7 +1155,9 @@ rec {
{
options = setAttrByPath from (mkOption {
inherit visible;
description = lib.mdDoc "Alias of {option}`${showOption to}`.";
description = if markdown
then lib.mdDoc "Alias of {option}`${showOption to}`."
else "Alias of <option>${showOption to}</option>.";
apply = x: use (toOf config);
} // optionalAttrs (toType != null) {
type = toType;

View File

@ -104,8 +104,6 @@ rec {
/* Creates an Option attribute set for an option that specifies the
package a module should use for some purpose.
Type: mkPackageOption :: pkgs -> string -> { default :: [string], example :: null | string | [string] } -> option
The package is specified as a list of strings representing its attribute path in nixpkgs.
Because of this, you need to pass nixpkgs itself as the first argument.
@ -116,6 +114,8 @@ rec {
You can omit the default path if the name of the option is also attribute path in nixpkgs.
Type: mkPackageOption :: pkgs -> string -> { default :: [string]; example :: null | string | [string]; } -> option
Example:
mkPackageOption pkgs "hello" { }
=> { _type = "option"; default = «derivation /nix/store/3r2vg51hlxj3cx5vscp0vkv60bqxkaq0-hello-2.10.drv»; defaultText = { ... }; description = "The hello package to use."; type = { ... }; }
@ -136,7 +136,7 @@ rec {
let default' = if !isList default then [ default ] else default;
in mkOption {
type = lib.types.package;
description = lib.mdDoc "The ${name} package to use.";
description = "The ${name} package to use.";
default = attrByPath default'
(throw "${concatStringsSep "." default'} cannot be found in pkgs") pkgs;
defaultText = literalExpression ("pkgs." + concatStringsSep "." default');
@ -144,6 +144,11 @@ rec {
(if isList example then "pkgs." + concatStringsSep "." example else example);
};
/* Like mkPackageOption, but emit an mdDoc description instead of DocBook. */
mkPackageOptionMD = args: name: extra:
let option = mkPackageOption args name extra;
in option // { description = lib.mdDoc option.description; };
/* This option accepts anything, but it does not produce any result.
This is useful for sharing a module across different module sets
@ -196,7 +201,7 @@ rec {
/* Extracts values of all "value" keys of the given list.
Type: getValues :: [ { value :: a } ] -> [a]
Type: getValues :: [ { value :: a; } ] -> [a]
Example:
getValues [ { value = 1; } { value = 2; } ] // => [ 1 2 ]
@ -206,7 +211,7 @@ rec {
/* Extracts values of all "file" keys of the given list
Type: getFiles :: [ { file :: a } ] -> [a]
Type: getFiles :: [ { file :: a; } ] -> [a]
Example:
getFiles [ { file = "file1"; } { file = "file2"; } ] // => [ "file1" "file2" ]

196
lib/path/README.md Normal file
View File

@ -0,0 +1,196 @@
# Path library
This document explains why the `lib.path` library is designed the way it is.
The purpose of this library is to process [filesystem paths]. It does not read files from the filesystem.
It exists to support the native Nix [path value type] with extra functionality.
[filesystem paths]: https://en.m.wikipedia.org/wiki/Path_(computing)
[path value type]: https://nixos.org/manual/nix/stable/language/values.html#type-path
As an extension of the path value type, it inherits the same intended use cases and limitations:
- Only use paths to access files at evaluation time, such as the local project source.
- Paths cannot point to derivations, so they are unfit to represent dependencies.
- A path implicitly imports the referenced files into the Nix store when interpolated to a string. Therefore paths are not suitable to access files at build- or run-time, as you risk importing the path from the evaluation system instead.
Overall, this library works with two types of paths:
- Absolute paths are represented with the Nix [path value type]. Nix automatically normalises these paths.
- Subpaths are represented with the [string value type] since path value types don't support relative paths. This library normalises these paths as safely as possible. Absolute paths in strings are not supported.
A subpath refers to a specific file or directory within an absolute base directory.
It is a stricter form of a relative path, notably [without support for `..` components][parents] since those could escape the base directory.
[string value type]: https://nixos.org/manual/nix/stable/language/values.html#type-string
This library is designed to be as safe and intuitive as possible, throwing errors when operations are attempted that would produce surprising results, and giving the expected result otherwise.
This library is designed to work well as a dependency for the `lib.filesystem` and `lib.sources` library components. Contrary to these library components, `lib.path` does not read any paths from the filesystem.
This library makes only these assumptions about paths and no others:
- `dirOf path` returns the path to the parent directory of `path`, unless `path` is the filesystem root, in which case `path` is returned.
- There can be multiple filesystem roots: `p == dirOf p` and `q == dirOf q` does not imply `p == q`.
- While there's only a single filesystem root in stable Nix, the [lazy trees feature](https://github.com/NixOS/nix/pull/6530) introduces [additional filesystem roots](https://github.com/NixOS/nix/pull/6530#discussion_r1041442173).
- `path + ("/" + string)` returns the path to the `string` subdirectory in `path`.
- If `string` contains no `/` characters, then `dirOf (path + ("/" + string)) == path`.
- If `string` contains no `/` characters, then `baseNameOf (path + ("/" + string)) == string`.
- `path1 == path2` returns `true` only if `path1` points to the same filesystem path as `path2`.
Notably we do not make the assumption that we can turn paths into strings using `toString path`.
## Design decisions
Each subsection here contains a decision along with arguments and counter-arguments for (+) and against (-) that decision.
### Leading dots for relative paths
[leading-dots]: #leading-dots-for-relative-paths
Observing: Since subpaths are a form of relative paths, they can have a leading `./` to indicate it being a relative path, this is generally not necessary for tools though.
Considering: Paths should be as explicit, consistent and unambiguous as possible.
Decision: Returned subpaths should always have a leading `./`.
<details>
<summary>Arguments</summary>
- (+) In shells, just running `foo` as a command wouldn't execute the file `foo`, whereas `./foo` would execute the file. In contrast, `foo/bar` does execute that file without the need for `./`. This can lead to confusion about when a `./` needs to be prefixed. If a `./` is always included, this becomes a non-issue. This effectively then means that paths don't overlap with command names.
- (+) Prepending with `./` makes the subpaths always valid as relative Nix path expressions.
- (+) Using paths in command line arguments could give problems if not escaped properly, e.g. if a path was `--version`. This is not a problem with `./--version`. This effectively then means that paths don't overlap with GNU-style command line options.
- (-) `./` is not required to resolve relative paths, resolution always has an implicit `./` as prefix.
- (-) It's less noisy without the `./`, e.g. in error messages.
- (+) But similarly, it could be confusing whether something was even a path.
e.g. `foo` could be anything, but `./foo` is more clearly a path.
- (+) Makes it more uniform with absolute paths (those always start with `/`).
- (-) That is not relevant for practical purposes.
- (+) `find` also outputs results with `./`.
- (-) But only if you give it an argument of `.`. If you give it the argument `some-directory`, it won't prefix that.
- (-) `realpath --relative-to` doesn't prefix relative paths with `./`.
- (+) There is no need to return the same result as `realpath`.
</details>
### Representation of the current directory
[curdir]: #representation-of-the-current-directory
Observing: The subpath that produces the base directory can be represented with `.` or `./` or `./.`.
Considering: Paths should be as consistent and unambiguous as possible.
Decision: It should be `./.`.
<details>
<summary>Arguments</summary>
- (+) `./` would be inconsistent with [the decision to not persist trailing slashes][trailing-slashes].
- (-) `.` is how `realpath` normalises paths.
- (+) `.` can be interpreted as a shell command (it's a builtin for sourcing files in `bash` and `zsh`).
- (+) `.` would be the only path without a `/`. It could not be used as a Nix path expression, since those require at least one `/` to be parsed as such.
- (-) `./.` is rather long.
- (-) We don't require users to type this though, as it's only output by the library.
As inputs all three variants are supported for subpaths (and we can't do anything about absolute paths)
- (-) `builtins.dirOf "foo" == "."`, so `.` would be consistent with that.
- (+) `./.` is consistent with the [decision to have leading `./`][leading-dots].
- (+) `./.` is a valid Nix path expression, although this property does not hold for every relative path or subpath.
</details>
### Subpath representation
[relrepr]: #subpath-representation
Observing: Subpaths such as `foo/bar` can be represented in various ways:
- string: `"foo/bar"`
- list with all the components: `[ "foo" "bar" ]`
- attribute set: `{ type = "relative-path"; components = [ "foo" "bar" ]; }`
Considering: Paths should be as safe to use as possible. We should generate string outputs in the library and not encourage users to do that themselves.
Decision: Paths are represented as strings.
<details>
<summary>Arguments</summary>
- (+) It's simpler for the users of the library. One doesn't have to convert a path a string before it can be used.
- (+) Naively converting the list representation to a string with `concatStringsSep "/"` would break for `[]`, requiring library users to be more careful.
- (+) It doesn't encourage people to do their own path processing and instead use the library.
With a list representation it would seem easy to just use `lib.lists.init` to get the parent directory, but then it breaks for `.`, which would be represented as `[ ]`.
- (+) `+` is convenient and doesn't work on lists and attribute sets.
- (-) Shouldn't use `+` anyways, we export safer functions for path manipulation.
</details>
### Parent directory
[parents]: #parent-directory
Observing: Relative paths can have `..` components, which refer to the parent directory.
Considering: Paths should be as safe and unambiguous as possible.
Decision: `..` path components in string paths are not supported, neither as inputs nor as outputs. Hence, string paths are called subpaths, rather than relative paths.
<details>
<summary>Arguments</summary>
- (+) If we wanted relative paths to behave according to the "physical" interpretation (as a directory tree with relations between nodes), it would require resolving symlinks, since e.g. `foo/..` would not be the same as `.` if `foo` is a symlink.
- (-) The "logical" interpretation is also valid (treating paths as a sequence of names), and is used by some software. It is simpler, and not using symlinks at all is safer.
- (+) Mixing both models can lead to surprises.
- (+) We can't resolve symlinks without filesystem access.
- (+) Nix also doesn't support reading symlinks at evaluation time.
- (-) We could just not handle such cases, e.g. `equals "foo" "foo/bar/.. == false`. The paths are different, we don't need to check whether the paths point to the same thing.
- (+) Assume we said `relativeTo /foo /bar == "../bar"`. If this is used like `/bar/../foo` in the end, and `bar` turns out to be a symlink to somewhere else, this won't be accurate.
- (-) We could decide to not support such ambiguous operations, or mark them as such, e.g. the normal `relativeTo` will error on such a case, but there could be `extendedRelativeTo` supporting that.
- (-) `..` are a part of paths, a path library should therefore support it.
- (+) If we can convincingly argue that all such use cases are better done e.g. with runtime tools, the library not supporting it can nudge people towards using those.
- (-) We could allow "..", but only in the prefix.
- (+) Then we'd have to throw an error for doing `append /some/path "../foo"`, making it non-composable.
- (+) The same is for returning paths with `..`: `relativeTo /foo /bar => "../bar"` would produce a non-composable path.
- (+) We argue that `..` is not needed at the Nix evaluation level, since we'd always start evaluation from the project root and don't go up from there.
- (+) `..` is supported in Nix paths, turning them into absolute paths.
- (-) This is ambiguous in the presence of symlinks.
- (+) If you need `..` for building or runtime, you can use build-/run-time tooling to create those (e.g. `realpath` with `--relative-to`), or use absolute paths instead.
This also gives you the ability to correctly handle symlinks.
</details>
### Trailing slashes
[trailing-slashes]: #trailing-slashes
Observing: Subpaths can contain trailing slashes, like `foo/`, indicating that the path points to a directory and not a file.
Considering: Paths should be as consistent as possible, there should only be a single normalisation for the same path.
Decision: All functions remove trailing slashes in their results.
<details>
<summary>Arguments</summary>
- (+) It allows normalisations to be unique, in that there's only a single normalisation for the same path. If trailing slashes were preserved, both `foo/bar` and `foo/bar/` would be valid but different normalisations for the same path.
- Comparison to other frameworks to figure out the least surprising behavior:
- (+) Nix itself doesn't support trailing slashes when parsing and doesn't preserve them when appending paths.
- (-) [Rust's std::path](https://doc.rust-lang.org/std/path/index.html) does preserve them during [construction](https://doc.rust-lang.org/std/path/struct.Path.html#method.new).
- (+) Doesn't preserve them when returning individual [components](https://doc.rust-lang.org/std/path/struct.Path.html#method.components).
- (+) Doesn't preserve them when [canonicalizing](https://doc.rust-lang.org/std/path/struct.Path.html#method.canonicalize).
- (+) [Python 3's pathlib](https://docs.python.org/3/library/pathlib.html#module-pathlib) doesn't preserve them during [construction](https://docs.python.org/3/library/pathlib.html#pathlib.PurePath).
- Notably it represents the individual components as a list internally.
- (-) [Haskell's filepath](https://hackage.haskell.org/package/filepath-1.4.100.0) has [explicit support](https://hackage.haskell.org/package/filepath-1.4.100.0/docs/System-FilePath.html#g:6) for handling trailing slashes.
- (-) Does preserve them for [normalisation](https://hackage.haskell.org/package/filepath-1.4.100.0/docs/System-FilePath.html#v:normalise).
- (-) [NodeJS's Path library](https://nodejs.org/api/path.html) preserves trailing slashes for [normalisation](https://nodejs.org/api/path.html#pathnormalizepath).
- (+) For [parsing a path](https://nodejs.org/api/path.html#pathparsepath) into its significant elements, trailing slashes are not preserved.
- (+) Nix's builtin function `dirOf` gives an unexpected result for paths with trailing slashes: `dirOf "foo/bar/" == "foo/bar"`.
Inconsistently, `baseNameOf` works correctly though: `baseNameOf "foo/bar/" == "bar"`.
- (-) We are writing a path library to improve handling of paths though, so we shouldn't use these functions and discourage their use.
- (-) Unexpected result when normalising intermediate paths, like `relative.normalise ("foo" + "/") + "bar" == "foobar"`.
- (+) This is not a practical use case though.
- (+) Don't use `+` to append paths, this library has a `join` function for that.
- (-) Users might use `+` out of habit though.
- (+) The `realpath` command also removes trailing slashes.
- (+) Even with a trailing slash, the path is the same, it's only an indication that it's a directory.
</details>
## Other implementations and references
- [Rust](https://doc.rust-lang.org/std/path/struct.Path.html)
- [Python](https://docs.python.org/3/library/pathlib.html)
- [Haskell](https://hackage.haskell.org/package/filepath-1.4.100.0/docs/System-FilePath.html)
- [Nodejs](https://nodejs.org/api/path.html)
- [POSIX.1-2017](https://pubs.opengroup.org/onlinepubs/9699919799/nframe.html)

274
lib/path/default.nix Normal file
View File

@ -0,0 +1,274 @@
# Functions for working with paths, see ./path.md
{ lib }:
let
inherit (builtins)
isString
isPath
split
match
;
inherit (lib.lists)
length
head
last
genList
elemAt
;
inherit (lib.strings)
concatStringsSep
substring
;
inherit (lib.asserts)
assertMsg
;
inherit (lib.path.subpath)
isValid
;
# Return the reason why a subpath is invalid, or `null` if it's valid
subpathInvalidReason = value:
if ! isString value then
"The given value is of type ${builtins.typeOf value}, but a string was expected"
else if value == "" then
"The given string is empty"
else if substring 0 1 value == "/" then
"The given string \"${value}\" starts with a `/`, representing an absolute path"
# We don't support ".." components, see ./path.md#parent-directory
else if match "(.*/)?\\.\\.(/.*)?" value != null then
"The given string \"${value}\" contains a `..` component, which is not allowed in subpaths"
else null;
# Split and normalise a relative path string into its components.
# Error for ".." components and doesn't include "." components
splitRelPath = path:
let
# Split the string into its parts using regex for efficiency. This regex
# matches patterns like "/", "/./", "/././", with arbitrarily many "/"s
# together. These are the main special cases:
# - Leading "./" gets split into a leading "." part
# - Trailing "/." or "/" get split into a trailing "." or ""
# part respectively
#
# These are the only cases where "." and "" parts can occur
parts = split "/+(\\./+)*" path;
# `split` creates a list of 2 * k + 1 elements, containing the k +
# 1 parts, interleaved with k matches where k is the number of
# (non-overlapping) matches. This calculation here gets the number of parts
# back from the list length
# floor( (2 * k + 1) / 2 ) + 1 == floor( k + 1/2 ) + 1 == k + 1
partCount = length parts / 2 + 1;
# To assemble the final list of components we want to:
# - Skip a potential leading ".", normalising "./foo" to "foo"
# - Skip a potential trailing "." or "", normalising "foo/" and "foo/." to
# "foo". See ./path.md#trailing-slashes
skipStart = if head parts == "." then 1 else 0;
skipEnd = if last parts == "." || last parts == "" then 1 else 0;
# We can now know the length of the result by removing the number of
# skipped parts from the total number
componentCount = partCount - skipEnd - skipStart;
in
# Special case of a single "." path component. Such a case leaves a
# componentCount of -1 due to the skipStart/skipEnd not verifying that
# they don't refer to the same character
if path == "." then []
# Generate the result list directly. This is more efficient than a
# combination of `filter`, `init` and `tail`, because here we don't
# allocate any intermediate lists
else genList (index:
# To get to the element we need to add the number of parts we skip and
# multiply by two due to the interleaved layout of `parts`
elemAt parts ((skipStart + index) * 2)
) componentCount;
# Join relative path components together
joinRelPath = components:
# Always return relative paths with `./` as a prefix (./path.md#leading-dots-for-relative-paths)
"./" +
# An empty string is not a valid relative path, so we need to return a `.` when we have no components
(if components == [] then "." else concatStringsSep "/" components);
in /* No rec! Add dependencies on this file at the top. */ {
/* Append a subpath string to a path.
Like `path + ("/" + string)` but safer, because it errors instead of returning potentially surprising results.
More specifically, it checks that the first argument is a [path value type](https://nixos.org/manual/nix/stable/language/values.html#type-path"),
and that the second argument is a valid subpath string (see `lib.path.subpath.isValid`).
Type:
append :: Path -> String -> Path
Example:
append /foo "bar/baz"
=> /foo/bar/baz
# subpaths don't need to be normalised
append /foo "./bar//baz/./"
=> /foo/bar/baz
# can append to root directory
append /. "foo/bar"
=> /foo/bar
# first argument needs to be a path value type
append "/foo" "bar"
=> <error>
# second argument needs to be a valid subpath string
append /foo /bar
=> <error>
append /foo ""
=> <error>
append /foo "/bar"
=> <error>
append /foo "../bar"
=> <error>
*/
append =
# The absolute path to append to
path:
# The subpath string to append
subpath:
assert assertMsg (isPath path) ''
lib.path.append: The first argument is of type ${builtins.typeOf path}, but a path was expected'';
assert assertMsg (isValid subpath) ''
lib.path.append: Second argument is not a valid subpath string:
${subpathInvalidReason subpath}'';
path + ("/" + subpath);
/* Whether a value is a valid subpath string.
- The value is a string
- The string is not empty
- The string doesn't start with a `/`
- The string doesn't contain any `..` path components
Type:
subpath.isValid :: String -> Bool
Example:
# Not a string
subpath.isValid null
=> false
# Empty string
subpath.isValid ""
=> false
# Absolute path
subpath.isValid "/foo"
=> false
# Contains a `..` path component
subpath.isValid "../foo"
=> false
# Valid subpath
subpath.isValid "foo/bar"
=> true
# Doesn't need to be normalised
subpath.isValid "./foo//bar/"
=> true
*/
subpath.isValid =
# The value to check
value:
subpathInvalidReason value == null;
/* Normalise a subpath. Throw an error if the subpath isn't valid, see
`lib.path.subpath.isValid`
- Limit repeating `/` to a single one
- Remove redundant `.` components
- Remove trailing `/` and `/.`
- Add leading `./`
Laws:
- Idempotency - normalising multiple times gives the same result:
subpath.normalise (subpath.normalise p) == subpath.normalise p
- Uniqueness - there's only a single normalisation for the paths that lead to the same file system node:
subpath.normalise p != subpath.normalise q -> $(realpath ${p}) != $(realpath ${q})
- Don't change the result when appended to a Nix path value:
base + ("/" + p) == base + ("/" + subpath.normalise p)
- Don't change the path according to `realpath`:
$(realpath ${p}) == $(realpath ${subpath.normalise p})
- Only error on invalid subpaths:
builtins.tryEval (subpath.normalise p)).success == subpath.isValid p
Type:
subpath.normalise :: String -> String
Example:
# limit repeating `/` to a single one
subpath.normalise "foo//bar"
=> "./foo/bar"
# remove redundant `.` components
subpath.normalise "foo/./bar"
=> "./foo/bar"
# add leading `./`
subpath.normalise "foo/bar"
=> "./foo/bar"
# remove trailing `/`
subpath.normalise "foo/bar/"
=> "./foo/bar"
# remove trailing `/.`
subpath.normalise "foo/bar/."
=> "./foo/bar"
# Return the current directory as `./.`
subpath.normalise "."
=> "./."
# error on `..` path components
subpath.normalise "foo/../bar"
=> <error>
# error on empty string
subpath.normalise ""
=> <error>
# error on absolute path
subpath.normalise "/foo"
=> <error>
*/
subpath.normalise =
# The subpath string to normalise
subpath:
assert assertMsg (isValid subpath) ''
lib.path.subpath.normalise: Argument is not a valid subpath string:
${subpathInvalidReason subpath}'';
joinRelPath (splitRelPath subpath);
}

View File

@ -0,0 +1,34 @@
{
nixpkgs ? ../../..,
system ? builtins.currentSystem,
pkgs ? import nixpkgs {
config = {};
overlays = [];
inherit system;
},
libpath ? ../..,
# Random seed
seed ? null,
}:
pkgs.runCommand "lib-path-tests" {
nativeBuildInputs = with pkgs; [
nix
jq
bc
];
} ''
# Needed to make Nix evaluation work
export NIX_STATE_DIR=$(mktemp -d)
cp -r ${libpath} lib
export TEST_LIB=$PWD/lib
echo "Running unit tests lib/path/tests/unit.nix"
nix-instantiate --eval lib/path/tests/unit.nix \
--argstr libpath "$TEST_LIB"
echo "Running property tests lib/path/tests/prop.sh"
bash lib/path/tests/prop.sh ${toString seed}
touch $out
''

View File

@ -0,0 +1,64 @@
# Generate random path-like strings, separated by null characters.
#
# Invocation:
#
# awk -f ./generate.awk -v <variable>=<value> | tr '\0' '\n'
#
# Customizable variables (all default to 0):
# - seed: Deterministic random seed to use for generation
# - count: Number of paths to generate
# - extradotweight: Give extra weight to dots being generated
# - extraslashweight: Give extra weight to slashes being generated
# - extranullweight: Give extra weight to null being generated, making paths shorter
BEGIN {
# Random seed, passed explicitly for reproducibility
srand(seed)
# Don't include special characters below 32
minascii = 32
# Don't include DEL at 128
maxascii = 127
upperascii = maxascii - minascii
# add extra weight for ., in addition to the one weight from the ascii range
upperdot = upperascii + extradotweight
# add extra weight for /, in addition to the one weight from the ascii range
upperslash = upperdot + extraslashweight
# add extra weight for null, indicating the end of the string
# Must be at least 1 to have strings end at all
total = upperslash + 1 + extranullweight
# new=1 indicates that it's a new string
new=1
while (count > 0) {
# Random integer between [0, total)
value = int(rand() * total)
if (value < upperascii) {
# Ascii range
printf("%c", value + minascii)
new=0
} else if (value < upperdot) {
# Dot range
printf "."
new=0
} else if (value < upperslash) {
# If it's the start of a new path, only generate a / in 10% of cases
# This is always an invalid subpath, which is not a very interesting case
if (new && rand() > 0.1) continue
printf "/"
} else {
# Do not generate empty strings
if (new) continue
printf "\x00"
count--
new=1
}
}
}

60
lib/path/tests/prop.nix Normal file
View File

@ -0,0 +1,60 @@
# Given a list of path-like strings, check some properties of the path library
# using those paths and return a list of attribute sets of the following form:
#
# { <string> = <lib.path.subpath.normalise string>; }
#
# If `normalise` fails to evaluate, the attribute value is set to `""`.
# If not, the resulting value is normalised again and an appropriate attribute set added to the output list.
{
# The path to the nixpkgs lib to use
libpath,
# A flat directory containing files with randomly-generated
# path-like values
dir,
}:
let
lib = import libpath;
# read each file into a string
strings = map (name:
builtins.readFile (dir + "/${name}")
) (builtins.attrNames (builtins.readDir dir));
inherit (lib.path.subpath) normalise isValid;
inherit (lib.asserts) assertMsg;
normaliseAndCheck = str:
let
originalValid = isValid str;
tryOnce = builtins.tryEval (normalise str);
tryTwice = builtins.tryEval (normalise tryOnce.value);
absConcatOrig = /. + ("/" + str);
absConcatNormalised = /. + ("/" + tryOnce.value);
in
# Check the lib.path.subpath.normalise property to only error on invalid subpaths
assert assertMsg
(originalValid -> tryOnce.success)
"Even though string \"${str}\" is valid as a subpath, the normalisation for it failed";
assert assertMsg
(! originalValid -> ! tryOnce.success)
"Even though string \"${str}\" is invalid as a subpath, the normalisation for it succeeded";
# Check normalisation idempotency
assert assertMsg
(originalValid -> tryTwice.success)
"For valid subpath \"${str}\", the normalisation \"${tryOnce.value}\" was not a valid subpath";
assert assertMsg
(originalValid -> tryOnce.value == tryTwice.value)
"For valid subpath \"${str}\", normalising it once gives \"${tryOnce.value}\" but normalising it twice gives a different result: \"${tryTwice.value}\"";
# Check that normalisation doesn't change a string when appended to an absolute Nix path value
assert assertMsg
(originalValid -> absConcatOrig == absConcatNormalised)
"For valid subpath \"${str}\", appending to an absolute Nix path value gives \"${absConcatOrig}\", but appending the normalised result \"${tryOnce.value}\" gives a different value \"${absConcatNormalised}\"";
# Return an empty string when failed
if tryOnce.success then tryOnce.value else "";
in lib.genAttrs strings normaliseAndCheck

179
lib/path/tests/prop.sh Executable file
View File

@ -0,0 +1,179 @@
#!/usr/bin/env bash
# Property tests for the `lib.path` library
#
# It generates random path-like strings and runs the functions on
# them, checking that the expected laws of the functions hold
set -euo pipefail
shopt -s inherit_errexit
# https://stackoverflow.com/a/246128
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
if test -z "${TEST_LIB:-}"; then
TEST_LIB=$SCRIPT_DIR/../..
fi
tmp="$(mktemp -d)"
clean_up() {
rm -rf "$tmp"
}
trap clean_up EXIT
mkdir -p "$tmp/work"
cd "$tmp/work"
# Defaulting to a random seed but the first argument can override this
seed=${1:-$RANDOM}
echo >&2 "Using seed $seed, use \`lib/path/tests/prop.sh $seed\` to reproduce this result"
# The number of random paths to generate. This specific number was chosen to
# be fast enough while still generating enough variety to detect bugs.
count=500
debug=0
# debug=1 # print some extra info
# debug=2 # print generated values
# Fine tuning parameters to balance the number of generated invalid paths
# to the variance in generated paths.
extradotweight=64 # Larger value: more dots
extraslashweight=64 # Larger value: more slashes
extranullweight=16 # Larger value: shorter strings
die() {
echo >&2 "test case failed: " "$@"
exit 1
}
if [[ "$debug" -ge 1 ]]; then
echo >&2 "Generating $count random path-like strings"
fi
# Read stream of null-terminated strings entry-by-entry into bash,
# write it to a file and the `strings` array.
declare -a strings=()
mkdir -p "$tmp/strings"
while IFS= read -r -d $'\0' str; do
printf "%s" "$str" > "$tmp/strings/${#strings[@]}"
strings+=("$str")
done < <(awk \
-f "$SCRIPT_DIR"/generate.awk \
-v seed="$seed" \
-v count="$count" \
-v extradotweight="$extradotweight" \
-v extraslashweight="$extraslashweight" \
-v extranullweight="$extranullweight")
if [[ "$debug" -ge 1 ]]; then
echo >&2 "Trying to normalise the generated path-like strings with Nix"
fi
# Precalculate all normalisations with a single Nix call. Calling Nix for each
# string individually would take way too long
nix-instantiate --eval --strict --json \
--argstr libpath "$TEST_LIB" \
--argstr dir "$tmp/strings" \
"$SCRIPT_DIR"/prop.nix \
>"$tmp/result.json"
# Uses some jq magic to turn the resulting attribute set into an associative
# bash array assignment
declare -A normalised_result="($(jq '
to_entries
| map("[\(.key | @sh)]=\(.value | @sh)")
| join(" \n")' -r < "$tmp/result.json"))"
# Looks up a normalisation result for a string
# Checks that the normalisation is only failing iff it's an invalid subpath
# For valid subpaths, returns 0 and prints the normalisation result
# For invalid subpaths, returns 1
normalise() {
local str=$1
# Uses the same check for validity as in the library implementation
if [[ "$str" == "" || "$str" == /* || "$str" =~ ^(.*/)?\.\.(/.*)?$ ]]; then
valid=
else
valid=1
fi
normalised=${normalised_result[$str]}
# An empty string indicates failure, this is encoded in ./prop.nix
if [[ -n "$normalised" ]]; then
if [[ -n "$valid" ]]; then
echo "$normalised"
else
die "For invalid subpath \"$str\", lib.path.subpath.normalise returned this result: \"$normalised\""
fi
else
if [[ -n "$valid" ]]; then
die "For valid subpath \"$str\", lib.path.subpath.normalise failed"
else
if [[ "$debug" -ge 2 ]]; then
echo >&2 "String \"$str\" is not a valid subpath"
fi
# Invalid and it correctly failed, we let the caller continue if they catch the exit code
return 1
fi
fi
}
# Intermediate result populated by test_idempotency_realpath
# and used in test_normalise_uniqueness
#
# Contains a mapping from a normalised subpath to the realpath result it represents
declare -A norm_to_real
test_idempotency_realpath() {
if [[ "$debug" -ge 1 ]]; then
echo >&2 "Checking idempotency of each result and making sure the realpath result isn't changed"
fi
# Count invalid subpaths to display stats
invalid=0
for str in "${strings[@]}"; do
if ! result=$(normalise "$str"); then
((invalid++)) || true
continue
fi
# Check the law that it doesn't change the result of a realpath
mkdir -p -- "$str" "$result"
real_orig=$(realpath -- "$str")
real_norm=$(realpath -- "$result")
if [[ "$real_orig" != "$real_norm" ]]; then
die "realpath of the original string \"$str\" (\"$real_orig\") is not the same as realpath of the normalisation \"$result\" (\"$real_norm\")"
fi
if [[ "$debug" -ge 2 ]]; then
echo >&2 "String \"$str\" gets normalised to \"$result\" and file path \"$real_orig\""
fi
norm_to_real["$result"]="$real_orig"
done
if [[ "$debug" -ge 1 ]]; then
echo >&2 "$(bc <<< "scale=1; 100 / $count * $invalid")% of the total $count generated strings were invalid subpath strings, and were therefore ignored"
fi
}
test_normalise_uniqueness() {
if [[ "$debug" -ge 1 ]]; then
echo >&2 "Checking for the uniqueness law"
fi
for norm_p in "${!norm_to_real[@]}"; do
real_p=${norm_to_real["$norm_p"]}
for norm_q in "${!norm_to_real[@]}"; do
real_q=${norm_to_real["$norm_q"]}
# Checks normalisation uniqueness law for each pair of values
if [[ "$norm_p" != "$norm_q" && "$real_p" == "$real_q" ]]; then
die "Normalisations \"$norm_p\" and \"$norm_q\" are different, but the realpath of them is the same: \"$real_p\""
fi
done
done
}
test_idempotency_realpath
test_normalise_uniqueness
echo >&2 tests ok

163
lib/path/tests/unit.nix Normal file
View File

@ -0,0 +1,163 @@
# Unit tests for lib.path functions. Use `nix-build` in this directory to
# run these
{ libpath }:
let
lib = import libpath;
inherit (lib.path) append subpath;
cases = lib.runTests {
# Test examples from the lib.path.append documentation
testAppendExample1 = {
expr = append /foo "bar/baz";
expected = /foo/bar/baz;
};
testAppendExample2 = {
expr = append /foo "./bar//baz/./";
expected = /foo/bar/baz;
};
testAppendExample3 = {
expr = append /. "foo/bar";
expected = /foo/bar;
};
testAppendExample4 = {
expr = (builtins.tryEval (append "/foo" "bar")).success;
expected = false;
};
testAppendExample5 = {
expr = (builtins.tryEval (append /foo /bar)).success;
expected = false;
};
testAppendExample6 = {
expr = (builtins.tryEval (append /foo "")).success;
expected = false;
};
testAppendExample7 = {
expr = (builtins.tryEval (append /foo "/bar")).success;
expected = false;
};
testAppendExample8 = {
expr = (builtins.tryEval (append /foo "../bar")).success;
expected = false;
};
# Test examples from the lib.path.subpath.isValid documentation
testSubpathIsValidExample1 = {
expr = subpath.isValid null;
expected = false;
};
testSubpathIsValidExample2 = {
expr = subpath.isValid "";
expected = false;
};
testSubpathIsValidExample3 = {
expr = subpath.isValid "/foo";
expected = false;
};
testSubpathIsValidExample4 = {
expr = subpath.isValid "../foo";
expected = false;
};
testSubpathIsValidExample5 = {
expr = subpath.isValid "foo/bar";
expected = true;
};
testSubpathIsValidExample6 = {
expr = subpath.isValid "./foo//bar/";
expected = true;
};
# Some extra tests
testSubpathIsValidTwoDotsEnd = {
expr = subpath.isValid "foo/..";
expected = false;
};
testSubpathIsValidTwoDotsMiddle = {
expr = subpath.isValid "foo/../bar";
expected = false;
};
testSubpathIsValidTwoDotsPrefix = {
expr = subpath.isValid "..foo";
expected = true;
};
testSubpathIsValidTwoDotsSuffix = {
expr = subpath.isValid "foo..";
expected = true;
};
testSubpathIsValidTwoDotsPrefixComponent = {
expr = subpath.isValid "foo/..bar/baz";
expected = true;
};
testSubpathIsValidTwoDotsSuffixComponent = {
expr = subpath.isValid "foo/bar../baz";
expected = true;
};
testSubpathIsValidThreeDots = {
expr = subpath.isValid "...";
expected = true;
};
testSubpathIsValidFourDots = {
expr = subpath.isValid "....";
expected = true;
};
testSubpathIsValidThreeDotsComponent = {
expr = subpath.isValid "foo/.../bar";
expected = true;
};
testSubpathIsValidFourDotsComponent = {
expr = subpath.isValid "foo/..../bar";
expected = true;
};
# Test examples from the lib.path.subpath.normalise documentation
testSubpathNormaliseExample1 = {
expr = subpath.normalise "foo//bar";
expected = "./foo/bar";
};
testSubpathNormaliseExample2 = {
expr = subpath.normalise "foo/./bar";
expected = "./foo/bar";
};
testSubpathNormaliseExample3 = {
expr = subpath.normalise "foo/bar";
expected = "./foo/bar";
};
testSubpathNormaliseExample4 = {
expr = subpath.normalise "foo/bar/";
expected = "./foo/bar";
};
testSubpathNormaliseExample5 = {
expr = subpath.normalise "foo/bar/.";
expected = "./foo/bar";
};
testSubpathNormaliseExample6 = {
expr = subpath.normalise ".";
expected = "./.";
};
testSubpathNormaliseExample7 = {
expr = (builtins.tryEval (subpath.normalise "foo/../bar")).success;
expected = false;
};
testSubpathNormaliseExample8 = {
expr = (builtins.tryEval (subpath.normalise "")).success;
expected = false;
};
testSubpathNormaliseExample9 = {
expr = (builtins.tryEval (subpath.normalise "/foo")).success;
expected = false;
};
# Some extra tests
testSubpathNormaliseIsValidDots = {
expr = subpath.normalise "./foo/.bar/.../baz...qux";
expected = "./foo/.bar/.../baz...qux";
};
testSubpathNormaliseWrongType = {
expr = (builtins.tryEval (subpath.normalise null)).success;
expected = false;
};
testSubpathNormaliseTwoDots = {
expr = (builtins.tryEval (subpath.normalise "..")).success;
expected = false;
};
};
in
if cases == [] then "Unit tests successful"
else throw "Path unit tests failed: ${lib.generators.toPretty {} cases}"

View File

@ -18,6 +18,7 @@ rec {
isInt
isList
isAttrs
isPath
isString
match
parseDrvName
@ -127,6 +128,17 @@ rec {
# List of input strings
list: concatStringsSep sep (lib.imap1 f list);
/* Concatenate a list of strings, adding a newline at the end of each one.
Defined as `concatMapStrings (s: s + "\n")`.
Type: concatLines :: [string] -> string
Example:
concatLines [ "foo" "bar" ]
=> "foo\nbar\n"
*/
concatLines = concatMapStrings (s: s + "\n");
/* Construct a Unix-style, colon-separated search path consisting of
the given `subDir` appended to each of the given paths.
@ -395,7 +407,7 @@ rec {
*/
toShellVar = name: value:
lib.throwIfNot (isValidPosixName name) "toShellVar: ${name} is not a valid shell variable name" (
if isAttrs value && ! isCoercibleToString value then
if isAttrs value && ! isStringLike value then
"declare -A ${name}=(${
concatStringsSep " " (lib.mapAttrsToList (n: v:
"[${escapeShellArg n}]=${escapeShellArg v}"
@ -798,10 +810,31 @@ rec {
in lib.warnIf (!precise) "Imprecise conversion from float to string ${result}"
result;
/* Check whether a value can be coerced to a string */
isCoercibleToString = x:
elem (typeOf x) [ "path" "string" "null" "int" "float" "bool" ] ||
(isList x && lib.all isCoercibleToString x) ||
/* Soft-deprecated function. While the original implementation is available as
isConvertibleWithToString, consider using isStringLike instead, if suitable. */
isCoercibleToString = lib.warnIf (lib.isInOldestRelease 2305)
"lib.strings.isCoercibleToString is deprecated in favor of either isStringLike or isConvertibleWithToString. Only use the latter if it needs to return true for null, numbers, booleans and list of similarly coercibles."
isConvertibleWithToString;
/* Check whether a list or other value can be passed to toString.
Many types of value are coercible to string this way, including int, float,
null, bool, list of similarly coercible values.
*/
isConvertibleWithToString = x:
isStringLike x ||
elem (typeOf x) [ "null" "int" "float" "bool" ] ||
(isList x && lib.all isConvertibleWithToString x);
/* Check whether a value can be coerced to a string.
The value must be a string, path, or attribute set.
String-like values can be used without explicit conversion in
string interpolations and in most functions that expect a string.
*/
isStringLike = x:
isString x ||
isPath x ||
x ? outPath ||
x ? __toString;
@ -818,7 +851,7 @@ rec {
=> false
*/
isStorePath = x:
if !(isList x) && isCoercibleToString x then
if isStringLike x then
let str = toString x; in
substring 0 1 str == "/"
&& dirOf str == storeDir

View File

@ -101,7 +101,14 @@ rec {
}.${final.parsed.kernel.name} or null;
# uname -m
processor = final.parsed.cpu.name;
processor =
if final.isPower64
then "ppc64${lib.optionalString final.isLittleEndian "le"}"
else if final.isPower
then "ppc${lib.optionalString final.isLittleEndian "le"}"
else if final.isMips64
then "mips64" # endianness is *not* included on mips64
else final.parsed.cpu.name;
# uname -r
release = null;
@ -135,12 +142,7 @@ rec {
if final.isAarch32 then "arm"
else if final.isx86_64 then "x86_64"
else if final.isx86 then "i386"
else {
powerpc = "ppc";
powerpcle = "ppc";
powerpc64 = "ppc64";
powerpc64le = "ppc64le";
}.${final.parsed.cpu.name} or final.parsed.cpu.name;
else final.uname.processor;
# Name used by UEFI for architectures.
efiArch =

View File

@ -68,6 +68,7 @@ in {
none = [];
arm = filterDoubles predicates.isAarch32;
armv7 = filterDoubles predicates.isArmv7;
aarch64 = filterDoubles predicates.isAarch64;
x86 = filterDoubles predicates.isx86;
i686 = filterDoubles predicates.isi686;
@ -75,6 +76,7 @@ in {
microblaze = filterDoubles predicates.isMicroBlaze;
mips = filterDoubles predicates.isMips;
mmix = filterDoubles predicates.isMmix;
power = filterDoubles predicates.isPower;
riscv = filterDoubles predicates.isRiscV;
riscv32 = filterDoubles predicates.isRiscV32;
riscv64 = filterDoubles predicates.isRiscV64;
@ -83,6 +85,7 @@ in {
or1k = filterDoubles predicates.isOr1k;
m68k = filterDoubles predicates.isM68k;
s390 = filterDoubles predicates.isS390;
s390x = filterDoubles predicates.isS390x;
js = filterDoubles predicates.isJavaScript;
bigEndian = filterDoubles predicates.isBigEndian;

View File

@ -7,6 +7,7 @@ let abis_ = abis; in
let abis = lib.mapAttrs (_: abi: builtins.removeAttrs abi [ "assertions" ]) abis_; in
rec {
# these patterns are to be matched against {host,build,target}Platform.parsed
patterns = rec {
isi686 = { cpu = cpuTypes.i686; };
isx86_32 = { cpu = { family = "x86"; bits = 32; }; };
@ -22,6 +23,9 @@ rec {
];
isx86 = { cpu = { family = "x86"; }; };
isAarch32 = { cpu = { family = "arm"; bits = 32; }; };
isArmv7 = map ({ arch, ... }: { cpu = { inherit arch; }; })
(lib.filter (cpu: lib.hasPrefix "armv7" cpu.arch or "")
(lib.attrValues cpuTypes));
isAarch64 = { cpu = { family = "arm"; bits = 64; }; };
isAarch = { cpu = { family = "arm"; }; };
isMicroBlaze = { cpu = { family = "microblaze"; }; };
@ -44,10 +48,12 @@ rec {
isOr1k = { cpu = { family = "or1k"; }; };
isM68k = { cpu = { family = "m68k"; }; };
isS390 = { cpu = { family = "s390"; }; };
isS390x = { cpu = { family = "s390"; bits = 64; }; };
isJavaScript = { cpu = cpuTypes.js; };
is32bit = { cpu = { bits = 32; }; };
is64bit = { cpu = { bits = 64; }; };
isILP32 = map (a: { abi = { abi = a; }; }) [ "n32" "ilp32" "x32" ];
isBigEndian = { cpu = { significantByte = significantBytes.bigEndian; }; };
isLittleEndian = { cpu = { significantByte = significantBytes.littleEndian; }; };
@ -76,8 +82,13 @@ rec {
isMusl = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf muslabin32 muslabi64 ];
isUClibc = with abis; map (a: { abi = a; }) [ uclibc uclibceabi uclibceabihf ];
isEfi = map (family: { cpu.family = family; })
[ "x86" "arm" "aarch64" ];
isEfi = [
{ cpu = { family = "arm"; version = "6"; }; }
{ cpu = { family = "arm"; version = "7"; }; }
{ cpu = { family = "arm"; version = "8"; }; }
{ cpu = { family = "riscv"; }; }
{ cpu = { family = "x86"; }; }
];
};
matchAnyAttrs = patterns:
@ -85,4 +96,13 @@ rec {
else matchAttrs patterns;
predicates = mapAttrs (_: matchAnyAttrs) patterns;
# these patterns are to be matched against the entire
# {host,build,target}Platform structure; they include a `parsed={}` marker so
# that `lib.meta.availableOn` can distinguish them from the patterns which
# apply only to the `parsed` field.
platformPatterns = mapAttrs (_: p: { parsed = {}; } // p) {
isStatic = { isStatic = true; };
};
}

View File

@ -91,10 +91,14 @@ rec {
microblaze = { bits = 32; significantByte = bigEndian; family = "microblaze"; };
microblazeel = { bits = 32; significantByte = littleEndian; family = "microblaze"; };
mips = { bits = 32; significantByte = bigEndian; family = "mips"; };
mipsel = { bits = 32; significantByte = littleEndian; family = "mips"; };
mips64 = { bits = 64; significantByte = bigEndian; family = "mips"; };
mips64el = { bits = 64; significantByte = littleEndian; family = "mips"; };
mips = { bits = 32; significantByte = bigEndian; family = "mips"; };
mipsel = { bits = 32; significantByte = littleEndian; family = "mips"; };
mipsisa32r6 = { bits = 32; significantByte = bigEndian; family = "mips"; };
mipsisa32r6el = { bits = 32; significantByte = littleEndian; family = "mips"; };
mips64 = { bits = 64; significantByte = bigEndian; family = "mips"; };
mips64el = { bits = 64; significantByte = littleEndian; family = "mips"; };
mipsisa64r6 = { bits = 64; significantByte = bigEndian; family = "mips"; };
mipsisa64r6el = { bits = 64; significantByte = littleEndian; family = "mips"; };
mmix = { bits = 64; significantByte = bigEndian; family = "mmix"; };

View File

@ -7,7 +7,8 @@ in {
type = types.str;
};
email = lib.mkOption {
type = types.str;
type = types.nullOr types.str;
default = null;
};
matrix = lib.mkOption {
type = types.nullOr types.str;

View File

@ -1,5 +1,6 @@
# to run these tests (and the others)
# nix-build nixpkgs/lib/tests/release.nix
# These tests should stay in sync with the comment in maintainers/maintainers-list.nix
{ # The pkgs used for dependencies for the testing itself
pkgs ? import ../.. {}
, lib ? pkgs.lib
@ -20,7 +21,7 @@ let
];
}).config;
checkGithubId = lib.optional (checkedAttrs.github != null && checkedAttrs.githubId == null) ''
checks = lib.optional (checkedAttrs.github != null && checkedAttrs.githubId == null) ''
echo ${lib.escapeShellArg (lib.showOption prefix)}': If `github` is specified, `githubId` must be too.'
# Calling this too often would hit non-authenticated API limits, but this
# shouldn't happen since such errors will get fixed rather quickly
@ -28,8 +29,12 @@ let
id=$(jq -r '.id' <<< "$info")
echo "The GitHub ID for GitHub user ${checkedAttrs.github} is $id:"
echo -e " githubId = $id;\n"
'' ++ lib.optional (checkedAttrs.email == null && checkedAttrs.github == null && checkedAttrs.matrix == null) ''
echo ${lib.escapeShellArg (lib.showOption prefix)}': At least one of `email`, `github` or `matrix` must be specified, so that users know how to reach you.'
'' ++ lib.optional (checkedAttrs.email != null && lib.hasSuffix "noreply.github.com" checkedAttrs.email) ''
echo ${lib.escapeShellArg (lib.showOption prefix)}': If an email address is given, it should allow people to reach you. If you do not want that, you can just provide `github` or `matrix` instead.'
'';
in lib.deepSeq checkedAttrs checkGithubId;
in lib.deepSeq checkedAttrs checks;
missingGithubIds = lib.concatLists (lib.mapAttrsToList checkMaintainer lib.maintainers);

View File

@ -153,6 +153,11 @@ runTests {
expected = "a,b,c";
};
testConcatLines = {
expr = concatLines ["a" "b" "c"];
expected = "a\nb\nc\n";
};
testSplitStringsSimple = {
expr = strings.splitString "." "a.b.c.d";
expected = [ "a" "b" "c" "d" ];
@ -212,6 +217,21 @@ runTests {
expected = [ "1" "2" "3" ];
};
testPadVersionLess = {
expr = versions.pad 3 "1.2";
expected = "1.2.0";
};
testPadVersionLessExtra = {
expr = versions.pad 3 "1.3-rc1";
expected = "1.3.0-rc1";
};
testPadVersionMore = {
expr = versions.pad 3 "1.2.3.4";
expected = "1.2.3";
};
testIsStorePath = {
expr =
let goodPath =
@ -459,6 +479,11 @@ runTests {
expected = [2 30 40 42];
};
testReplicate = {
expr = replicate 3 "a";
expected = ["a" "a" "a"];
};
testToIntShouldConvertStringToInt = {
expr = toInt "27";
expected = 27;

View File

@ -1,11 +1,11 @@
{ # The pkgs used for dependencies for the testing itself
# Don't test properties of pkgs.lib, but rather the lib in the parent directory
pkgs ? import ../.. {} // { lib = throw "pkgs.lib accessed, but the lib tests should use nixpkgs' lib path directly!"; }
pkgs ? import ../.. {} // { lib = throw "pkgs.lib accessed, but the lib tests should use nixpkgs' lib path directly!"; },
nix ? pkgs.nix,
}:
pkgs.runCommand "nixpkgs-lib-tests" {
buildInputs = [
pkgs.nix
(import ./check-eval.nix)
(import ./maintainers.nix {
inherit pkgs;
@ -15,9 +15,16 @@ pkgs.runCommand "nixpkgs-lib-tests" {
inherit pkgs;
lib = import ../.;
})
(import ../path/tests {
inherit pkgs;
})
];
nativeBuildInputs = [
nix
];
strictDeps = true;
} ''
datadir="${pkgs.nix}/share"
datadir="${nix}/share"
export TEST_ROOT=$(pwd)/test-tmp
export NIX_BUILD_HOOK=
export NIX_CONF_DIR=$TEST_ROOT/etc

View File

@ -16,12 +16,15 @@ with lib.systems.doubles; lib.runTests {
testall = mseteq all (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos ++ wasi ++ windows ++ embedded ++ mmix ++ js ++ genode ++ redox);
testarm = mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv6l-netbsd" "armv6l-none" "armv7a-linux" "armv7a-netbsd" "armv7l-linux" "armv7l-netbsd" "arm-none" "armv7a-darwin" ];
testarmv7 = mseteq armv7 [ "armv7a-darwin" "armv7a-linux" "armv7l-linux" "armv7a-netbsd" "armv7l-netbsd" ];
testi686 = mseteq i686 [ "i686-linux" "i686-freebsd13" "i686-genode" "i686-netbsd" "i686-openbsd" "i686-cygwin" "i686-windows" "i686-none" "i686-darwin" ];
testmips = mseteq mips [ "mips64el-linux" "mipsel-linux" "mipsel-netbsd" ];
testmmix = mseteq mmix [ "mmix-mmixware" ];
testpower = mseteq power [ "powerpc-netbsd" "powerpc-none" "powerpc64-linux" "powerpc64le-linux" "powerpcle-none" ];
testriscv = mseteq riscv [ "riscv32-linux" "riscv64-linux" "riscv32-netbsd" "riscv64-netbsd" "riscv32-none" "riscv64-none" ];
testriscv32 = mseteq riscv32 [ "riscv32-linux" "riscv32-netbsd" "riscv32-none" ];
testriscv64 = mseteq riscv64 [ "riscv64-linux" "riscv64-netbsd" "riscv64-none" ];
tests390x = mseteq s390x [ "s390x-linux" "s390x-none" ];
testx86_64 = mseteq x86_64 [ "x86_64-linux" "x86_64-darwin" "x86_64-freebsd13" "x86_64-genode" "x86_64-redox" "x86_64-openbsd" "x86_64-netbsd" "x86_64-cygwin" "x86_64-solaris" "x86_64-windows" "x86_64-none" ];
testcygwin = mseteq cygwin [ "i686-cygwin" "x86_64-cygwin" ];

View File

@ -179,7 +179,7 @@ rec {
they take effect as soon as the oldest release reaches end of life. */
oldestSupportedRelease =
# Update on master only. Do not backport.
2205;
2211;
/* Whether a feature is supported in all supported releases (at the time of
release branch-off, if applicable). See `oldestSupportedRelease`. */

View File

@ -54,7 +54,7 @@ let
concatStringsSep
escapeNixString
hasInfix
isCoercibleToString
isStringLike
;
inherit (lib.trivial)
boolToString
@ -227,7 +227,7 @@ rec {
merge = loc: defs:
let
getType = value:
if isAttrs value && isCoercibleToString value
if isAttrs value && isStringLike value
then "stringCoercibleSet"
else builtins.typeOf value;
@ -479,7 +479,7 @@ rec {
path = mkOptionType {
name = "path";
descriptionClass = "noun";
check = x: isCoercibleToString x && builtins.substring 0 1 (toString x) == "/";
check = x: isStringLike x && builtins.substring 0 1 (toString x) == "/";
merge = mergeEqualOption;
};
@ -558,7 +558,7 @@ rec {
nestedTypes.elemType = elemType;
};
# TODO: drop this in the future:
# TODO: deprecate this in the future:
loaOf = elemType: types.attrsOf elemType // {
name = "loaOf";
deprecationMessage = "Mixing lists with attribute values is no longer"

View File

@ -46,4 +46,19 @@ rec {
builtins.concatStringsSep "."
(lib.take 2 (splitVersion v));
/* Pad a version string with zeros to match the given number of components.
Example:
pad 3 "1.2"
=> "1.2.0"
pad 3 "1.3-rc1"
=> "1.3.0-rc1"
pad 3 "1.2.3.4"
=> "1.2.3"
*/
pad = n: version: let
numericVersion = lib.head (lib.splitString "-" version);
versionSuffix = lib.removePrefix numericVersion version;
in lib.concatStringsSep "." (lib.take n (lib.splitVersion numericVersion ++ lib.genList (_: "0") n)) + versionSuffix;
}

File diff suppressed because it is too large Load Diff

View File

@ -41,7 +41,7 @@ pandoc_flags=(
# - diagram-generator.lua (we do not support that in NixOS manual to limit dependencies)
# - media extraction (was only required for diagram generator)
# - myst-reader/roles.lua (only relevant for MyST → DocBook)
# - link-unix-man-references.lua (links should only be added to display output)
# - link-manpages.lua (links should only be added to display output)
# - docbook-writer/rst-roles.lua (only relevant for → DocBook)
# - docbook-writer/labelless-link-is-xref.lua (only relevant for → DocBook)
"--lua-filter=$DIR/../../doc/build-aux/pandoc-filters/docbook-reader/citerefentry-to-rst-role.lua"

View File

@ -17,6 +17,7 @@ let
if (builtins.tryEval attrs.drvPath).success
then { inherit (attrs) name drvPath; }
else { failed = true; }
else if attrs == null then {}
else { recurseForDerivations = true; } //
mapAttrs (n: v: let path' = path ++ [n]; in trace path' (recurse path' v)) attrs
else { };

View File

@ -112,7 +112,8 @@ main = do
["get-report"] -> getBuildReports
["ping-maintainers"] -> printMaintainerPing
["mark-broken-list"] -> printMarkBrokenList
_ -> putStrLn "Usage: get-report | ping-maintainers | mark-broken-list"
["eval-info"] -> printEvalInfo
_ -> putStrLn "Usage: get-report | ping-maintainers | mark-broken-list | eval-info"
reportFileName :: IO FilePath
reportFileName = getXdgDirectory XdgCache "haskell-updates-build-report.json"
@ -396,12 +397,22 @@ jobTotals (summaryBuilds -> Table mapping) = getSum <$> Table (Map.foldMapWithKe
details :: Text -> [Text] -> [Text]
details summary content = ["<details><summary>" <> summary <> " </summary>", ""] <> content <> ["</details>", ""]
evalLine :: Eval -> UTCTime -> Text
evalLine Eval{id, jobsetevalinputs = JobsetEvalInputs{nixpkgs = Nixpkgs{revision}}} fetchTime =
"*evaluation ["
<> showT id
<> "](https://hydra.nixos.org/eval/"
<> showT id
<> ") of nixpkgs commit ["
<> Text.take 7 revision
<> "](https://github.com/NixOS/nixpkgs/commits/"
<> revision
<> ") as of "
<> Text.pack (formatTime defaultTimeLocale "%Y-%m-%d %H:%M UTC" fetchTime)
<> "*"
printBuildSummary :: Eval -> UTCTime -> StatusSummary -> [(Text, Int)] -> Text
printBuildSummary
Eval{id, jobsetevalinputs = JobsetEvalInputs{nixpkgs = Nixpkgs{revision}}}
fetchTime
summary
topBrokenRdeps =
printBuildSummary eval@Eval{id} fetchTime summary topBrokenRdeps =
Text.unlines $
headline <> [""] <> tldr <> ((" * "<>) <$> (errors <> warnings)) <> [""]
<> totals
@ -415,26 +426,15 @@ printBuildSummary
<> ["","*:arrow_heading_up:: The number of packages that depend (directly or indirectly) on this package (if any). If two numbers are shown the first (lower) number considers only packages which currently have enabled hydra jobs, i.e. are not marked broken. The second (higher) number considers all packages.*",""]
<> footer
where
footer = ["*Report generated with [maintainers/scripts/haskell/hydra-report.hs](https://github.com/NixOS/nixpkgs/blob/haskell-updates/maintainers/scripts/haskell/hydra-report.sh)*"]
footer = ["*Report generated with [maintainers/scripts/haskell/hydra-report.hs](https://github.com/NixOS/nixpkgs/blob/haskell-updates/maintainers/scripts/haskell/hydra-report.hs)*"]
headline =
[ "### [haskell-updates build report from hydra](https://hydra.nixos.org/jobset/nixpkgs/haskell-updates)"
, evalLine eval fetchTime ]
totals =
[ "#### Build summary"
, ""
]
<> printTable "Platform" (\x -> makeSearchLink id (platform x <> " " <> platformIcon x) ("." <> platform x)) (\x -> showT x <> " " <> icon x) showT numSummary
headline =
[ "### [haskell-updates build report from hydra](https://hydra.nixos.org/jobset/nixpkgs/haskell-updates)"
, "*evaluation ["
<> showT id
<> "](https://hydra.nixos.org/eval/"
<> showT id
<> ") of nixpkgs commit ["
<> Text.take 7 revision
<> "](https://github.com/NixOS/nixpkgs/commits/"
<> revision
<> ") as of "
<> Text.pack (formatTime defaultTimeLocale "%Y-%m-%d %H:%M UTC" fetchTime)
<> "*"
]
brokenLine (name, rdeps) = "[" <> name <> "](https://packdeps.haskellers.com/reverse/" <> name <> ") :arrow_heading_up: " <> Text.pack (show rdeps) <> " "
numSummary = statusToNumSummary summary
jobsByState predicate = Map.filter (predicate . worstState) summary
@ -469,6 +469,11 @@ printBuildSummary
maintainedJob = Map.lookup "maintained" summary
mergeableJob = Map.lookup "mergeable" summary
printEvalInfo :: IO ()
printEvalInfo = do
(eval, fetchTime, _) <- readBuildReports
putStrLn (Text.unpack $ evalLine eval fetchTime)
printMaintainerPing :: IO ()
printMaintainerPing = do
(maintainerMap, (reverseDependencyMap, topBrokenRdeps)) <- concurrently getMaintainerMap do

View File

@ -34,6 +34,7 @@ clear="env -u HOME -u NIXPKGS_CONFIG"
$clear maintainers/scripts/haskell/regenerate-hackage-packages.sh
$clear maintainers/scripts/haskell/regenerate-transitive-broken-packages.sh
$clear maintainers/scripts/haskell/regenerate-hackage-packages.sh
evalline=$(maintainers/scripts/haskell/hydra-report.hs eval-info)
if [[ "${1:-}" == "--do-commit" ]]; then
git add $broken_config
@ -42,6 +43,8 @@ git add pkgs/development/haskell-modules/hackage-packages.nix
git commit -F - << EOF
haskellPackages: mark builds failing on hydra as broken
This commit has been generated by maintainers/scripts/haskell/mark-broken.sh
This commit has been generated by maintainers/scripts/haskell/mark-broken.sh based on
$evalline
from the haskell-updates jobset on hydra under https://hydra.nixos.org/jobset/nixpkgs/haskell-updates
EOF
fi

View File

@ -1,5 +1,5 @@
#! /usr/bin/env nix-shell
#! nix-shell -i bash -p coreutils nix gnused -I nixpkgs=.
#! nix-shell -i bash -p coreutils jq nix -I nixpkgs=.
config_file=pkgs/development/haskell-modules/configuration-hackage2nix/transitive-broken.yaml
@ -12,4 +12,4 @@ dont-distribute-packages:
EOF
echo "Regenerating list of transitive broken packages ..."
echo -e $(nix-instantiate --eval --strict maintainers/scripts/haskell/transitive-broken-packages.nix) | sed 's/\"//' | LC_ALL=C.UTF-8 sort -i >> $config_file
nix-instantiate --eval --option restrict-eval true -I . --strict --json maintainers/scripts/haskell/transitive-broken-packages.nix | jq -r . | LC_ALL=C.UTF-8 sort -i >> $config_file

Some files were not shown because too many files have changed in this diff Show More