Merge branch 'master' into current

This commit is contained in:
2026-07-24 15:22:21 +02:00
11484 changed files with 247412 additions and 133363 deletions
+5 -5
View File
@@ -56,12 +56,12 @@ body:
description: |
Can [Hydra](https://hydra.nixos.org), Nixpkgs' Continuous Integration system, reproduce this build failure?
Please use the search function in the header bar to locate the last build job for the package in question.
- If there's a <img src="https://raw.githubusercontent.com/NixOS/hydra/refs/heads/master/src/root/static/images/emojione-red-x-274c.svg" width="20px" align="top" alt="Red X"> icon near the package entry, say '**Yes, Hydra can reproduce this build failure.**'
- If there's a <img src="https://raw.githubusercontent.com/NixOS/hydra/refs/heads/master/src/root/static/images/emojione-gray-x-2716.svg" width="20px" align="top" alt="Dark Gray X"> icon near the package entry, then the build failure occurs with another package, and you need to track the original failing package by going down the chain of 'Cached failures' until you reach the final package in the failing dependency chain. Once you locate the failing package, re-write this report against that package and say '**Yes, Hydra can reproduce this build failure.**'
- If there's a <img src="https://raw.githubusercontent.com/NixOS/hydra/refs/heads/master/src/root/static/images/emojione-check-2714.svg" width="20px" align="top" alt="Green Check Mark"> icon near the package entry, then it most likely means it's a local issue with your system. (Maybe you ran out of space?)
- If there's a <img src="https://raw.githubusercontent.com/NixOS/hydra/refs/heads/master/subprojects/hydra/root/static/images/emojione-red-x-274c.svg" width="20px" align="top" alt="Red X"> icon near the package entry, say '**Yes, Hydra can reproduce this build failure.**'
- If there's a <img src="https://raw.githubusercontent.com/NixOS/hydra/refs/heads/master/subprojects/hydra/root/static/images/emojione-gray-x-2716.svg" width="20px" align="top" alt="Dark Gray X"> icon near the package entry, then the build failure occurs with another package, and you need to track the original failing package by going down the chain of 'Cached failures' until you reach the final package in the failing dependency chain. Once you locate the failing package, re-write this report against that package and say '**Yes, Hydra can reproduce this build failure.**'
- If there's a <img src="https://raw.githubusercontent.com/NixOS/hydra/refs/heads/master/subprojects/hydra/root/static/images/emojione-check-2714.svg" width="20px" align="top" alt="Green Check Mark"> icon near the package entry, then it most likely means it's a local issue with your system. (Maybe you ran out of space?)
You can still open a build failure report, but please say '**No, Hydra cannot reproduce this build failure.**' below.
- If there's a <img src="https://raw.githubusercontent.com/NixOS/hydra/refs/heads/master/src/root/static/images/emojione-question-2754.svg" width="20px" align="top" alt="Gray Question Mark"> icon near the package entry, say '**Hydra is currently rebuilding this package.**'
- If there's a <img src="https://raw.githubusercontent.com/NixOS/hydra/refs/heads/master/src/root/static/images/emojione-stopsign-1f6d1.svg" width="20px" align="top" alt="Red Stop Sign"> icon near the package entry, then the build job was stopped manually. If this occurs, please coordinate with the [Infrastructure Team](https://matrix.to/#/#infra:nixos.org), and say '**The last build job was manually cancelled.**'
- If there's a <img src="https://raw.githubusercontent.com/NixOS/hydra/refs/heads/master/subprojects/hydra/root/static/images/emojione-question-2754.svg" width="20px" align="top" alt="Gray Question Mark"> icon near the package entry, say '**Hydra is currently rebuilding this package.**'
- If there's a <img src="https://raw.githubusercontent.com/NixOS/hydra/refs/heads/master/subprojects/hydra/root/static/images/emojione-stopsign-1f6d1.svg" width="20px" align="top" alt="Red Stop Sign"> icon near the package entry, then the build job was stopped manually. If this occurs, please coordinate with the [Infrastructure Team](https://matrix.to/#/#infra:nixos.org), and say '**The last build job was manually cancelled.**'
- If Hydra isn't supposed to build the package at all, say '**Hydra doesnt try to build the package.**'
options:
- "Please select the Hydra Status."
-1
View File
@@ -13,7 +13,6 @@ For new packages please briefly describe the package or provide a link to its ho
- Built on platform:
- [ ] x86_64-linux
- [ ] aarch64-linux
- [ ] x86_64-darwin
- [ ] aarch64-darwin
- Tested, as applicable:
- [ ] [NixOS tests] in [nixos/tests].
+1
View File
@@ -19,6 +19,7 @@ runs:
TARGET_SHA: ${{ inputs.target-as-trusted-at }}
PIN_BUMP_SHA: ${{ inputs.untrusted-pin-bump }}
with:
retries: 3
script: |
const { rm, writeFile } = require('node:fs/promises')
const { spawn } = require('node:child_process')
-11
View File
@@ -22,17 +22,6 @@
- doc/**/*
- nixos/doc/**/*
"backport release-25.11":
- all:
- changed-files:
- any-glob-to-any-file:
- .github/actions/**/*
- .github/workflows/*
- .github/labeler*.yml
- ci/**/*.*
- maintainers/github-teams.json
- base-branch: ['master']
"backport release-26.05":
- all:
- changed-files:
+1 -1
View File
@@ -49,7 +49,7 @@ jobs:
- name: Create backport PRs
id: backport
uses: korthout/backport-action@66065406958f46e82238fd59546f5a99e69e22aa # v4.5.2
uses: korthout/backport-action@2e830a1d0b8269505846ddd407a70876913ad1f8 # v4.6.0
with:
# Config README: https://github.com/korthout/backport-action#backport-action
add_author_as_reviewer: true
+5 -8
View File
@@ -41,10 +41,6 @@ jobs:
run:
runs-on: ubuntu-slim
if: github.event_name != 'schedule' || github.repository_owner == 'NixOS'
env:
# TODO: Remove after 2026-03-04, when Node 24 becomes the default.
# https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
@@ -53,7 +49,8 @@ jobs:
ci/github-script
- name: Install dependencies
run: npm install @actions/artifact@6.2.1 bottleneck@2.19.5
run: npm ci --package-lock-only=false @actions/artifact bottleneck
working-directory: ci/github-script
# Use a GitHub App, because it has much higher rate limits: 12,500 instead of 5,000 req / hour.
- uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
@@ -91,7 +88,7 @@ jobs:
GH_TOKEN: ${{ steps.app-token.outputs.token || github.token }}
run: gh api /rate_limit | jq
- uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6.1.0
- uses: actions/labeler@b8dd2d9be0f68b860e7dae5dae7d772984eacd6d # v6.2.0
name: Labels from touched files
if: |
github.event_name == 'pull_request_target' &&
@@ -101,7 +98,7 @@ jobs:
configuration-path: .github/labeler.yml # default
sync-labels: true
- uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6.1.0
- uses: actions/labeler@b8dd2d9be0f68b860e7dae5dae7d772984eacd6d # v6.2.0
name: Labels from touched files (no sync)
if: |
github.event_name == 'pull_request_target' &&
@@ -111,7 +108,7 @@ jobs:
configuration-path: .github/labeler-no-sync.yml
sync-labels: false
- uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6.1.0
- uses: actions/labeler@b8dd2d9be0f68b860e7dae5dae7d772984eacd6d # v6.2.0
name: Labels from touched files (development branches)
# Development branches like staging-next, haskell-updates and python-updates get special labels.
# This is to avoid the mass of labels there, which is mostly useless - and really annoying for
+9 -10
View File
@@ -34,21 +34,18 @@ jobs:
matrix:
include:
- runner: ubuntu-24.04
name: x86_64-linux
systems: x86_64-linux
system: x86_64-linux
builds: [shell, manual-nixos, lib-tests, tarball]
desc: shell, docs, lib, tarball
- runner: ubuntu-24.04-arm
name: aarch64-linux
systems: aarch64-linux
system: aarch64-linux
builds: [shell, manual-nixos, manual-nixpkgs]
desc: shell, docs
- runner: macos-14
name: darwin
systems: aarch64-darwin x86_64-darwin
system: aarch64-darwin
builds: [shell]
desc: shell
name: '${{ matrix.name }}: ${{ matrix.desc }}'
name: '${{ matrix.system }}: ${{ matrix.desc }}'
runs-on: ${{ matrix.runner }}
timeout-minutes: 60
steps:
@@ -62,7 +59,7 @@ jobs:
merged-as-untrusted-at: ${{ inputs.mergedSha }}
target-as-trusted-at: ${{ inputs.targetSha }}
- uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
- uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0
with:
# Sandbox is disabled on MacOS by default.
extra_nix_config: sandbox = true
@@ -80,7 +77,9 @@ jobs:
- name: Build shell
if: contains(matrix.builds, 'shell')
run: echo "${{ matrix.systems }}" | xargs -n1 nix-build-uncached nixpkgs/untrusted/ci --arg nixpkgs ./nixpkgs/untrusted-pinned -A shell --argstr system
env:
system: ${{ matrix.system }}
run: nix-build-uncached nixpkgs/untrusted/ci --arg nixpkgs ./nixpkgs/untrusted-pinned -A shell --argstr system "$system"
- name: Build NixOS manual
if: |
@@ -108,5 +107,5 @@ jobs:
contains(fromJSON(inputs.baseBranch).type, 'primary')
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ inputs.artifact-prefix }}nixos-manual-${{ matrix.name }}
name: ${{ inputs.artifact-prefix }}nixos-manual-${{ matrix.system }}
path: nixos-manual
+5 -4
View File
@@ -51,7 +51,8 @@ jobs:
ci/github-script
- name: Install dependencies
run: npm install bottleneck@2.19.5
run: npm ci --package-lock-only=false bottleneck
working-directory: trusted/ci/github-script
- uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
if: github.event_name != 'pull_request' && vars.NIXPKGS_COMMIT_CHECK_CLIENT_ID
@@ -92,8 +93,8 @@ jobs:
if: inputs.baseBranch && inputs.headBranch
permissions:
pull-requests: write
runs-on: ubuntu-slim
timeout-minutes: 3
runs-on: ubuntu-24.04-arm
timeout-minutes: 8
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
@@ -147,7 +148,7 @@ jobs:
merged-as-untrusted-at: ${{ inputs.mergedSha }}
target-as-trusted-at: ${{ inputs.targetSha }}
- uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
- uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0
- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
continue-on-error: true
+9 -4
View File
@@ -15,6 +15,9 @@ on:
targetSha:
required: true
type: string
baseBranch:
required: true
type: string
systems:
required: true
type: string
@@ -136,7 +139,7 @@ jobs:
core.info(`Found pinned.json commit: ${ciPinBumpCommit}`)
- name: Install Nix
uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0
- name: Load supported versions
id: versions
@@ -184,7 +187,7 @@ jobs:
target-as-trusted-at: ${{ inputs.targetSha }}
- name: Install Nix
uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0
- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
continue-on-error: true
@@ -274,7 +277,7 @@ jobs:
merge-multiple: true
- name: Install Nix
uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0
- name: Combine all output paths and eval stats
run: |
@@ -291,6 +294,7 @@ jobs:
- name: Compare against the target branch
env:
TARGET_SHA: ${{ inputs.mergedSha }}
BASE_BRANCH: ${{ fromJSON(inputs.baseBranch).branch }}
run: |
git -C nixpkgs/trusted diff --name-only "$TARGET_SHA" \
| jq --raw-input --slurp 'split("\n")[:-1]' > touched-files.json
@@ -299,6 +303,7 @@ jobs:
nix-build nixpkgs/trusted/ci --arg nixpkgs ./nixpkgs/trusted-pinned -A eval.compare \
--arg combinedDir ./combined \
--arg touchedFilesJson ./touched-files.json \
--argstr baseBranch "$BASE_BRANCH" \
--out-link comparison
cat comparison/step-summary.md >> "$GITHUB_STEP_SUMMARY"
@@ -481,7 +486,7 @@ jobs:
merged-as-untrusted-at: ${{ inputs.mergedSha }}
- name: Install Nix
uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0
- name: Ensure flake outputs on all systems still evaluate
run: nix flake check --all-systems --no-build './nixpkgs/untrusted?shallow=1'
+5 -5
View File
@@ -35,7 +35,7 @@ jobs:
with:
merged-as-untrusted-at: ${{ inputs.mergedSha }}
- uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
- uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0
# TODO: Figure out how to best enable caching for the treefmt job. Cachix won't work well,
# because the cache would be invalidated on every commit - treefmt checks every file.
@@ -70,7 +70,7 @@ jobs:
with:
merged-as-untrusted-at: ${{ inputs.mergedSha }}
- uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
- uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0
- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
continue-on-error: true
@@ -100,7 +100,7 @@ jobs:
merged-as-untrusted-at: ${{ inputs.mergedSha }}
target-as-trusted-at: ${{ inputs.targetSha }}
- uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
- uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0
- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
continue-on-error: true
@@ -131,8 +131,8 @@ jobs:
# Luckily there's no need to lint commit messages in the Merge Queue, because
# changes to the target branch can't change commit messages on the base branch.
if: ${{ github.event.pull_request.number }}
runs-on: ubuntu-slim
timeout-minutes: 5
runs-on: ubuntu-24.04-arm
timeout-minutes: 8
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
+1
View File
@@ -97,6 +97,7 @@ jobs:
artifact-prefix: ${{ inputs.artifact-prefix }}
mergedSha: ${{ needs.prepare.outputs.mergedSha }}
targetSha: ${{ needs.prepare.outputs.targetSha }}
baseBranch: ${{ needs.prepare.outputs.baseBranch }}
systems: ${{ needs.prepare.outputs.systems }}
build:
-6
View File
@@ -31,12 +31,6 @@ jobs:
max-parallel: 1
matrix:
pairs:
- from: release-25.11
into: staging-next-25.11
- from: staging-next-25.11
into: staging-25.11
- from: release-25.11
into: staging-nixos-25.11
- from: release-26.05
into: staging-next-26.05
- from: staging-next-26.05
@@ -110,6 +110,7 @@ jobs:
mergedSha: ${{ needs.prepare.outputs.mergedSha }}
headSha: ${{ github.event.pull_request.head.sha }}
targetSha: ${{ needs.prepare.outputs.targetSha }}
baseBranch: ${{ needs.prepare.outputs.baseBranch }}
systems: ${{ needs.prepare.outputs.systems }}
testVersions: ${{ contains(fromJSON(needs.prepare.outputs.touched), 'pinned') && !contains(fromJSON(needs.prepare.outputs.headBranch).type, 'development') }}
+2 -1
View File
@@ -38,7 +38,8 @@ jobs:
maintainers/github-teams.json
- name: Install dependencies
run: npm install bottleneck@2.19.5
run: npm ci --package-lock-only=false bottleneck
working-directory: ci/github-script
- name: Synchronise teams
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+2
View File
@@ -64,6 +64,7 @@ jobs:
'ci/github-script/supportedSystems.js',
'ci/pinned.json',
'ci/supportedBranches.js',
'pkgs/top-level/release-supported-systems.json',
].includes(file))) core.setOutput('merge-group', true)
if (files.some(file => [
@@ -88,6 +89,7 @@ jobs:
'ci/github-script/withRateLimit.js',
'ci/pinned.json',
'ci/supportedBranches.js',
'pkgs/top-level/release-supported-systems.json',
].includes(file))) core.setOutput('pr', true)
merge-group:
+3
View File
@@ -27,6 +27,9 @@ tags
.mypy_cache
__pycache__
/AGENTS.md
/CLAUDE.md
/pkgs/development/libraries/qt-5/*/tmp/
/pkgs/desktops/kde-5/*/tmp/
/pkgs/development/mobile/androidenv/xml/*
+51 -58
View File
@@ -25,26 +25,27 @@
/shell.nix @infinisil @NixOS/Security
# Libraries
/lib @infinisil @hsjobeki
/lib/generators.nix @infinisil @hsjobeki
/lib/cli.nix @infinisil @hsjobeki
/lib/debug.nix @infinisil @hsjobeki
/lib/asserts.nix @infinisil @hsjobeki
/lib/path/* @infinisil @hsjobeki
/lib/fileset @infinisil @hsjobeki
/maintainers/github-teams.json @infinisil
/maintainers/computed-team-list.nix @infinisil
/lib @infinisil @hsjobeki @llakala
/lib/generators.nix @infinisil @hsjobeki @llakala
/lib/cli.nix @infinisil @hsjobeki @llakala
/lib/debug.nix @infinisil @hsjobeki @llakala
/lib/asserts.nix @infinisil @hsjobeki @llakala
/lib/path/* @infinisil @hsjobeki @llakala
/lib/fileset @infinisil @hsjobeki @llakala
/maintainers/github-teams.json @infinisil @llakala
/maintainers/computed-team-list.nix @infinisil @llakala
## Standard environmentrelated libraries
/lib/customisation.nix @alyssais @NixOS/stdenv
/lib/derivations.nix @NixOS/stdenv
/lib/fetchers.nix @alyssais @NixOS/stdenv
/lib/meta.nix @alyssais @NixOS/stdenv
/lib/source-types.nix @alyssais @NixOS/stdenv
/lib/customisation.nix @alyssais @NixOS/stdenv @llakala
/lib/derivations.nix @NixOS/stdenv @llakala
/lib/fetchers.nix @alyssais @NixOS/stdenv @llakala
/lib/meta.nix @alyssais @NixOS/stdenv @llakala
/lib/meta-types.nix @infinisil @adisbladis @NixOS/stdenv @llakala
/lib/source-types.nix @alyssais @NixOS/stdenv @llakala
/lib/systems @alyssais @NixOS/stdenv
## Libraries / Module system
/lib/modules.nix @infinisil @roberth @hsjobeki
/lib/types.nix @infinisil @roberth @hsjobeki
/lib/options.nix @infinisil @roberth @hsjobeki
/lib/modules.nix @infinisil @roberth @hsjobeki @llakala
/lib/types.nix @infinisil @roberth @hsjobeki @llakala
/lib/options.nix @infinisil @roberth @hsjobeki @llakala
/lib/tests/modules.sh @infinisil @roberth @hsjobeki
/lib/tests/modules @infinisil @roberth @hsjobeki
@@ -62,20 +63,17 @@
/pkgs/top-level/packages-info.nix @jopejoe1
/pkgs/top-level/release-lib.nix @jopejoe1
/pkgs/top-level/release.nix @jopejoe1
/pkgs/stdenv @philiptaron @NixOS/stdenv
/pkgs/stdenv/generic @Ericson2314 @NixOS/stdenv
/pkgs/stdenv/generic/problems.nix @infinisil
/pkgs/stdenv @philiptaron @NixOS/stdenv @llakala
/pkgs/stdenv/generic @Ericson2314 @NixOS/stdenv @llakala
/pkgs/stdenv/generic/problems.nix @infinisil @llakala
/pkgs/test/problems @infinisil
/pkgs/stdenv/generic/check-meta.nix @infinisil @Ericson2314 @adisbladis @NixOS/stdenv
/pkgs/stdenv/generic/meta-types.nix @infinisil @adisbladis @NixOS/stdenv
/pkgs/stdenv/generic/check-meta.nix @infinisil @Ericson2314 @adisbladis @NixOS/stdenv @llakala
/pkgs/stdenv/cross @Ericson2314 @NixOS/stdenv
/pkgs/build-support @philiptaron
/pkgs/build-support/cc-wrapper @Ericson2314
/pkgs/build-support/bintools-wrapper @Ericson2314
/pkgs/build-support/setup-hooks @Ericson2314
/pkgs/build-support/setup-hooks/arrayUtilities @ConnorBaker
/pkgs/build-support/setup-hooks/auto-patchelf.sh @layus
/pkgs/by-name/au/auto-patchelf @layus
## Format generators/serializers
/pkgs/pkgs-lib @Stunkymonkey @h7x4
@@ -84,10 +82,6 @@
# Nixpkgs build-support
/pkgs/build-support/writers @lassulus
# Nixpkgs make-disk-image
/doc/build-helpers/images/makediskimage.section.md @raitobezarius
/nixos/lib/make-disk-image.nix @raitobezarius
# Nix, the package manager
# @raitobezarius is not "code owner", but is listed here to be notified of changes
# pertaining to the Nix package manager.
@@ -101,16 +95,16 @@ nixos/modules/installer/tools/nix-fallback-paths.nix @Artturin @Ericson2314 @lo
/maintainers/scripts/doc @jtojnar @ryantm
# Contributor documentation
/CONTRIBUTING.md @infinisil
/.github/PULL_REQUEST_TEMPLATE.md @infinisil
/doc/contributing/ @infinisil
/doc/contributing/contributing-to-documentation.chapter.md @jtojnar @infinisil
/lib/README.md @infinisil
/doc/README.md @infinisil
/nixos/README.md @infinisil
/pkgs/README.md @infinisil
/pkgs/by-name/README.md @infinisil
/maintainers/README.md @infinisil
/CONTRIBUTING.md
/.github/PULL_REQUEST_TEMPLATE.md
/doc/contributing/
/doc/contributing/contributing-to-documentation.chapter.md @jtojnar
/lib/README.md
/doc/README.md
/nixos/README.md
/pkgs/README.md
/pkgs/by-name/README.md
/maintainers/README.md
# User-facing development documentation
/doc/development.md @infinisil
@@ -129,10 +123,6 @@ nixos/modules/installer/tools/nix-fallback-paths.nix @Artturin @Ericson2314 @lo
/doc/redirects.json @GetPsyched
/nixos/doc/manual/redirects.json @GetPsyched
# NixOS integration test driver
/nixos/lib/test-driver @tfc
/nixos/lib/testing @tfc
# NixOS QEMU virtualisation
/nixos/modules/virtualisation/qemu-vm.nix @raitobezarius
/nixos/modules/services/backup/libvirtd-autosnapshot.nix @6543
@@ -192,10 +182,10 @@ nixos/modules/installer/tools/nix-fallback-paths.nix @Artturin @Ericson2314 @lo
/pkgs/by-name/an/android* @NixOS/android
# Python-related code and docs
/doc/languages-frameworks/python.section.md @mweinelt @natsukium
/maintainers/scripts/update-python-libraries @mweinelt @natsukium
/pkgs/by-name/up/update-python-libraries @mweinelt @natsukium
/pkgs/development/interpreters/python @mweinelt @natsukium
/doc/languages-frameworks/python.section.md @mweinelt
/maintainers/scripts/update-python-libraries @mweinelt
/pkgs/by-name/up/update-python-libraries @mweinelt
/pkgs/development/interpreters/python @mweinelt
# CUDA
/pkgs/top-level/cuda-packages.nix @NixOS/cuda-maintainers
@@ -225,10 +215,10 @@ nixos/modules/installer/tools/nix-fallback-paths.nix @Artturin @Ericson2314 @lo
/pkgs/development/r-modules @jbedo
# Rust
/pkgs/development/compilers/rust @alyssais @Mic92 @winterqt
/pkgs/build-support/rust @winterqt
/pkgs/development/compilers/rust @NixOS/rust @alyssais
/pkgs/build-support/rust @NixOS/rust
/pkgs/build-support/rust/fetch-cargo-vendor* @TomaSajt
/doc/languages-frameworks/rust.section.md @winterqt
/doc/languages-frameworks/rust.section.md @NixOS/rust
# Tcl
/pkgs/development/interpreters/tcl @fgaz
@@ -240,14 +230,10 @@ nixos/modules/installer/tools/nix-fallback-paths.nix @Artturin @Ericson2314 @lo
# C compilers
/pkgs/development/compilers/gcc
/pkgs/development/compilers/llvm @NixOS/llvm
/pkgs/development/compilers/emscripten @raitobezarius
/doc/toolchains/llvm.chapter.md @NixOS/llvm
/doc/languages-frameworks/emscripten.section.md @raitobezarius
# Audio
/nixos/modules/services/audio/botamusique.nix @mweinelt
/nixos/modules/services/audio/snapserver.nix @mweinelt
/nixos/tests/botamusique.nix @mweinelt
/nixos/tests/snapcast.nix @mweinelt
# Browsers
@@ -336,9 +322,9 @@ pkgs/development/python-modules/buildcatrust/ @ajs124 @lukegb @mweinelt
/nixos/tests/knot.nix @mweinelt
# Web servers
/doc/packages/nginx.section.md @raitobezarius
/pkgs/servers/http/nginx/ @raitobezarius
/nixos/modules/services/web-servers/nginx/ @raitobezarius
/doc/packages/nginx.section.md @leona-ya @Ma27
/pkgs/servers/http/nginx/ @helsinki-Jo @leona-ya @Ma27
/nixos/modules/services/web-servers/nginx/ @leona-ya @Ma27
# D
/pkgs/build-support/dlang @jtbx @TomaSajt
@@ -378,7 +364,8 @@ pkgs/development/python-modules/buildcatrust/ @ajs124 @lukegb @mweinelt
/pkgs/development/lua-modules @NixOS/lua
# Neovim
/pkgs/applications/editors/neovim @NixOS/neovim
/pkgs/applications/editors/neovim @NixOS/neovim
/doc/languages-frameworks/neovim.section.md @NixOS/neovim
# VimPlugins
/pkgs/applications/editors/vim/plugins @NixOS/neovim
@@ -519,7 +506,7 @@ pkgs/by-name/oc/octodns/ @anthonyroussel
pkgs/by-name/te/teleport* @arianvp @justinas @sigma @tomberek @techknowlogick @JuliusFreudenberger
# Warp-terminal
pkgs/by-name/wa/warp-terminal/ @emilytrau @imadnyc @FlameFlag @johnrtitor
pkgs/by-name/wa/warp-terminal/ @emilytrau @imadnyc @4evy @johnrtitor
# Nim
/doc/languages-frameworks/nim.section.md @NixOS/nim
@@ -533,3 +520,9 @@ pkgs/by-name/wa/warp-terminal/ @emilytrau @imadnyc @FlameFlag @johnrtitor
# Zellij plugins
/pkgs/by-name/ze/zellij/plugins/ @PerchunPak
# Test-driver
/nixos/lib/test-driver @NixOS/test-driver
/nixos/lib/testing @NixOS/test-driver
/nixos/tests/nixos-test-driver @NixOS/test-driver
/nixos/modules/virtualisation/nspawn-container/run-nspawn @NixOS/test-driver
+11
View File
@@ -51,6 +51,16 @@ To ensure security and a focused utility, the bot adheres to specific limitation
- opened by [@r-ryantm](https://nix-community.github.io/nixpkgs-update/r-ryantm/).
- The user attempting to merge is a member of [@NixOS/nixpkgs-maintainers].
- The user attempting to merge is a maintainer of all packages touched by the PR.
- No [committer][@NixOS/nixpkgs-committers] has an outstanding "changes requested" review.
These block both the merge queue and auto-merge, so the bot refuses to merge until the review is addressed or dismissed.
Once these constraints are met, the bot picks a merge strategy based on the `no PR failures` commit status:
- CI passing: the PR is added to the merge queue.
- CI unfinished (pending or missing status): the bot enables [Auto Merge], which queues the PR once required checks succeed.
Note that if CI later fails, nothing happens until it is fixed and passes.
- CI already failing (`error`/`failure` status): the bot does not enable Auto Merge, because it would never trigger, and fixing CI requires a new push that invalidates the merge command.
A fresh `@NixOS/nixpkgs-merge-bot merge` comment is needed once CI is green again.
### Approving merge bot changes
@@ -104,3 +114,4 @@ This script can also be run locally to print basic test cases.
[@NixOS/nixpkgs-ci]: https://github.com/orgs/NixOS/teams/nixpkgs-ci
[@NixOS/nixpkgs-core]: https://github.com/orgs/NixOS/teams/nixpkgs-core
[RFC 172]: https://github.com/NixOS/rfcs/pull/172
[Auto Merge]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/automatically-merging-a-pull-request
+17 -11
View File
@@ -26,11 +26,7 @@ let
fmt =
let
treefmtNixSrc = fetchTarball {
inherit (pinned.treefmt-nix) url;
sha256 = pinned.treefmt-nix.hash;
};
treefmtEval = (import treefmtNixSrc).evalModule pkgs ./treefmt.nix;
treefmt = pkgs.treefmt.withConfig ./treefmt.nix;
fs = pkgs.lib.fileset;
nixFilesSrc = fs.toSource {
root = ../.;
@@ -38,14 +34,24 @@ let
};
in
{
shell = treefmtEval.config.build.devShell;
pkg = treefmtEval.config.build.wrapper;
check = treefmtEval.config.build.check nixFilesSrc;
pkg = treefmt;
check = treefmt.check nixFilesSrc;
};
# nixos-render-docs and nixos-render-docs-redirects
# Should be used from tree to build the matching in-tree documentation
docPkgs = pkgs.extend (
final: prev: {
nixos-render-docs = final.callPackage ../pkgs/by-name/ni/nixos-render-docs/package.nix { };
nixos-render-docs-redirects =
final.callPackage ../pkgs/by-name/ni/nixos-render-docs-redirects/package.nix
{ };
}
);
in
rec {
inherit pkgs fmt;
inherit pkgs docPkgs fmt;
codeownersValidator = pkgs.callPackage ./codeowners-validator { };
# FIXME(lf-): it might be useful to test other Nix implementations
@@ -58,13 +64,13 @@ rec {
# CI jobs
lib-tests = import ../lib/tests/release.nix { inherit pkgs; };
manual-nixos = (import ../nixos/release.nix { }).manual.${system} or null;
manual-nixpkgs = (import ../doc { inherit pkgs; });
manual-nixpkgs = (import ../doc { pkgs = docPkgs; });
nixpkgs-vet = pkgs.callPackage ./nixpkgs-vet.nix {
nix = pkgs.nixVersions.latest;
};
parse = pkgs.lib.recurseIntoAttrs {
nix_latest = pkgs.callPackage ./parse.nix { nix = pkgs.nixVersions.latest; };
nix_2_28 = pkgs.callPackage ./parse.nix { nix = pkgs.nixVersions.nix_2_28; };
stable = pkgs.callPackage ./parse.nix { nix = pkgs.nixVersions.stable; };
lix = pkgs.callPackage ./parse.nix { nix = pkgs.lix; };
lix_latest = pkgs.callPackage ./parse.nix { nix = pkgs.lixPackageSets.latest.lix; };
};
-85
View File
@@ -1,85 +0,0 @@
# This expression will, as efficiently as possible, dump a
# *superset* of all attrpaths of derivations which might be
# part of a release on *any* platform.
#
# This expression runs single-threaded under all current Nix
# implementations, but much faster and with much less memory
# used than ./outpaths.nix itself.
#
# Once you have the list of attrnames you can split it up into
# $NUM_CORES batches and evaluate the outpaths separately for each
# batch, in parallel.
#
# To dump the attrnames:
#
# nix-instantiate --eval --strict --json ci/eval/attrpaths.nix -A names
#
{
lib ? import (path + "/lib"),
trace ? false,
path ? ./../..,
extraNixpkgsConfigJson ? "{}",
}:
let
# TODO: Use mapAttrsToListRecursiveCond when this PR lands:
# https://github.com/NixOS/nixpkgs/pull/395160
justAttrNames =
path: value:
let
result =
if path == [ "AAAAAASomeThingsFailToEvaluate" ] || !(lib.isAttrs value) then
[ ]
else if lib.isDerivation value then
[ path ]
else
lib.pipe value [
(lib.mapAttrsToList (
name: value:
lib.addErrorContext "while evaluating package set attribute path '${
lib.showAttrPath (path ++ [ name ])
}'" (justAttrNames (path ++ [ name ]) value)
))
lib.concatLists
];
in
lib.traceIf trace "** ${lib.showAttrPath path}" result;
outpaths = import ./outpaths.nix {
inherit path;
extraNixpkgsConfig = builtins.fromJSON extraNixpkgsConfigJson;
attrNamesOnly = true;
};
paths = [
# Some of the following are based on variants, which are disabled with `attrNamesOnly = true`.
# Until these have been removed from release.nix / hydra, we manually add them to the list.
[
"pkgsLLVM"
"stdenv"
]
[
"pkgsArocc"
"stdenv"
]
[
"pkgsZig"
"stdenv"
]
[
"pkgsStatic"
"stdenv"
]
[
"pkgsMusl"
"stdenv"
]
]
++ justAttrNames [ ] outpaths;
names = map lib.showAttrPath paths;
in
{
inherit paths names;
}
+5 -4
View File
@@ -2,8 +2,8 @@
{
lib ? import ../../lib,
path ? ../..,
# The file containing all available attribute paths, which are split into chunks here
attrpathFile,
# The file containing the preEval result
preEvalFile,
chunkSize,
myChunk,
includeBroken,
@@ -12,12 +12,13 @@
}:
let
attrpaths = lib.importJSON attrpathFile;
myAttrpaths = lib.sublist (chunkSize * myChunk) chunkSize attrpaths;
preEvalResult = lib.importJSON preEvalFile;
myAttrpaths = lib.sublist (chunkSize * myChunk) chunkSize preEvalResult.paths;
unfiltered = import ./outpaths.nix {
inherit path;
inherit includeBroken systems;
inherit (preEvalResult) attrPathsDisallowedForInternalUse;
extraNixpkgsConfig = builtins.fromJSON extraNixpkgsConfigJson;
};
+2 -1
View File
@@ -49,6 +49,7 @@ in
{
combinedDir,
touchedFilesJson,
baseBranch,
ownersFile ? ../../OWNERS,
}:
let
@@ -242,7 +243,7 @@ runCommand "compare"
echo
echo "# Performance comparison"
echo
echo "This compares the performance of this branch against its pull request base branch (e.g., 'master')"
echo "This compares the performance of this branch against the \`${baseBranch}\` branch."
echo
} >> $out/step-summary.md
+110 -45
View File
@@ -17,6 +17,7 @@
busybox,
jq,
nix,
perf,
}:
{
@@ -38,7 +39,7 @@ let
fileset = unions (
map (lib.path.append ../..) [
".version"
"ci/eval/attrpaths.nix"
"ci/eval/pre-eval.nix"
"ci/eval/chunk.nix"
"ci/eval/outpaths.nix"
"default.nix"
@@ -56,11 +57,11 @@ let
builtins.readFile ../../pkgs/top-level/release-supported-systems.json
);
attrpathsSuperset =
preEval =
{
evalSystem,
}:
runCommand "attrpaths-superset.json"
runCommand "pre-eval"
{
src = nixpkgs;
# Don't depend on -dev outputs to reduce closure size for CI.
@@ -73,15 +74,15 @@ let
export NIX_STATE_DIR=$(mktemp -d)
mkdir $out
export GC_INITIAL_HEAP_SIZE=4g
command time -f "Attribute eval done [%MKB max resident, %Es elapsed] %C" \
command time -f "Pre-eval done [%MKB max resident, %Es elapsed] %C" \
nix-instantiate --eval --strict --json --show-trace \
"$src/ci/eval/attrpaths.nix" \
-A paths \
"$src/ci/eval/pre-eval.nix" \
-A result \
-I "$src" \
--argstr extraNixpkgsConfigJson ${lib.escapeShellArg (builtins.toJSON extraNixpkgsConfig)} \
--option restrict-eval true \
--option allow-import-from-derivation false \
--option eval-system "${evalSystem}" > $out/paths.json
--option eval-system "${evalSystem}" > $out/result.json
'';
singleSystem =
@@ -90,8 +91,10 @@ let
# Note that this is intentionally not called `system`,
# because `--argstr system` would only be passed to the ci/default.nix file!
evalSystem ? builtins.currentSystem,
# The path to the `paths.json` file from `attrpathsSuperset`
attrpathFile ? "${attrpathsSuperset { inherit evalSystem; }}/paths.json",
# The path to the `result.json` file from `preEval`
preEvalFile ? "${preEval { inherit evalSystem; }}/result.json",
# Output the number of assembly instructions executed during evaluation
countInstructions ? false,
}:
let
singleChunk = writeShellScript "single-chunk" ''
@@ -100,6 +103,7 @@ let
myChunk=$2
system=$3
outputDir=$4
preEvalFile=$5
# Default is 5, higher values effectively disable the warning.
# This randomly breaks Eval.
@@ -121,12 +125,12 @@ let
--show-trace \
--arg chunkSize "$chunkSize" \
--arg myChunk "$myChunk" \
--arg attrpathFile "${attrpathFile}" \
--arg preEvalFile "$preEvalFile" \
--arg systems "[ \"$system\" ]" \
--arg includeBroken ${lib.boolToString includeBroken} \
--argstr extraNixpkgsConfigJson ${lib.escapeShellArg (builtins.toJSON extraNixpkgsConfig)} \
-I ${nixpkgs} \
-I ${attrpathFile} \
-I "$preEvalFile" \
> "$outputDir/result/$myChunk" \
2> "$outputDir/stderr/$myChunk"
exitCode=$?
@@ -146,13 +150,16 @@ let
runCommand "nixpkgs-eval-${evalSystem}"
{
# Don't depend on -dev outputs to reduce closure size for CI.
nativeBuildInputs = map lib.getBin [
busybox
jq
nix
];
nativeBuildInputs = map lib.getBin (
[
busybox
jq
nix
]
++ lib.optionals countInstructions [ perf ]
);
env = {
inherit evalSystem chunkSize;
inherit evalSystem chunkSize countInstructions;
};
__structuredAttrs = true;
unsafeDiscardReferences.out = true;
@@ -164,12 +171,6 @@ let
echo "System: $evalSystem"
cores=$NIX_BUILD_CORES
echo "Cores: $cores"
attrCount=$(jq length "${attrpathFile}")
echo "Attribute count: $attrCount"
echo "Chunk size: $chunkSize"
# Same as `attrCount / chunkSize` but rounded up
chunkCount=$(( (attrCount - 1) / chunkSize + 1 ))
echo "Chunk count: $chunkCount"
mkdir -p $out/${evalSystem}
@@ -190,29 +191,78 @@ let
done
) &
seq_end=$(( chunkCount - 1 ))
chunkedEval() {
local chunkOutputDir=$1
local preEvalFile=$2
${lib.optionalString quickTest ''
seq_end=0
''}
local attrCount=$(jq '.paths | length' "$preEvalFile")
echo "Attribute count: $attrCount"
echo "Chunk size: $chunkSize"
# Same as `attrCount / chunkSize` but rounded up
local chunkCount=$(( (attrCount - 1) / chunkSize + 1 ))
echo "Chunk count: $chunkCount"
chunkOutputDir=$(mktemp -d)
mkdir "$chunkOutputDir"/{result,stats,timestats,stderr}
local seq_end=$(( chunkCount - 1 ))
${lib.optionalString quickTest ''
seq_end=0
''}
seq -w 0 "$seq_end" |
command time -f "%e" -o "$out/${evalSystem}/total-time" \
xargs -I{} -P"$cores" \
${singleChunk} "$chunkSize" {} "$evalSystem" "$chunkOutputDir"
mkdir -p "$chunkOutputDir"/{result,stats,timestats,stderr}
cp -r "$chunkOutputDir"/stats $out/${evalSystem}/stats-by-chunk
runAllChunks() {
seq -w 0 "$seq_end" |
xargs -I{} -P"$cores" \
${singleChunk} "$chunkSize" {} "$evalSystem" "$chunkOutputDir" "$preEvalFile"
}
if (( chunkSize * chunkCount != attrCount )); then
# A final incomplete chunk would mess up the stats, don't include it
rm "$chunkOutputDir"/stats/"$seq_end"
if [[ -n "$countInstructions" ]]; then
export seq_end cores chunkSize evalSystem chunkOutputDir preEvalFile
export -f runAllChunks
perf stat \
--event instructions:u --field-separator , --output "$chunkOutputDir"/perf-output-file \
bash -c runAllChunks
cat "$chunkOutputDir"/perf-output-file | tail -n 1 | cut -d, -f1 > "$chunkOutputDir"/instructions
rm "$chunkOutputDir"/perf-output-file
else
runAllChunks
fi
if (( chunkSize * chunkCount != attrCount )); then
# A final incomplete chunk would mess up the stats, don't include it
rm "$chunkOutputDir"/stats/"$seq_end"
fi
}
chunkOutputDirs=$(mktemp -d)
# Preparation for the second eval
disallowedAttributesPreEvalFile=$(mktemp)
jq '{
paths: (.attrPathsDisallowedForInternalUse | map(.attrPath)),
attrPathsDisallowedForInternalUse: []
}' ${preEvalFile} > "$disallowedAttributesPreEvalFile"
startEpoch=$(date +%s)
# The first eval evaluates only attributes that are not disallowed for internal Nixpkgs use, ensuring that they don't depend on disallowed attributes
# Because the first eval doesn't evaluate the disallowed attributes themselves, but we still want to check that they don't fail evaluation, we evaluate them separately in a second eval
# The reason we need two evals is because we want disallowed attributes to be able to depend on other disallowed attributes, which inherently needs a separate Nixpkgs instantiation
# And while we could interleave that instantiation into a single eval, that would ~double memory usage for all chunks, while doing it separately doesn't
echo "Evaluating the internally allowed attributes"
chunkedEval "$chunkOutputDirs"/allowed ${preEvalFile}
echo "Evaluating the internally disallowed attributes"
chunkedEval "$chunkOutputDirs"/disallowed "$disallowedAttributesPreEvalFile"
echo $(( $(date +%s) - startEpoch )) > "$out/${evalSystem}/total-time"
# We only use the stats from the allowed attrs eval, because the disallowed attrs are generally not even a full chunk
cp -r "$chunkOutputDirs"/allowed/stats $out/${evalSystem}/stats-by-chunk
if [[ -f "$chunkOutputDirs"/allowed/instructions ]]; then
cp "$chunkOutputDirs"/allowed/instructions $out/${evalSystem}/instructions
fi
cat "$chunkOutputDir"/result/* | jq -s 'add | map_values(.outputs)' > $out/${evalSystem}/paths.json
cat "$chunkOutputDir"/result/* | jq -s 'add | map_values(.meta)' > $out/${evalSystem}/meta.json
cat "$chunkOutputDirs"/*/result/* | jq -s 'add | map_values(.outputs)' > $out/${evalSystem}/paths.json
cat "$chunkOutputDirs"/*/result/* | jq -s 'add | map_values(.meta)' > $out/${evalSystem}/meta.json
'';
diff = callPackage ./diff.nix { };
@@ -249,14 +299,20 @@ let
}) | from_entries
' > $out/maintainers.json
mkdir -p $out/before/stats
mkdir -p $out/before/stats $out/before/instructions
for d in ${diffDir}/before/*; do
cp -r "$d"/stats-by-chunk $out/before/stats/$(basename "$d")
if [[ -f "$d"/instructions ]]; then
cp "$d"/instructions $out/before/instructions/$(basename "$d")
fi
done
mkdir -p $out/after/stats
mkdir -p $out/after/stats $out/after/instructions
for d in ${diffDir}/after/*; do
cp -r "$d"/stats-by-chunk $out/after/stats/$(basename "$d")
if [[ -f "$d"/instructions ]]; then
cp "$d"/instructions $out/after/instructions/$(basename "$d")
fi
done
'';
@@ -266,13 +322,16 @@ let
{
# Whether to evaluate on a specific set of systems, by default all are evaluated
evalSystems ? if quickTest then [ "x86_64-linux" ] else supportedSystems,
# Output the number of assembly instructions executed during evaluation on
# each system
countInstructions ? false,
}:
symlinkJoin {
name = "nixpkgs-eval-baseline";
paths = map (
evalSystem:
singleSystem {
inherit evalSystem;
inherit evalSystem countInstructions;
}
) evalSystems;
};
@@ -288,6 +347,12 @@ let
# | jq --raw-input --slurp 'split("\n")[:-1]' > touched-files.json
# ```
touchedFilesJson ? builtins.toFile "touched-files.json" "[ ]",
# The branch the local comparison is made against; matches the `master`
# used in the touched-files expression above.
baseBranch ? "master",
# Output the number of assembly instructions executed during evaluation on
# each system
countInstructions ? false,
}:
let
diffs = symlinkJoin {
@@ -298,14 +363,14 @@ let
inherit evalSystem;
beforeDir = baseline;
afterDir = singleSystem {
inherit evalSystem;
inherit evalSystem countInstructions;
};
}
) evalSystems;
};
comparisonReport = compare {
combinedDir = combine { diffDir = diffs; };
inherit touchedFilesJson;
inherit touchedFilesJson baseBranch;
};
in
comparisonReport;
@@ -313,7 +378,7 @@ let
in
{
inherit
attrpathsSuperset
preEval
singleSystem
diff
combine
+19 -1
View File
@@ -6,7 +6,7 @@
includeBroken ? true, # set this to false to exclude meta.broken packages from the output
path ? ./../..,
# used by ./attrpaths.nix
# used by ./pre-eval.nix
attrNamesOnly ? false,
# Set this to `null` to build for builtins.currentSystem only
@@ -14,6 +14,8 @@
builtins.readFile (path + "/pkgs/top-level/release-supported-systems.json")
),
attrPathsDisallowedForInternalUse ? [ ],
# Customize the config used to evaluate nixpkgs
extraNixpkgsConfig ? { },
}:
@@ -35,6 +37,22 @@ let
allowVariants = !attrNamesOnly;
checkMeta = true;
# We don't need to care about problems being caught using the
# standard mechanism, because any problems whose kind is not
# nixpkgsInternalUseAllowed cause the corresponding attributes to
# be disallowed entirely for internal use with
# attrPathsDisallowedForInternalUse, see also ./pre-eval.nix
problems.matchers = lib.mkForce [
# We only need to set the broken handler to error, so that CI
# doesn't evaluate those. No reason it couldn't evaluate them
# afaik, but this is how it's been before.
{
kind = "broken";
handler = "error";
}
];
inherit attrPathsDisallowedForInternalUse;
# Silence the `x86_64-darwin` deprecation warning.
allowDeprecatedx86_64Darwin = true;
+128
View File
@@ -0,0 +1,128 @@
# This file does a fast pre-evaluation of Nixpkgs to determine:
# - paths: A *superset* of all attrpaths of derivations which might be part of a release on *any* platform.
# - attrPathsDisallowedForInternalUse: Attribute paths whose meta.problems has problems whose kinds should not be used internally in Nixpkgs
#
# This expression runs single-threaded under all current Nix
# implementations, but much faster and with much less memory
# used than ./outpaths.nix itself.
#
# Once you have the list of attrnames you can split it up into
# $NUM_CORES batches and evaluate the outpaths separately for each
# batch, in parallel.
#
# To dump the result:
#
# nix-instantiate --eval --strict --json ci/eval/pre-eval.nix -A result
#
{
lib ? import (path + "/lib"),
trace ? false,
path ? ./../..,
extraNixpkgsConfigJson ? "{}",
}:
let
# TODO: Use mapAttrsToListRecursiveCond when this PR lands:
# https://github.com/NixOS/nixpkgs/pull/395160
listAttrs =
path: value:
let
result =
if path == [ "AAAAAASomeThingsFailToEvaluate" ] || !(lib.isAttrs value) then
[ ]
else if lib.isDerivation value then
[
{
inherit path value;
}
]
else
lib.pipe value [
(lib.mapAttrsToList (
name: value:
lib.addErrorContext "while evaluating package set attribute path '${
lib.showAttrPath (path ++ [ name ])
}'" (listAttrs (path ++ [ name ]) value)
))
lib.concatLists
];
in
lib.traceIf trace "** ${lib.showAttrPath path}" result;
outpaths = import ./outpaths.nix {
inherit path;
extraNixpkgsConfig = builtins.fromJSON extraNixpkgsConfigJson;
attrNamesOnly = true;
};
list =
map
(path: {
inherit path;
# This looks a bit weird, but the only reason we care about this value
# is for the meta.problems check below, and stdenv's certainly don't
# have any problems, so this is fine :)
value = { };
})
[
# Some of the following are based on variants, which are disabled with `attrNamesOnly = true`.
# Until these have been removed from release.nix / hydra, we manually add them to the list.
[
"pkgsLLVM"
"stdenv"
]
[
"pkgsArocc"
"stdenv"
]
[
"pkgsZig"
"stdenv"
]
[
"pkgsStatic"
"stdenv"
]
[
"pkgsMusl"
"stdenv"
]
]
++ listAttrs [ ] outpaths;
paths = map (attrs: attrs.path) list;
names = map lib.showAttrPath paths;
inherit (import ../../pkgs/stdenv/generic/problems.nix { inherit lib; })
disallowNixpkgsInternalUseKinds
;
# Determine the list of attributes whose packages have any meta.problems
# with a kind that's disallowed from internal Nixpkgs use
attrPathsDisallowedForInternalUse = lib.pipe list [
(lib.map (
attrs:
attrs
// {
problematicProblems = builtins.tryEval (
lib.filterAttrs (name: problem: disallowNixpkgsInternalUseKinds ? ${problem.kind}) (
attrs.value.meta.problems or { }
)
);
}
))
(lib.filter (attrs: attrs.problematicProblems.success && attrs.problematicProblems.value != { }))
(lib.map (attrs: {
attrPath = attrs.path;
reason = "it has certain meta.problems whose kinds are disallowed: ${
lib.generators.toPretty { } attrs.problematicProblems.value
}";
}))
];
in
{
# TODO: Do we still need these? Probably not
inherit paths names;
result = {
inherit paths attrPathsDisallowedForInternalUse;
};
}
+23 -13
View File
@@ -206,20 +206,8 @@ module.exports = async ({ github, context, core, dry }) => {
const maintainers = await getMaintainerMap(pull_request.base.ref)
const merge_bot_eligible = await handleMerge({
github,
context,
core,
log,
dry,
pull_request,
events,
maintainers,
getTeamMembers,
getUser,
})
// Check for any human reviews other than the PR author, GitHub actions and other GitHub apps.
// `commit { oid }` is needed by handleMerge to verify approvals are against the current head.
const reviews = (
await github.graphql(
`query($owner: String!, $repo: String!, $pr: Int!) {
@@ -231,6 +219,7 @@ module.exports = async ({ github, context, core, dry }) => {
reviews(first: 100) {
nodes {
state
commit { oid }
user: author {
# Only get users, no bots
... on User {
@@ -266,6 +255,20 @@ module.exports = async ({ github, context, core, dry }) => {
r.user.id !== pull_request.user?.id,
)
const merge_bot_eligible = await handleMerge({
github,
context,
core,
log,
dry,
pull_request,
events,
reviews,
maintainers,
getTeamMembers,
getUser,
})
const approvals = new Set(
reviews
.filter((review) => review.state === 'APPROVED')
@@ -392,6 +395,13 @@ module.exports = async ({ github, context, core, dry }) => {
pull_number,
per_page: 100,
})
// label llm-assisted PRs accordingly
const assistedByPattern = /Assisted-by: (?!nix-init)/i
evalLabels['llm-assisted'] = prCommits.some((c) =>
assistedByPattern.test(c.commit.message),
)
const commitSubjects = prCommits.map(
(c) => c.commit.message.split('\n')[0],
)
+2
View File
@@ -74,8 +74,10 @@ async function checkCommitMessages({ commits, core }) {
'fix',
'perf',
'refactor',
'services',
'style',
'test',
'update',
]
/**
+87 -26
View File
@@ -2,11 +2,11 @@ const { classify } = require('../supportedBranches.js')
function runChecklist({
committers,
events,
files,
pull_request,
log,
maintainers,
reviews,
user,
userIsMaintainer,
}) {
@@ -27,18 +27,35 @@ function runChecklist({
.reduce((acc, cur) => acc?.intersection(cur) ?? cur)
const approvals = new Set(
events
reviews
.filter(
({ event, state, commit_id }) =>
event === 'reviewed' &&
state === 'approved' &&
({ state, commit }) =>
state === 'APPROVED' &&
// Only approvals for the current head SHA count, otherwise authors could push
// bad code between the approval and the merge.
commit_id === pull_request.head.sha,
commit?.oid === pull_request.head.sha,
)
.map(({ user }) => user?.id)
// Some users have been deleted, so filter these out.
.filter(Boolean),
.map(({ user }) => user.id),
)
// A "changes requested" review from a committer blocks both the merge queue and
// auto-merge, even if it was made on an older commit (unlike approvals, GitHub does
// not auto-dismiss changes-requested reviews on push). For each committer, take their
// latest actionable review; if it's CHANGES_REQUESTED, they're blocking the PR.
// Dismissed reviews surface as DISMISSED and comment-only follow-ups as COMMENTED, so
// both are skipped naturally — the prior actionable review still stands until the
// committer explicitly approves or requests changes again.
const committerReviewState = new Map()
for (const { user, state } of reviews) {
if (
committers.has(user.id) &&
['APPROVED', 'CHANGES_REQUESTED'].includes(state)
) {
committerReviewState.set(user.id, state)
}
}
const noBlockingReviews = !Array.from(committerReviewState.values()).includes(
'CHANGES_REQUESTED',
)
const checklist = {
@@ -57,6 +74,11 @@ function runChecklist({
pull_request.user.login === 'r-ryantm',
},
'PR is not a draft': !pull_request.draft,
// CI state is intentionally *not* a checklist item: auto-merge exists precisely to
// cover unfinished CI, and an already-failed CI is reported via the merge message
// (see merge() below) rather than a blanket refusal.
'PR is not blocked by a "changes requested" review from a [committer](https://github.com/orgs/NixOS/teams/nixpkgs-committers).':
noBlockingReviews,
}
if (user) {
@@ -123,6 +145,7 @@ async function handleMerge({
dry,
pull_request,
events,
reviews,
maintainers,
getTeamMembers,
getUser,
@@ -148,6 +171,14 @@ async function handleMerge({
// including an early exit when the first non-by-name file is found.
if (files.length >= 100) return false
const noPrFailuresState = (
await github.rest.repos.listCommitStatusesForRef({
...context.repo,
ref: pull_request.head.sha,
per_page: 100,
})
).data.find(({ context }) => context === 'no PR failures')?.state
// Only look through comments *after* the latest (force) push.
const lastPush = events.findLastIndex(
({ event, sha, commit_id }) =>
@@ -173,10 +204,12 @@ async function handleMerge({
)),
)
// Returns `{ reaction, messages }`: the reaction to leave on the merge comment and the
// lines to append to the bot's reply. Throws only on an unexpected API error.
async function merge() {
if (dry) {
core.info(`Merging #${pull_number}... (dry)`)
return ['Merge completed (dry)']
return { reaction: 'ROCKET', messages: ['Merge completed (dry)'] }
}
// Using GraphQL mutations instead of the REST /merge endpoint, because the latter
@@ -197,16 +230,37 @@ async function handleMerge({
{ node_id: pull_request.node_id, sha: pull_request.head.sha },
)
log('merge', 'Queued for merge')
return [
`:heavy_check_mark: [Queued](${resp.enqueuePullRequest.mergeQueueEntry.mergeQueue.url}) for merge (#306934)`,
]
return {
reaction: 'ROCKET',
messages: [
`:heavy_check_mark: [Queued](${resp.enqueuePullRequest.mergeQueueEntry.mergeQueue.url}) for merge (#306934)`,
],
}
} catch (e) {
log('Enqueuing failed', e.response.errors[0].message)
}
// If required status checks are not satisfied, yet, the above will fail. In this case
// we can enable auto-merge. We could also only use auto-merge, but this often gets
// stuck for no apparent reason.
// Enqueuing fails when the required status checks are not satisfied, yet. If CI has
// already failed, enabling auto-merge would be pointless: it would never fire, and
// fixing CI requires a new push, which invalidates this merge command anyway (we only
// act on comments after the latest push). So we don't enable auto-merge and instead
// ask for a fresh command once CI is green again.
if (['error', 'failure'].includes(noPrFailuresState)) {
log('merge', 'CI has failed, not enabling auto-merge')
return {
reaction: 'THUMBS_DOWN',
messages: [
':x: Pull Request could not be merged: CI has failed (#305350).',
'',
'> [!TIP]',
'> PRs cannot be merged while CI is failing.',
'> Once CI is passing, comment `@NixOS/nixpkgs-merge-bot merge` again.',
],
}
}
// CI has not finished yet, so we enable auto-merge. We could also only use auto-merge,
// but this often gets stuck for no apparent reason.
try {
await github.graphql(
`mutation($node_id: ID!, $sha: GitObjectID) {
@@ -219,12 +273,17 @@ async function handleMerge({
{ node_id: pull_request.node_id, sha: pull_request.head.sha },
)
log('merge', 'Auto-merge enabled')
return [
`:heavy_check_mark: Enabled Auto Merge (#306934)`,
'',
'> [!TIP]',
'> Sometimes GitHub gets stuck after enabling Auto Merge. In this case, leaving another approval should trigger the merge.',
]
return {
reaction: 'ROCKET',
messages: [
`:heavy_check_mark: Enabled Auto Merge (#306934)`,
'',
'> [!TIP]',
'> [Auto Merge](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/automatically-merging-a-pull-request) will queue this PR once required CI checks succeed.',
'> If CI fails instead, fixing it needs a new push, which disables Auto Merge and invalidates this command — comment `@NixOS/nixpkgs-merge-bot merge` again once CI is green.',
'> If GitHub gets stuck even though CI passed (it sometimes does), leaving another approval should kick off the merge.',
],
}
} catch (e) {
log('Auto Merge failed', e.response.errors[0].message)
throw new Error(e.response.errors[0].message)
@@ -267,11 +326,11 @@ async function handleMerge({
const { result, eligible, checklist } = runChecklist({
committers,
events,
files,
pull_request,
log,
maintainers,
reviews,
user: comment.user,
userIsMaintainer: await isMaintainer(comment.user.login),
})
@@ -308,10 +367,12 @@ async function handleMerge({
}
if (result) {
await react('ROCKET')
try {
body.push(...(await merge()))
const { reaction, messages } = await merge()
await react(reaction)
body.push(...messages)
} catch (e) {
await react('THUMBS_DOWN')
// Remove the HTML comment with node_id reference to allow retrying this merge on the next run.
body.shift()
body.push(`:x: Merge failed with: ${e} (#371492)`)
@@ -336,11 +397,11 @@ async function handleMerge({
const { result } = runChecklist({
committers,
events,
files,
pull_request,
log,
maintainers,
reviews,
})
// Returns a boolean, which indicates whether the PR is merge-bot eligible in principle.
-1
View File
@@ -4,7 +4,6 @@
"requires": true,
"packages": {
"": {
"name": "github-script",
"dependencies": {
"@actions/artifact": "6.2.1",
"@actions/core": "1.10.1",
+1 -3
View File
@@ -2,9 +2,7 @@
"private": true,
"//": [
"Keep `@actions/core` and `@actions/github` in sync with",
"https://github.com/actions/github-script/blob/main/package.json.",
"Keep `@actions/artifact` and `bottleneck` in sync with",
"`.github/workflows/bot.yml`."
"https://github.com/actions/github-script/blob/main/package.json."
],
"dependencies": {
"@actions/artifact": "6.2.1",
+3 -16
View File
@@ -9,22 +9,9 @@
},
"branch": "nixpkgs-unstable",
"submodules": false,
"revision": "8c91a71d13451abc40eb9dae8910f972f979852f",
"url": "https://github.com/NixOS/nixpkgs/archive/8c91a71d13451abc40eb9dae8910f972f979852f.tar.gz",
"hash": "sha256-fnzKKPvS+oieI/pTzotA5tkoM47EB1NpaBcgk4R97hE="
},
"treefmt-nix": {
"type": "Git",
"repository": {
"type": "GitHub",
"owner": "numtide",
"repo": "treefmt-nix"
},
"branch": "main",
"submodules": false,
"revision": "db947814a175b7ca6ded66e21383d938df01c227",
"url": "https://github.com/numtide/treefmt-nix/archive/db947814a175b7ca6ded66e21383d938df01c227.tar.gz",
"hash": "sha256-eynAfOmbmxJnkp7YewvCEbShNnnYJ9gLLqkzsYtBPeM="
"revision": "421eebfd0ec7bccd4abe826ce62d7e6e83129493",
"url": "https://github.com/NixOS/nixpkgs/archive/421eebfd0ec7bccd4abe826ce62d7e6e83129493.tar.gz",
"hash": "sha256:1lxfhfgiv1sz2v7fg43gny57sa6wf59n98q7ldsyb2p06f4sal7w"
}
},
"version": 8
+167 -114
View File
@@ -1,122 +1,175 @@
{ pkgs, ... }: {
# Important: The auto-rebase script uses `git filter-branch --tree-filter`,
# which creates trees within the Git repository under `.git-rewrite/t`,
# notably without having a `.git` themselves.
# So if this projectRootFile were the default `.git/config`,
# having the auto-rebase script use treefmt on such a tree would make it
# format all files in the _parent_ Git tree as well.
projectRootFile = ".git-blame-ignore-revs";
# Be a bit more verbose by default, so we can see progress happening
settings.verbose = 1;
# By default it's info, which is too noisy since we have many unmatched files
settings.on-unmatched = "debug";
programs.actionlint.enable = true;
programs.biome = {
enable = true;
# Disable settings validation because its inputs are liable to hash mismatch
validate.enable = false;
settings.formatter = {
useEditorconfig = true;
};
settings.javascript.formatter = {
quoteStyle = "single";
semicolons = "asNeeded";
};
settings.json.formatter.enabled = false;
};
settings.formatter.biome.excludes = [
"*.min.js"
"pkgs/*"
{
lib,
pkgs,
...
}:
{
runtimeInputs = [
# tree-root uses `git rev-parse --show-toplevel`
pkgs.gitMinimal
];
programs.keep-sorted.enable = true;
# This uses nixfmt underneath, the default formatter for Nix code.
# See https://github.com/NixOS/nixfmt
programs.nixfmt = {
enable = true;
package = pkgs.nixfmt;
};
programs.yamlfmt = {
enable = true;
settings.formatter = {
retain_line_breaks = true;
};
};
settings.formatter.yamlfmt.excludes = [
# Aligns comments with whitespace
"pkgs/development/haskell-modules/configuration-hackage2nix/main.yaml"
# TODO: Fix formatting for auto-generated file
"pkgs/development/haskell-modules/configuration-hackage2nix/transitive-broken.yaml"
];
programs.nixf-diagnose = {
enable = true;
ignore = [
# Rule names can currently be looked up here:
# https://github.com/nix-community/nixd/blob/main/libnixf/src/Basic/diagnostic.py
# TODO: Remove the following and fix things.
"sema-unused-def-lambda-noarg-formal"
"sema-unused-def-lambda-witharg-arg"
"sema-unused-def-lambda-witharg-formal"
"sema-unused-def-let"
# Keep this rule, because we have `lib.or`.
"or-identifier"
# TODO: remove after outstanding prelude diagnostics issues are fixed:
# https://github.com/nix-community/nixd/issues/761
# https://github.com/nix-community/nixd/issues/762
"sema-primop-removed-prefix"
"sema-primop-overridden"
"sema-constant-overridden"
"sema-primop-unknown"
];
};
settings.formatter.nixf-diagnose = {
# Ensure nixfmt cleans up after nixf-diagnose.
priority = -1;
settings = {
# numtide/treefmt-nix defaults
excludes = [
# Auto-generated; violates sema-extra-with
# Can only sensibly be removed when --auto-fix supports multiple fixes at once:
# https://github.com/inclyc/nixf-diagnose/issues/13
"pkgs/servers/home-assistant/component-packages.nix"
# https://github.com/nix-community/nixd/issues/708
"nixos/maintainers/scripts/azure-new/examples/basic/system.nix"
"*.lock"
"*.patch"
"*.diff"
"package-lock.json"
"go.mod"
"go.sum"
".gitattributes"
".gitignore"
".gitmodules"
"COPYING"
"LICENSE"
];
};
settings.formatter.editorconfig-checker = {
command = "${pkgs.lib.getExe pkgs.editorconfig-checker}";
options = [
"-disable-indent-size"
# TODO: Remove this once this upstream issue is fixed:
# https://github.com/editorconfig-checker/editorconfig-checker/issues/505
"-disable-charset"
];
includes = [ "*" ];
priority = 1;
};
# Be a bit more verbose by default, so we can see progress happening
verbose = 1;
# TODO: Upstream this into treefmt-nix eventually:
# https://github.com/numtide/treefmt-nix/issues/387
settings.formatter.markdown-code-runner = {
command = pkgs.lib.getExe pkgs.markdown-code-runner;
options =
let
config = pkgs.writers.writeTOML "markdown-code-runner-config" {
presets.nixfmt = {
language = "nix";
command = [ (pkgs.lib.getExe pkgs.nixfmt) ];
};
};
in
[ "--config=${config}" ];
includes = [ "*.md" ];
};
# By default it's info, which is too noisy since we have many unmatched files
on-unmatched = "debug";
programs.zizmor.enable = true;
formatter = {
# keep-sorted start block=yes newline_separated=yes
actionlint = {
command = lib.getExe pkgs.actionlint;
includes = [
".github/workflows/*.yml"
".github/workflows/*.yaml"
];
};
biome = {
command = lib.getExe pkgs.biome;
excludes = [
"*.min.js"
"pkgs/*"
];
includes = [
"*.js"
"*.ts"
"*.mjs"
"*.mts"
"*.cjs"
"*.cts"
"*.jsx"
"*.tsx"
"*.d.ts"
"*.d.cts"
"*.d.mts"
"*.css"
];
options = [
"check"
"--write"
"--no-errors-on-unmatched"
"--use-editorconfig=true"
"--javascript-formatter-quote-style=single"
"--semicolons=as-needed"
];
};
editorconfig-checker = {
command = lib.getExe pkgs.editorconfig-checker;
options = [
"-disable-indent-size"
# TODO: Remove this once this upstream issue is fixed:
# https://github.com/editorconfig-checker/editorconfig-checker/issues/505
"-disable-charset"
];
includes = [ "*" ];
priority = 1;
};
keep-sorted = {
command = lib.getExe pkgs.keep-sorted;
includes = [ "*" ];
};
markdown-code-runner = {
command = lib.getExe pkgs.markdown-code-runner;
options =
let
config = pkgs.writers.writeTOML "markdown-code-runner-config" {
presets.nixfmt = {
language = "nix";
command = [ (lib.getExe pkgs.nixfmt) ];
};
};
in
[ "--config=${config}" ];
includes = [ "*.md" ];
};
nixf-diagnose = {
command = lib.getExe pkgs.nixf-diagnose;
excludes = [
# Auto-generated; violates sema-extra-with
# Can only sensibly be removed when --auto-fix supports multiple fixes at once:
# https://github.com/inclyc/nixf-diagnose/issues/13
"pkgs/servers/home-assistant/component-packages.nix"
# https://github.com/nix-community/nixd/issues/708
"nixos/maintainers/scripts/azure-new/examples/basic/system.nix"
];
includes = [ "*.nix" ];
options = [
"--auto-fix"
# Rule names can currently be looked up here:
# https://github.com/nix-community/nixd/blob/main/libnixf/src/Basic/diagnostic.py
# TODO: Remove the following and fix things.
"--ignore=sema-unused-def-lambda-noarg-formal"
"--ignore=sema-unused-def-lambda-witharg-arg"
"--ignore=sema-unused-def-lambda-witharg-formal"
"--ignore=sema-unused-def-let"
# TODO: remove after outstanding prelude diagnostics issues are fixed:
# https://github.com/nix-community/nixd/issues/761
# https://github.com/nix-community/nixd/issues/762
"--ignore=sema-primop-removed-prefix"
"--ignore=sema-primop-overridden"
"--ignore=sema-constant-overridden"
"--ignore=sema-primop-unknown"
];
# Ensure nixfmt cleans up after nixf-diagnose.
priority = -1;
};
# This uses nixfmt underneath, the default formatter for Nix code.
# See https://github.com/NixOS/nixfmt
nixfmt = {
command = lib.getExe pkgs.nixfmt;
includes = [ "*.nix" ];
};
yamlfmt = {
command = lib.getExe pkgs.yamlfmt;
excludes = [
# Aligns comments with whitespace
"pkgs/development/haskell-modules/configuration-hackage2nix/main.yaml"
# TODO: Fix formatting for auto-generated file
"pkgs/development/haskell-modules/configuration-hackage2nix/transitive-broken.yaml"
];
includes = [
"*.yaml"
"*.yml"
];
options = [
"-formatter"
"retain_line_breaks=true"
];
};
zizmor = {
command = lib.getExe pkgs.zizmor;
includes = [
".github/workflows/*.yml"
".github/workflows/*.yaml"
".github/actions/**/*.yml"
".github/actions/**/*.yaml"
];
};
# keep-sorted end
};
};
}
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p npins -I nixpkgs=../
#!nix-shell -i bash -E 'with import ../. {}; mkShell { packages = [ npins ]; }'
set -euo pipefail
+93 -16
View File
@@ -1,21 +1,32 @@
# Contributing to the Nixpkgs reference manual
# Contributing to the Nixpkgs manual
This directory houses the source files for the Nixpkgs reference manual.
This directory houses the source files for the Nixpkgs manual.
> [!IMPORTANT]
> We are actively restructuring our documentation to follow the [Diátaxis framework](https://diataxis.fr/)
> [!NOTE]
>
> Going forward, this directory should **only** contain [reference documentation](https://nix.dev/contributing/documentation/diataxis#reference).
> For tutorials, guides and explanations, contribute to <https://nix.dev/> instead.
> We are actively restructuring our documentation to be more beginner friendly.
>
> We are actively working to generate **all** reference documentation from the [doc-comments](https://github.com/NixOS/rfcs/blob/master/rfcs/0145-doc-strings.md) present in code.
> This also provides the benefit of using `:doc` in the `nix repl` to view reference documentation locally on the fly.
For documentation only relevant for contributors, use Markdown files next to the source and regular code comments.
When writing new docs use **Progressive Disclosure**
> [!TIP]
> Feedback for improving support for parsing and rendering doc-comments is highly appreciated.
> [Open an issue](https://github.com/NixOS/nixpkgs/issues/new?labels=6.topic%3A+documentation&title=Doc%3A+) to request bugfixes or new features.
Start simple, pick up beginners.
Use **examples** first to show how to get something done. Keep **Explanation** lean.
Use our [styleguide](./styleguide.md) for more in depth guidance on writing good documentation.
This directory contains **guides** and **reference** documentation for Nixpkgs.
Borrowing from [Diátaxis framework](https://diataxis.fr/) what suits our needs:
**Guides** are task-oriented. They can be tutorial-style walkthroughs or how-to sections.
Explanations appear as prose after examples.
**Reference** documentation is the specification of functions and attributes.
We are actively working to generate **all** reference documentation from the [doc-comments](https://github.com/NixOS/rfcs/blob/master/rfcs/0145-doc-strings.md) present in code.
This also provides the benefit of using `:doc` in the `nix repl` to view reference documentation locally on the fly.
See [Document structure](#document-structure) for a structural template.
Rendered documentation:
- [Unstable (from master)](https://nixos.org/manual/nixpkgs/unstable/)
@@ -36,7 +47,7 @@ If the build succeeds, the manual will be in `./result/share/doc/nixpkgs/manual.
### Development environment
In order to reduce repetition, consider using tools from the provided development environment:
To reduce repetition, consider using tools from the provided development environment:
Load it from the Nixpkgs documentation directory with
@@ -54,9 +65,11 @@ Make sure that your local files aren't added to Git history by adding the follow
/**/.direnv
```
#### `devmode`
#### Live preview
Use [`devmode`](../pkgs/by-name/de/devmode/README.md) for a live preview when editing the manual.
Run [`devmode`](../pkgs/by-name/de/devmode/README.md) for a live preview while editing the manual: it rebuilds on every change and reloads the page in your browser automatically.
Changes to the renderer 'pkgs/by-name/ni/nixos-render-docs' need a manual restart. Run: `devmode` again.
### Testing redirects
@@ -209,6 +222,62 @@ You, as the writer of documentation, are still in charge of its content.
**For prose style, see the [documentation styleguide](./styleguide.md).**
### Document structure
Organize each chapter as guide sections first, then a single `## Reference` section.
A well-structured chapter looks like this:
````markdown
# Foo {#foo}
`foo` builds Foo projects from a `foo.toml`.
## Package a Foo application {#foo-packaging}
:::{.example #ex-foo-packaging}
# Package the hello app
```nix
{ foo }:
buildFooPackage {
pname = "hello";
version = "1.0";
}
```
:::
`buildFooPackage` needs `pname` and `version`.
Keep explanation short, and place it after the example.
## Reference {#foo-reference}
### `buildFooPackage` {#foo-buildFooPackage}
Builds a Foo application from source.
#### Inputs {#foo-buildFooPackage-inputs}
`pname` (String)
: The program name.
#### Examples {#foo-buildFooPackage-examples}
See [](#ex-foo-packaging).
````
Examples live in one place: the guide owns them and the reference links to them.
Guides introduce minimal working examples that are goal-oriented (typical usage).
Reference may introduce additional examples that are unit-oriented. (minimal usage, edge-cases).
If the guide example is already sufficient, just link to it from the reference.
Follow this structure strictly; to deviate, ping @NixOS/documentation-team.
### One sentence per line
Put each sentence in its own line.
@@ -284,7 +353,15 @@ Use the [admonition syntax](#admonitions) for callouts and examples.
### `callPackage`-compatible examples
Provide at least one example per function.
Provide at least one example per function, in its doc-comment.
Keep each example at the level it documents:
- A **reference example** might sometimes live in a doc-comment and show function call shape.
- A **guide example** lives in a guide section and shows a complete task that may compose several functions.
When the task is nothing more than the call itself, the guide example is enough.
The reference example links to the guide example.
Example code should be such that it can be passed to `pkgs.callPackage`.
Instead of something like:
-1
View File
@@ -25,6 +25,5 @@ build-helpers/dev-shell-tools.chapter.md
build-helpers/special.md
build-helpers/images.md
hooks/index.md
languages-frameworks/index.md
packages/index.md
```
+1 -1
View File
@@ -2,7 +2,7 @@
The `nix-shell` command has popularized the concept of transient shell environments for development or testing purposes.
<!--
We should try to document the product, not its development process in the Nixpkgs reference manual,
We should try to document the product, not its development process in the Nixpkgs manual,
but *something* needs to be said to provide context for this library.
This is the most future proof sentence I could come up with while Nix itself does not yet make use of this.
Relevant is the current status of the devShell attribute "project": https://github.com/NixOS/nix/issues/7501
@@ -1,48 +1,50 @@
# Fixed-point arguments of build helpers {#chap-build-helpers-finalAttrs}
As mentioned in the beginning of this part, `stdenv.mkDerivation` could alternatively accept a fixed-point function. The input of this function, typically named `finalAttrs`, is expected to be the final state of the attribute set. A build helper like this is said to accept **fixed-point arguments**.
`stdenv.mkDerivation` also accepts a [fixed-point function](#function-library-lib.fixedPoints.fix) instead of a plain attribute set:
Build helpers don't always support fixed-point arguments yet, as support in [`stdenv.mkDerivation`](#mkderivation-recursive-attributes) was first included in Nixpkgs 22.05.
```nix
{
stdenv,
fetchurl,
}:
stdenv.mkDerivation (finalAttrs: {
pname = "hello";
version = "2.12";
## Defining a build helper with `lib.extendMkDerivation` {#sec-build-helper-extendMkDerivation}
src = fetchurl {
url = "mirror://gnu/hello/hello-${finalAttrs.version}.tar.gz";
hash = "sha256-...";
};
})
```
Developers can use the Nixpkgs library function [`lib.customisation.extendMkDerivation`](#function-library-lib.customisation.extendMkDerivation) to define a build helper supporting fixed-point arguments from an existing one with such support, with an attribute overlay similar to the one taken by [`<pkg>.overrideAttrs`](#sec-pkg-overrideAttrs).
The function's input, conventionally named `finalAttrs`, is the final state of the attribute set. Here `src` reads `finalAttrs.version` instead of repeating the version string. A build helper like this is said to accept **fixed-point arguments**.
Attributes that reference each other through `finalAttrs` stay correct when changing any of them with [`overrideAttrs`](#sec-pkg-overrideAttrs), because they all access the final values of the fixed-point computation.
`rec` cannot do this: its self-references are fixed when the set is defined and ignore later overrides.
See [recursive-sets](https://nix.dev/manual/nix/stable/language/syntax#recursive-sets) for the underlying mechanism.
## Define a build helper with `lib.extendMkDerivation` {#sec-build-helper-extendMkDerivation}
Use [`lib.customisation.extendMkDerivation`](#function-library-lib.customisation.extendMkDerivation) to define a build helper with fixed-point support from an existing one.
Its argument `extendDrvArgs` takes an attribute overlay similar to [`<pkg>.overrideAttrs`](#sec-pkg-overrideAttrs).
Besides overriding, `lib.extendMkDerivation` also supports `excludeDrvArgNames` to optionally exclude some arguments in the input fixed-point arguments from passing down to the base build helper (specified as `constructDrv`).
:::{.example #ex-build-helpers-extendMkDerivation}
# Example definition of `mkLocalDerivation` extended from `stdenv.mkDerivation` with `lib.extendMkDerivation`
# Example `mkLocalDerivation` - a build helper over `mkDerivation`
We want to define a build helper named `mkLocalDerivation` that builds locally without using substitutes by default.
Define a build helper named `mkLocalDerivation` that builds locally without using substitutes by default.
Instead of taking a plain attribute set,
Use `lib.extendMkDerivation`:
```nix
{
preferLocalBuild ? true,
allowSubstitute ? false,
specialArg ? (_: false),
...
}@args:
stdenv.mkDerivation (
removeAttrs [
# Don't pass specialArg into mkDerivation.
"specialArg"
] args
// {
# Arguments to pass
inherit preferLocalBuild allowSubstitute;
# Some expressions involving specialArg
greeting = if specialArg "hi" then "hi" else "hello";
}
)
```
we could define with `lib.extendMkDerivation` an attribute overlay to make the result build helper also accept the attribute set's fixed point passing to the underlying `stdenv.mkDerivation`, named `finalAttrs` here:
```nix
lib,
stdenv,
}:
lib.extendMkDerivation {
constructDrv = stdenv.mkDerivation;
excludeDrvArgNames = [
@@ -67,4 +69,78 @@ lib.extendMkDerivation {
```
:::
If one needs to apply extra changes to the result derivation, pass the derivation transformation function to `lib.extendMkDerivation` as `lib.customisation.extendMkDerivation { transformDrv = drv: ...; }`.
To apply extra changes to the result derivation, pass `transformDrv` to `lib.extendMkDerivation`:
```nix
lib.customisation.extendMkDerivation { transformDrv = drv: /...; }
```
Construct a wrapper derivation around another derivation using `transformDrv`
The wrapper has access to the original arguments
:::{.example #ex-build-helpers-extendMkDerivation-transformDrv-wrapper}
# Define a custom build helper that downloads and builds
```nix
{
lib,
stdenvNoCC,
cacert,
configure-example,
download-example,
}:
lib.extendMkDerivation {
constructDrv = stdenvNoCC.mkDerivation;
excludeDrvArgNames = [
"bar"
];
extendDrvArgs =
finalAttrs:
{
bar,
foo,
hash ? "",
...
}@args:
{
inherit hash;
nativeBuildInputs = args.nativeBuildInputs or [ ] ++ [
cacert
download-example
];
buildPhase = ''
runHook preBuild
download-example --foo="$foo" --out="$out"
runHook postBuild
'';
impureEnvVars = lib.fetchers.proxyImpureEnvVars;
outputHash = if finalAttrs.hash != "" then finalAttrs.hash else lib.fakeHash;
outputHashFormat = "recursive";
passthru = args.passthru or { } // {
inherit bar;
};
};
transformDrv =
unwrapped:
stdenvNoCC.mkDerivation (finalAttrs: {
name = finalAttrs.src.name + "-wrapped";
src = unwrapped;
nativeBuildInputs = [
configure-example
];
inherit (unwrapped) bar;
buildPhase = ''
runHook preBuild
configure-example --bar="$bar"
runHook postBuild
'';
});
}
```
:::
+108
View File
@@ -737,4 +737,112 @@ Notable attributes:
* `driverInteractive`: a script that launches an interactive Python session in the context of the `testScript`.
## `modularServiceCompliance` {#tester-modularServiceCompliance}
Compliance suite for [modular service](https://nixos.org/manual/nixos/unstable/#modular-services) integrations.
Tests that a service manager integration correctly handles the portable modular services contract: `process.argv`, sub-services, assertions, and warnings.
### Return value {#tester-modularServiceCompliance-return}
An attribute set of derivations which perform the tests during their build.
### Inputs {#tester-modularServiceCompliance-inputs}
`evalConfig` (function)
: `{ services } -> { config; checkDrv; }`.
Function to evaluate the given services in the integration's full context.
This function is called for evaluation checks on configurations that will not be run.
- Input `services` is an attrset of modular service configurations. These should be used verbatim.
- Output attribute `config` is the resulting evaluated services attrset (e.g., the value of the `system.services` option in NixOS).
This attribute must be available even if `checkDrv` would fail.
- Output attribute `checkDrv` is a representative derivation whose existence and buildability prove the eval is sound (e.g., `system.build.toplevel` in NixOS, but could perhaps be more specific in the case of another process manager integration).
- The generic tester only reads `config` and `checkDrv`. An integration may return additional attributes for its own integration-specific eval checks. Such extra attributes are optional.
`mkTest` (function)
: `{ name, services, testExe } -> derivation`.
- Input `name` is a test name, suitable for use as a derivation name.
- Input `services` is an attrset of modular service configurations, matching the structure of the integration's services option.
- Input `testExe` is a store path to an executable that verifies the services.
- Output: a derivation that runs the service manager with the provided configuration inputs and then calls `testExe` after starting the services. That executable must have access to `sharedDir`.
`sharedDir` (string)
: Path to a directory writable by service processes and readable by `testExe`.
The integration must ensure this directory is available when the services and `testExe` run.
`callReload` (function)
: `path -> string`.
Given a service's name `path` (the list of service names from the top-level service down to the target sub-service, e.g. `[ "reload" "inner" ]`), returns a shell command that reloads that service.
The command is embedded in `testExe` and executed with sufficient privilege to reload the service (e.g. as root in the test VM).
There is no manager-agnostic reload command, so every integration must provide this; the integration joins the `path` per its own unit-naming convention (the suite does not assume one).
On NixOS the `path` dash-joins into the systemd unit name with a `.service` suffix, so the command is `systemctl reload ${lib.concatStringsSep "-" path}.service` (a top-level service is a single-element path `[ "svc" ]` -> `svc.service`; a nested sub-service `[ "parent" "child" ]` -> `parent-child.service`).
:::{.example #ex-modularServiceCompliance-nixos}
# NixOS invocation of the compliance suite
```nix
# In nixos/tests/all-tests.nix:
# modularServiceCompliance =
recurseIntoAttrs (
pkgs.testers.modularServiceCompliance {
sharedDir = "/tmp/modular-service-compliance";
evalConfig =
{ services }:
let
machine = evalSystem (
{ ... }:
{
system.services = services;
system.stateVersion = "25.05";
fileSystems."/" = {
device = "/test/dummy";
fsType = "auto";
};
boot.loader.grub.enable = false;
}
);
in
{
config = machine.config.system.services;
checkDrv = machine.config.system.build.toplevel;
};
callReload = path: "systemctl reload ${lib.concatStringsSep "-" path}.service";
mkTest =
{
name,
services,
testExe,
}:
runTest {
_class = "nixosTest";
inherit name;
nodes.machine.system.services = services;
testScript = ''
machine.wait_for_unit("multi-user.target")
machine.succeed("${testExe}")
'';
};
}
)
```
:::
### Manual compliance items {#tester-modularServiceCompliance-manual}
The following compliance items are not yet automated and must be verified manually when implementing a new modular service integration.
- **Failing assertions prevent deployment.**
A service with `assertions = [{ assertion = false; message = "..."; }]` must cause the deployment to fail.
The mechanism is integration-specific (e.g., NixOS checks assertions during `system.build.toplevel` evaluation).
- **Warnings are visible to the user.**
A service with `warnings = [ "..." ]` must surface the warning to the user.
On NixOS these are `builtins.warn` messages emitted during evaluation.
[file system object]: https://nix.dev/manual/nix/latest/store/file-system-object
@@ -165,7 +165,7 @@ They are useful for creating files from Nix expressions, and are all implemented
Each of these functions will cause a derivation to be produced.
When you coerce the result of each of these functions to a string with [string interpolation](https://nixos.org/manual/nix/stable/language/string-interpolation) or [`toString`](https://nixos.org/manual/nix/stable/language/builtins#builtins-toString), it will evaluate to the [store path](https://nixos.org/manual/nix/stable/store/store-path) of this derivation.
:::: {.note}
::: {.note}
Some of these functions will put the resulting files within a directory inside the [derivation output](https://nixos.org/manual/nix/stable/language/derivations#attr-outputs).
If you need to refer to the resulting files somewhere else in a Nix expression, append their path to the derivation's store path.
@@ -190,7 +190,7 @@ writeShellScript "evaluate-my-file.sh" ''
cat ${my-file}/share/my-file
''
```
::::
:::
### `makeDesktopItem` {#trivial-builder-makeDesktopItem}
+26
View File
@@ -0,0 +1,26 @@
# How channels work {#how-channels-work}
nixpkgs uses the [channels feature](https://nixos.org/nix/manual/#sec-channels) of nix.
nixpkgs is distributed for users of Nix on non-NixOS distributions through the channel
`nixpkgs-unstable`. Users of NixOS generally use one of the `nixos-*` channels,
e.g. `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.
Both `nixos-unstable` and `nixpkgs-unstable` follow the `master` branch of the
nixpkgs repository, although both do lag the `master` branch by generally
[a couple of days](https://status.nixos.org/). Updates to a channel are
distributed as soon as all tests for that channel pass, e.g.
[this table](https://hydra.nixos.org/job/nixpkgs/trunk/unstable#tabs-constituents)
shows the status of tests for the `nixpkgs-unstable` channel.
The tests are conducted by a cluster called [Hydra](https://nixos.org/hydra/),
which also builds binary packages from the Nix expressions in Nixpkgs for
`x86_64-linux`, `aarch64-linux`, `x86_64-darwin` and `aarch64-darwin`.
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 repository](https://github.com/NixOS/nixpkgs) in branches
that correspond to the channel names (e.g. `nixos-22.11-small`).
+1 -1
View File
@@ -1,5 +1,5 @@
{
pkgs ? (import ../ci { }).pkgs,
pkgs ? (import ../ci { }).docPkgs,
nixpkgs ? { },
}:
+7
View File
@@ -0,0 +1,7 @@
<div class="manual-header">
<nav class="manual-header--tabs">
<a class="manual-header--tab manual-header--tab-active" href="#">Nixpkgs</a>
<a class="manual-header--tab" href="https://nixos.org/manual/nixos/stable/">NixOS</a>
</nav>
<span class="manual-header--title">Nixpkgs Manual</span>
</div>
+5 -2
View File
@@ -73,6 +73,7 @@ stdenvNoCC.mkDerivation (
../anchor.min.js
../manpage-urls.json
../redirects.json
../nav.json
]
);
};
@@ -116,8 +117,10 @@ stdenvNoCC.mkDerivation (
--script ./highlightjs/loader.js \
--script ./anchor.min.js \
--script ./anchor-use.js \
--toc-depth 1 \
--section-toc-depth 1 \
--sidebar-depth 3 \
--nav ./nav.json \
--header ${./header.html}\
--no-navheader \
manual.md \
out/index.html
+84
View File
@@ -0,0 +1,84 @@
# Package your first application {#chap-first-package}
Package an application with Nixpkgs by picking the build helper for its language and setting a few attributes.
Each language ecosystem has its own build helper.
See [](#chap-language-support) for the full set.
## Package a Go application {#first-package-go}
`buildGoModule` builds Go programs that use Go modules.
Write the package to `package.nix`:
:::{.example #ex-first-package-go}
# Package `pet` with `buildGoModule`
```nix
# package.nix
{
buildGoModule,
fetchFromGitHub,
lib,
}:
buildGoModule (finalAttrs: {
pname = "pet";
version = "0.3.4";
src = fetchFromGitHub {
owner = "knqyf263";
repo = "pet";
tag = "v${finalAttrs.version}";
hash = "sha256-Gjw1dRrgM8D3G7v6WIM2+50r4HmTXvx0Xxme2fH9TlQ=";
};
vendorHash = "sha256-6hCgv2/8UIRHw1kCe3nLkxF23zE/7t5RDwEjSzX3pBQ=";
meta = {
description = "Simple command-line snippet manager, written in Go";
homepage = "https://github.com/knqyf263/pet";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [ kalbasit ];
};
})
```
:::
`buildGoModule` needs `pname`, `version`, `src`, and `vendorHash`.
Pin Nixpkgs and call the package from `default.nix`:
```nix
# default.nix
let
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/archive/nixos-unstable.tar.gz";
pkgs = import nixpkgs { };
in
pkgs.callPackage ./package.nix { }
```
Build it:
```shell
$ nix-build ./default.nix
# or equivalent
$ nix-build
```
Run it:
```shell
$ ./result/bin/pet --help
pet - Simple command-line snippet manager.
```
`vendorHash` pins the fetched dependencies.
To find its value:
1. Set `vendorHash` to an empty string `""`.
2. Run `nix-build`.
3. Copy the correct value from the error into `vendorHash`.
See the [Go reference](#sec-language-go) for every attribute and advanced usage.
@@ -0,0 +1,24 @@
# checkPhaseThreadLimitHook {#setup-hook-check-phase-thread-limit}
This hook defaults a variety of environment variables known
to control thread counts to 1. Many of these otherwise default
to `$(nproc)`, which causes massive overloads on build machines
if nix build jobs and build cores are already tuned to fully utilize
compute capacity of a builder without additional parallelism.
Currently sets the following environment variables:
- [`OMP_NUM_THREADS`](https://www.openmp.org/spec-html/5.0/openmpse50.html)
- [`OPENBLAS_NUM_THREADS`](https://github.com/OpenMathLib/OpenBLAS/blob/e7b45174355edec1f04de1cabcf5ca6a98ea7fbc/USAGE.md#how-can-i-use-openblas-in-multi-threaded-applications)
- [`MKL_NUM_THREADS`](https://www.intel.com/content/www/us/en/docs/onemkl/developer-guide-linux/2023-0/mkl-domain-num-threads.html)
- [`BLIS_NUM_THREADS`](https://github.com/flame/blis/blob/b8b75b4e19459f5d618b57aa814ca38b1d82eb82/docs/Multithreading.md#specifying-multithreading)
- `VECLIB_MAXIMUM_THREADS`: Only affects darwin, see [`man 7 Accelerate`](https://manp.gs/mac/7/Accelerate)
- [`NUMBA_NUM_THREADS`](https://numba.readthedocs.io/en/stable/reference/envvars.html#threading-control)
- [`NUMEXPR_NUM_THREADS`](https://numexpr.readthedocs.io/en/latest/user_guide.html#threadpool-configuration)
The `NIX_CHECK_PHASE_DEFAULT_NUM_THREADS` environment variable
can be used to override the default thread count limit.
`dontLimitCheckPhaseThreads = true;` can be used to disable
thread limiting on an individual package.
This hook will not attempt to override already existing
definitions for thread count environment variables.
+1
View File
@@ -13,6 +13,7 @@ aws-c-common.section.md
bmake.section.md
breakpoint.section.md
cernlib.section.md
check-phase-thread-limit-hook.section.md
cmake.section.md
desktop-file-utils.section.md
gdk-pixbuf.section.md
+5 -5
View File
@@ -7,7 +7,7 @@ The `pnpmBuildHook` in Nixpkgs overrides the default build phase for building pa
:::{.example #ex-pnpm-build-hook}
## pnpmBuildHook example code snippet {#pnpm-build-hook-code-snippet}
```
```nix
{
lib,
stdenv,
@@ -38,7 +38,7 @@ stdenv.mkDerivation (finalAttrs: {
pnpmDeps = fetchPnpmDeps {
inherit (finalAttrs) pname version src;
inherit pnpm;
fetcherversion = 4;
fetcherVersion = 4;
hash = lib.fakeHash;
};
@@ -94,7 +94,7 @@ Controls the flags pass only to the pnpm build script invocation.
Disables automatically running `pnpmBuildHook`. The build can still be run manually if needed, for example:
```
```nix
{
lib,
rustPlatform,
@@ -123,9 +123,9 @@ rustPlatform.buildRustPackage (finalAttrs: {
pnpmDeps = fetchPnpmDeps {
inherit (finalAttrs) pname version src;
inherit pnpm;
fetcherversion = 3;
fetcherVersion = 4;
hash = lib.fakeHash;
}
};
dontPnpmBuild = true;
postBuild = ''
+3 -3
View File
@@ -125,7 +125,7 @@ There are 2 ways to package backend dependencies: either per-dependency mix2nix
When writing an elixir project targeting `mixRelease`, you can also consider using [deps_nix](https://github.com/code-supply/deps_nix) with `mixNixDeps`. `deps_nix` supports git dependencies, but is intended to be added to the project's `mix.exs` directly.
###### mix2nix {#mix2nix}
##### mix2nix {#mix2nix}
`mix2nix` is a cli tool available in Nixpkgs. It will generate a Nix expression from a `mix.lock` file. It is quite standard in the 2nix tool series.
@@ -175,7 +175,7 @@ If there are git dependencies.
You will need to run the build process once to fix the hash to correspond to your new git src.
###### FOD {#fixed-output-derivation}
##### 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 [akkoma](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/ak/akkoma/package.nix) for a usage example of FOD.
@@ -255,7 +255,7 @@ Setup will require the following steps:
#### Example of creating a service for an Elixir - Phoenix project {#example-of-creating-a-service-for-an-elixir---phoenix-project}
In order to create a service with your release, you could add a `service.nix`
To create a service with your release, you could add a `service.nix`
in your project with the following
```nix
+1 -1
View File
@@ -105,7 +105,7 @@ Given the requirements above, the package expression would become messy quickly:
}
```
Fortunately, we have a [family of hooks]{#ssec-gnome-hooks-wrapgappshook} that automate this. They work in conjunction with other setup hooks that populate environment variables, and will then wrap all executables in `bin` and `libexec` directories using said variables.
Fortunately, we have a [family of hooks]{#ssec-gnome-hooks-wrapgappshook} that automate this. They work in conjunction with other setup hooks that populate environment variables, and will then wrap all executables in `bin` and `libexec` directories using said variables. If a package has multiple outputs, these hooks will work on `outputBin` by default, or on the outputs listed in `wrapGAppsInOutputs` if set.
- [`wrapGAppsHook3`]{#ssec-gnome-hooks-wrapgappshook3} for GTK 3 apps. For convenience, it also adds `dconf.lib` for a GIO module implementing a GSettings backend using `dconf`, `gtk3` for GSettings schemas, and `librsvg` for GdkPixbuf loader to the closure.
- [`wrapGAppsHook4`]{#ssec-gnome-hooks-wrapgappshook4} for GTK 4 apps. Same as `wrapGAppsHook3` but replaces `gtk3` with `gtk4`.
+1 -1
View File
@@ -679,7 +679,7 @@ Defaults to `false`.
`genericBuilderArgsModifier`
: This argument accepts a function allowing you to modify the arguments passed
to `mkDerivation` in order to create the development environment. For example,
to `mkDerivation` to create the development environment. For example,
`args: { doCheck = false; }` would cause the environment to not include any test
dependencies. Defaults to `lib.id`.
+5 -1
View File
@@ -2,6 +2,10 @@
The [standard build environment](#chap-stdenv) makes it easy to build typical Autotools-based packages with very little code. Any other kind of package can be accommodated by overriding the appropriate phases of `stdenv`. However, there are specialised functions in Nixpkgs to easily build packages for other programming languages, such as Perl or Haskell. These are described in this chapter.
::: {.tip}
New to packaging? Start with [](#chap-first-package), then return here for the ecosystem you need.
:::
Each supported language or software ecosystem has its own package set named `<language or ecosystem>Packages`, which can be explored in various ways:
- Search on [search.nixos.org](https://search.nixos.org/packages)
@@ -56,7 +60,6 @@ android.section.md
astal.section.md
beam.section.md
chicken.section.md
rocq.section.md
cosmic.section.md
crystal.section.md
cuda.section.md
@@ -92,6 +95,7 @@ pkg-config.section.md
python.section.md
qt.section.md
r.section.md
rocq.section.md
ruby.section.md
rust.section.md
scheme.section.md
@@ -305,7 +305,7 @@ This package puts the corepack wrappers for pnpm and yarn in your PATH, and they
### pnpm {#javascript-pnpm}
pnpm is available as the top-level package `pnpm`. Additionally, there are variants pinned to certain major versions, like `pnpm_8`, `pnpm_9`, `pnpm_10`, `pnpm_10_29_2` and `pnpm_11`, which support different sets of lock file versions.
pnpm is available as the top-level package `pnpm`. Additionally, there are variants pinned to certain major versions, like `pnpm_9`, `pnpm_10`, `pnpm_10_29_2` and `pnpm_11`, which support different sets of lock file versions.
When packaging an application that includes a `pnpm-lock.yaml`, you need to fetch the pnpm store for that project using a fixed-output-derivation. The function `fetchPnpmDeps` can create this pnpm store derivation. In conjunction, the setup hook `pnpmConfigHook` will prepare the build environment to install the pre-fetched dependencies store. Here is an example for a package that contains `package.json` and a `pnpm-lock.yaml` files using the fetcher and setup hook above:
@@ -408,6 +408,8 @@ In case you are patching `package.json` or `pnpm-lock.yaml`, make sure to pass `
}
```
If needed, `dontPnpmConfigure = true;` can be used to fully disable `pnpmConfigHook` without manually removing it from inputs.
#### Dealing with `sourceRoot` {#javascript-pnpm-sourceRoot}
If the pnpm project is in a subdirectory, you can just define `sourceRoot` or `setSourceRoot` for `fetchPnpmDeps`.
@@ -493,7 +495,7 @@ In this example, `prePnpmInstall` will be run by both `pnpmConfigHook` and by th
#### pnpm `fetcherVersion` {#javascript-pnpm-fetcherVersion}
This is the version of the output of `fetchPnpmDeps`. New packages should use `3`:
This is the version of the output of `fetchPnpmDeps`. New packages should use `4`:
```nix
{
+11
View File
@@ -162,6 +162,17 @@ the package `luarocks-packages-updater`:
nix-shell -p luarocks-packages-updater --run luarocks-packages-updater
```
To add a new package without updating all packages, run
```sh
nix-shell -p luarocks-packages-updater
luarocks-packages-updater add [--maintainers "<maintainer>"] <package-name>
```
The optional `--maintainers` argument accepts a space-separated list of nixpkgs maintainer names.
When omitted, the package is added without maintainers.
[luarocks2nix](https://github.com/nix-community/luarocks) is a tool capable of generating nix derivations from both rockspec and src.rock (and favors the src.rock).
The automation only goes so far though and some packages need to be customized.
These customizations go in [pkgs/development/lua-modules/overrides.nix](https://github.com/NixOS/nixpkgs/tree/master/pkgs/development/lua-modules/overrides.nix).
+55 -2
View File
@@ -174,6 +174,59 @@ To make sure that your package does not add extra manual effort when upgrading M
</plugin>
```
## Maven 4 {#maven-4}
Alongside the default `maven` package (the latest Maven 3 release), nixpkgs ships `maven_4`, which packages the [Maven 4](https://maven.apache.org/whatsnewinmaven4.html) release line.
`maven_4` is a standalone derivation and can be used as a drop-in replacement wherever `maven` is used, for example to build a project with the latest Maven 4:
```nix
{
lib,
fetchFromGitHub,
jre,
makeWrapper,
maven_4,
}:
maven_4.buildMavenPackage (finalAttrs: {
pname = "jd-cli";
version = "1.2.1";
src = fetchFromGitHub {
owner = "intoolswetrust";
repo = "jd-cli";
tag = "jd-cli-${finalAttrs.version}";
hash = "sha256-rRttA5H0A0c44loBzbKH7Waoted3IsOgxGCD2VM0U/Q=";
};
mvnHash = "";
nativeBuildInputs = [ makeWrapper ];
installPhase = ''
runHook preInstall
mkdir -p $out/bin $out/share/jd-cli
install -Dm644 jd-cli/target/jd-cli.jar $out/share/jd-cli
makeWrapper ${jre}/bin/java $out/bin/jd-cli \
--add-flags "-jar $out/share/jd-cli/jd-cli.jar"
runHook postInstall
'';
meta = {
description = "Simple command line wrapper around JD Core Java Decompiler project";
homepage = "https://github.com/intoolswetrust/jd-cli";
license = lib.licenses.gpl3Plus;
maintainers = with lib.maintainers; [ majiir ];
};
})
```
`maven_4` exposes the same `buildMavenPackage` helper as `maven` (see [](#maven-buildmavenpackage)), so all of the patterns documented above apply equally. Note that the Maven dependencies resolved by Maven 4 differ from those resolved by Maven 3, so `mvnHash` must be recomputed when switching between the two.
## Manually using `mvn2nix` {#maven-mvn2nix}
::: {.warning}
This way is no longer recommended; see [](#maven-buildmavenpackage) for the simpler and preferred way.
@@ -288,7 +341,7 @@ The double invocation is a _simple_ way to get around the problem that `nix-buil
It treats the entire Maven repository as a single source to be downloaded, relying on Maven's dependency resolution to satisfy the output hash. This is similar to fetchers like `fetchgit`, except it has to run a Maven build to determine what to download.
The first step will be to build the Maven project as a fixed-output derivation in order to collect the Maven repository -- below is an [example](https://github.com/fzakaria/nixos-maven-example/blob/main/double-invocation-repository.nix).
The first step will be to build the Maven project as a fixed-output derivation to collect the Maven repository -- below is an [example](https://github.com/fzakaria/nixos-maven-example/blob/main/double-invocation-repository.nix).
::: {.note}
Traditionally the Maven repository is at `~/.m2/repository`. We will override this to be the `$out` directory.
@@ -416,7 +469,7 @@ The previous example builds a `jar` file but that's not a file one can run.
You need to use it with `java -jar $out/share/java/output.jar` and make sure to provide the required dependencies on the classpath.
The following explains how to use `makeWrapper` in order to make the derivation produce an executable that will run the JAR file you created.
The following explains how to use `makeWrapper` to make the derivation produce an executable that will run the JAR file you created.
We will use the same repository we built above (either _double invocation_ or _buildMaven_) to setup a CLASSPATH for our JAR.
+66 -11
View File
@@ -25,7 +25,7 @@ neovim.override {
withRuby = false;
configure = {
customRC = ''
# here your custom viml configuration goes!
" here your custom viml configuration goes!
'';
packages.myVimPackage = with pkgs.vimPlugins; {
# See examples below on how to use custom packages.
@@ -47,7 +47,7 @@ neovim-qt.override {
neovim = neovim.override {
configure = {
customRC = ''
# your custom viml configuration
" your custom viml configuration
'';
};
};
@@ -64,11 +64,14 @@ For instance, `sqlite-lua` needs `g:sqlite_clib_path` to be set to work. Nixpkgs
- `wrapRc`: Nix, not being able to write in your `$HOME`, loads the
generated Neovim configuration via the `$VIMINIT` environment variable, i.e. : `export VIMINIT='lua dofile("/nix/store/…-init.lua")'`. This has side effects like preventing Neovim from sourcing your `init.lua` in `$XDG_CONFIG_HOME/nvim` (see bullet 7 of [`:help startup`](https://neovim.io/doc/user/starting.html#startup) in Neovim). Disable it if you want to generate your own wrapper. You can still reuse the generated vimscript init code via `neovim.passthru.initRc`.
- `plugins`: A list of plugins to add to the wrapper.
- `extraLuaPackages`: A function passed on to `lua.withPackages`
- `withPython3`, `withNodeJs`, `withRuby` control when to enable neovim
- `extraLuaPackages`: A function passed on to `lua.withPackages`.
- `extraPython3Packages`: A function passed on to `python3.withPackages`.
- `withPython3`, `withNodeJs`, `withRuby`, `withPerl` control when to enable neovim
providers (see `:h provider`).
- `vimAlias` and `viAlias` control whether to symlink the `vim` and `vi` binaries to `nvim` respectively.
- `extraName` is a string appended to the package name and derivation name.
```
```nix
wrapNeovimUnstable neovim-unwrapped {
autoconfigure = true;
autowrapRuntimeDeps = true;
@@ -80,7 +83,8 @@ wrapNeovimUnstable neovim-unwrapped {
vim.opt.colorcolumn = { 100 }
vim.opt.termguicolors = true
'';
# plugins accepts a list of either plugins or { plugin = ...; config = ..vimscript.. };
# plugins accepts a list of either plugins or attribute sets containing:
# { plugin = ...; config = ...; type = "viml"|"lua"; } (type defaults to "viml")
plugins = with vimPlugins; [
{
plugin = vim-obsession;
@@ -88,7 +92,19 @@ wrapNeovimUnstable neovim-unwrapped {
map <Leader>$ <Cmd>Obsession<CR>
'';
}
(nvim-treesitter.withPlugins (p: [ p.nix p.python ]))
{
plugin = grug-far-nvim;
type = "lua";
config = ''
require('grug-far').setup({
startInInsertMode = false,
})
'';
}
(nvim-treesitter.withPlugins (p: [
p.nix
p.python
]))
hex-nvim
];
extraLuaPackages = lp: [ lp.mpack ];
@@ -98,12 +114,12 @@ wrapNeovimUnstable neovim-unwrapped {
}
```
You can explore the configuration with`nix repl` to discover these options and
You can explore the configuration with `nix repl` to discover these options and
override them. For instance:
```nix
neovim.overrideAttrs (oldAttrs: {
neovim.override {
autowrapRuntimeDeps = false;
})
}
```
## Specificities for some plugins {#neovim-plugin-specificities}
@@ -136,7 +152,7 @@ For example, if upstream documents that a plugin uses the Vim license but GitHub
## LuaRocks based plugins {#neovim-luarocks-based-plugins}
In order to automatically handle plugin dependencies, several Neovim plugins
To automatically handle plugin dependencies, several Neovim plugins
upload their package to [LuaRocks](https://www.luarocks.org). This means less work for nixpkgs maintainers in the long term as dependencies get updated automatically.
This means several Neovim plugins are first packaged as nixpkgs [lua
packages](#packaging-a-library-on-luarocks), and converted via `buildNeovimPlugin` in
@@ -151,6 +167,8 @@ For instance:
```
To update these packages, you should use the lua updater rather than vim's.
To add a lua package to the `vimPlugins` set, add it to the `luarocksPackageNames` list in [luaPackagePlugins.nix](https://github.com/nixos/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/luaPackagePlugins.nix).
## Treesitter {#neovim-plugin-treesitter}
[Treesitter](https://tree-sitter.github.io/) provides syntax parsing for Neovim, enabling features like:
@@ -246,6 +264,43 @@ You can install the standalone parsers and queries directly without installing `
})
```
### Treesitter setup using WASM parsers and queries {#neovim-plugin-treesitter-wasm}
Neovim can load WASM parsers when it is built with Wasmtime support.
In nixpkgs, WASM parser plugins are available from the `wasi32` cross package set:
```nix
(pkgs.wrapNeovim (pkgs.neovim-unwrapped.override { wasmSupport = true; }) {
configure = {
packages.myPlugins =
with pkgs.pkgsCross.wasi32.vimPlugins;
let
# Select the grammars you need
treesitter-grammars = with nvim-treesitter-parsers; [
nix
python
];
# Queries are needed for treesitter based syntax highlighting and folds.
treesitter-queries = map (p: p.associatedQuery) treesitter-grammars;
in
{
start = [
# regular plugins
]
++ treesitter-grammars
++ treesitter-queries;
};
};
})
```
Do not install both native and WASM parsers for the same language.
For example, installing both `pkgs.vimPlugins.nvim-treesitter-parsers.nix` and
`pkgs.pkgsCross.wasi32.vimPlugins.nvim-treesitter-parsers.nix` is invalid because Neovim
loads the first `parser/nix.*` found on `runtimepath`.
Use `:checkhealth vim.treesitter` to verify Nix-managed WASM parsers.
You can enable treesitter features for installed grammars in a `FileType` autocommand
or in an `ftplugin/<language>.lua` script, e.g.
+8 -22
View File
@@ -204,25 +204,9 @@ following are specific to `buildPythonPackage`:
* `setupPyGlobalFlags ? []`: List of flags passed to `setup.py` command.
* `setupPyBuildFlags ? []`: List of flags passed to `setup.py build_ext` command.
##### Using fixed-point arguments {#buildpythonpackage-fixed-point-arguments}
##### Writing override-compatible packages {#buildpythonpackage-fixed-point-arguments}
Both `buildPythonPackage` and `buildPythonApplication` support [fixed-point arguments](#chap-build-helpers-finalAttrs), similar to `stdenv.mkDerivation`.
This allows you to reference the final attributes of the derivation.
Instead of using `rec`:
```nix
buildPythonPackage rec {
pname = "pyspread";
version = "2.4";
src = fetchPypi {
inherit pname version;
hash = "sha256-...";
};
}
```
You can use the `finalAttrs` pattern:
Use `finalAttrs` to make a package easy to update and override:
```nix
buildPythonPackage (finalAttrs: {
@@ -236,7 +220,9 @@ buildPythonPackage (finalAttrs: {
})
```
See the [general documentation on fixed-point arguments](#chap-build-helpers-finalAttrs) for more details on the benefits of this pattern.
When a downstream callsite *overrides* `version` the override becomes visible as `finalAttrs.version`.
Both `buildPythonPackage` and `buildPythonApplication` support [fixed-point arguments](#chap-build-helpers-finalAttrs), similar to `stdenv.mkDerivation`.
::: {.note}
@@ -1628,7 +1614,7 @@ looked at how you can create environments in which specified packages are
available.
At some point you'll likely have multiple packages which you would
like to be able to use in different projects. In order to minimise unnecessary
like to be able to use in different projects. To minimise unnecessary
duplication we now look at how you can maintain a repository with your
own packages. The important functions here are `import` and `callPackage`.
@@ -1875,7 +1861,7 @@ pkgs.mkShell rec {
pythonPackages.numpy
pythonPackages.requests
# In this particular example, in order to compile any binary extensions they may
# In this particular example, to compile any binary extensions they may
# require, the Python modules listed in the hypothetical requirements.txt need
# the following packages to be installed locally:
taglib
@@ -2106,7 +2092,7 @@ See also [contributing section](#contributing).
### Are Python interpreters built deterministically? {#deterministic-builds}
The Python interpreters are now built deterministically. Minor modifications had
to be made to the interpreters in order to generate deterministic bytecode. This
to be made to the interpreters to generate deterministic bytecode. This
has security implications and is relevant for those using Python in a
`nix-shell`.
+6 -4
View File
@@ -51,7 +51,7 @@ The recommended way of defining a derivation for a Rocq library, is to use the `
* if it is a string of the form `owner:branch` then it tries to download the `branch` of owner `owner` for a project of the same name using the same vcs, and the `version` attribute of the resulting derivation is set to `"dev"`, additionally if the owner is not provided (i.e. if the `owner:` prefix is missing), it defaults to the original owner of the package (see below),
* if it is a string of the form `"#N"`, and the domain is github, then it tries to download the current head of the pull request `#N` from github,
* `defaultVersion` (optional). Rocq libraries may be compatible with some specific versions of Rocq only. The `defaultVersion` attribute is used when no `version` is provided (or if `version = null`) to select the version of the library to use by default, depending on the context. This selection will mainly depend on a `rocq-core` version number but also possibly on other packages versions (e.g. `mathcomp`). If its value ends up to be `null`, the package is marked for removal in end-user `rocqPackages` attribute set.
* `release` (optional, defaults to `{}`), lists all the known releases of the library and for each of them provides an attribute set with at least a `hash` attribute (you may put the empty string `""` in order to automatically insert a fake hash, this will trigger an error which will allow you to find the correct hash), each attribute set of the list of releases also takes optional overloading arguments for the fetcher as below (i.e.`domain`, `owner`, `repo`, `rev`, `artifact` assuming the default fetcher is used) and optional overrides for the result of the fetcher (i.e. `version` and `src`).
* `release` (optional, defaults to `{}`), lists all the known releases of the library and for each of them provides an attribute set with at least a `hash` attribute (you may put the empty string `""` to automatically insert a fake hash, this will trigger an error which will allow you to find the correct hash), each attribute set of the list of releases also takes optional overloading arguments for the fetcher as below (i.e.`domain`, `owner`, `repo`, `rev`, `artifact` assuming the default fetcher is used) and optional overrides for the result of the fetcher (i.e. `version` and `src`).
* `fetcher` (optional, defaults to a generic fetching mechanism supporting github or gitlab based infrastructures), is a function that takes at least an `owner`, a `repo`, a `rev`, and a `hash` and returns an attribute set with a `version` and `src`.
* `repo` (optional, defaults to the value of `pname`),
* `owner` (optional, defaults to `"rocq-community"`).
@@ -59,7 +59,7 @@ The recommended way of defining a derivation for a Rocq library, is to use the `
* `releaseRev` (optional, defaults to `(v: v)`), provides a default mapping from release names to revision hashes/branch names/tags,
* `releaseArtifact` (optional, defaults to `(v: null)`), provides a default mapping from release names to artifact names (only works for github artifact for now),
* `displayVersion` (optional), provides a way to alter the computation of `name` from `pname`, by explaining how to display version numbers,
* `namePrefix` (optional, defaults to `[ "rocq-core" ]`), provides a way to alter the computation of `name` from `pname`, by explaining which dependencies must occur in `name`,
* `namePrefix` (optional, defaults to `[ "rocq" ]`), provides a way to alter the computation of `name` from `pname`, by explaining which dependencies must occur in `name`,
* `nativeBuildInputs` (optional), is a list of executables that are required to build the current derivation, in addition to the default ones (namely `which`, `dune` and `ocaml` depending on whether `useDune`, `useDuneifVersion` and `mlPlugin` are set).
* `extraNativeBuildInputs` (optional, deprecated), an additional list of derivation to add to `nativeBuildInputs`,
* `overrideNativeBuildInputs` (optional) replaces the default list of derivation to which `nativeBuildInputs` and `extraNativeBuildInputs` adds extra elements,
@@ -68,12 +68,14 @@ The recommended way of defining a derivation for a Rocq library, is to use the `
* `overrideBuildInputs` (optional) replaces the default list of derivation to which `buildInputs` and `extraBuildInputs` adds extras elements,
* `propagatedBuildInputs` (optional) is passed as is to `mkDerivation`, we recommend to use this for Rocq libraries and Rocq plugin dependencies, as this makes sure the paths of the compiled libraries and plugins will always be added to the build environments of subsequent derivation, which is necessary for Rocq packages to work correctly,
* `mlPlugin` (optional, defaults to `false`). Some extensions (plugins) might require OCaml and sometimes other OCaml packages. Standard dependencies can be added by setting the current option to `true`. For a finer grain control, the `rocq-core.ocamlPackages` attribute can be used in `nativeBuildInputs`, `buildInputs`, and `propagatedBuildInputs` to depend on the same package set Rocq was built against.
* `useDuneifVersion` (optional, default to `(x: false)` uses Dune to build the package if the provided predicate evaluates to true on the version, e.g. `useDuneifVersion = versions.isGe "1.1"` will use dune if the version of the package is greater or equal to `"1.1"`,
* `useDuneifVersion` (optional, default to `(x: false)`) uses Dune to build the package if the provided predicate evaluates to true on the version, e.g. `useDuneifVersion = versions.isGe "1.1"` will use dune if the version of the package is greater or equal to `"1.1"`,
* `useDune` (optional, defaults to `false`) uses Dune to build the package if set to true, the presence of this attribute overrides the behavior of the previous one.
* `opam-name` (optional, defaults to concatenating with a dash separator the components of `namePrefix` and `pname`), name of the Dune package to build.
* `enableParallelBuilding` (optional, defaults to `true`), since it is activated by default, we provide a way to disable it.
* `extraInstallFlags` (optional), allows to extend `installFlags` which initializes the variables `COQLIBINSTALL` and `COQPLUGININSTALL` so as to install in the proper subdirectory. Indeed Rocq libraries should be installed in `$(out)/lib/coq/${rocq-core.rocq-version}/user-contrib/`. Such directories are automatically added to the `$ROCQPATH` environment variable by the hook defined in the Rocq derivation.
* `setROCQBIN` (optional, defaults to `true`), by default, the environment variable `$ROCQBIN` is set to the current Rocq's binary, but one can disable this behavior by setting it to `false`,
* `useCoq` (optional, defaults to `false`), adds the Coq compatibility binaries to the build environment, which is necessary for some packages that still depend on them and sets `COQBIN` to the path of the `coqc` binary (if `setROCQBIN` is also set to `true`). A wrapper `mkCoqDerivation` is provided that sets this option to `true`.
* `useCoqifVersion` (optional, defaults to `(x: false)`), adds the Coq compatibility binaries to the build environment if the provided predicate evaluates to true on the version. This can be useful for supporting old package versions that need the Coq compatibility binaries, while newer versions do not.
* `useMelquiondRemake` (optional, default to `null`) is an attribute set, which, if given, overloads the `preConfigurePhases`, `configureFlags`, `buildPhase`, and `installPhase` attributes of the derivation for a specific use in libraries using `remake` as set up by Guillaume Melquiond for `flocq`, `gappalib`, `interval`, and `coquelicot` (see the corresponding derivation for concrete examples of use of this option). For backward compatibility, the attribute `useMelquiondRemake.logpath` must be set to the logical root of the library (otherwise, one can pass `useMelquiondRemake = {}` to activate this without backward compatibility).
* `dropAttrs`, `keepAttrs`, `dropDerivationAttrs` are all optional and allow to tune which attribute is added or removed from the final call to `mkDerivation`.
@@ -153,7 +155,7 @@ For example, assuming you have a special `mathcomp` dependency you want to use,
multinomials.override { mathcomp = my-special-mathcomp; }
```
In Nixpkgs, all Rocq derivations take a `version` argument. This can be overridden in order to easily use a different version:
In Nixpkgs, all Rocq derivations take a `version` argument. This can be overridden to easily use a different version:
```nix
rocqPackages.multinomials.override { version = "1.5.1"; }
+2 -2
View File
@@ -125,7 +125,7 @@ With this file in your directory, you can run `nix-shell` to build and use the g
The `bundlerEnv` is a wrapper over all the gems in your gemset. This means that all the `/lib` and `/bin` directories will be available, and the executables of all gems (even of indirect dependencies) will end up in your `$PATH`. The `wrappedRuby` provides you with all executables that come with Ruby itself, but wrapped so they can easily find the gems in your gemset.
One common issue that you might have is that you have Ruby, but also `bundler` in your gemset. That leads to a conflict for `/bin/bundle` and `/bin/bundler`. You can resolve this by wrapping either your Ruby or your gems in a `lowPrio` call. So in order to give the `bundler` from your gemset priority, it would be used like this:
One common issue that you might have is that you have Ruby, but also `bundler` in your gemset. That leads to a conflict for `/bin/bundle` and `/bin/bundler`. You can resolve this by wrapping either your Ruby or your gems in a `lowPrio` call. So to give the `bundler` from your gemset priority, it would be used like this:
```nix
# ...
@@ -265,7 +265,7 @@ Now that you know how to get a working Ruby environment with Nix, it's time to g
All gems in the standard set are automatically generated from a single `Gemfile`. The dependency resolution is done with `bundler` and makes it more likely that all gems are compatible with each other.
In order to add a new gem to nixpkgs, you can put it into the `/pkgs/development/ruby-modules/with-packages/Gemfile` and run `./maintainers/scripts/update-ruby-packages`.
To add a new gem to nixpkgs, you can put it into the `/pkgs/development/ruby-modules/with-packages/Gemfile` and run `./maintainers/scripts/update-ruby-packages`.
To test that it works, you can then try using the gem with:
+29 -2
View File
@@ -885,8 +885,7 @@ general. A number of other parameters can be overridden:
empty, or `"forbid"` (no cap) when `lints` is set. Because `rustc`
only honours the first `--cap-lints` it receives, this cannot be
changed via `extraRustcOpts`; use this attribute instead. Useful
when overriding the `rust` attribute to point at `clippy-driver`,
since clippy lints are also capped by this flag:
with `useClippy`, since clippy lints are also capped by this flag:
```nix
(hello { }).override { capLints = "warn"; }
@@ -912,6 +911,34 @@ general. A number of other parameters can be overridden:
}
```
- Whether to compile the crate with `clippy-driver` instead of `rustc`.
Build scripts (`build.rs`) keep plain `rustc`. The default `capLints`
of `"allow"` suppresses all lints including clippy's, so this is
usually paired with `capLints` and lint flags via `extraRustcOpts`:
```nix
(hello { }).override {
useClippy = true;
capLints = "warn";
extraRustcOpts = [
"-Dwarnings"
"-Wclippy::all"
];
}
```
When using a Rust toolchain that bundles its own `clippy-driver`
(rust-overlay, Fenix), pass it via `clippy` so the sysroot matches:
```nix
(hello { }).override {
rust = myToolchain;
clippy = myToolchain;
useClippy = true;
capLints = "warn";
}
```
- Phases, just like in any other derivation, can be specified using
the following attributes: `preUnpack`, `postUnpack`, `prePatch`,
`patches`, `postPatch`, `preConfigure` (in the case of a Rust crate,
+1 -1
View File
@@ -160,7 +160,7 @@ This essentially runs: `swift test -c release`
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
provides these as symlinks to read-only `/nix/store` paths. To patch
them, we need to make them writable.
A special function `swiftpmMakeMutable` is available to replace the symlink
@@ -32,6 +32,21 @@ There is a TeX Live packaging that lives entirely under attribute `texlive`.
)
```
- Packages can be overriden by passing a new package with the same `pname` to `.withPackages`. For instance, the following replaces Asymptote with the version from Nixpkgs, which is usually more up to date:
```nix
texliveMedium.withPackages (ps: [ asymptote ])
```
- To exclude a package from a collection, use an empty override as below:
```nix
texliveBasic.withPackages (
ps: with ps; [
collection-bibtexextra
{ pname = "bib2gls"; }
]
)
```
- To add the documentation for all packages in the environment, use
```nix
texliveSmall.overrideAttrs { withDocs = true; }
+6 -1
View File
@@ -149,11 +149,16 @@ Note: this is not possible anymore for Neovim.
## Adding new plugins to nixpkgs {#adding-new-plugins-to-nixpkgs}
:::{.note}
Before adding a Neovim Lua plugin, check if a release is available on [luarocks](https://luarocks.org/).
If it is, add it as a [LuaRocks based plugin](#neovim-luarocks-based-plugins).
:::
Nix expressions for Vim plugins are stored in [pkgs/applications/editors/vim/plugins](https://github.com/NixOS/nixpkgs/tree/master/pkgs/applications/editors/vim/plugins). For the vast majority of plugins, Nix expressions are automatically generated by running [`nix-shell -p vimPluginsUpdater --run vim-plugins-updater`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/utils/updater.nix). This creates a [generated.nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/generated.nix) file based on the plugins listed in [vim-plugin-names](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/vim-plugin-names).
When the vim updater detects an nvim-treesitter update, it also runs [`nvim-treesitter/update.py $(nix-build -A vimPlugins.nvim-treesitter)`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/utils/update.py) to update the tree sitter grammars for `nvim-treesitter`.
Some plugins require overrides in order to function properly. Overrides are placed in [overrides.nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/overrides.nix). Overrides are most often required when a plugin requires some dependencies, or extra steps are required during the build process. For example `deoplete-fish` requires both `deoplete-nvim` and `vim-fish`, and so the following override was added:
Some plugins require overrides to function properly. Overrides are placed in [overrides.nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/overrides.nix). Overrides are most often required when a plugin requires some dependencies, or extra steps are required during the build process. For example `deoplete-fish` requires both `deoplete-nvim` and `vim-fish`, and so the following override was added:
```nix
{
+6 -1
View File
@@ -1,8 +1,9 @@
# Nixpkgs Reference Manual {#nixpkgs-manual}
# Nixpkgs Manual {#nixpkgs-manual}
## Version @MANUAL_VERSION@
```{=include=} chapters
preface.chapter.md
first-package.chapter.md
```
```{=include=} parts
@@ -17,6 +18,10 @@ contributing.md
interoperability.md
```
```{=include=} chapters
languages-frameworks/index.md
```
```{=include=} appendix html:into-file=//release-notes.html
release-notes/release-notes.md
```
+3
View File
@@ -0,0 +1,3 @@
{
"open": []
}
+2 -2
View File
@@ -10,7 +10,7 @@ The tarball archive needs to be downloaded manually, as the license agreements o
The [self-service](https://support.citrix.com/article/CTX200337) is an application for managing Citrix desktops and applications. Please note that this feature only works with at least `citrix_workspace_20_06_0` and later versions.
In order to set this up, you first have to [download the `.cr` file from the Netscaler Gateway](https://its.uiowa.edu/support/article/102186). After that, you can configure the `selfservice` like this:
To set this up, you first have to [download the `.cr` file from the Netscaler Gateway](https://its.uiowa.edu/support/article/102186). After that, you can configure the `selfservice` like this:
```ShellSession
$ storebrowse -C ~/Downloads/receiverconfig.cr
@@ -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://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`:
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`. 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; };
+1 -1
View File
@@ -24,7 +24,7 @@ The Emacs package comes with some extra helpers to make it easier to configure.
}
```
You can install it like any other package via `nix-env -iA myEmacs`. However, this will only install those packages. It will not `configure` them for us. To do this, we need to provide a configuration file. Luckily, it is possible to do this from within Nix! By modifying the above example, we can make Emacs load a custom config file. The key is to create a package that provides a `default.el` file in `/share/emacs/site-start/`. Emacs knows to load this file automatically when it starts.
You can install it like any other package via `nix-env -iA myEmacs`. However, this will only install those packages. It will not `configure` them for us. To do this, we need to provide a configuration file. Luckily, it is possible to do this from within Nix! By modifying the above example, we can make Emacs load a custom config file. The key is to create a package that provides a `default.el` file in `/share/emacs/site-start/`. Emacs knows to load this file automatically when it starts. Similarly, for `early-init.el`, you can create a package that provides an `early-default.el` file in `/share/emacs/site-start/`.
```nix
{
+1
View File
@@ -25,6 +25,7 @@ etc-files.section.md
nginx.section.md
nrfutil.section.md
opengl.section.md
packer.section.md
shell-helpers.section.md
python-tree-sitter.section.md
treefmt.section.md
+70
View File
@@ -0,0 +1,70 @@
# Packer {#sec-packer}
[Packer](https://www.packer.io) is a tool for creating identical machine images
for multiple platforms from a single source configuration.
## Using Packer with plugins {#sec-packer-with-plugins}
Packer's functionality is extended through
[plugins](https://developer.hashicorp.com/packer/docs/plugins). Rather than
letting Packer download plugins at runtime, you can build a Packer wrapper that
bundles the plugins you need with `packer.withPlugins`.
`packer.withPlugins` takes a function that receives the set of available plugins
and returns the list of plugins to include:
```nix
packer.withPlugins (ps: [ ps.docker ])
```
This produces a `packer` executable wrapped with the `PACKER_PLUGIN_PATH`
environment variable set, so the selected plugins are available without a
separate `packer plugins install` step.
For example, to get a development shell with Packer and the Docker plugin:
```nix
{
pkgs ? import <nixpkgs> { },
}:
pkgs.mkShell {
packages = [
(pkgs.packer.withPlugins (ps: [ ps.docker ]))
];
}
```
Multiple plugins can be selected at once:
```nix
packer.withPlugins (ps: [
ps.docker
ps.qemu
])
```
## Listing available plugins {#sec-packer-list-plugins}
The packaged plugins are exposed as the `packer.plugins` attribute set. To list
every plugin available in your version of Nixpkgs, query its attribute names:
```ShellSession
$ nix eval nixpkgs#packer.plugins --apply builtins.attrNames
[ "docker" "qemu" ]
```
Without flakes:
```ShellSession
$ nix-env -f '<nixpkgs>' -qaP -A packer.plugins
packer.plugins.docker packer-plugin-docker-1.1.2
packer.plugins.qemu packer-plugin-qemu-1.1.4
```
The attribute name (for example `docker` or `qemu`) is what you pass to
`packer.withPlugins`.
Notes:
- `mkPackerPlugin` currently only supports `fetchFromGitHub` as the fetcher.
+1 -1
View File
@@ -22,7 +22,7 @@ rxvt-unicode.override {
If the `configure` function returns an attrset without the `plugins` attribute, `availablePlugins` will be used automatically.
In order to add plugins but also keep all default plugins installed, it is possible to use the following method:
To add plugins but also keep all default plugins installed, it is possible to use the following method:
```nix
rxvt-unicode.override {
+1 -1
View File
@@ -39,7 +39,7 @@ weechat.override {
}
```
In order to also keep all default plugins installed, it is possible to use the following method:
To also keep all default plugins installed, it is possible to use the following method:
```nix
weechat.override {
+7 -43
View File
@@ -1,50 +1,14 @@
# Preface {#preface}
# Overview {#preface}
The Nix Packages collection (Nixpkgs) is a set of thousands of packages for the
[Nix package manager](https://nixos.org/nix/), released under a
[permissive MIT license](https://github.com/NixOS/nixpkgs/blob/master/COPYING).
Packages are available for several platforms, and can be used with the Nix
package manager on most GNU/Linux distributions as well as [NixOS](https://nixos.org/nixos).
Nixpkgs is a set of packages for the [Nix package manager](https://nixos.org/nix/), released under the [MIT license](https://github.com/NixOS/nixpkgs/blob/master/COPYING).
This document is the user [_reference_](https://nix.dev/contributing/documentation/diataxis#reference) manual for Nixpkgs.
It describes the entire public interface of Nixpkgs in a concise and orderly manner, and all relevant behaviors, with examples and cross-references.
Further documentation:
To discover other kinds of documentation:
- [nix.dev](https://nix.dev/): Tutorials and guides for getting things done with Nix
- [NixOS **Option Search**](https://search.nixos.org/options) and reference documentation
- [Nixpkgs **Package Search**](https://search.nixos.org/packages)
- [**NixOS** manual](https://nixos.org/manual/nixos/stable/): Reference documentation for the NixOS Linux distribution
- [`CONTRIBUTING.md`](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md): Contributing to Nixpkgs, including this manual
## Overview of Nixpkgs {#overview-of-nixpkgs}
- [NixOS Search](https://search.nixos.org)
- [Contributing](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md): to Nixpkgs
Nix expressions describe how to build packages from source and are collected in
the [Nixpkgs repository](https://github.com/NixOS/nixpkgs). Also included in the
collection are Nix expressions for
[NixOS modules](https://nixos.org/nixos/manual/index.html#sec-writing-modules).
With these expressions the Nix package manager can build binary packages.
the [nixpkgs repository](https://github.com/NixOS/nixpkgs).
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-unstable`. Users of NixOS generally use one of the `nixos-*` channels,
e.g., `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.
Both `nixos-unstable` and `nixpkgs-unstable` follow the `master` branch of the
Nixpkgs repository, although both do lag the `master` branch by generally
[a couple of days](https://status.nixos.org/). Updates to a channel are
distributed as soon as all tests for that channel pass, e.g.,
[this table](https://hydra.nixos.org/job/nixpkgs/trunk/unstable#tabs-constituents)
shows the status of tests for the `nixpkgs-unstable` channel.
The tests are conducted by a cluster called [Hydra](https://nixos.org/hydra/),
which also builds binary packages from the Nix expressions in Nixpkgs for
`x86_64-linux`, `aarch64-linux`, `x86_64-darwin` and `aarch64-darwin`.
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 repository](https://github.com/NixOS/nixpkgs) in branches
that correspond to the channel names (e.g., `nixos-22.11-small`).
Packages are distributed through [channels](#how-channels-work).
+53 -3
View File
@@ -2,6 +2,9 @@
"chap-build-helpers-finalAttrs": [
"index.html#chap-build-helpers-finalAttrs"
],
"chap-first-package": [
"index.html#chap-first-package"
],
"chap-release-notes": [
"release-notes.html#chap-release-notes"
],
@@ -105,6 +108,15 @@
"ex-build-helpers-extendMkDerivation": [
"index.html#ex-build-helpers-extendMkDerivation"
],
"ex-build-helpers-extendMkDerivation-transformDrv-wrapper": [
"index.html#ex-build-helpers-extendMkDerivation-transformDrv-wrapper"
],
"ex-first-package-go": [
"index.html#ex-first-package-go"
],
"ex-modularServiceCompliance-nixos": [
"index.html#ex-modularServiceCompliance-nixos"
],
"ex-pkgs-replace-vars": [
"index.html#ex-pkgs-replace-vars",
"index.html#ex-pkgs-substituteAll",
@@ -128,6 +140,9 @@
"ex-writeShellApplication": [
"index.html#ex-writeShellApplication"
],
"first-package-go": [
"index.html#first-package-go"
],
"friction-graphics": [
"index.html#friction-graphics"
],
@@ -137,6 +152,9 @@
"ghc-deprecation-policy": [
"index.html#ghc-deprecation-policy"
],
"how-channels-work": [
"index.html#how-channels-work"
],
"inkscape-plugins": [
"index.html#inkscape-plugins"
],
@@ -221,6 +239,9 @@
"neovim-luarocks-based-plugins": [
"index.html#neovim-luarocks-based-plugins"
],
"neovim-plugin-treesitter-wasm": [
"index.html#neovim-plugin-treesitter-wasm"
],
"nixpkgs-manual": [
"index.html#nixpkgs-manual"
],
@@ -377,9 +398,7 @@
"index.html#pnpm-build-hook-honored-variables"
],
"preface": [
"index.html#preface"
],
"overview-of-nixpkgs": [
"index.html#preface",
"index.html#overview-of-nixpkgs"
],
"part-using": [
@@ -620,6 +639,15 @@
"chap-overrides": [
"index.html#chap-overrides"
],
"sec-packer": [
"index.html#sec-packer"
],
"sec-packer-list-plugins": [
"index.html#sec-packer-list-plugins"
],
"sec-packer-with-plugins": [
"index.html#sec-packer-with-plugins"
],
"sec-pkg-override": [
"index.html#sec-pkg-override"
],
@@ -902,6 +930,18 @@
"glibcxxassertions": [
"index.html#glibcxxassertions"
],
"tester-modularServiceCompliance": [
"index.html#tester-modularServiceCompliance"
],
"tester-modularServiceCompliance-inputs": [
"index.html#tester-modularServiceCompliance-inputs"
],
"tester-modularServiceCompliance-manual": [
"index.html#tester-modularServiceCompliance-manual"
],
"tester-modularServiceCompliance-return": [
"index.html#tester-modularServiceCompliance-return"
],
"tester-shfmt": [
"index.html#tester-shfmt"
],
@@ -1091,6 +1131,9 @@
"x86_64-darwin-26.05": [
"release-notes.html#x86_64-darwin-26.05"
],
"x86_64-darwin-26.11": [
"release-notes.html#x86_64-darwin-26.11"
],
"zip-files": [
"index.html#zip-files"
],
@@ -2878,6 +2921,10 @@
"setup-hook-mpi-check": [
"index.html#setup-hook-mpi-check"
],
"setup-hook-check-phase-thread-limit": [
"index.html#setup-hook-check-phase-thread-limit",
"index.html#setup-hook-omp-check"
],
"ninja": [
"index.html#ninja"
],
@@ -3972,6 +4019,9 @@
"maven": [
"index.html#maven"
],
"maven-4": [
"index.html#maven-4"
],
"maven-buildmavenpackage": [
"index.html#maven-buildmavenpackage"
],
+2
View File
@@ -380,6 +380,8 @@
- `collabora-desktop` The desktop version of Collabora Office is now available, package version `25.05.9.2-2`.
- The `services.geoserver` NixOS module has been added to allow running [Geoserver](https://geoserver.org/) as a service.
- `fetchPnpmDeps` and `pnpmConfigHook` were added as top-level attributes, replacing the now deprecated `pnpm.fetchDeps` and `pnpm.configHook` attributes.
- `fetchPnpmDeps`' `fetcherVersion = 1` and `fetcherVersion = 2` are deprecated
+93 -5
View File
@@ -4,21 +4,68 @@
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
- Create the first release note entry in this section!
- The {file}`nixexprs.tar.xz` tarball will be discontinued together with Nixpkgs
27.05 after 2027-12-31. Migrate to the {file}`nixexprs.tar.zst` tarball
instead.
This affects for example users who pull Nixpkgs as a flake input from
https://channels.nixos.org:
```diff
-nixpkgs.url = "https://channels.nixos.org/nixos-26.05/nixexprs.tar.xz";
+nixpkgs.url = "https://channels.nixos.org/nixos-26.05/nixexprs.tar.zst";
```
## Backward Incompatibilities {#sec-nixpkgs-release-26.11-incompatibilities}
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
- []{#x86_64-darwin-26.11}
Support for `x86_64-darwin` has been dropped, due to Apples deprecation of the platform and limited build infrastructure and developer time.
We will no longer build packages for the platform or support building them from source.
The Nixpkgs 26.05 stable branch will still maintain platform support and binaries will be built until it goes out of support at the end of 2026.
Users of `x86_64-darwin` will receive an error message explaining how to switch to 26.05.
By the time of this release, Homebrew will offer only limited [Tier 3](https://docs.brew.sh/Support-Tiers#tier-3) support for the platform, but MacPorts will likely continue to support it for a long time.
We also recommend users consider installing NixOS, which should continue to run on essentially all Intel Macs, especially after Apple stops security support for macOS 26 in 2028.
- `bundlerApp` now sets `__structuredAttrs = true` for its result package.
Out-of-tree packages passing `postBuild` to `bundlerApp` should examine if their `postBuild` commands are compatible with structured attributes.
- `databricks-cli` has been updated from `0.290.2` to `1.x.x`, the first major release. OAuth tokens for interactive logins (`auth_type = databricks-cli`) are now stored in the OS-native secure store by default (Secret Service on Linux) instead of `~/.databricks/token-cache.json`; cached tokens from older versions are not migrated, so run `databricks auth login` once per profile after upgrading. To keep the previous file-backed storage, set `DATABRICKS_AUTH_STORAGE=plaintext` or add `auth_storage = plaintext` under `[__settings__]` in `~/.databrickscfg`. Additionally, the `vector_search_endpoints` DABs resource renamed `min_qps` to `target_qps` (and the `vector-search-endpoints` command renamed `--min-qps` to `--target-qps`). See the [upstream changelog](https://github.com/databricks/cli/blob/main/CHANGELOG.md) for details.
- `hurl` has been updated to `8.x.x` which has some breaking changes. See [upstream changelog](https://github.com/Orange-OpenSource/hurl/releases/tag/8.0.0) for details.
- `gotosocial` has been updated to 0.22.0. This release contains a very long database migration, which should not be cancelled or interrupted under any circumstances.
- Postgres users: Following the migration, if you encounter slowdown on Postgres specifically (ie., timing out while loading timelines) you may need to run some manual database maintenance steps. Please check https://docs.gotosocial.org/en/stable/admin/database_maintenance/#postgres.
- `xsecurelock` no longer supports authentication via htaccess files (`~/.xsecurelock.pw`) or via the `pamtester` program by default. Only the recommended PAM module is supported unless rebuilt with `withHtaccess` or `withPamtester`.
- `python3Packages.django-health-check` has been updated to major version 4. See its [migration guide](https://codingjoe.dev/django-health-check/migrate-to-v4/) and [changelog](https://github.com/codingjoe/django-health-check/releases/tag/4.0.0) for breaking changes.
- `jmtpfs` has been removed due to lack of maintenance and fuse3 support.
- `libgdata` has been removed, as it was archived upstream and relied on the insecure libsoup 2.4.
- `mcphost` has been removed, as it was archived upstream and declared unmaintained.
- `fflogs` has been removed because it was no longer functional. Users should switch to `archon-lite`.
- `services.mysql` now sets `root@localhost` authentication to `auth_socket` when used with `mysql` or `percona-server`.
Existing deployments will also be adjusted if possible. See the [security advisory GHSA-6qxx-6rg8-c4p8](https://github.com/NixOS/nixpkgs/security/advisories/GHSA-6qxx-6rg8-c4p8) for more information.
- `zerofs` has been updated from `1.x` to `2.x` which is a breaking change. Volumes created by earlier releases are refused at open with a clear error. There is no migration tool; older volumes remain readable and writable by the release that created them.
- `keycloak.plugins.keycloak-metrics-spi` has been removed. Keycloak exposes Prometheus metrics natively on its management interface; enable them with the `metrics-enabled` setting (and `event-metrics-user-enabled` for login and event counters). See [Gaining insights with metrics](https://www.keycloak.org/observability/configuration-metrics).
- `alps` has been rewritten upstream, see [upstream repository](https://github.com/migadu/alps) for documentation.
- `uhttpmock` providing 0.0 ABI was removed. `uhttpmock_1_0` providing 1.0 ABI was renamed to `uhttpmock` and `uhttpmock_1_0` was kept as an alias.
- `nix-serve-ng` (and `haskellPackages.nix-serve-ng`) is now built against Lix instead of CppNix, following upstream which has switched to Lix as its supported Nix implementation.
- Linux kernel configuration has been moved out of the `linux-kernel` field of the platform structure into the kernel builders:
- `linux-kernel.name` has been removed.
- `linux-kernel.target` is available as the `target` parameter and passthru attribute on the kernel builders.
@@ -34,12 +81,32 @@
`lib.systems.{examples,platforms}.{sheevaplug,pogoplug4}` have been unified into `lib.systems.examples.armv5tel-multiplatform`.
Note that there is no official support for ARMv5 and it is not possible to build even a simple NixOS configuration out of the box.
- `pdns` has been updated from `5.0.x` to `5.1.x`. Please be sure to review the [Upgrade Notes](https://doc.powerdns.com/authoritative/upgrading.html#to-5-1-0) before upgrading. Namely LUA record updates are no longer allowed by default, and the embedded webserver no longer includes a `access-control-allow-origin: *` header by default.
- Support for the legacy UBoot image format has been removed from the Linux kernel builders, as it is deprecated upstream and no longer used by any platform in Nixpkgs.
- `etcd_3_4` package was dropped, as it's gone EOL. Please upgrade to either 3.5 or 3.6. See [migration notes](https://etcd.io/docs/v3.6/upgrades/upgrade_3_6/) for incompatibilities and upgrade procedure.
- `rke2` retires ingress-nginx and transitions to Traefik starting in `rke2_1_36`. Because ingress-nginx was retired upstream as of March 2026, Traefik is now the default
for new clusters starting in v1.36 (existing clusters will keep their current ingress upon upgrade to avoid breakage). This transition brings the following structural changes:
- Airgapped Environments: The rke2-images-core tarball now contains Traefik images instead of ingress-nginx. The standalone rke2-images-traefik tarball has been removed.
Users who must continue using ingress-nginx will now need to manually provide the rke2-images-ingress-nginx tarball.
- Future Removal: The ingress-nginx chart will not receive any additional updates and will be completely removed in v1.37 for community users.
- `buildFHSEnvChroot` has been removed after deprecation in 23.05.
- `gh-actions-cache` has been removed since its functionality has been integrated directly into `gh` (`gh cache`). See [upstream readme](https://github.com/actions/gh-actions-cache).
- `requireFile` now sets `meta.license = lib.licenses.unfree` by default. Users of `requireFile`-based derivations that preserve this default will need to explicitly allow their evaluation as described in [](#sec-allow-unfree).
- `texlive.combine` is deprecated and scheduled for removal in 27.05. Please migrate to `texliveSmall.withPackages` (see [](#sec-language-texlive-user-guide)).
- `keycloak` was updated to >= 26.7.0 and includes some breaking internal (API) changes. See the [upstream migration guide](https://www.keycloak.org/docs/latest/upgrading/#migrating-to-26-7-0) for more information.
- `librest` providing 0.7 ABI was removed. `librest_1_0` providing 1.0 ABI was renamed to `librest` and `librest_1_0` was kept as an alias.
- `pnpm_10` was upgraded to version 10.34.1+, which introduced stricter integrity checks. If you encounter `ERR_PNPM_MISSING_TARBALL_INTEGRITY`, you can fall back to the older `pnpm_10_34_0`.
- `fetchPnpmDeps`' `fetcherVersion = 1` and `fetcherVersion = 2` have been
removed, as announced in the 26.05 release. Packages still using them now
throw an evaluation error and must migrate to `fetcherVersion = 3` (or later)
@@ -47,31 +114,52 @@
[pnpm `fetcherVersion` section](#javascript-pnpm-fetcherVersion) of the manual
for details.
- `rebuilderd` has been updated to 0.27.0 introducing breaking changes. See upstream changelog for details: [0.26.0](https://github.com/kpcyrd/rebuilderd/releases/tag/v0.26.0), [0.27.0](https://github.com/kpcyrd/rebuilderd/releases/tag/v0.27.0)
- Starting with v14, `flameshot` will primarily utilise xdg-desktop-portal calls for screenshotting. This will directly affect users on X11 window managers due to the lack of a compatible portal with Screenshot feature. See [upstream changelog](https://github.com/flameshot-org/flameshot/releases/tag/v14.0.0) or [NixOS Flameshot](https://wiki.nixos.org/wiki/Flameshot) wiki page for workarounds.
- `nim1` and respective aliases have been removed due to entering EOL; please migrate to `nim` or `nim-unwrapped` (nim 2).
- `nim-2_0` & `nim-2_2` and respective aliases have been removed; please migrate to `nim` or `nim-unwrapped` (nim 2.2.10).
- `domoticz` has been updated from `2024.7` to `2026.x`, breaking third party applications and scripts using the old RType calls. Review the [release notes](https://github.com/domoticz/domoticz/blob/2026.2/History.txt#L398) for more information.
- `vimacs` has been removed, as it has not been maintained in 10 years and was built for an old version of vim (6.0).
## Other Notable Changes {#sec-nixpkgs-release-26.11-notable-changes}
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
- `super-productivity` has been updated. The binary has been renamed from `super-productivity` to `superproductivity`. A symlink from the old name is provided for backward compatibility.
- Package-URL (PURL, https://github.com/package-url/purl-spec) metadata identifier has been added for `fetchgit`, `fetchpypi` and `fetchFromGithub` fetchers.
`mkDerivation` has been adjusted to reuse this information.
Package-URLs allow reliably identifying and locating software packages.
Maintainers of derivations using the adapted fetchers should rely on the `drv.src.meta.identifiers.v1.purl` default identifier and can enhance their `drv.meta.identifiers.v1.purls` list once they would like to have additional identifiers.
Maintainers using `fetchurl` for `drv.src` are urged to adapt their `drv.meta.identifiers.purlParts` for proper identification.
- Emacs loads the `early-default` library after `early-init.el`.
Users can add `early-init.el` via `emacs.pkgs.withPackages`
by packaging `early-init.el` into a library named `early-default`.
To prevent loading the `early-default` library,
set `inhibit-early-default-init` in `early-init.el`.
- `services.ceph` enabled the generation of Ceph log files at `/var/log/ceph/`.
They were missing before because Ceph omitted logs when this directory was missing.
Ceph logs can grow large, so you may want to configure rotation of these logs.
## Nixpkgs Library {#sec-nixpkgs-release-26.11-lib}
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
### Breaking changes {#sec-nixpkgs-release-26.11-lib-breaking}
- Create the first release note entry in this section!
- `fittrackee` 1.0.0 now requires postgres with postgis. The [upgrade guide](https://docs.fittrackee.org/en/upgrading-to-1.0.0.html) has steps to prepare for this upgrade.
### Deprecations {#sec-nixpkgs-release-26.11-lib-deprecations}
- Create the first release note entry in this section!
- Setting `config.allowBrokenPredicate` is deprecated in favor of
using `config.problems.handlers.PackageName.broken = "warn"` (or `=
"ignore"`). For more information see [](#sec-allow-broken).
### Additions and Improvements {#sec-nixpkgs-release-26.11-lib-additions-improvements}
- Create the first release note entry in this section!
+1 -1
View File
@@ -50,7 +50,7 @@ The exact schema these fields follow is a bit ill-defined due to a long and conv
`system`
: This is a two-component shorthand for the platform. Examples of this would be "x86_64-darwin" and "i686-linux"; see `lib.systems.doubles` for more. The first component corresponds to the CPU architecture of the platform and the second to the operating system of the platform (`[cpu]-[os]`). This format has built-in support in Nix, such as the `builtins.currentSystem` impure string.
: This is a two-component shorthand for the platform. Examples of this would be "aarch64-darwin" and "i686-linux"; see `lib.systems.doubles` for more. The first component corresponds to the CPU architecture of the platform and the second to the operating system of the platform (`[cpu]-[os]`). This format has built-in support in Nix, such as the `builtins.currentSystem` impure string.
`config`
+3 -3
View File
@@ -776,7 +776,7 @@ By default, the flag `--disable-dependency-tracking` is added to the configure f
##### `dontFixLibtool` {#var-stdenv-dontFixLibtool}
By default, the configure phase applies some special hackery to all files called `ltmain.sh` before running the configure script in order to improve the purity of Libtool-based packages [^footnote-stdenv-sys-lib-search-path] . If this is undesirable, set this variable to true.
By default, the configure phase applies some special hackery to all files called `ltmain.sh` before running the configure script to improve the purity of Libtool-based packages [^footnote-stdenv-sys-lib-search-path] . If this is undesirable, set this variable to true.
##### `dontDisableStatic` {#var-stdenv-dontDisableStatic}
@@ -939,7 +939,7 @@ The fixup phase performs (Nix-specific) post-processing actions on the files ins
- It moves the `man/`, `doc/` and `info/` subdirectories of `$out` to `share/`.
- It strips libraries and executables of debug information.
- On Linux, it applies the `patchelf` command to ELF executables and libraries to remove unused directories from the `RPATH` in order to prevent unnecessary runtime dependencies.
- On Linux, it applies the `patchelf` command to ELF executables and libraries to remove unused directories from the `RPATH` to prevent unnecessary runtime dependencies.
- It rewrites the interpreter paths of shell scripts to paths found in `PATH`. E.g., `/usr/bin/perl` will be rewritten to `/nix/store/some-perl/bin/perl` found in `PATH`. See [](#patch-shebangs.sh) for details.
#### Variables controlling the fixup phase {#variables-controlling-the-fixup-phase}
@@ -1345,7 +1345,7 @@ $ echo $configureFlags
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.
In order to alleviate this burden, the setup hook mechanism was written, where any package can include a shell script that \[by convention rather than enforcement by Nix\], any downstream reverse-dependency will source as part of its build process. That allows the downstream dependency to merely specify its dependencies, and lets those dependencies effectively initialize themselves. No boilerplate mirroring the list of dependencies is needed.
To alleviate this burden, the setup hook mechanism was written, where any package can include a shell script that \[by convention rather than enforcement by Nix\], any downstream reverse-dependency will source as part of its build process. That allows the downstream dependency to merely specify its dependencies, and lets those dependencies effectively initialize themselves. No boilerplate mirroring the list of dependencies is needed.
The setup hook mechanism is a bit of a sledgehammer though: a powerful feature with a broad and indiscriminate area of effect. The combination of its power and implicit use may be expedient, but isnt without costs. Nix itself is unchanged, but the spirit of added dependencies being effect-free is violated even if the latter isnt. For example, if a derivation path is mentioned more than once, Nix itself doesnt care and makes sure the dependency derivation is already built just the same—depending is just needing something to exist, and needing is idempotent. However, a dependency specified twice will have its setup hook run twice, and that could easily change the build environment (though a well-written setup hook will therefore strive to be idempotent so this is in fact not observable). More broadly, setup hooks are anti-modular in that multiple dependencies, whether the same or different, should not interfere and yet their setup hooks may well do so.
+347 -148
View File
@@ -23,21 +23,17 @@ body {
@media screen and (min-width: 992px) {
.book,
.appendix {
max-width: 60rem;
max-width: 55rem;
}
}
@media screen and (min-width: 1200px) {
.book,
.appendix {
max-width: 73rem;
max-width: 55rem;
}
}
.book .list-of-examples {
display: none;
}
h1 {
font-size: 2em;
margin: 0.67em 0;
@@ -118,7 +114,7 @@ html {
body {
font-size: 1rem;
font-family: "Roboto", sans-serif;
font-weight: 300;
font-weight: 400;
color: var(--main-text-color);
background-color: var(--background);
min-height: 100vh;
@@ -131,11 +127,36 @@ body {
padding-left: 1rem;
padding-right: 1rem;
}
/*
See: https://developer.mozilla.org/en-US/docs/Web/API/Popover_API
- :popover-open pseudo-class matches a popover element when it is in the showing state
- ::backdrop full-screen element placed directly behind popover
*/
nav.toc-sidebar:popover-open {
position: fixed;
inset: 0 auto 0 0;
width: min(20rem, 85vw);
height: 100dvh;
max-height: none;
margin: 0;
padding: 1rem;
overflow-y: auto;
overscroll-behavior: contain;
background: var(--background);
border: 0;
border-right: 0.0625rem solid #d8d8d8;
box-shadow: 0 0 1.5rem rgb(0 0 0 / 0.35);
}
nav.toc-sidebar::backdrop {
background: rgb(0 0 0 / 0.5);
}
}
a {
text-decoration: none;
border-bottom: 1px solid;
text-decoration: underline;
color: var(--link-color);
}
@@ -162,63 +183,52 @@ hr {
margin-bottom: 1rem;
}
h1 {
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 800;
line-height: 110%;
font-size: 200%;
margin-bottom: 1rem;
line-height: 1.1;
margin: 1.5rem 0 0.5rem;
}
/*
Major-second scale see: https://typescale.com/
rounded to .025rem (0.4px)
*/
h1 {
font-size: 2rem;
color: var(--heading-color);
}
h2 {
font-weight: 800;
line-height: 110%;
font-size: 170%;
margin-bottom: 0.625rem;
font-size: 1.8rem;
color: var(--heading-color);
}
h2:not(:first-child) {
margin-top: 1rem;
}
h3 {
font-weight: 800;
line-height: 110%;
margin-bottom: 1rem;
font-size: 150%;
font-size: 1.6rem;
color: var(--heading-color);
}
.note h3,
.tip h3,
.warning h3,
.caution h3,
.important h3 {
font-size: 120%;
}
h4 {
font-weight: 800;
line-height: 110%;
margin-bottom: 1rem;
font-size: 140%;
font-size: 1.425rem;
color: var(--heading-color);
}
h5 {
font-weight: 800;
line-height: 110%;
margin-bottom: 1rem;
font-size: 130%;
font-size: 1.275rem;
color: var(--small-heading-color);
}
h6 {
font-weight: 800;
line-height: 110%;
margin-bottom: 1rem;
font-size: 120%;
font-size: 1.125rem;
}
:is(.note, .tip, .warning, .caution, .important) h3 {
font-size: 1.425rem;
}
strong {
@@ -246,13 +256,9 @@ code {
}
code {
color: #ff8657;
background: #f4f4f4;
display: inline-block;
padding: 0 0.5rem;
border: 1px solid #d8d8d8;
border-radius: 0.5rem;
line-height: 1.57777778;
padding: 0.2em 0.4em;
background: var(--inline-code-background);
border-radius: 0.375rem;
}
div.book .programlisting,
@@ -264,16 +270,7 @@ div.appendix .programlisting {
color: var(--codeblock-text-color);
}
div.book .note,
div.book .tip,
div.book .warning,
div.book .caution,
div.book .important,
div.appendix .note,
div.appendix .tip,
div.appendix .warning,
div.appendix .caution,
div.appendix .important {
:is(.note, .tip, .warning, .caution, .important) {
margin-bottom: 1rem;
border-radius: 0.5rem;
padding: 1.5rem;
@@ -281,69 +278,44 @@ div.appendix .important {
background: #f4f4f4;
}
div.book .note > .title,
div.book .tip > .title,
div.book .warning > .title,
div.book .caution > .title,
div.book .important > .title,
div.appendix .note > .title,
div.appendix .tip > .title,
div.appendix .warning > .title,
div.appendix .caution > .title,
div.appendix .important > .title {
:is(.note, .tip, .warning, .caution, .important) > .title {
font-weight: 800;
line-height: 110%;
color: inherit;
margin-bottom: 0;
}
div.book .note > :first-child,
div.book .tip > :first-child,
div.book .warning > :first-child,
div.book .caution > :first-child,
div.book .important > :first-child,
div.appendix .note > :first-child,
div.appendix .tip > :first-child,
div.appendix .warning > :first-child,
div.appendix .caution > :first-child,
div.appendix .important > :first-child {
:is(.note, .tip, .warning, .caution, .important) > :first-child {
margin-top: 0;
}
div.book .note > :last-child,
div.book .tip > :last-child,
div.book .warning > :last-child,
div.book .caution > :last-child,
div.book .important > :last-child,
div.appendix .note > :last-child,
div.appendix .tip > :last-child,
div.appendix .warning > :last-child,
div.appendix .caution > :last-child,
div.appendix .important > :last-child {
:is(.note, .tip, .warning, .caution, .important) > :last-child {
margin-bottom: 0;
}
div.book .note,
div.book .tip,
div.book .important,
div.appendix .note,
div.appendix .tip,
div.appendix .important {
.note {
color: var(--note-text-color);
background: var(--note-background);
}
div.book .warning,
div.book .caution,
div.appendix .warning,
div.appendix .caution {
color: var(--warning-text-color);
background-color: var(--warning-background);
.tip {
color: var(--tip-text-color);
background: var(--tip-background);
}
div.book .section,
div.appendix .section {
margin-top: 2em;
.important {
color: var(--important-text-color);
background: var(--important-background);
}
.warning {
color: var(--warning-text-color);
background: var(--warning-background);
}
.caution {
color: var(--caution-text-color);
background: var(--caution-background);
}
div.book div.example,
@@ -387,39 +359,13 @@ div.appendix dt {
margin-top: 1em;
}
div.book .toc dt,
div.appendix .toc dt {
margin-top: 0;
}
div.book .list-of-examples dt,
div.appendix .list-of-examples dt {
margin-top: 0;
}
div.book code,
div.appendix code {
padding: 0;
border: 0;
background-color: inherit;
color: inherit;
font-size: 100%;
-webkit-hyphens: none;
-moz-hyphens: none;
hyphens: none;
}
div.book div.toc,
div.appendix div.toc {
margin-bottom: 3em;
border-bottom: 0.0625rem solid #d8d8d8;
}
div.book div.toc dd,
div.appendix div.toc dd {
margin-left: 2em;
}
div.book span.command,
div.appendix span.command {
font-family: monospace;
@@ -450,17 +396,31 @@ div.appendix .variablelist .term {
}
:root {
--sidebar-width: 20rem;
--header-height: 3rem;
--background: #fff;
--main-text-color: #000;
--link-color: #405d99;
--heading-color: #6586c8;
--small-heading-color: #6a6a6a;
--note-text-color: #5277c3;
--note-background: #f2f8fd;
--warning-text-color: #cc3900;
--warning-background: #fff5e1;
/* NOTE */
--note-text-color: #0065d2;
--note-background: #e4f5ff;
/* TIP */
--tip-text-color: #188000;
--tip-background: #e8fae3;
/* IMPORTANT */
--important-text-color: #8a3db8;
--important-background: #fbedff;
/* WARNING */
--warning-text-color: #aa4a00;
--warning-background: #fff0db;
/* CAUTION */
--caution-text-color: #be222a;
--caution-background: #ffebe8;
--codeblock-background: #f2f8fd;
--codeblock-text-color: #000;
--inline-code-background: #818b981f;
}
@media (prefers-color-scheme: dark) {
@@ -469,20 +429,27 @@ div.appendix .variablelist .term {
--main-text-color: #fff;
--link-color: #6586c8;
--small-heading-color: #fff;
--note-background: none;
--warning-background: none;
/* NOTE */
--note-text-color: #66c6ff;
--note-background: #1e2f44;
/* TIP */
--tip-text-color: #80e05f;
--tip-background: #22331d;
/* IMPORTANT */
--important-text-color: #ea9dff;
--important-background: #35273f;
/* WARNING */
--warning-text-color: #ffaa00;
--warning-background: #3c2a13;
/* CAUTION */
--caution-text-color: #ff8c84;
--caution-background: #422522;
--codeblock-background: #393939;
--codeblock-text-color: #fff;
--inline-code-background: #656c7633;
}
div.book .note,
div.book .tip,
div.appendix .note,
div.appendix .tip,
div.book .warning,
div.book .caution,
div.appendix .warning,
div.appendix .caution {
:is(.note, .tip, .warning, .caution, .important) {
border: 2px solid;
font-weight: 400;
}
@@ -490,9 +457,241 @@ div.appendix .variablelist .term {
@font-face {
font-family: Roboto;
src: url(Roboto.ttf);
src:
url(Roboto.ttf) format("truetype") tech(variations),
url(Roboto.ttf) format("truetype-variations");
font-weight: 100 900;
font-style: normal;
font-display: swap;
}
.chapter {
content-visibility: auto;
}
.navheader {
position: sticky;
top: 0;
z-index: 1;
background-color: var(--background);
}
nav.toc-sidebar {
height: 100%;
padding: 0 1rem 2rem;
background-color: var(--background);
color: var(--main-text-color);
}
/* menu button, shown on mobile, hidden on desktop */
.toc-toggle {
display: inline-flex;
align-items: center;
margin: 0.75rem 0 0;
padding: 0.4rem 0.8rem;
border: 0.0625rem solid #d8d8d8;
border-radius: 0.25rem;
background: var(--background);
color: var(--main-text-color);
font: inherit;
cursor: pointer;
position: fixed;
top: 0.5rem;
left: 0.8rem;
z-index: 2;
}
nav.toc-sidebar .toc {
margin-bottom: 0;
}
nav.toc-sidebar ol.toc,
nav.toc-sidebar ol.toc ol {
list-style: none;
margin: 0;
padding-left: 0;
}
nav.toc-sidebar ol.toc ol {
padding-left: 1em;
}
nav.toc-sidebar li {
margin: 0;
}
nav.toc-sidebar summary {
cursor: pointer;
display: flex;
align-items: center;
list-style: none;
}
nav.toc-sidebar summary::before {
content: "▸";
flex: none;
font-size: 0.75em;
}
nav.toc-sidebar details[open] > summary::before {
content: "▾";
}
nav.toc-sidebar a {
display: block;
width: 100%;
padding: 3px 8px;
border-left: 3px solid transparent;
border-radius: 3px;
color: inherit;
transition:
background-color 120ms ease,
border-color 120ms ease;
}
nav.toc-sidebar a:hover {
background-color: #f2f2f2 !important;
}
nav.toc-sidebar a.active {
background-color: #d8d8d8;
border-left-color: #444;
font-weight: 600;
}
nav.toc-sidebar a.active-trail {
border-left-color: #bbb;
background-color: #e8e8e8;
}
@media (prefers-color-scheme: dark) {
nav.toc-sidebar a:hover {
/* hover should win over scroll selectors despite beeing less specific */
background-color: #606060 !important;
}
nav.toc-sidebar a.active {
background-color: #373737;
border-left-color: #eee;
font-weight: 600;
}
nav.toc-sidebar a.active-trail {
border-left-color: #eee;
background-color: #323232;
}
}
@media screen and (min-width: 768px) {
body {
height: 100vh;
min-height: 0;
display: grid;
grid-template-columns: minmax(0, 1fr);
grid-template-rows: var(--header-height) auto minmax(0, 1fr);
}
body:has(> nav.toc-sidebar) {
grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
}
.navheader {
grid-column: 1 / -1;
grid-row: 2;
}
nav.toc-sidebar {
/* un-pop the drawer */
display: block;
position: static;
inset: auto;
/* */
margin: 0;
grid-column: 1;
grid-row: 3;
max-height: none;
overflow-y: auto;
border: none;
}
/* Hide the toggle button on desktop */
.toc-toggle {
display: none;
}
main.content {
grid-column: 1 / -1;
grid-row: 3;
overflow-y: auto;
padding: 0 1rem;
}
body:has(> nav.toc-sidebar) main.content {
grid-column: 2;
}
}
.manual-header {
background-color: var(--background);
border-bottom: 0.0625rem solid #d8d8d8;
display: flex;
flex-direction: column;
}
.manual-header--title {
order: -1;
padding: 0.5rem 1rem 0;
font-size: 0.875rem;
font-weight: 500;
color: var(--small-heading-color);
text-align: center;
}
.manual-header--tabs {
display: flex;
align-items: stretch;
justify-content: space-around;
margin: 0;
padding: 0;
}
.manual-header--tab {
display: flex;
align-items: center;
padding: 0 1rem;
font-size: 0.875rem;
font-weight: 500;
color: var(--main-text-color);
text-decoration: none;
border-bottom: 0.1875rem solid transparent;
border-top: 0.1875rem solid transparent;
transition: border-bottom-color 0.15s ease;
}
.manual-header--tab:hover {
border-bottom-color: var(--heading-color);
color: var(--main-text-color);
}
.manual-header--tab-active {
border-bottom-color: var(--heading-color);
color: var(--heading-color);
font-weight: 700;
}
@media screen and (min-width: 768px) {
.manual-header {
height: var(--header-height);
flex-direction: row;
align-items: stretch;
grid-column: 1 / -1;
grid-row: 1;
}
.manual-header--title {
order: 0;
margin-left: auto;
padding: 0 1rem;
align-self: center;
}
.manual-header--tabs {
justify-content: flex-start;
padding: 0 1rem;
}
}
+1
View File
@@ -1,6 +1,7 @@
# Using Nixpkgs {#part-using}
```{=include=} chapters
channels.chapter.md
using/platform-support.chapter.md
using/configuration.chapter.md
using/overlays.chapter.md
+25 -28
View File
@@ -1,16 +1,16 @@
# Platform Support {#chap-platform-support}
Packages receive varying degrees of support, both in terms of maintainer attention and available computation resources for continuous integration (CI). We have 7 defined tiers denoting how well supported each platform is.
Packages receive varying degrees of support, both in terms of maintainer and security team attention and available computation resources for continuous integration (CI). We have 7 defined tiers denoting how well supported each platform is.
## Tiers {#sec-platform-tiers}
### Tier 1 {#sec-platform-tier1}
[Tier 1](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-1) platforms receive the highest level of support where problems can block updates, platform-specific patches are freely applied, and most packages are expected to work.
[Tier 1](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-1) platforms receive the highest level of support where problems can block updates, security fixes are treated with urgency, platform-specific patches are freely applied, and most packages are expected to work.
### Tier 2 {#sec-platform-tier2}
[Tier 2](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-2) platforms are expected to remain functional with updates, receive platform-specific patches as needed, and have many packages built by Hydra with full ofBorg support.
[Tier 2](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-2) platforms are expected to remain functional and secure with updates, receive platform-specific patches as needed, and have many packages built by Hydra with full ofBorg support.
### Tier 3 {#sec-platform-tier3}
@@ -22,28 +22,25 @@ Platform Tiers [4 through 7](https://github.com/NixOS/rfcs/blob/master/rfcs/0046
## Breakdown {#sec-platform-breakdown}
| Triple | Support Tier | Channel Blockers | Hydra Support | Ofborg Support | Bootstrap Tarballs | Cross Compiling Support |
| ------------------------------------- | ------------ | ---------------- | ------------- | -------------- | ------------------ | ----------------------- |
| `x86_64-unknown-linux-gnu` | [Tier 1](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-1) | Many | ✔️ | ✔️ | ✔️ | ✔️ |
| `aarch64-unknown-linux-gnu` | [Tier 2](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-2) | Some | ✔️ | ✔️ | ✔️ | ✔️ |
| `x86_64-unknown-linux-musl` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | Limited | ❌ | ✔️ | ✔️ |
| `aarch64-unknown-linux-musl` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | Limited | ❌ | ✔️ | ✔️ |
| `x86_64-unknown-unknown-freebsd` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ✔️ | ✔️ |
| `arm64-apple-darwin` | [Tier 2](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-2) | Some | ✔️ | ✔️ | ✔️ | ❌\* |
| `x86_64-apple-darwin` | [Tier 2](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-2) | Some | ✔️ | ✔️ | ✔️ | ❌\* |
| `i686-unknown-linux-gnu` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | Limited | ❌ | ✔️ | ✔️ |
| `riscv32-unknown-linux-gnu` | [Tier 4](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-4) | None | ❌ | ❌ | | ✔️ |
| `riscv64-unknown-linux-gnu` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ✔️ | ✔️ |
| `loongarch64-unknown-linux-gnu` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ✔️ | ✔️ |
| `armv6l-unknown-linux-gnueabihf` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ✔️ | ✔️ |
| `armv6l-unknown-linux-musleabihf` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ✔️ | ✔️ |
| `armv7l-unknown-linux-gnueabihf` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ✔️ | ✔️ |
| `armv5tel-unknown-linux-gnueabi` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ✔️ | ✔️ |
| `mips64el-unknown-linux-gnuabi64` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ✔️ | ✔️ |
| `mips64el-unknown-linux-gnuabin32` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ✔️ | ✔️ |
| `mipsel-unknown-linux-gnu` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ✔️ | ✔️ |
| `powerpc64-unknown-linux-gnuabielfv2` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ✔️ | ✔️ |
| `powerpc64le-unknown-linux-gnu` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ✔️ | ✔️ |
| `s390x-unknown-linux-gnu` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ✔️ | ✔️ |
\* - Cross compiling is only supported on Darwin hosts.
| Triple | Support Tier | Channel Blockers | Hydra Support | Security Support | Ofborg Support | Bootstrap Tarballs | Cross Compiling Support |
|---------------------------------------|------------------------------------------------------------------------------------------------|------------------|---------------|------------------|----------------|--------------------|-------------------------|
| `x86_64-unknown-linux-gnu` | [Tier 1](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-1) | Many | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| `aarch64-unknown-linux-gnu` | [Tier 2](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-2) | Some | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| `x86_64-unknown-linux-musl` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | Limited | ❌ | ❌ | ✔️ | ✔️ |
| `aarch64-unknown-linux-musl` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | Limited | ❌ | ❌ | ✔️ | ✔️ |
| `x86_64-unknown-unknown-freebsd` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ❌ | ✔️ | ✔️ |
| `arm64-apple-darwin` | [Tier 2](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-2) | Some | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
| `i686-unknown-linux-gnu` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | Limited | ❌ | | ✔️ | ✔️ |
| `riscv32-unknown-linux-gnu` | [Tier 4](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-4) | None | ❌ | ❌ | ❌ | | ✔️ |
| `riscv64-unknown-linux-gnu` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ❌ | ✔️ | ✔️ |
| `loongarch64-unknown-linux-gnu` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ❌ | ✔️ | ✔️ |
| `armv6l-unknown-linux-gnueabihf` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ❌ | ✔️ | ✔️ |
| `armv6l-unknown-linux-musleabihf` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ❌ | ✔️ | ✔️ |
| `armv7l-unknown-linux-gnueabihf` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ❌ | ✔️ | ✔️ |
| `armv5tel-unknown-linux-gnueabi` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ❌ | ✔️ | ✔️ |
| `mips64el-unknown-linux-gnuabi64` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ❌ | ✔️ | ✔️ |
| `mips64el-unknown-linux-gnuabin32` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ❌ | ✔️ | ✔️ |
| `mipsel-unknown-linux-gnu` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ❌ | ✔️ | ✔️ |
| `powerpc64-unknown-linux-gnuabielfv2` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ❌ | ✔️ | ✔️ |
| `powerpc64le-unknown-linux-gnu` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ❌ | ✔️ | ✔️ |
| `s390x-unknown-linux-gnu` | [Tier 3](https://github.com/NixOS/rfcs/blob/master/rfcs/0046-platform-support-tiers.md#tier-3) | None | ❌ | ❌ | ❌ | ✔️ | ✔️ |
+19 -11
View File
@@ -220,17 +220,25 @@
evaluation. Evaluating the attribute value tends to require a significant
amount of computation, even considering lazy evaluation.
*/
legacyPackages = forAllSystems (
system:
(import ./. {
inherit system;
overlays = import ./pkgs/top-level/impure-overlays.nix ++ [
(final: prev: {
lib = prev.lib.extend libVersionInfoOverlay;
})
];
})
);
legacyPackages =
let
# We include `x86_64-darwin` here to ensure that users get a
# good error message for the 26.11 deprecation of the platform,
# while excluding it from `lib.systems.flakeExposed` so that we
# dont break `nix flake check` for downstream users.
forAllSystems' = lib.genAttrs (lib.systems.flakeExposed ++ [ "x86_64-darwin" ]);
in
forAllSystems' (
system:
(import ./. {
inherit system;
overlays = import ./pkgs/top-level/impure-overlays.nix ++ [
(final: prev: {
lib = prev.lib.extend libVersionInfoOverlay;
})
];
})
);
/**
Optional modules that can be imported into a NixOS configuration.
+37 -26
View File
@@ -5,7 +5,6 @@
let
inherit (builtins) head length;
inherit (lib.trivial) mergeAttrs;
inherit (lib.strings)
concatStringsSep
concatMapStringsSep
@@ -13,16 +12,18 @@ let
sanitizeDerivationName
;
inherit (lib.lists)
filter
foldr
foldl'
all
concatLists
concatMap
elemAt
all
partition
groupBy
take
filter
foldl
foldl'
foldr
groupBy
partition
reverseList
take
;
in
@@ -370,7 +371,11 @@ rec {
:::
*/
concatMapAttrs = f: v: foldl' mergeAttrs { } (attrValues (mapAttrs f v));
concatMapAttrs =
f: v:
listToAttrs (
concatLists (reverseList (mapAttrsToList (name: value: attrsToList (f name value)) v))
);
/**
Update or set specific paths of an attribute set.
@@ -1135,7 +1140,7 @@ rec {
For a function that gives you control over what counts as a leaf, see `mapAttrsRecursiveCond`.
:::{#map-attrs-recursive-example .example}
::: {.example #map-attrs-recursive-example}
# Map over leaf attributes
```nix
@@ -1160,7 +1165,7 @@ rec {
If the predicate returns false, `mapAttrsRecursiveCond` does not recurse, but instead applies the mapping function.
If the predicate returns true, it does recurse, and does not apply the mapping function.
:::{#map-attrs-recursive-cond-example .example}
::: {.example #map-attrs-recursive-cond-example}
# Map over an leaf attributes defined by a condition
Map derivations to their `name` attribute.
@@ -1800,22 +1805,28 @@ rec {
:::
*/
matchAttrs =
pattern: attrs:
let
recurse =
pattern: attrs:
all (
# Compare equality between `pattern` & `attrs`.
attr:
# Missing attr, not equal.
attrs ? ${attr}
&& (
let
lhs = pattern.${attr};
rhs = attrs.${attr};
in
# Simple equality check is primarily for non-attrsets, but we run it
# on attrsets too, since it may let us avoid recursing
lhs == rhs || isAttrs lhs && isAttrs rhs && recurse lhs rhs
)
) (attrNames pattern);
in
pattern:
assert isAttrs pattern;
all (
# Compare equality between `pattern` & `attrs`.
attr:
# Missing attr, not equal.
attrs ? ${attr}
&& (
let
lhs = pattern.${attr};
rhs = attrs.${attr};
in
# If attrset check recursively
if isAttrs lhs then isAttrs rhs && matchAttrs lhs rhs else lhs == rhs
)
) (attrNames pattern);
recurse pattern;
/**
Override only the attributes that are already present in the old set
+39 -27
View File
@@ -1,6 +1,22 @@
{ lib }:
{
let
inherit (lib)
concatLists
concatMap
escapeShellArgs
isBool
isList
mapAttrsToList
oldestSupportedReleaseIsAtLeast
optional
stringLength
warnIf
;
inherit (lib.generators) mkValueStringDefault;
mkValueString = mkValueStringDefault { };
in
rec {
/**
Automatically convert an attribute set to command-line options.
@@ -40,9 +56,9 @@
:::
*/
toGNUCommandLineShell =
lib.warnIf (lib.oldestSupportedReleaseIsAtLeast 2511)
warnIf (oldestSupportedReleaseIsAtLeast 2511)
"lib.cli.toGNUCommandLineShell is deprecated, please use lib.cli.toCommandLineShell or lib.cli.toCommandLineShellGNU instead."
(options: attrs: lib.escapeShellArgs (lib.cli.toGNUCommandLine options attrs));
(options: attrs: escapeShellArgs (toGNUCommandLine options attrs));
/**
Automatically convert an attribute set to a list of command-line options.
@@ -116,15 +132,15 @@
:::
*/
toGNUCommandLine =
lib.warnIf (lib.oldestSupportedReleaseIsAtLeast 2511)
warnIf (oldestSupportedReleaseIsAtLeast 2511)
"lib.cli.toGNUCommandLine is deprecated, please use lib.cli.toCommandLine or lib.cli.toCommandLineShellGNU instead."
(
{
mkOptionName ? k: if builtins.stringLength k == 1 then "-${k}" else "--${k}",
mkOptionName ? k: if stringLength k == 1 then "-${k}" else "--${k}",
mkBool ? k: v: lib.optional v (mkOptionName k),
mkBool ? k: v: optional v (mkOptionName k),
mkList ? k: v: lib.concatMap (mkOption k) v,
mkList ? k: concatMap (mkOption k),
mkOption ?
k: v:
@@ -133,26 +149,24 @@
else if optionValueSeparator == null then
[
(mkOptionName k)
(lib.generators.mkValueStringDefault { } v)
(mkValueString v)
]
else
[ "${mkOptionName k}${optionValueSeparator}${lib.generators.mkValueStringDefault { } v}" ],
[ "${mkOptionName k}${optionValueSeparator}${mkValueString v}" ],
optionValueSeparator ? null,
}:
options:
let
render =
k: v:
if builtins.isBool v then
if isBool v then
mkBool k v
else if builtins.isList v then
else if isList v then
mkList k v
else
mkOption k v;
in
builtins.concatLists (lib.mapAttrsToList render options)
options: concatLists (mapAttrsToList render options)
);
/**
@@ -163,8 +177,7 @@
For further reference see:
[`lib.cli.toCommandLineGNU`](#function-library-lib.cli.toCommandLineGNU)
*/
toCommandLineShellGNU =
options: attrs: lib.escapeShellArgs (lib.cli.toCommandLineGNU options attrs);
toCommandLineShellGNU = options: attrs: escapeShellArgs (toCommandLineGNU options attrs);
/**
Converts an attribute set into a list of GNU-style command-line arguments.
@@ -227,9 +240,9 @@
*/
toCommandLineGNU =
{
isLong ? optionName: builtins.stringLength optionName > 1,
isLong ? optionName: stringLength optionName > 1,
explicitBool ? false,
formatArg ? lib.generators.mkValueStringDefault { },
formatArg ? mkValueString,
}:
let
optionFormat = optionName: {
@@ -238,7 +251,7 @@
inherit explicitBool formatArg;
};
in
lib.cli.toCommandLine optionFormat;
toCommandLine optionFormat;
/**
Converts the given attributes into a single shell-escaped command-line
@@ -248,8 +261,7 @@
For further reference see:
[`lib.cli.toCommandLine`](#function-library-lib.cli.toCommandLine)
*/
toCommandLineShell =
optionFormat: attrs: lib.escapeShellArgs (lib.cli.toCommandLine optionFormat attrs);
toCommandLineShell = optionFormat: attrs: escapeShellArgs (toCommandLine optionFormat attrs);
/**
Converts an attribute set into a list of command-line arguments.
@@ -421,14 +433,14 @@
- `lib.cli.toCommandLineShellGNU`
*/
toCommandLine =
optionFormat: attrs:
optionFormat:
let
handlePair =
k: v:
if k == "" then
lib.throw "lib.cli.toCommandLine only accepts non-empty option names."
else if builtins.isList v then
builtins.concatMap (handleOption k) v
throw "lib.cli.toCommandLine only accepts non-empty option names."
else if isList v then
concatMap (handleOption k) v
else
handleOption k v;
@@ -439,7 +451,7 @@
option,
sep,
explicitBool,
formatArg ? lib.generators.mkValueStringDefault { },
formatArg ? mkValueString,
}:
k: v:
if v == null || (!explicitBool && v == false) then
@@ -458,5 +470,5 @@
arg
];
in
builtins.concatLists (lib.mapAttrsToList handlePair attrs);
attrs: concatLists (mapAttrsToList handlePair attrs);
}
+2 -2
View File
@@ -564,7 +564,7 @@ rec {
# Examples
:::{#ex-makeScope .example}
:::{.example #ex-makeScope}
# Create an interdependent package set on top of `pkgs`
The functions in `foo.nix` and `bar.nix` can depend on each other, in the sense that `foo.nix` can contain a function that expects `bar` as an attribute in its argument.
@@ -593,7 +593,7 @@ rec {
```
:::
:::{#ex-makeScope-callPackage .example}
:::{.example #ex-makeScope-callPackage}
# Using `callPackage` from a scope
```nix
+13 -13
View File
@@ -6,7 +6,6 @@ let
isString
mapAttrs
removeAttrs
throwIfNot
;
showMaybeAttrPosPre =
@@ -108,18 +107,18 @@ in
# attrset spine returned by lazyDerivation does not depend on it.
# Instead, the individual derivation attributes do depend on it.
checked =
throwIfNot (derivation.type or null == "derivation") "lazyDerivation: input must be a derivation."
throwIfNot
# NOTE: Technically we could require our outputs to be a subset of the
# actual ones, or even leave them unchecked and fail on a lazy basis.
# However, consider the case where an output is added in the underlying
# derivation, such as dev. lazyDerivation would remove it and cause it
# to fail as a buildInputs item, without any indication as to what
# happened. Hence the more stringent condition. We could consider
# adding a flag to control this behavior if there's a valid case for it,
# but the documentation must have a note like this.
(derivation.outputs == outputs)
''
if derivation.type or null != "derivation" then
throw "lazyDerivation: input must be a derivation."
# NOTE: Technically we could require our outputs to be a subset of the
# actual ones, or even leave them unchecked and fail on a lazy basis.
# However, consider the case where an output is added in the underlying
# derivation, such as dev. lazyDerivation would remove it and cause it
# to fail as a buildInputs item, without any indication as to what
# happened. Hence the more stringent condition. We could consider
# adding a flag to control this behavior if there's a valid case for it,
# but the documentation must have a note like this.
else if derivation.outputs != outputs then
throw ''
lib.lazyDerivation: The derivation ${derivation.name or "<unknown>"} has outputs that don't match the assumed outputs.
Assumed outputs passed to lazyDerivation${showMaybeAttrPosPre ",\n at " "outputs" args}:
@@ -142,6 +141,7 @@ in
If none of the above works for you, replace the lib.lazyDerivation call by the
expression in the derivation argument.
''
else
derivation;
in
{
+1 -2
View File
@@ -22,7 +22,6 @@ let
concatMapStringsSep
head
length
throwIf
;
inherit (lib.attrsets)
attrsToList
@@ -130,7 +129,7 @@ rec {
hashesAsNVPairs = attrsToList (intersectAttrs hashSet args);
in
if hashesAsNVPairs == [ ] then
throwIf required "fetcher called without `hash`" null
if required then throw "fetcher called without `hash`" else null
else if length hashesAsNVPairs != 1 then
throw "fetcher called with mutually-incompatible arguments: ${
concatMapStringsSep ", " (a: a.name) hashesAsNVPairs
+1 -3
View File
@@ -24,7 +24,6 @@ let
inherit (lib)
addErrorContext
any
assertMsg
attrNames
attrValues
concatLists
@@ -64,7 +63,6 @@ let
reverseList
splitString
tail
toList
;
inherit (lib.strings)
@@ -849,7 +847,7 @@ rec {
_type == "lua-inline";
generatedBindings =
assert assertMsg (badVarNames == [ ]) "Bad Lua var names: ${toPretty { } badVarNames}";
assert badVarNames == [ ] || throw "Bad Lua var names: ${toPretty { } badVarNames}";
concatStrings (mapAttrsToList (key: value: "${indent}${key} = ${toLua innerArgs value}\n") v);
# https://en.wikibooks.org/wiki/Lua_Programming/variable#Variable_names
+9 -4
View File
@@ -191,10 +191,15 @@ rec {
mkArray =
elems:
let
vs = map mkValue (lib.throwIf (elems == [ ]) "Please create empty array with mkEmptyArray." elems);
elemType = lib.throwIfNot (lib.all (t: (head vs).type == t) (
map (v: v.type) vs
)) "Elements in a list should have same type." (head vs).type;
vs = map mkValue (
if elems == [ ] then throw "Please create empty array with mkEmptyArray." else elems
);
firstType = (head vs).type;
elemType =
if lib.any (v: v.type != firstType) vs then
throw "Elements in a list should have same type."
else
firstType;
in
mkPrimitive (type.arrayOf elemType) vs
// {
+43
View File
@@ -310,6 +310,11 @@ lib.mapAttrs mkLicense (
redistributable = true;
};
buddy = {
spdxId = "Buddy";
fullName = "Buddy License";
};
bzip2 = {
spdxId = "bzip2-1.0.6";
fullName = "bzip2 and libbzip2 License v1.0.6";
@@ -382,6 +387,13 @@ lib.mapAttrs mkLicense (
free = false;
};
cc-by-nc-30-igo = {
# Currently does not have a spdxID will get one in the future https://github.com/spdx/license-list-XML/issues/2845
# spdxId = "CC-BY-NC-3.0-IGO";
fullName = "Creative Commons Attribution Non Commercial 3.0 IGO";
free = false;
};
cc-by-nc-40 = {
spdxId = "CC-BY-NC-4.0";
fullName = "Creative Commons Attribution Non Commercial 4.0 International";
@@ -926,6 +938,11 @@ lib.mapAttrs mkLicense (
free = false;
};
jpl-image = {
fullName = "JPL Image Use Policy";
spdxId = "JPL-image";
};
knuth = {
fullName = "Knuth CTAN License";
spdxId = "Knuth-CTAN";
@@ -1052,6 +1069,11 @@ lib.mapAttrs mkLicense (
fullName = "MIT License";
};
mit-click = {
spdxId = "MIT-Click";
fullName = "MIT Click License";
};
mit-cmu = {
spdxId = "MIT-CMU";
fullName = "CMU License";
@@ -1168,6 +1190,11 @@ lib.mapAttrs mkLicense (
fullName = "Nethack General Public License";
};
ngrep = {
spdxId = "ngrep";
fullName = "ngrep License";
};
nistSoftware = {
spdxId = "NIST-Software";
fullName = "NIST Software License";
@@ -1323,6 +1350,17 @@ lib.mapAttrs mkLicense (
fullName = "Qwt exception 1.0";
};
reticulum = {
# The Reticulum License restricts certain fields of use, notably systems
# intended to harm human beings and AI/ML training datasets. Such usage
# restrictions are incompatible with the Open Source Definition
# (https://opensource.org/osd), in particular "No Discrimination Against
# Fields of Endeavor".
free = false;
fullName = "Reticulum License";
url = "https://reticulum.network/license";
};
ruby = {
spdxId = "Ruby";
fullName = "Ruby License";
@@ -1590,6 +1628,11 @@ lib.mapAttrs mkLicense (
url = "https://fedoraproject.org/wiki/Licensing:Wadalab?rd=Licensing/Wadalab";
};
wordnet = {
spdxId = "WordNet";
fullName = "WordNet License";
};
wtfpl = {
spdxId = "WTFPL";
fullName = "Do What The F*ck You Want To Public License";
+75 -36
View File
@@ -6,12 +6,12 @@ let
inherit (lib.strings) toInt;
inherit (lib.trivial)
compare
min
id
min
seq
warn
;
inherit (lib.attrsets) mapAttrs attrNames attrValues;
inherit (lib) max;
in
rec {
@@ -276,11 +276,14 @@ rec {
:::
*/
foldl' =
let
inherit (builtins) foldl';
in
op: acc:
# The builtin `foldl'` is a bit lazier than one might expect.
# See https://github.com/NixOS/nix/pull/7158.
# In particular, the initial accumulator value is not forced before the first iteration starts.
builtins.seq acc (builtins.foldl' op acc);
seq acc (foldl' op acc);
/**
Map with index starting from 0
@@ -442,7 +445,7 @@ rec {
:::
*/
flatten = x: if isList x then concatMap (y: flatten y) x else [ x ];
flatten = x: if isList x then concatMap flatten x else [ x ];
/**
Remove elements equal to `e` from a list. Useful for `buildInputs`.
@@ -1122,9 +1125,10 @@ rec {
reverseList =
xs:
let
l = length xs;
# subtract one to save an __sub call on every element
lastIndex = length xs - 1;
in
genList (n: elemAt xs (l - n - 1)) l;
genList (n: elemAt xs (lastIndex - n)) (lastIndex + 1);
/**
Depth-First Search (DFS) for lists `list != []`.
@@ -1181,13 +1185,13 @@ rec {
c = filter (x: before x us) visited;
b = partition (x: before x us) rest;
in
if stopOnCycles && (length c > 0) then
if stopOnCycles && c != [ ] then
{
cycle = us;
loops = c;
inherit visited rest;
}
else if length b.right == 0 then
else if b.right == [ ] then
# nothing is before us
{
minimal = us;
@@ -1244,27 +1248,33 @@ rec {
:::
*/
toposort =
before: list:
before:
let
dfsthis = listDfs true before list;
toporest = toposort before (dfsthis.visited ++ dfsthis.rest);
dfs = listDfs true before;
recurse =
list:
let
dfsthis = dfs list;
toporest = recurse (dfsthis.visited ++ dfsthis.rest);
in
if length list < 2 then
# finish
{ result = list; }
else if dfsthis ? cycle then
# there's a cycle, starting from the current vertex, return it
{
cycle = reverseList dfsthis.visited ++ [ dfsthis.cycle ];
inherit (dfsthis) loops;
}
else if toporest ? cycle then
# there's a cycle somewhere else in the graph, return it
toporest
# Slow, but short. Can be made a bit faster with an explicit stack.
else
# there are no cycles
{ result = [ dfsthis.minimal ] ++ toporest.result; };
in
if length list < 2 then
# finish
{ result = list; }
else if dfsthis ? cycle then
# there's a cycle, starting from the current vertex, return it
{
cycle = reverseList ([ dfsthis.cycle ] ++ dfsthis.visited);
inherit (dfsthis) loops;
}
else if toporest ? cycle then
# there's a cycle somewhere else in the graph, return it
toporest
# Slow, but short. Can be made a bit faster with an explicit stack.
else
# there are no cycles
{ result = [ dfsthis.minimal ] ++ toporest.result; };
recurse;
/**
Sort a list based on a comparator function which compares two
@@ -1504,7 +1514,12 @@ rec {
:::
*/
take = count: sublist 0 count;
take =
count: list:
let
len = length list;
in
genList (elemAt list) (if count > len then len else count);
/**
Returns the last (at most) N elements of a list.
@@ -1538,7 +1553,13 @@ rec {
:::
*/
takeEnd = n: xs: drop (max 0 (length xs - n)) xs;
takeEnd =
count: list:
let
len = length list;
start = if count > len then 0 else len - count;
in
genList (i: elemAt list (start + i)) (if start > len then 0 else len - start);
/**
Remove the first (at most) N elements of a list.
@@ -1572,7 +1593,12 @@ rec {
:::
*/
drop = count: list: sublist count (length list) list;
drop =
count: list:
let
len = length list;
in
genList (n: elemAt list (n + count)) (if count > len then 0 else len - count);
/**
Remove the last (at most) N elements of a list.
@@ -1606,7 +1632,19 @@ rec {
```
:::
*/
dropEnd = n: xs: take (max 0 (length xs - n)) xs;
dropEnd =
n: list:
let
len = length list;
in
genList (elemAt list) (
if n > len then
0
else if n < 0 then
len
else
len - n
);
/**
Whether the first list is a prefix of the second list.
@@ -1810,7 +1848,7 @@ rec {
*/
last =
list:
assert lib.assertMsg (list != [ ]) "lists.last: list must not be empty!";
assert list != [ ] || throw "lists.last: list must not be empty!";
elemAt list (length list - 1);
/**
@@ -1843,8 +1881,8 @@ rec {
*/
init =
list:
assert lib.assertMsg (list != [ ]) "lists.init: list must not be empty!";
take (length list - 1) list;
assert list != [ ] || throw "lists.init: list must not be empty!";
genList (elemAt list) (length list - 1);
/**
Returns the image of the cross product of some lists by a function.
@@ -2119,7 +2157,8 @@ rec {
*/
replaceElemAt =
list: idx: newElem:
assert lib.assertMsg (idx >= 0 && idx < length list)
"'lists.replaceElemAt' called with index ${toString idx} on a list of size ${toString (length list)}";
assert
idx >= 0 && idx < length list
|| throw "'lists.replaceElemAt' called with index ${toString idx} on a list of size ${toString (length list)}";
genList (i: if i == idx then newElem else elemAt list i) (length list);
}
@@ -1,6 +1,7 @@
{ lib }:
# Simple internal type checks for meta.
# This file is not a stable interface and may be changed arbitrarily.
# This file is only intended for internal nixpkgs use.
# It is not a stable interface and may be changed arbitrarily.
#
# TODO: add a method to the module system types
# see https://github.com/NixOS/nixpkgs/pull/273935#issuecomment-1854173100
@@ -159,6 +160,32 @@ lib.fix (self: {
verify = v: all (func: func v) funcs;
};
either =
t1: t2:
assert isTypeDef t1 && isTypeDef t2;
let
# Store the functions directly so we don't have to pay the cost of attrset lookups at runtime.
v1 = t1.verify;
v2 = t2.verify;
in
{
name = "either<${t1.name},${t2.name}>";
verify = v: v1 v || v2 v;
};
both =
t1: t2:
assert isTypeDef t1 && isTypeDef t2;
let
# Store the functions directly so we don't have to pay the cost of attrset lookups at runtime.
v1 = t1.verify;
v2 = t2.verify;
in
{
name = "both<${t1.name},${t2.name}>";
verify = v: v1 v && v2 v;
};
not =
t:
assert isTypeDef t;
@@ -172,10 +199,10 @@ lib.fix (self: {
enum =
values:
assert isList values && all isString values;
assert isList values;
{
name = "enum<${concatStringsSep "," values}>";
verify = v: isString v && elem v values;
name = if all isString values then "enum<${concatStringsSep "," values}>" else "enum";
verify = v: elem v values;
};
record =
+9 -7
View File
@@ -12,7 +12,6 @@ let
all
isDerivation
getBin
assertMsg
;
inherit (lib.attrsets) mapAttrs' filterAttrs;
inherit (builtins)
@@ -571,12 +570,15 @@ rec {
*/
getExe' =
x: y:
assert assertMsg (isDerivation x)
"lib.meta.getExe': The first argument is of type ${typeOf x}, but it should be a derivation instead.";
assert assertMsg (isString y)
"lib.meta.getExe': The second argument is of type ${typeOf y}, but it should be a string instead.";
assert assertMsg (match ".*/.*" y == null)
"lib.meta.getExe': The second argument \"${y}\" is a nested path with a \"/\" character, but it should just be the name of the executable instead.";
assert
isDerivation x
|| throw "lib.meta.getExe': The first argument is of type ${typeOf x}, but it should be a derivation instead.";
assert
isString y
|| throw "lib.meta.getExe': The second argument is of type ${typeOf y}, but it should be a string instead.";
assert
match ".*/.*" y == null
|| throw "lib.meta.getExe': The second argument \"${y}\" is a nested path with a \"/\" character, but it should just be the name of the executable instead.";
"${getBin x}/bin/${y}";
/**
+5 -3
View File
@@ -46,7 +46,6 @@ let
setAttrByPath
substring
take
throwIfNot
trace
typeOf
types
@@ -680,8 +679,11 @@ let
config = addFreeformType (addMeta (m.config or { }));
}
else
# shorthand syntax
throwIfNot (isAttrs m) "module ${file} (${key}) does not look like a module." {
# shorthand syntax
if !isAttrs m then
throw "module ${file} (${key}) does not look like a module."
else
{
_file = toString m._file or file;
_class = m._class or null;
key = toString m.key or key;
+2 -2
View File
@@ -104,9 +104,9 @@ let
*/
parseExpandedIpv6 =
addr:
assert lib.assertMsg (
assert
length addr == ipv6Pieces
) "parseExpandedIpv6: expected list of integers with ${ipv6Pieces} elements";
|| throw "parseExpandedIpv6: expected list of integers with ${ipv6Pieces} elements";
let
u16FromHexStr =
hex:
+2 -2
View File
@@ -90,12 +90,12 @@ rec {
`defaultText`
: Substitute for documenting the `default`, if evaluating the default value during documentation rendering is not possible.
: Can be any nix value that evaluates.
: Usage with `lib.literalMD` or `lib.literalExpression` is supported
: Usage with `lib.literalMD`, `lib.literalExpression`, or `lib.literalCode` is supported
`example`
: Optional example value used in the manual.
: Can be any nix value that evaluates.
: Usage with `lib.literalMD` or `lib.literalExpression` is supported
: Usage with `lib.literalMD`, `lib.literalExpression`, or `lib.literalCode` is supported
`description`
: Optional string describing the option. This is required if option documentation is generated.
+51 -38
View File
@@ -32,10 +32,6 @@ let
substring
;
inherit (lib.asserts)
assertMsg
;
inherit (lib.path.subpath)
isValid
;
@@ -238,11 +234,14 @@ in
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}'';
assert
isPath path
|| throw "lib.path.append: The first argument is of type ${builtins.typeOf path}, but a path was expected";
assert
isValid subpath
|| throw ''
lib.path.append: Second argument is not a valid subpath string:
${subpathInvalidReason subpath}'';
path + ("/" + subpath);
/**
@@ -285,21 +284,25 @@ in
*/
hasPrefix =
path1:
assert assertMsg (isPath path1)
"lib.path.hasPrefix: First argument is of type ${typeOf path1}, but a path was expected";
assert
isPath path1
|| throw "lib.path.hasPrefix: First argument is of type ${typeOf path1}, but a path was expected";
let
path1Deconstructed = deconstructPath path1;
in
path2:
assert assertMsg (isPath path2)
"lib.path.hasPrefix: Second argument is of type ${typeOf path2}, but a path was expected";
assert
isPath path2
|| throw "lib.path.hasPrefix: Second argument is of type ${typeOf path2}, but a path was expected";
let
path2Deconstructed = deconstructPath path2;
in
assert assertMsg (path1Deconstructed.root == path2Deconstructed.root) ''
lib.path.hasPrefix: Filesystem roots must be the same for both paths, but paths with different roots were given:
first argument: "${toString path1}" with root "${toString path1Deconstructed.root}"
second argument: "${toString path2}" with root "${toString path2Deconstructed.root}"'';
assert
path1Deconstructed.root == path2Deconstructed.root
|| throw ''
lib.path.hasPrefix: Filesystem roots must be the same for both paths, but paths with different roots were given:
first argument: "${toString path1}" with root "${toString path1Deconstructed.root}"
second argument: "${toString path2}" with root "${toString path2Deconstructed.root}"'';
take (length path1Deconstructed.components) path2Deconstructed.components
== path1Deconstructed.components;
@@ -344,15 +347,17 @@ in
*/
removePrefix =
path1:
assert assertMsg (isPath path1)
"lib.path.removePrefix: First argument is of type ${typeOf path1}, but a path was expected.";
assert
isPath path1
|| throw "lib.path.removePrefix: First argument is of type ${typeOf path1}, but a path was expected.";
let
path1Deconstructed = deconstructPath path1;
path1Length = length path1Deconstructed.components;
in
path2:
assert assertMsg (isPath path2)
"lib.path.removePrefix: Second argument is of type ${typeOf path2}, but a path was expected.";
assert
isPath path2
|| throw "lib.path.removePrefix: Second argument is of type ${typeOf path2}, but a path was expected.";
let
path2Deconstructed = deconstructPath path2;
success = take path1Length path2Deconstructed.components == path1Deconstructed.components;
@@ -362,10 +367,12 @@ in
else
throw ''lib.path.removePrefix: The first path argument "${toString path1}" is not a component-wise prefix of the second path argument "${toString path2}".'';
in
assert assertMsg (path1Deconstructed.root == path2Deconstructed.root) ''
lib.path.removePrefix: Filesystem roots must be the same for both paths, but paths with different roots were given:
first argument: "${toString path1}" with root "${toString path1Deconstructed.root}"
second argument: "${toString path2}" with root "${toString path2Deconstructed.root}"'';
assert
path1Deconstructed.root == path2Deconstructed.root
|| throw ''
lib.path.removePrefix: Filesystem roots must be the same for both paths, but paths with different roots were given:
first argument: "${toString path1}" with root "${toString path1Deconstructed.root}"
second argument: "${toString path2}" with root "${toString path2Deconstructed.root}"'';
joinRelPath components;
/**
@@ -422,8 +429,9 @@ in
splitRoot =
# The path to split the root off of
path:
assert assertMsg (isPath path)
"lib.path.splitRoot: Argument is of type ${typeOf path}, but a path was expected";
assert
isPath path
|| throw "lib.path.splitRoot: Argument is of type ${typeOf path}, but a path was expected";
let
deconstructed = deconstructPath path;
in
@@ -494,14 +502,15 @@ in
let
deconstructed = deconstructPath path;
in
assert assertMsg (isPath path)
"lib.path.hasStorePathPrefix: Argument is of type ${typeOf path}, but a path was expected";
assert assertMsg
assert
isPath path
|| throw "lib.path.hasStorePathPrefix: Argument is of type ${typeOf path}, but a path was expected";
assert
# This function likely breaks or needs adjustment if used with other filesystem roots, if they ever get implemented.
# Let's try to error nicely in such a case, though it's unclear how an implementation would work even and whether this could be detected.
# See also https://github.com/NixOS/nix/pull/6530#discussion_r1422843117
(deconstructed.root == /. && toString deconstructed.root == "/")
"lib.path.hasStorePathPrefix: Argument has a filesystem root (${toString deconstructed.root}) that's not /, which is currently not supported.";
deconstructed.root == /. && toString deconstructed.root == "/"
|| throw "lib.path.hasStorePathPrefix: Argument has a filesystem root (${toString deconstructed.root}) that's not /, which is currently not supported.";
componentsHaveStorePathPrefix deconstructed.components;
/**
@@ -702,9 +711,11 @@ in
subpath.components =
# The subpath string to split into components
subpath:
assert assertMsg (isValid subpath) ''
lib.path.subpath.components: Argument is not a valid subpath string:
${subpathInvalidReason subpath}'';
assert
isValid subpath
|| throw ''
lib.path.subpath.components: Argument is not a valid subpath string:
${subpathInvalidReason subpath}'';
splitRelPath subpath;
/**
@@ -799,9 +810,11 @@ in
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}'';
assert
isValid subpath
|| throw ''
lib.path.subpath.normalise: Argument is not a valid subpath string:
${subpathInvalidReason subpath}'';
joinRelPath (splitRelPath subpath);
}
+55 -2
View File
@@ -6,10 +6,12 @@
# The module
{
lib,
config,
options,
...
}:
let
inherit (lib) mkOption types;
inherit (lib) mkEnableOption mkOption types;
pathOrStr = types.coercedTo types.path (x: "${x}") types.str;
in
{
@@ -39,7 +41,7 @@ in
visible = "shallow";
};
process = {
argv = lib.mkOption {
argv = mkOption {
type = types.listOf pathOrStr;
example = lib.literalExpression ''[ (lib.getExe config.package) "--nobackground" ]'';
description = ''
@@ -49,6 +51,57 @@ in
a shell script or `importas` from `pkgs.execline`.
'';
};
reloadSignal = mkOption {
type = types.nullOr types.str;
default = null;
example = "HUP";
description = ''
Configures the reload signal to send to the service manager.
'';
};
reloadCommand = mkOption {
type = types.nullOr types.str;
default = null;
example = lib.literalExpression ''"''${pkgs.coreutils}/bin/kill -HUP $MAINPID"'';
description = ''
Command used for reloading in the underlying service manager to reload.
'';
};
};
notificationProtocol = mkOption {
type = types.submodule {
options = {
systemd = mkEnableOption "Whether the service supports systemd-notify.";
s6 = mkEnableOption "Whether the service supports s6-notify.";
};
};
description = ''
Notification protocol that this service supports with the underlying service manager.
'';
};
};
config = {
assertions = [
{
# `reloadSignal` derives `reloadCommand` at `mkDefault` priority below, so a
# conflict only exists when the user *also* set `reloadCommand` explicitly.
# An explicit (non-`mkDefault`) definition has `defaultOverridePriority`.
assertion =
!(
config.process.reloadSignal != null
&& options.process.reloadCommand.highestPrio <= lib.modules.defaultOverridePriority
);
message = "reloadSignal conflicts with reloadCommand. Please either use reloadSignal or reloadCommand.";
}
];
process.reloadCommand = lib.mkIf (config.process.reloadSignal != null) (
lib.mkDefault "${pkgs.coreutils}/bin/kill -${config.process.reloadSignal} $MAINPID"
);
};
}
+78 -50
View File
@@ -4,22 +4,31 @@
# Tested in lib/tests/sources.sh
let
inherit (lib.strings)
match
split
storeDir
escapeRegex
hasPrefix
hasSuffix
match
removePrefix
removeSuffix
split
splitString
storeDir
stringLength
substring
;
inherit (lib)
boolToString
filter
isString
readFile
concatStrings
length
elemAt
isList
any
boolToString
concatStrings
elemAt
fileContents
filter
head
isList
isString
last
length
readFile
;
inherit (lib.filesystem)
pathIsRegularFile
@@ -41,6 +50,12 @@ let
: 2\. Function argument
*/
cleanSourceFilter =
let
hasEmacsBackupFileSuffix = hasSuffix "~";
hasObjectSuffix = hasSuffix ".o";
hasSharedObjectSuffix = hasSuffix ".so";
hasResultPrefix = hasPrefix "result";
in
name: type:
let
baseName = baseNameOf name;
@@ -62,17 +77,15 @@ let
)
||
# Filter out editor backup / swap files.
lib.hasSuffix "~" baseName
hasEmacsBackupFileSuffix baseName
|| match "^\\.sw[a-z]$" baseName != null
|| match "^\\..*\\.sw[a-z]$" baseName != null
||
# Filter out generates files.
lib.hasSuffix ".o" baseName
|| lib.hasSuffix ".so" baseName
# Filter out generated files.
|| hasObjectSuffix baseName
|| hasSharedObjectSuffix baseName
||
# Filter out nix-build result symlinks
(type == "symlink" && lib.hasPrefix "result" baseName)
(type == "symlink" && hasResultPrefix baseName)
||
# Filter out sockets and other types of files we can't have in the store.
(type == "unknown")
@@ -133,13 +146,13 @@ let
{
# A path or cleanSourceWith result to filter and/or rename.
src,
# Optional with default value: constant true (include everything)
# Optional with default value of null (include everything)
# The function will be combined with the && operator such
# that src.filter is called lazily.
# For implementing a filter, see
# https://nixos.org/nix/manual/#builtin-filterSource
# Type: A function (Path -> Type -> Bool)
filter ? _path: _type: true,
filter ? null,
# Optional name to use as part of the store path.
# This defaults to `src.name` or otherwise `"source"`.
name ? null,
@@ -149,7 +162,13 @@ let
in
fromSourceAttributes {
inherit (orig) origSrc;
filter = path: type: filter path type && orig.filter path type;
filter =
if orig.filter == null then
filter
else if filter == null then
orig.filter
else
path: type: filter path type && orig.filter path type;
name = if name != null then name else orig.name;
};
@@ -178,11 +197,14 @@ let
attrs
// {
filter =
path: type:
let
r = attrs.filter path type;
in
builtins.trace "${attrs.name}.filter ${path} = ${boolToString r}" r;
if attrs.filter == null then
path: type: builtins.trace "${attrs.name}.filter ${path} = true" true
else
path: type:
let
r = attrs.filter path type;
in
builtins.trace "${attrs.name}.filter ${path} = ${boolToString r}" r;
}
)
// {
@@ -218,13 +240,13 @@ let
isFiltered = src ? _isLibCleanSourceWith;
origSrc = if isFiltered then src.origSrc else src;
in
lib.cleanSourceWith {
cleanSourceWith {
filter = (
path: type:
let
relPath = lib.removePrefix (toString origSrc + "/") (toString path);
relPath = removePrefix (toString origSrc + "/") (toString path);
in
lib.any (re: match re relPath != null) regexes
any (re: match re relPath != null) regexes
);
inherit src;
};
@@ -272,7 +294,7 @@ let
let
base = baseNameOf name;
in
type == "directory" || lib.any (ext: lib.hasSuffix ext base) exts;
type == "directory" || any (ext: hasSuffix ext base) exts;
in
cleanSourceWith { inherit filter src; };
@@ -319,9 +341,9 @@ let
packedRefsName = path + "/packed-refs";
absolutePath =
base: path:
if lib.hasPrefix "/" path then
if hasPrefix "/" path then
path
else if lib.hasPrefix "/" base then
else if hasPrefix "/" base then
"${base}/${path}"
else
"/${base}/${path}";
@@ -337,12 +359,12 @@ let
{ error = "File contains no gitdir reference: " + path; }
else
let
gitDir = absolutePath (dirOf path) (lib.head m);
gitDir = absolutePath (dirOf path) (head m);
commonDir'' =
if pathIsRegularFile "${gitDir}/commondir" then lib.fileContents "${gitDir}/commondir" else gitDir;
commonDir' = lib.removeSuffix "/" commonDir'';
if pathIsRegularFile "${gitDir}/commondir" then fileContents "${gitDir}/commondir" else gitDir;
commonDir' = removeSuffix "/" commonDir'';
commonDir = absolutePath gitDir commonDir';
refFile = lib.removePrefix "${commonDir}/" "${gitDir}/${file}";
refFile = removePrefix "${commonDir}/" "${gitDir}/${file}";
in
readCommitFromFile refFile commonDir
@@ -352,10 +374,10 @@ let
# sometimes it stores something like: «ref: refs/heads/branch-name»
then
let
fileContent = lib.fileContents fileName;
fileContent = fileContents fileName;
matchRef = match "^ref: (.*)$" fileContent;
in
if matchRef == null then { value = fileContent; } else readCommitFromFile (lib.head matchRef) path
if matchRef == null then { value = fileContent; } else readCommitFromFile (head matchRef) path
else if
pathIsRegularFile packedRefsName
@@ -373,14 +395,14 @@ let
if refs == [ ] then
{ error = "Could not find " + file + " in " + packedRefsName; }
else
{ value = lib.head (matchRef (lib.head refs)); }
{ value = head (matchRef (head refs)); }
else
{ error = "Not a .git directory: " + toString path; };
in
readCommitFromFile "HEAD";
pathHasContext = builtins.hasContext or (lib.hasPrefix storeDir);
pathHasContext = builtins.hasContext or (hasPrefix storeDir);
canCleanSource = src: src ? _isLibCleanSourceWith || !(pathHasContext (toString src));
@@ -403,7 +425,7 @@ let
{
# The original path
origSrc = if isFiltered then src.origSrc else src;
filter = if isFiltered then src.filter else _: _: true;
filter = if isFiltered then src.filter else null; # make sure to handle this!
name = if isFiltered then src.name else "source";
};
@@ -411,6 +433,9 @@ let
#
# Inverse of toSourceAttributes for Source objects.
fromSourceAttributes =
let
inherit (builtins) path;
in
{
origSrc,
filter,
@@ -418,9 +443,13 @@ let
}:
{
_isLibCleanSourceWith = true;
inherit origSrc filter name;
outPath = builtins.path {
inherit filter name;
inherit origSrc name;
# preserve outside checks, since a filter of null looks odd for
# comparisons
filter = if filter == null then _: _: true else filter;
outPath = path {
inherit name;
${if filter != null then "filter" else null} = filter;
path = origSrc;
};
};
@@ -431,15 +460,14 @@ let
urlToName =
url:
let
inherit (lib.strings) stringLength;
base = baseNameOf (lib.removeSuffix "/" (lib.last (lib.splitString ":" (toString url))));
base = baseNameOf (removeSuffix "/" (last (splitString ":" (toString url))));
# chop away one git or archive-related extension
removeExt =
name:
let
matchExt = match "(.*)\\.(git|tar|zip|gz|tgz|bz|tbz|bz2|tbz2|lzma|txz|xz|zstd)$" name;
in
if matchExt != null then lib.head matchExt else name;
if matchExt != null then head matchExt else name;
# apply function f to string x while the result shrinks
shrink =
f: x:
@@ -461,9 +489,9 @@ let
matchVer = match "([A-Za-z]+[-_. ]?)*(v)?([0-9.]+.*)" baseRev;
in
if matchHash != null then
builtins.substring 0 7 baseRev
substring 0 7 baseRev
else if matchVer != null then
lib.last matchVer
last matchVer
else
baseRev;
@@ -623,7 +651,7 @@ let
in
src: patterns:
lib.cleanSourceWith {
cleanSourceWith {
filter = mkSourceFilter src patterns;
inherit src;
};
+124 -116
View File
@@ -6,8 +6,6 @@ let
inherit (builtins) length;
inherit (lib.trivial) warnIf;
asciiTable = import ./ascii-table.nix;
in
@@ -16,6 +14,7 @@ rec {
inherit (builtins)
compareVersions
concatMap
elem
elemAt
filter
@@ -564,7 +563,10 @@ rec {
:::
*/
makeSearchPath =
subDir: paths: concatStringsSep ":" (map (path: path + "/" + subDir) (filter (x: x != null) paths));
subDir: paths:
concatStringsSep ":" (
concatMap (path: if path != null then [ (path + "/" + subDir) ] else [ ]) paths
);
/**
Construct a Unix-style search path by appending the given
@@ -602,8 +604,14 @@ rec {
:::
*/
makeSearchPathOutput =
output: subDir: pkgs:
makeSearchPath subDir (map (lib.getOutput output) pkgs);
output:
let
getOutput' = lib.getOutput output;
in
subDir: pkgs:
concatStringsSep ":" (
concatMap (path: if path != null then [ (getOutput' path + "/" + subDir) ] else [ ]) pkgs
);
/**
Construct a library search path (such as RPATH) containing the
@@ -721,15 +729,17 @@ rec {
:::
*/
normalizePath =
let
startsWithSlash = hasSuffix "/";
in
s:
warnIf (isPath s)
''
if isPath s then
throw ''
lib.strings.normalizePath: The argument (${toString s}) is a path value, but only strings are supported.
Path values are always normalised in Nix, so there's no need to call this function on them.
This function also copies the path to the Nix store and returns the store path, the same as "''${path}" will, which may not be what you want.
This behavior is deprecated and will throw an error in the future.''
(
builtins.foldl' (x: y: if y == "/" && hasSuffix "/" x then x else x + y) "" (stringToCharacters s)
Path values are always normalised in Nix, so there's no need to call this function on them.''
else
builtins.foldl' (x: y: if y == "/" && startsWithSlash x then x else x + y) "" (
stringToCharacters s
);
/**
@@ -796,17 +806,18 @@ rec {
:::
*/
hasPrefix =
pref: str:
# Before 23.05, paths would be copied to the store before converting them
# to strings and comparing. This was surprising and confusing.
warnIf (isPath pref)
''
pref:
let
lenPrefix = stringLength pref;
in
if isPath pref then
# Before 23.05, paths would be copied to the store before converting them
# to strings and comparing. This was surprising and confusing.
throw ''
lib.strings.hasPrefix: The first argument (${toString pref}) is a path value, but only strings are supported.
There is almost certainly a bug in the calling code, since this function always returns `false` in such a case.
This function also copies the path to the Nix store, which may not be what you want.
This behavior is deprecated and will throw an error in the future.
You might want to use `lib.path.hasPrefix` instead, which correctly supports paths.''
(substring 0 (stringLength pref) str == pref);
else
str: substring 0 lenPrefix str == pref;
/**
Determine whether a string has given suffix.
@@ -839,20 +850,23 @@ rec {
:::
*/
hasSuffix =
suffix: content:
suffix:
let
lenContent = stringLength content;
lenSuffix = stringLength suffix;
in
# Before 23.05, paths would be copied to the store before converting them
# to strings and comparing. This was surprising and confusing.
warnIf (isPath suffix)
''
if isPath suffix then
# Before 23.05, paths would be copied to the store before converting them
# to strings and comparing. This was surprising and confusing.
throw ''
lib.strings.hasSuffix: The first argument (${toString suffix}) is a path value, but only strings are supported.
There is almost certainly a bug in the calling code, since this function always returns `false` in such a case.
This function also copies the path to the Nix store, which may not be what you want.
This behavior is deprecated and will throw an error in the future.''
(lenContent >= lenSuffix && substring (lenContent - lenSuffix) lenContent content == suffix);
There is almost certainly a bug in the calling code, since this function always returns `false` in such a case.
This function also copies the path to the Nix store, which may not be what you want.''
else
content:
let
lenContent = stringLength content;
in
lenContent >= lenSuffix && substring (lenContent - lenSuffix) lenContent content == suffix;
/**
Determine whether a string contains the given infix
@@ -889,16 +903,19 @@ rec {
:::
*/
hasInfix =
infix: content:
# Before 23.05, paths would be copied to the store before converting them
# to strings and comparing. This was surprising and confusing.
warnIf (isPath infix)
''
infix:
let
escapedInfix = escapeRegex infix;
in
if isPath infix then
# Before 23.05, paths would be copied to the store before converting them
# to strings and comparing. This was surprising and confusing.
throw ''
lib.strings.hasInfix: The first argument (${toString infix}) is a path value, but only strings are supported.
There is almost certainly a bug in the calling code, since this function always returns `false` in such a case.
This function also copies the path to the Nix store, which may not be what you want.
This behavior is deprecated and will throw an error in the future.''
(builtins.match ".*${escapeRegex infix}.*" "${content}" != null);
This function also copies the path to the Nix store, which may not be what you want.''
else
content: builtins.match ".*${escapedInfix}.*" "${content}" != null;
/**
Convert a string `s` to a list of characters (i.e. singleton strings).
@@ -1303,8 +1320,11 @@ rec {
:::
*/
toShellVar =
name: value:
lib.throwIfNot (isValidPosixName name) "toShellVar: ${name} is not a valid shell variable name" (
name:
if (!isValidPosixName name) then
throw "toShellVar: ${name} is not a valid shell variable name"
else
value:
if isAttrs value && !isStringLike value then
"declare -A ${name}=(${
concatStringsSep " " (lib.mapAttrsToList (n: v: "[${escapeShellArg n}]=${escapeShellArg v}") value)
@@ -1312,8 +1332,7 @@ rec {
else if isList value then
"declare -a ${name}=(${escapeShellArgs value})"
else
"${name}=${escapeShellArg value}"
);
"${name}=${escapeShellArg value}";
/**
Translate an attribute set `vars` into corresponding shell variable declarations
@@ -1570,15 +1589,14 @@ rec {
*/
toSentenceCase =
str:
lib.throwIfNot (isString str)
"toSentenceCase does only accepts string values, but got ${typeOf str}"
(
let
firstChar = substring 0 1 str;
rest = substring 1 (stringLength str) str;
in
addContextFrom str (toUpper firstChar + toLower rest)
);
if !isString str then
throw "toSentenceCase does only accepts string values, but got ${typeOf str}"
else
let
firstChar = substring 0 1 str;
rest = substring 1 (-1) str; # -1 takes till the end of the string
in
toUpper firstChar + toLower rest;
/**
Converts a string to camelCase. Handles snake_case, PascalCase,
@@ -1614,7 +1632,9 @@ rec {
*/
toCamelCase =
str:
lib.throwIfNot (isString str) "toCamelCase does only accepts string values, but got ${typeOf str}" (
if !isString str then
throw "toCamelCase does only accepts string values, but got ${typeOf str}"
else
let
separators = splitStringBy (
prev: curr:
@@ -1634,8 +1654,7 @@ rec {
first = if length parts > 0 then toLower (head parts) else "";
rest = if length parts > 1 then map toSentenceCase (tail parts) else [ ];
in
concatStrings (map (addContextFrom str) ([ first ] ++ rest))
);
concatStrings ([ first ] ++ rest);
/**
Appends string context from string like object `src` to `target`.
@@ -1721,13 +1740,11 @@ rec {
:::
*/
splitString =
sep: s:
sep:
let
splits = builtins.filter builtins.isString (
builtins.split (escapeRegex (toString sep)) (toString s)
);
escapedSep = escapeRegex (toString sep);
in
map (addContextFrom s) splits;
s: map (addContextFrom s) (filter isString (split escapedSep (toString s)));
/**
Splits a string into substrings based on a predicate that examines adjacent characters.
@@ -1794,31 +1811,27 @@ rec {
predicate: keepSplit: str:
let
len = stringLength str;
withContext = addContextFrom str;
# Helper function that processes the string character by character
go =
pos: currentPart: result:
# Base case: reached end of string
if pos == len then
result ++ [ currentPart ]
result ++ [ (withContext currentPart) ]
else
let
currChar = substring pos 1 str;
prevChar = if pos > 0 then substring (pos - 1) 1 str else "";
isSplit = predicate prevChar currChar;
in
if isSplit then
if predicate prevChar currChar then
# Split here - add current part to results and start a new one
let
newResult = result ++ [ currentPart ];
newCurrentPart = if keepSplit then currChar else "";
in
go (pos + 1) newCurrentPart newResult
go (pos + 1) (if keepSplit then currChar else "") (result ++ [ (withContext currentPart) ])
else
# Keep building current part
go (pos + 1) (currentPart + currChar) result;
in
if len == 0 then [ (addContextFrom str "") ] else map (addContextFrom str) (go 0 "" [ ]);
if len == 0 then [ (withContext "") ] else go 0 "" [ ];
/**
Returns a string without the specified prefix, if the prefix matches.
@@ -1851,25 +1864,24 @@ rec {
:::
*/
removePrefix =
prefix: str:
# Before 23.05, paths would be copied to the store before converting them
# to strings and comparing. This was surprising and confusing.
warnIf (isPath prefix)
''
prefix:
let
preLen = stringLength prefix;
in
if isPath prefix then
# Before 23.05, paths would be copied to the store before converting them
# to strings and comparing. This was surprising and confusing.
throw ''
lib.strings.removePrefix: The first argument (${toString prefix}) is a path value, but only strings are supported.
There is almost certainly a bug in the calling code, since this function never removes any prefix in such a case.
This function also copies the path to the Nix store, which may not be what you want.
This behavior is deprecated and will throw an error in the future.''
(
let
preLen = stringLength prefix;
in
if substring 0 preLen str == prefix then
# -1 will take the string until the end
substring preLen (-1) str
else
str
);
This function also copies the path to the Nix store, which may not be what you want.''
else
str:
if substring 0 preLen str == prefix then
# -1 will take the string until the end
substring preLen (-1) str
else
str;
/**
Returns a string without the specified suffix, if the suffix matches.
@@ -1902,25 +1914,26 @@ rec {
:::
*/
removeSuffix =
suffix: str:
# Before 23.05, paths would be copied to the store before converting them
# to strings and comparing. This was surprising and confusing.
warnIf (isPath suffix)
''
suffix:
let
sufLen = stringLength suffix;
in
if isPath suffix then
# Before 23.05, paths would be copied to the store before converting them
# to strings and comparing. This was surprising and confusing.
throw ''
lib.strings.removeSuffix: The first argument (${toString suffix}) is a path value, but only strings are supported.
There is almost certainly a bug in the calling code, since this function never removes any suffix in such a case.
This function also copies the path to the Nix store, which may not be what you want.
This behavior is deprecated and will throw an error in the future.''
(
let
sufLen = stringLength suffix;
sLen = stringLength str;
in
if sufLen <= sLen && suffix == substring (sLen - sufLen) sufLen str then
substring 0 (sLen - sufLen) str
else
str
);
This function also copies the path to the Nix store, which may not be what you want.''
else
str:
let
sLen = stringLength str;
in
if sufLen <= sLen && suffix == substring (sLen - sufLen) sufLen str then
substring 0 (sLen - sufLen) str
else
str;
/**
Returns true if string `v1` denotes a version older than `v2`.
@@ -1986,7 +1999,7 @@ rec {
:::
*/
versionAtLeast = v1: v2: !versionOlder v1 v2;
versionAtLeast = v1: v2: compareVersions v2 v1 != 1;
/**
This function takes an argument `x` that's either a derivation or a
@@ -2149,8 +2162,9 @@ rec {
"LIST"
];
in
type: feature: value:
type:
assert (elem (toUpper type) types);
feature: value:
assert (isString feature);
assert (isString value);
"-D${feature}:${toUpper type}=${value}";
@@ -2186,9 +2200,8 @@ rec {
*/
cmakeBool =
condition: flag:
assert (lib.isString condition);
assert (lib.isBool flag);
cmakeOptionType "bool" condition (lib.toUpper (lib.boolToString flag));
cmakeOptionType "bool" condition (if flag then "TRUE" else "FALSE");
/**
Create a `"-D<feature>:STRING=<value>"` string that can be passed to typical
@@ -2220,11 +2233,7 @@ rec {
:::
*/
cmakeFeature =
feature: value:
assert (lib.isString feature);
assert (lib.isString value);
cmakeOptionType "string" feature value;
cmakeFeature = cmakeOptionType "string";
/**
Create a `"-D<feature>=<value>"` string that can be passed to typical Meson
@@ -2294,7 +2303,6 @@ rec {
*/
mesonBool =
condition: flag:
assert (lib.isString condition);
assert (lib.isBool flag);
mesonOption condition (lib.boolToString flag);
@@ -2331,7 +2339,6 @@ rec {
*/
mesonEnable =
feature: flag:
assert (lib.isString feature);
assert (lib.isBool flag);
mesonOption feature (if flag then "enabled" else "disabled");
@@ -2525,8 +2532,9 @@ rec {
strw = lib.stringLength str;
reqWidth = width - (lib.stringLength filler);
in
assert lib.assertMsg (strw <= width)
"fixedWidthString: requested string length (${toString width}) must not be shorter than actual length (${toString strw})";
assert
strw <= width
|| throw "fixedWidthString: requested string length (${toString width}) must not be shorter than actual length (${toString strw})";
if strw == width then str else filler + fixedWidthString reqWidth filler str;
/**
+20 -2
View File
@@ -17,12 +17,17 @@ let
inherit (lib.strings) toJSON;
inherit (lib.trivial)
oldestSupportedReleaseIsAtLeast
;
doubles = import ./doubles.nix { inherit lib; };
parse = import ./parse.nix { inherit lib; };
inspect = import ./inspect.nix { inherit lib; };
platforms = import ./platforms.nix { inherit lib; };
examples = import ./examples.nix { inherit lib; };
architectures = import ./architectures.nix { inherit lib; };
rustc-target-env = import ./rustc-target-env.nix;
/**
Elaborated systems contain functions, which means that they don't satisfy
@@ -449,6 +454,16 @@ let
else
final.parsed.cpu.name;
# https://doc.rust-lang.org/reference/conditional-compilation.html#target_env
# Accomodate system definitions written before Nixpkgs learned about target_env.
env =
if rust ? platform.env then
rust.platform.env
else if rustc-target-env ? ${final.rust.rustcTargetSpec} then
rustc-target-env.${final.rust.rustcTargetSpec}
else
"";
# https://doc.rust-lang.org/reference/conditional-compilation.html#target_os
os =
if rust ? platform then
@@ -690,9 +705,12 @@ let
};
};
in
# TODO: Remove in 27.05.
# Platforms elaborated by pre-26.11 Nixpkgs will include the `linux-kernel` attr,
# so we can't assert its absence until 26.11 is the oldest supported release.
# Assertion will activate during the 27.05 cycle, when 26.05 support ends.
# TODO: Remove assertion in the 27.11 cycle.
assert
args ? linux-kernel
oldestSupportedReleaseIsAtLeast 2611 && args ? linux-kernel
-> throw "lib.systems.elaborate: linux-kernel has been removed; see the 26.11 release notes";
assert final.useAndroidPrebuilt -> final.isAndroid;
+26 -10
View File
@@ -1,19 +1,29 @@
{ lib }:
let
inherit (lib) lists;
inherit (lib)
lists
splitString
;
inherit (lib.systems) parse;
inherit (parse)
mkSystemFromSkeleton
mkSkeletonFromList
doubleFromSystem
;
inherit (lib.systems.inspect) predicates;
inherit (lib.attrsets) matchAttrs;
all = [
# our primary systems. at the top of the list for fastest matching
# inside check-meta
"x86_64-linux"
"aarch64-darwin"
"aarch64-linux"
# Cygwin
"i686-cygwin"
"x86_64-cygwin"
# Darwin
"x86_64-darwin"
"aarch64-darwin"
# FreeBSD
"i686-freebsd"
"x86_64-freebsd"
@@ -30,8 +40,7 @@ let
# JS
"javascript-ghcjs"
# Linux
"aarch64-linux"
# Linux (excluding the primary two at the top)
"arc-linux"
"armv5tel-linux"
"armv6l-linux"
@@ -54,7 +63,6 @@ let
"riscv64-linux"
"s390-linux"
"s390x-linux"
"x86_64-linux"
# MMIXware
"mmix-mmixware"
@@ -117,9 +125,17 @@ let
"x86_64-uefi"
];
allParsed = map parse.mkSystemFromString all;
uncheckedSystemFromString =
let
systemType = {
_type = "system";
};
in
s: mkSystemFromSkeleton (mkSkeletonFromList (splitString "-" s)) // systemType;
filterDoubles = f: map parse.doubleFromSystem (lists.filter f allParsed);
allParsed = map uncheckedSystemFromString all;
filterDoubles = f: map doubleFromSystem (lists.filter f allParsed);
in
{

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