mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-07-14 06:00:33 +03:00
Merge branch 'master' into pr/bcachefs
This commit is contained in:
commit
db59d03371
7621 changed files with 201446 additions and 91861 deletions
25
.github/CODEOWNERS
vendored
25
.github/CODEOWNERS
vendored
|
@ -25,7 +25,7 @@
|
||||||
/lib/cli.nix @infinisil @Profpatsch
|
/lib/cli.nix @infinisil @Profpatsch
|
||||||
/lib/debug.nix @infinisil @Profpatsch
|
/lib/debug.nix @infinisil @Profpatsch
|
||||||
/lib/asserts.nix @infinisil @Profpatsch
|
/lib/asserts.nix @infinisil @Profpatsch
|
||||||
/lib/path.* @infinisil @fricklerhandwerk
|
/lib/path.* @infinisil
|
||||||
/lib/fileset @infinisil
|
/lib/fileset @infinisil
|
||||||
## Libraries / Module system
|
## Libraries / Module system
|
||||||
/lib/modules.nix @infinisil @roberth
|
/lib/modules.nix @infinisil @roberth
|
||||||
|
@ -73,13 +73,14 @@
|
||||||
# Contributor documentation
|
# Contributor documentation
|
||||||
/CONTRIBUTING.md @infinisil
|
/CONTRIBUTING.md @infinisil
|
||||||
/.github/PULL_REQUEST_TEMPLATE.md @infinisil
|
/.github/PULL_REQUEST_TEMPLATE.md @infinisil
|
||||||
/doc/contributing/ @fricklerhandwerk @infinisil
|
/doc/contributing/ @infinisil
|
||||||
/doc/contributing/contributing-to-documentation.chapter.md @jtojnar @fricklerhandwerk @infinisil
|
/doc/contributing/contributing-to-documentation.chapter.md @jtojnar @infinisil
|
||||||
/lib/README.md @infinisil
|
/lib/README.md @infinisil
|
||||||
/doc/README.md @infinisil
|
/doc/README.md @infinisil
|
||||||
/nixos/README.md @infinisil
|
/nixos/README.md @infinisil
|
||||||
/pkgs/README.md @infinisil
|
/pkgs/README.md @infinisil
|
||||||
/maintainers/README.md @infinisil
|
/maintainers/README.md @infinisil
|
||||||
|
/maintainers/* @piegamesde @Janik-Haag
|
||||||
|
|
||||||
# User-facing development documentation
|
# User-facing development documentation
|
||||||
/doc/development.md @infinisil
|
/doc/development.md @infinisil
|
||||||
|
@ -166,6 +167,8 @@
|
||||||
|
|
||||||
# Browsers
|
# Browsers
|
||||||
/pkgs/applications/networking/browsers/firefox @mweinelt
|
/pkgs/applications/networking/browsers/firefox @mweinelt
|
||||||
|
/pkgs/applications/networking/browsers/chromium @emilylange
|
||||||
|
/nixos/tests/chromium.nix @emilylange
|
||||||
|
|
||||||
# Certificate Authorities
|
# Certificate Authorities
|
||||||
pkgs/data/misc/cacert/ @ajs124 @lukegb @mweinelt
|
pkgs/data/misc/cacert/ @ajs124 @lukegb @mweinelt
|
||||||
|
@ -267,13 +270,6 @@ pkgs/development/python-modules/buildcatrust/ @ajs124 @lukegb @mweinelt
|
||||||
/pkgs/development/php-packages @aanderse @drupol @etu @globin @ma27 @talyz
|
/pkgs/development/php-packages @aanderse @drupol @etu @globin @ma27 @talyz
|
||||||
/pkgs/top-level/php-packages.nix @jtojnar @aanderse @drupol @etu @globin @ma27 @talyz
|
/pkgs/top-level/php-packages.nix @jtojnar @aanderse @drupol @etu @globin @ma27 @talyz
|
||||||
|
|
||||||
# Podman, CRI-O modules and related
|
|
||||||
/nixos/modules/virtualisation/containers.nix @adisbladis
|
|
||||||
/nixos/modules/virtualisation/cri-o.nix @adisbladis
|
|
||||||
/nixos/modules/virtualisation/podman @adisbladis
|
|
||||||
/nixos/tests/cri-o.nix @adisbladis
|
|
||||||
/nixos/tests/podman @adisbladis
|
|
||||||
|
|
||||||
# Docker tools
|
# Docker tools
|
||||||
/pkgs/build-support/docker @roberth
|
/pkgs/build-support/docker @roberth
|
||||||
/nixos/tests/docker-tools* @roberth
|
/nixos/tests/docker-tools* @roberth
|
||||||
|
@ -337,8 +333,13 @@ nixos/modules/tasks/filesystems/zfs.nix @raitobezarius
|
||||||
nixos/tests/zfs.nix @raitobezarius
|
nixos/tests/zfs.nix @raitobezarius
|
||||||
|
|
||||||
# Zig
|
# Zig
|
||||||
/pkgs/development/compilers/zig @AndersonTorres @figsoda
|
/pkgs/development/compilers/zig @figsoda
|
||||||
/doc/hooks/zig.section.md @AndersonTorres @figsoda
|
/doc/hooks/zig.section.md @figsoda
|
||||||
|
|
||||||
# Linux Kernel
|
# Linux Kernel
|
||||||
pkgs/os-specific/linux/kernel/manual-config.nix @amjoseph-nixpkgs
|
pkgs/os-specific/linux/kernel/manual-config.nix @amjoseph-nixpkgs
|
||||||
|
|
||||||
|
# Buildbot
|
||||||
|
nixos/modules/services/continuous-integration/buildbot @Mic92 @zowoq
|
||||||
|
nixos/tests/buildbot.nix @Mic92 @zowoq
|
||||||
|
pkgs/development/tools/continuous-integration/buildbot @Mic92 @zowoq
|
||||||
|
|
145
.github/workflows/check-by-name.yml
vendored
145
.github/workflows/check-by-name.yml
vendored
|
@ -1,5 +1,7 @@
|
||||||
# Checks pkgs/by-name (see pkgs/by-name/README.md)
|
# Checks pkgs/by-name (see pkgs/by-name/README.md)
|
||||||
# using the nixpkgs-check-by-name tool (see pkgs/test/nixpkgs-check-by-name)
|
# using the nixpkgs-check-by-name tool (see pkgs/test/nixpkgs-check-by-name)
|
||||||
|
#
|
||||||
|
# When you make changes to this workflow, also update pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh adequately
|
||||||
name: Check pkgs/by-name
|
name: Check pkgs/by-name
|
||||||
|
|
||||||
# The pre-built tool is fetched from a channel,
|
# The pre-built tool is fetched from a channel,
|
||||||
|
@ -8,8 +10,9 @@ on:
|
||||||
# Using pull_request_target instead of pull_request avoids having to approve first time contributors
|
# Using pull_request_target instead of pull_request avoids having to approve first time contributors
|
||||||
pull_request_target
|
pull_request_target
|
||||||
|
|
||||||
# The tool doesn't need any permissions, it only outputs success or not based on the checkout
|
permissions:
|
||||||
permissions: {}
|
# We need this permission to cancel the workflow run if there's a merge conflict
|
||||||
|
actions: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check:
|
check:
|
||||||
|
@ -20,6 +23,9 @@ jobs:
|
||||||
# The default of 6 hours is definitely too long
|
# The default of 6 hours is definitely too long
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
steps:
|
steps:
|
||||||
|
# This step has to be in this file,
|
||||||
|
# because it's needed to determine which revision of the repository to fetch,
|
||||||
|
# and we can only use other files from the repository once it's fetched.
|
||||||
- name: Resolving the merge commit
|
- name: Resolving the merge commit
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ github.token }}
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
@ -62,7 +68,14 @@ jobs:
|
||||||
if [[ "$mergeable" == "true" ]]; then
|
if [[ "$mergeable" == "true" ]]; then
|
||||||
echo "The PR can be merged, checking the merge commit $mergedSha"
|
echo "The PR can be merged, checking the merge commit $mergedSha"
|
||||||
else
|
else
|
||||||
echo "The PR cannot be merged, it has a merge conflict"
|
echo "The PR cannot be merged, it has a merge conflict, cancelling the workflow.."
|
||||||
|
gh api \
|
||||||
|
--method POST \
|
||||||
|
-H "Accept: application/vnd.github+json" \
|
||||||
|
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||||
|
/repos/"$GITHUB_REPOSITORY"/actions/runs/"$GITHUB_RUN_ID"/cancel
|
||||||
|
sleep 60
|
||||||
|
# If it's still not canceled after a minute, something probably went wrong, just exit
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
echo "mergedSha=$mergedSha" >> "$GITHUB_ENV"
|
echo "mergedSha=$mergedSha" >> "$GITHUB_ENV"
|
||||||
|
@ -72,124 +85,20 @@ jobs:
|
||||||
ref: ${{ env.mergedSha }}
|
ref: ${{ env.mergedSha }}
|
||||||
# Fetches the merge commit and its parents
|
# Fetches the merge commit and its parents
|
||||||
fetch-depth: 2
|
fetch-depth: 2
|
||||||
- name: Determining PR git hashes
|
- name: Checking out base branch
|
||||||
run: |
|
run: |
|
||||||
# For pull_request_target this is the same as $GITHUB_SHA
|
base=$(mktemp -d)
|
||||||
echo "baseSha=$(git rev-parse HEAD^1)" >> "$GITHUB_ENV"
|
git worktree add "$base" "$(git rev-parse HEAD^1)"
|
||||||
|
echo "base=$base" >> "$GITHUB_ENV"
|
||||||
echo "headSha=$(git rev-parse HEAD^2)" >> "$GITHUB_ENV"
|
|
||||||
- uses: cachix/install-nix-action@7ac1ec25491415c381d9b62f0657c7a028df52a7 # v24
|
- uses: cachix/install-nix-action@7ac1ec25491415c381d9b62f0657c7a028df52a7 # v24
|
||||||
- name: Determining channel to use for dependencies
|
- name: Fetching the tool
|
||||||
run: |
|
run: pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh "$GITHUB_BASE_REF" result
|
||||||
echo "Determining the preferred channel to use for PR base branch $GITHUB_BASE_REF"
|
|
||||||
if [[ "$GITHUB_BASE_REF" =~ ^(release|staging|staging-next)-([0-9][0-9]\.[0-9][0-9])$ ]]; then
|
|
||||||
# Use the release channel for all PRs to release-XX.YY, staging-XX.YY and staging-next-XX.YY
|
|
||||||
channel=nixos-${BASH_REMATCH[2]}
|
|
||||||
echo "PR is for a release branch, preferred channel is $channel"
|
|
||||||
else
|
|
||||||
# Use the nixos-unstable channel for all other PRs
|
|
||||||
channel=nixos-unstable
|
|
||||||
echo "PR is for a non-release branch, preferred channel is $channel"
|
|
||||||
fi
|
|
||||||
# Check that the channel exists. It doesn't exist for fresh release branches
|
|
||||||
if ! curl -fSs "https://channels.nixos.org/$channel"; then
|
|
||||||
# Fall back to nixos-unstable, makes sense for fresh release branches
|
|
||||||
echo "Preferred channel $channel could not be fetched, falling back to nixos-unstable"
|
|
||||||
channel=nixos-unstable
|
|
||||||
fi
|
|
||||||
echo "channel=$channel" >> "$GITHUB_ENV"
|
|
||||||
- name: Fetching latest version of channel
|
|
||||||
run: |
|
|
||||||
echo "Fetching latest version of channel $channel"
|
|
||||||
# This is probably the easiest way to get Nix to output the path to a downloaded channel!
|
|
||||||
nixpkgs=$(nix-instantiate --find-file nixpkgs -I nixpkgs=channel:"$channel")
|
|
||||||
# This file only exists in channels
|
|
||||||
rev=$(<"$nixpkgs"/.git-revision)
|
|
||||||
echo "Channel $channel is at revision $rev"
|
|
||||||
echo "nixpkgs=$nixpkgs" >> "$GITHUB_ENV"
|
|
||||||
echo "rev=$rev" >> "$GITHUB_ENV"
|
|
||||||
- name: Fetching pre-built nixpkgs-check-by-name from the channel
|
|
||||||
run: |
|
|
||||||
echo "Fetching pre-built nixpkgs-check-by-name from channel $channel at revision $rev"
|
|
||||||
# Passing --max-jobs 0 makes sure that we won't build anything
|
|
||||||
nix-build "$nixpkgs" -A tests.nixpkgs-check-by-name --max-jobs 0
|
|
||||||
- name: Running nixpkgs-check-by-name
|
- name: Running nixpkgs-check-by-name
|
||||||
run: |
|
run: |
|
||||||
echo "Checking whether the check succeeds on the base branch $GITHUB_BASE_REF"
|
if result/bin/nixpkgs-check-by-name --base "$base" .; then
|
||||||
git checkout -q "$baseSha"
|
exit 0
|
||||||
if baseOutput=$(result/bin/nixpkgs-check-by-name . 2>&1); then
|
|
||||||
baseSuccess=1
|
|
||||||
else
|
else
|
||||||
baseSuccess=
|
exitCode=$?
|
||||||
|
echo "To run locally: ./maintainers/scripts/check-by-name.sh $GITHUB_BASE_REF https://github.com/$GITHUB_REPOSITORY.git"
|
||||||
|
exit "$exitCode"
|
||||||
fi
|
fi
|
||||||
printf "%s\n" "$baseOutput"
|
|
||||||
|
|
||||||
echo "Checking whether the check would succeed after merging this pull request"
|
|
||||||
git checkout -q "$mergedSha"
|
|
||||||
if mergedOutput=$(result/bin/nixpkgs-check-by-name . 2>&1); then
|
|
||||||
mergedSuccess=1
|
|
||||||
exitCode=0
|
|
||||||
else
|
|
||||||
mergedSuccess=
|
|
||||||
exitCode=1
|
|
||||||
fi
|
|
||||||
printf "%s\n" "$mergedOutput"
|
|
||||||
|
|
||||||
resultToEmoji() {
|
|
||||||
if [[ -n "$1" ]]; then
|
|
||||||
echo ":heavy_check_mark:"
|
|
||||||
else
|
|
||||||
echo ":x:"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Print a markdown summary in GitHub actions
|
|
||||||
{
|
|
||||||
echo "| Nixpkgs version | Check result |"
|
|
||||||
echo "| --- | --- |"
|
|
||||||
echo "| Latest base commit | $(resultToEmoji "$baseSuccess") |"
|
|
||||||
echo "| After merging this PR | $(resultToEmoji "$mergedSuccess") |"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
if [[ -n "$baseSuccess" ]]; then
|
|
||||||
if [[ -n "$mergedSuccess" ]]; then
|
|
||||||
echo "The check succeeds on both the base branch and after merging this PR"
|
|
||||||
else
|
|
||||||
echo "The check succeeds on the base branch, but would fail after merging this PR:"
|
|
||||||
echo "\`\`\`"
|
|
||||||
echo "$mergedOutput"
|
|
||||||
echo "\`\`\`"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [[ -n "$mergedSuccess" ]]; then
|
|
||||||
echo "The check fails on the base branch, but this PR fixes it, nicely done!"
|
|
||||||
else
|
|
||||||
echo "The check fails on both the base branch and after merging this PR, unknown if only this PRs changes would satisfy the check, the base branch needs to be fixed first."
|
|
||||||
echo ""
|
|
||||||
echo "Failure on the base branch:"
|
|
||||||
echo "\`\`\`"
|
|
||||||
echo "$baseOutput"
|
|
||||||
echo "\`\`\`"
|
|
||||||
echo ""
|
|
||||||
echo "Failure after merging this PR:"
|
|
||||||
echo "\`\`\`"
|
|
||||||
echo "$mergedOutput"
|
|
||||||
echo "\`\`\`"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "### Details"
|
|
||||||
echo "- nixpkgs-check-by-name tool:"
|
|
||||||
echo " - Channel: $channel"
|
|
||||||
echo " - Nixpkgs commit: [$rev](https://github.com/${GITHUB_REPOSITORY}/commit/$rev)"
|
|
||||||
echo " - Store path: \`$(realpath result)\`"
|
|
||||||
echo "- Tested Nixpkgs:"
|
|
||||||
echo " - Base branch: $GITHUB_BASE_REF"
|
|
||||||
echo " - Latest base branch commit: [$baseSha](https://github.com/${GITHUB_REPOSITORY}/commit/$baseSha)"
|
|
||||||
echo " - Latest PR commit: [$headSha](https://github.com/${GITHUB_REPOSITORY}/commit/$headSha)"
|
|
||||||
echo " - Merge commit: [$mergedSha](https://github.com/${GITHUB_REPOSITORY}/commit/$mergedSha)"
|
|
||||||
} >> "$GITHUB_STEP_SUMMARY"
|
|
||||||
|
|
||||||
exit "$exitCode"
|
|
||||||
|
|
2
.github/workflows/manual-nixpkgs.yml
vendored
2
.github/workflows/manual-nixpkgs.yml
vendored
|
@ -29,4 +29,4 @@ jobs:
|
||||||
name: nixpkgs-ci
|
name: nixpkgs-ci
|
||||||
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
||||||
- name: Building Nixpkgs manual
|
- name: Building Nixpkgs manual
|
||||||
run: NIX_PATH=nixpkgs=$(pwd) nix-build --option restrict-eval true pkgs/top-level/release.nix -A manual
|
run: NIX_PATH=nixpkgs=$(pwd) nix-build --option restrict-eval true pkgs/top-level/release.nix -A manual -A manual.tests
|
||||||
|
|
|
@ -60,7 +60,7 @@ jobs:
|
||||||
|
|
||||||
Check that all providers build with:
|
Check that all providers build with:
|
||||||
```
|
```
|
||||||
@ofborg build terraform.full
|
@ofborg build opentofu.full
|
||||||
```
|
```
|
||||||
If there is more than ten commits in the PR `ofborg` won't build it automatically and you will need to use the above command.
|
If there is more than ten commits in the PR `ofborg` won't build it automatically and you will need to use the above command.
|
||||||
branch: terraform-providers-update
|
branch: terraform-providers-update
|
||||||
|
|
2
.mailmap
2
.mailmap
|
@ -12,3 +12,5 @@ Sandro Jäckel <sandro.jaeckel@gmail.com> <sandro.jaeckel@sap.com>
|
||||||
superherointj <5861043+superherointj@users.noreply.github.com>
|
superherointj <5861043+superherointj@users.noreply.github.com>
|
||||||
Vladimír Čunát <v@cunat.cz> <vcunat@gmail.com>
|
Vladimír Čunát <v@cunat.cz> <vcunat@gmail.com>
|
||||||
Vladimír Čunát <v@cunat.cz> <vladimir.cunat@nic.cz>
|
Vladimír Čunát <v@cunat.cz> <vladimir.cunat@nic.cz>
|
||||||
|
Yifei Sun <ysun@hey.com> StepBroBD <Hi@StepBroBD.com>
|
||||||
|
Yifei Sun <ysun@hey.com> <ysun+git@stepbrobd.com>
|
||||||
|
|
|
@ -26,7 +26,7 @@ This file contains general contributing information, but individual parts also h
|
||||||
|
|
||||||
This section describes in some detail how changes can be made and proposed with pull requests.
|
This section describes in some detail how changes can be made and proposed with pull requests.
|
||||||
|
|
||||||
> **Note**
|
> [!Note]
|
||||||
> Be aware that contributing implies licensing those contributions under the terms of [COPYING](./COPYING), an MIT-like license.
|
> Be aware that contributing implies licensing those contributions under the terms of [COPYING](./COPYING), an MIT-like license.
|
||||||
|
|
||||||
0. Set up a local version of Nixpkgs to work with using GitHub and Git
|
0. Set up a local version of Nixpkgs to work with using GitHub and Git
|
||||||
|
@ -273,7 +273,7 @@ Once a pull request has been merged into `master`, a backport pull request to th
|
||||||
|
|
||||||
### Automatically backporting changes
|
### Automatically backporting changes
|
||||||
|
|
||||||
> **Note**
|
> [!Note]
|
||||||
> You have to be a [Nixpkgs maintainer](./maintainers) to automatically create a backport pull request.
|
> You have to be a [Nixpkgs maintainer](./maintainers) to automatically create a backport pull request.
|
||||||
|
|
||||||
Add the [`backport release-YY.MM` label](https://github.com/NixOS/nixpkgs/labels?q=backport) to the pull request on the `master` branch.
|
Add the [`backport release-YY.MM` label](https://github.com/NixOS/nixpkgs/labels?q=backport) to the pull request on the `master` branch.
|
||||||
|
@ -285,16 +285,17 @@ This can be done on both open or already merged pull requests.
|
||||||
To manually create a backport pull request, follow [the standard pull request process][pr-create], with these notable differences:
|
To manually create a backport pull request, follow [the standard pull request process][pr-create], with these notable differences:
|
||||||
|
|
||||||
- Use `release-YY.MM` for the base branch, both for the local branch and the pull request.
|
- Use `release-YY.MM` for the base branch, both for the local branch and the pull request.
|
||||||
> **Warning**
|
|
||||||
> Do not use the `nixos-YY.MM` branch, that is a branch pointing to the tested release channel commit
|
> [!Warning]
|
||||||
|
> Do not use the `nixos-YY.MM` branch, that is a branch pointing to the tested release channel commit
|
||||||
|
|
||||||
- Instead of manually making and committing the changes, use [`git cherry-pick -x`](https://git-scm.com/docs/git-cherry-pick) for each commit from the pull request you'd like to backport.
|
- Instead of manually making and committing the changes, use [`git cherry-pick -x`](https://git-scm.com/docs/git-cherry-pick) for each commit from the pull request you'd like to backport.
|
||||||
Either `git cherry-pick -x <commit>` when the reason for the backport is obvious (such as minor versions, fixes, etc.), otherwise use `git cherry-pick -xe <commit>` to add a reason for the backport to the commit message.
|
Either `git cherry-pick -x <commit>` when the reason for the backport is obvious (such as minor versions, fixes, etc.), otherwise use `git cherry-pick -xe <commit>` to add a reason for the backport to the commit message.
|
||||||
Here is [an example](https://github.com/nixos/nixpkgs/commit/5688c39af5a6c5f3d646343443683da880eaefb8) of this.
|
Here is [an example](https://github.com/nixos/nixpkgs/commit/5688c39af5a6c5f3d646343443683da880eaefb8) of this.
|
||||||
|
|
||||||
> **Warning**
|
> [!Warning]
|
||||||
> Ensure the commits exists on the master branch.
|
> Ensure the commits exists on the master branch.
|
||||||
> In the case of squashed or rebased merges, the commit hash will change and the new commits can be found in the merge message at the bottom of the master pull request.
|
> In the case of squashed or rebased merges, the commit hash will change and the new commits can be found in the merge message at the bottom of the master pull request.
|
||||||
|
|
||||||
- In the pull request description, link to the original pull request to `master`.
|
- In the pull request description, link to the original pull request to `master`.
|
||||||
The pull request title should include `[YY.MM]` matching the release you're backporting to.
|
The pull request title should include `[YY.MM]` matching the release you're backporting to.
|
||||||
|
@ -305,7 +306,7 @@ To manually create a backport pull request, follow [the standard pull request pr
|
||||||
## How to review pull requests
|
## How to review pull requests
|
||||||
[pr-review]: #how-to-review-pull-requests
|
[pr-review]: #how-to-review-pull-requests
|
||||||
|
|
||||||
> **Warning**
|
> [!Warning]
|
||||||
> The following section is a draft, and the policy for reviewing is still being discussed in issues such as [#11166](https://github.com/NixOS/nixpkgs/issues/11166) and [#20836](https://github.com/NixOS/nixpkgs/issues/20836).
|
> The following section is a draft, and the policy for reviewing is still being discussed in issues such as [#11166](https://github.com/NixOS/nixpkgs/issues/11166) and [#20836](https://github.com/NixOS/nixpkgs/issues/20836).
|
||||||
|
|
||||||
The Nixpkgs project receives a fairly high number of contributions via GitHub pull requests. Reviewing and approving these is an important task and a way to contribute to the project.
|
The Nixpkgs project receives a fairly high number of contributions via GitHub pull requests. Reviewing and approving these is an important task and a way to contribute to the project.
|
||||||
|
@ -384,7 +385,7 @@ By keeping the `staging-next` branch separate from `staging`, this batching does
|
||||||
In order for the `staging` and `staging-next` branches to be up-to-date with the latest commits on `master`, there are regular _automated_ merges from `master` into `staging-next` and `staging`.
|
In order for the `staging` and `staging-next` branches to be up-to-date with the latest commits on `master`, there are regular _automated_ merges from `master` into `staging-next` and `staging`.
|
||||||
This is implemented using GitHub workflows [here](.github/workflows/periodic-merge-6h.yml) and [here](.github/workflows/periodic-merge-24h.yml).
|
This is implemented using GitHub workflows [here](.github/workflows/periodic-merge-6h.yml) and [here](.github/workflows/periodic-merge-24h.yml).
|
||||||
|
|
||||||
> **Note**
|
> [!Note]
|
||||||
> Changes must be sufficiently tested before being merged into any branch.
|
> Changes must be sufficiently tested before being merged into any branch.
|
||||||
> Hydra builds should not be used as testing platform.
|
> Hydra builds should not be used as testing platform.
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
# Contributing to the Nixpkgs manual
|
# Contributing to the Nixpkgs reference manual
|
||||||
|
|
||||||
This directory houses the sources files for the Nixpkgs manual.
|
This directory houses the sources files for the Nixpkgs reference manual.
|
||||||
|
|
||||||
|
Going forward, it should only contain [reference](https://nix.dev/contributing/documentation/diataxis#reference) documentation.
|
||||||
|
For tutorials, guides and explanations, contribute to <https://nix.dev/> instead.
|
||||||
|
|
||||||
|
For documentation only relevant for contributors, use Markdown files and code comments in the source code.
|
||||||
|
|
||||||
|
Rendered documentation:
|
||||||
|
- [Unstable (from master)](https://nixos.org/manual/nixpkgs/unstable/)
|
||||||
|
- [Stable (from latest release)](https://nixos.org/manual/nixpkgs/stable/)
|
||||||
|
|
||||||
You can find the [rendered documentation for Nixpkgs `unstable` on nixos.org](https://nixos.org/manual/nixpkgs/unstable/).
|
|
||||||
The rendering tool is [nixos-render-docs](../pkgs/tools/nix/nixos-render-docs/src/nixos_render_docs), sometimes abbreviated `nrd`.
|
The rendering tool is [nixos-render-docs](../pkgs/tools/nix/nixos-render-docs/src/nixos_render_docs), sometimes abbreviated `nrd`.
|
||||||
|
|
||||||
[Docs for Nixpkgs stable](https://nixos.org/manual/nixpkgs/stable/) are also available.
|
|
||||||
|
|
||||||
If you're only getting started with Nix, go to [nixos.org/learn](https://nixos.org/learn).
|
|
||||||
|
|
||||||
## Contributing to this documentation
|
## Contributing to this documentation
|
||||||
|
|
||||||
You can quickly check your edits with `nix-build`:
|
You can quickly check your edits with `nix-build`:
|
||||||
|
@ -48,7 +52,7 @@ It uses the widely compatible [header attributes](https://github.com/jgm/commonm
|
||||||
## Syntax {#sec-contributing-markup}
|
## Syntax {#sec-contributing-markup}
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note**
|
> [!Note]
|
||||||
> NixOS option documentation does not support headings in general.
|
> NixOS option documentation does not support headings in general.
|
||||||
|
|
||||||
#### Inline Anchors
|
#### Inline Anchors
|
||||||
|
@ -102,6 +106,19 @@ The following are supported:
|
||||||
- [`note`](https://tdg.docbook.org/tdg/5.0/note.html)
|
- [`note`](https://tdg.docbook.org/tdg/5.0/note.html)
|
||||||
- [`tip`](https://tdg.docbook.org/tdg/5.0/tip.html)
|
- [`tip`](https://tdg.docbook.org/tdg/5.0/tip.html)
|
||||||
- [`warning`](https://tdg.docbook.org/tdg/5.0/warning.html)
|
- [`warning`](https://tdg.docbook.org/tdg/5.0/warning.html)
|
||||||
|
- [`example`](https://tdg.docbook.org/tdg/5.0/example.html)
|
||||||
|
|
||||||
|
Example admonitions require a title to work.
|
||||||
|
If you don't provide one, the manual won't be built.
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
::: {.example #ex-showing-an-example}
|
||||||
|
|
||||||
|
# Title for this example
|
||||||
|
|
||||||
|
Text for the example.
|
||||||
|
:::
|
||||||
|
```
|
||||||
|
|
||||||
#### [Definition lists](https://github.com/jgm/commonmark-hs/blob/master/commonmark-extensions/test/definition_lists.md)
|
#### [Definition lists](https://github.com/jgm/commonmark-hs/blob/master/commonmark-extensions/test/definition_lists.md)
|
||||||
|
|
||||||
|
@ -135,3 +152,54 @@ watermelon
|
||||||
Closes #216321.
|
Closes #216321.
|
||||||
|
|
||||||
- If the commit contains more than just documentation changes, follow the commit message format relevant for the rest of the changes.
|
- If the commit contains more than just documentation changes, follow the commit message format relevant for the rest of the changes.
|
||||||
|
|
||||||
|
## Documentation conventions
|
||||||
|
|
||||||
|
In an effort to keep the Nixpkgs manual in a consistent style, please follow the conventions below, unless they prevent you from properly documenting something.
|
||||||
|
In that case, please open an issue about the particular documentation convention and tag it with a "needs: documentation" label.
|
||||||
|
|
||||||
|
- Put each sentence in its own line.
|
||||||
|
This makes reviewing documentation much easier, since GitHub's review system is based on lines.
|
||||||
|
|
||||||
|
- Use the admonitions syntax for any callouts and examples (see [section above](#admonitions)).
|
||||||
|
|
||||||
|
- If you provide an example involving Nix code, make your example into a fully-working package (something that can be passed to `pkgs.callPackage`).
|
||||||
|
This will help others quickly test that the example works, and will also make it easier if we start automatically testing all example code to make sure it works.
|
||||||
|
For example, instead of providing something like:
|
||||||
|
|
||||||
|
```
|
||||||
|
pkgs.dockerTools.buildLayeredImage {
|
||||||
|
name = "hello";
|
||||||
|
contents = [ pkgs.hello ];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Provide something like:
|
||||||
|
|
||||||
|
```
|
||||||
|
{ dockerTools, hello }:
|
||||||
|
dockerTools.buildLayeredImage {
|
||||||
|
name = "hello";
|
||||||
|
contents = [ hello ];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Use [definition lists](#definition-lists) to document function arguments, and the attributes of such arguments. For example:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# pkgs.coolFunction
|
||||||
|
|
||||||
|
Description of what `coolFunction` does.
|
||||||
|
`coolFunction` expects a single argument which should be an attribute set, with the following possible attributes:
|
||||||
|
|
||||||
|
`name`
|
||||||
|
|
||||||
|
: The name of the resulting image.
|
||||||
|
|
||||||
|
`tag` _optional_
|
||||||
|
|
||||||
|
: Tag of the generated image.
|
||||||
|
|
||||||
|
_Default value:_ the output path's hash.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
|
@ -1,48 +1,167 @@
|
||||||
# pkgs.appimageTools {#sec-pkgs-appimageTools}
|
# pkgs.appimageTools {#sec-pkgs-appimageTools}
|
||||||
|
|
||||||
`pkgs.appimageTools` is a set of functions for extracting and wrapping [AppImage](https://appimage.org/) files. They are meant to be used if traditional packaging from source is infeasible, or it would take too long. To quickly run an AppImage file, `pkgs.appimage-run` can be used as well.
|
`pkgs.appimageTools` is a set of functions for extracting and wrapping [AppImage](https://appimage.org/) files.
|
||||||
|
They are meant to be used if traditional packaging from source is infeasible, or if it would take too long.
|
||||||
|
To quickly run an AppImage file, `pkgs.appimage-run` can be used as well.
|
||||||
|
|
||||||
::: {.warning}
|
::: {.warning}
|
||||||
The `appimageTools` API is unstable and may be subject to backwards-incompatible changes in the future.
|
The `appimageTools` API is unstable and may be subject to backwards-incompatible changes in the future.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## AppImage formats {#ssec-pkgs-appimageTools-formats}
|
|
||||||
|
|
||||||
There are different formats for AppImages, see [the specification](https://github.com/AppImage/AppImageSpec/blob/74ad9ca2f94bf864a4a0dac1f369dd4f00bd1c28/draft.md#image-format) for details.
|
|
||||||
|
|
||||||
- Type 1 images are ISO 9660 files that are also ELF executables.
|
|
||||||
- Type 2 images are ELF executables with an appended filesystem.
|
|
||||||
|
|
||||||
They can be told apart with `file -k`:
|
|
||||||
|
|
||||||
```ShellSession
|
|
||||||
$ file -k type1.AppImage
|
|
||||||
type1.AppImage: ELF 64-bit LSB executable, x86-64, version 1 (SYSV) ISO 9660 CD-ROM filesystem data 'AppImage' (Lepton 3.x), scale 0-0,
|
|
||||||
spot sensor temperature 0.000000, unit celsius, color scheme 0, calibration: offset 0.000000, slope 0.000000, dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.18, BuildID[sha1]=d629f6099d2344ad82818172add1d38c5e11bc6d, stripped\012- data
|
|
||||||
|
|
||||||
$ file -k type2.AppImage
|
|
||||||
type2.AppImage: ELF 64-bit LSB executable, x86-64, version 1 (SYSV) (Lepton 3.x), scale 232-60668, spot sensor temperature -4.187500, color scheme 15, show scale bar, calibration: offset -0.000000, slope 0.000000 (Lepton 2.x), scale 4111-45000, spot sensor temperature 412442.250000, color scheme 3, minimum point enabled, calibration: offset -75402534979642766821519867692934234112.000000, slope 5815371847733706829839455140374904832.000000, dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.18, BuildID[sha1]=79dcc4e55a61c293c5e19edbd8d65b202842579f, stripped\012- data
|
|
||||||
```
|
|
||||||
|
|
||||||
Note how the type 1 AppImage is described as an `ISO 9660 CD-ROM filesystem`, and the type 2 AppImage is not.
|
|
||||||
|
|
||||||
## Wrapping {#ssec-pkgs-appimageTools-wrapping}
|
## Wrapping {#ssec-pkgs-appimageTools-wrapping}
|
||||||
|
|
||||||
Depending on the type of AppImage you're wrapping, you'll have to use `wrapType1` or `wrapType2`.
|
Use `wrapType2` to wrap any AppImage.
|
||||||
|
This will create a FHS environment with many packages [expected to exist](https://github.com/AppImage/pkg2appimage/blob/master/excludelist) for the AppImage to work.
|
||||||
|
`wrapType2` expects an argument with the `src` attribute, and either a `name` attribute or `pname` and `version` attributes.
|
||||||
|
|
||||||
|
It will eventually call into [`buildFHSEnv`](#sec-fhs-environments), and any extra attributes in the argument to `wrapType2` will be passed through to it.
|
||||||
|
This means that you can pass the `extraInstallCommands` attribute, for example, and it will have the same effect as described in [`buildFHSEnv`](#sec-fhs-environments).
|
||||||
|
|
||||||
|
::: {.note}
|
||||||
|
In the past, `appimageTools` provided both `wrapType1` and `wrapType2`, to be used depending on the type of AppImage that was being wrapped.
|
||||||
|
However, [those were unified early 2020](https://github.com/NixOS/nixpkgs/pull/81833), meaning that both `wrapType1` and `wrapType2` have the same behaviour now.
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::{.example #ex-wrapping-appimage-from-github}
|
||||||
|
|
||||||
|
# Wrapping an AppImage from GitHub
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
appimageTools.wrapType2 { # or wrapType1
|
{ appimageTools, fetchurl }:
|
||||||
name = "patchwork";
|
let
|
||||||
|
pname = "nuclear";
|
||||||
|
version = "0.6.30";
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "https://github.com/ssbc/patchwork/releases/download/v3.11.4/Patchwork-3.11.4-linux-x86_64.AppImage";
|
url = "https://github.com/nukeop/nuclear/releases/download/v${version}/${pname}-v${version}.AppImage";
|
||||||
hash = "sha256-OqTitCeZ6xmWbqYTXp8sDrmVgTNjPZNW0hzUPW++mq4=";
|
hash = "sha256-he1uGC1M/nFcKpMM9JKY4oeexJcnzV0ZRxhTjtJz6xw=";
|
||||||
};
|
};
|
||||||
extraPkgs = pkgs: with pkgs; [ ];
|
in
|
||||||
|
appimageTools.wrapType2 {
|
||||||
|
inherit pname version src;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `name` specifies the name of the resulting image.
|
:::
|
||||||
- `src` specifies the AppImage file to extract.
|
|
||||||
- `extraPkgs` allows you to pass a function to include additional packages inside the FHS environment your AppImage is going to run in. There are a few ways to learn which dependencies an application needs:
|
The argument passed to `wrapType2` can also contain an `extraPkgs` attribute, which allows you to include additional packages inside the FHS environment your AppImage is going to run in.
|
||||||
- Looking through the extracted AppImage files, reading its scripts and running `patchelf` and `ldd` on its executables. This can also be done in `appimage-run`, by setting `APPIMAGE_DEBUG_EXEC=bash`.
|
`extraPkgs` must be a function that returns a list of packages.
|
||||||
|
There are a few ways to learn which dependencies an application needs:
|
||||||
|
|
||||||
|
- Looking through the extracted AppImage files, reading its scripts and running `patchelf` and `ldd` on its executables.
|
||||||
|
This can also be done in `appimage-run`, by setting `APPIMAGE_DEBUG_EXEC=bash`.
|
||||||
- Running `strace -vfefile` on the wrapped executable, looking for libraries that can't be found.
|
- Running `strace -vfefile` on the wrapped executable, looking for libraries that can't be found.
|
||||||
|
|
||||||
|
:::{.example #ex-wrapping-appimage-with-extrapkgs}
|
||||||
|
|
||||||
|
# Wrapping an AppImage with extra packages
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{ appimageTools, fetchurl }:
|
||||||
|
let
|
||||||
|
pname = "irccloud";
|
||||||
|
version = "0.16.0";
|
||||||
|
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://github.com/irccloud/irccloud-desktop/releases/download/v${version}/IRCCloud-${version}-linux-x86_64.AppImage";
|
||||||
|
sha256 = "sha256-/hMPvYdnVB1XjKgU2v47HnVvW4+uC3rhRjbucqin4iI=";
|
||||||
|
};
|
||||||
|
in appimageTools.wrapType2 {
|
||||||
|
inherit pname version src;
|
||||||
|
extraPkgs = pkgs: [ pkgs.at-spi2-core ];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Extracting {#ssec-pkgs-appimageTools-extracting}
|
||||||
|
|
||||||
|
Use `extract` if you need to extract the contents of an AppImage.
|
||||||
|
This is usually used in Nixpkgs to install extra files in addition to [wrapping](#ssec-pkgs-appimageTools-wrapping) the AppImage.
|
||||||
|
`extract` expects an argument with the `src` attribute, and either a `name` attribute or `pname` and `version` attributes.
|
||||||
|
|
||||||
|
::: {.note}
|
||||||
|
In the past, `appimageTools` provided both `extractType1` and `extractType2`, to be used depending on the type of AppImage that was being extracted.
|
||||||
|
However, [those were unified early 2020](https://github.com/NixOS/nixpkgs/pull/81572), meaning that both `extractType1` and `extractType2` have the same behaviour as `extract` now.
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::{.example #ex-extracting-appimage}
|
||||||
|
|
||||||
|
# Extracting an AppImage to install extra files
|
||||||
|
|
||||||
|
This example was adapted from a real package in Nixpkgs to show how `extract` is usually used in combination with `wrapType2`.
|
||||||
|
Note how `appimageContents` is used in `extraInstallCommands` to install additional files that were extracted from the AppImage.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{ appimageTools, fetchurl }:
|
||||||
|
let
|
||||||
|
pname = "irccloud";
|
||||||
|
version = "0.16.0";
|
||||||
|
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://github.com/irccloud/irccloud-desktop/releases/download/v${version}/IRCCloud-${version}-linux-x86_64.AppImage";
|
||||||
|
sha256 = "sha256-/hMPvYdnVB1XjKgU2v47HnVvW4+uC3rhRjbucqin4iI=";
|
||||||
|
};
|
||||||
|
|
||||||
|
appimageContents = appimageTools.extract {
|
||||||
|
inherit pname version src;
|
||||||
|
};
|
||||||
|
in appimageTools.wrapType2 {
|
||||||
|
inherit pname version src;
|
||||||
|
|
||||||
|
extraPkgs = pkgs: [ pkgs.at-spi2-core ];
|
||||||
|
|
||||||
|
extraInstallCommands = ''
|
||||||
|
mv $out/bin/${pname}-${version} $out/bin/${pname}
|
||||||
|
install -m 444 -D ${appimageContents}/irccloud.desktop $out/share/applications/irccloud.desktop
|
||||||
|
install -m 444 -D ${appimageContents}/usr/share/icons/hicolor/512x512/apps/irccloud.png \
|
||||||
|
$out/share/icons/hicolor/512x512/apps/irccloud.png
|
||||||
|
substituteInPlace $out/share/applications/irccloud.desktop \
|
||||||
|
--replace 'Exec=AppRun' 'Exec=${pname}'
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
The argument passed to `extract` can also contain a `postExtract` attribute, which allows you to execute additional commands after the files are extracted from the AppImage.
|
||||||
|
`postExtract` must be a string with commands to run.
|
||||||
|
|
||||||
|
:::{.example #ex-extracting-appimage-with-postextract}
|
||||||
|
|
||||||
|
# Extracting an AppImage to install extra files, using `postExtract`
|
||||||
|
|
||||||
|
This is a rewrite of [](#ex-extracting-appimage) to use `postExtract`.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{ appimageTools, fetchurl }:
|
||||||
|
let
|
||||||
|
pname = "irccloud";
|
||||||
|
version = "0.16.0";
|
||||||
|
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://github.com/irccloud/irccloud-desktop/releases/download/v${version}/IRCCloud-${version}-linux-x86_64.AppImage";
|
||||||
|
sha256 = "sha256-/hMPvYdnVB1XjKgU2v47HnVvW4+uC3rhRjbucqin4iI=";
|
||||||
|
};
|
||||||
|
|
||||||
|
appimageContents = appimageTools.extract {
|
||||||
|
inherit pname version src;
|
||||||
|
postExtract = ''
|
||||||
|
substituteInPlace $out/irccloud.desktop --replace 'Exec=AppRun' 'Exec=${pname}'
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in appimageTools.wrapType2 {
|
||||||
|
inherit pname version src;
|
||||||
|
|
||||||
|
extraPkgs = pkgs: [ pkgs.at-spi2-core ];
|
||||||
|
|
||||||
|
extraInstallCommands = ''
|
||||||
|
mv $out/bin/${pname}-${version} $out/bin/${pname}
|
||||||
|
install -m 444 -D ${appimageContents}/irccloud.desktop $out/share/applications/irccloud.desktop
|
||||||
|
install -m 444 -D ${appimageContents}/usr/share/icons/hicolor/512x512/apps/irccloud.png \
|
||||||
|
$out/share/icons/hicolor/512x512/apps/irccloud.png
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
|
@ -1,49 +1,58 @@
|
||||||
# pkgs.mkBinaryCache {#sec-pkgs-binary-cache}
|
# pkgs.mkBinaryCache {#sec-pkgs-binary-cache}
|
||||||
|
|
||||||
`pkgs.mkBinaryCache` is a function for creating Nix flat-file binary caches. Such a cache exists as a directory on disk, and can be used as a Nix substituter by passing `--substituter file:///path/to/cache` to Nix commands.
|
`pkgs.mkBinaryCache` is a function for creating Nix flat-file binary caches.
|
||||||
|
Such a cache exists as a directory on disk, and can be used as a Nix substituter by passing `--substituter file:///path/to/cache` to Nix commands.
|
||||||
|
|
||||||
Nix packages are most commonly shared between machines using [HTTP, SSH, or S3](https://nixos.org/manual/nix/stable/package-management/sharing-packages.html), but a flat-file binary cache can still be useful in some situations. For example, you can copy it directly to another machine, or make it available on a network file system. It can also be a convenient way to make some Nix packages available inside a container via bind-mounting.
|
Nix packages are most commonly shared between machines using [HTTP, SSH, or S3](https://nixos.org/manual/nix/stable/package-management/sharing-packages.html), but a flat-file binary cache can still be useful in some situations.
|
||||||
|
For example, you can copy it directly to another machine, or make it available on a network file system.
|
||||||
|
It can also be a convenient way to make some Nix packages available inside a container via bind-mounting.
|
||||||
|
|
||||||
Note that this function is meant for advanced use-cases. The more idiomatic way to work with flat-file binary caches is via the [nix-copy-closure](https://nixos.org/manual/nix/stable/command-ref/nix-copy-closure.html) command. You may also want to consider [dockerTools](#sec-pkgs-dockerTools) for your containerization needs.
|
`mkBinaryCache` expects an argument with the `rootPaths` attribute.
|
||||||
|
`rootPaths` must be a list of derivations.
|
||||||
|
The transitive closure of these derivations' outputs will be copied into the cache.
|
||||||
|
|
||||||
## Example {#sec-pkgs-binary-cache-example}
|
::: {.note}
|
||||||
|
This function is meant for advanced use cases.
|
||||||
|
The more idiomatic way to work with flat-file binary caches is via the [nix-copy-closure](https://nixos.org/manual/nix/stable/command-ref/nix-copy-closure.html) command.
|
||||||
|
You may also want to consider [dockerTools](#sec-pkgs-dockerTools) for your containerization needs.
|
||||||
|
:::
|
||||||
|
|
||||||
|
[]{#sec-pkgs-binary-cache-example}
|
||||||
|
:::{.example #ex-mkbinarycache-copying-package-closure}
|
||||||
|
|
||||||
|
# Copying a package and its closure to another machine with `mkBinaryCache`
|
||||||
|
|
||||||
The following derivation will construct a flat-file binary cache containing the closure of `hello`.
|
The following derivation will construct a flat-file binary cache containing the closure of `hello`.
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
|
{ mkBinaryCache, hello }:
|
||||||
mkBinaryCache {
|
mkBinaryCache {
|
||||||
rootPaths = [hello];
|
rootPaths = [hello];
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `rootPaths` specifies a list of root derivations. The transitive closure of these derivations' outputs will be copied into the cache.
|
Build the cache on a machine.
|
||||||
|
Note that the command still builds the exact nix package above, but adds some boilerplate to build it directly from an expression.
|
||||||
Here's an example of building and using the cache.
|
|
||||||
|
|
||||||
Build the cache on one machine, `host1`:
|
|
||||||
|
|
||||||
```shellSession
|
```shellSession
|
||||||
nix-build -E 'with import <nixpkgs> {}; mkBinaryCache { rootPaths = [hello]; }'
|
$ nix-build -E 'let pkgs = import <nixpkgs> {}; in pkgs.callPackage ({ mkBinaryCache, hello }: mkBinaryCache { rootPaths = [hello]; }) {}'
|
||||||
|
/nix/store/azf7xay5xxdnia4h9fyjiv59wsjdxl0g-binary-cache
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Copy the resulting directory to another machine, which we'll call `host2`:
|
||||||
|
|
||||||
```shellSession
|
```shellSession
|
||||||
/nix/store/cc0562q828rnjqjyfj23d5q162gb424g-binary-cache
|
$ scp result host2:/tmp/hello-cache
|
||||||
```
|
```
|
||||||
|
|
||||||
Copy the resulting directory to the other machine, `host2`:
|
At this point, the cache can be used as a substituter when building derivations on `host2`:
|
||||||
|
|
||||||
```shellSession
|
```shellSession
|
||||||
scp result host2:/tmp/hello-cache
|
$ nix-build -A hello '<nixpkgs>' \
|
||||||
```
|
|
||||||
|
|
||||||
Substitute the derivation using the flat-file binary cache on the other machine, `host2`:
|
|
||||||
```shellSession
|
|
||||||
nix-build -A hello '<nixpkgs>' \
|
|
||||||
--option require-sigs false \
|
--option require-sigs false \
|
||||||
--option trusted-substituters file:///tmp/hello-cache \
|
--option trusted-substituters file:///tmp/hello-cache \
|
||||||
--option substituters file:///tmp/hello-cache
|
--option substituters file:///tmp/hello-cache
|
||||||
|
/nix/store/zhl06z4lrfrkw5rp0hnjjfrgsclzvxpm-hello-2.12.1
|
||||||
```
|
```
|
||||||
|
|
||||||
```shellSession
|
:::
|
||||||
/nix/store/gl5a41azbpsadfkfmbilh9yk40dh5dl0-hello-2.12.1
|
|
||||||
```
|
|
||||||
|
|
|
@ -7,4 +7,5 @@ special/fhs-environments.section.md
|
||||||
special/makesetuphook.section.md
|
special/makesetuphook.section.md
|
||||||
special/mkshell.section.md
|
special/mkshell.section.md
|
||||||
special/vm-tools.section.md
|
special/vm-tools.section.md
|
||||||
|
special/checkpoint-build.section.md
|
||||||
```
|
```
|
||||||
|
|
36
doc/build-helpers/special/checkpoint-build.section.md
Normal file
36
doc/build-helpers/special/checkpoint-build.section.md
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# pkgs.checkpointBuildTools {#sec-checkpoint-build}
|
||||||
|
|
||||||
|
`pkgs.checkpointBuildTools` provides a way to build derivations incrementally. It consists of two functions to make checkpoint builds using Nix possible.
|
||||||
|
|
||||||
|
For hermeticity, Nix derivations do not allow any state to carry over between builds, making a transparent incremental build within a derivation impossible.
|
||||||
|
|
||||||
|
However, we can tell Nix explicitly what the previous build state was, by representing that previous state as a derivation output. This allows the passed build state to be used for an incremental build.
|
||||||
|
|
||||||
|
To change a normal derivation to a checkpoint based build, these steps must be taken:
|
||||||
|
- apply `prepareCheckpointBuild` on the desired derivation
|
||||||
|
e.g.:
|
||||||
|
```nix
|
||||||
|
checkpointArtifacts = (pkgs.checkpointBuildTools.prepareCheckpointBuild pkgs.virtualbox);
|
||||||
|
```
|
||||||
|
- change something you want in the sources of the package. (e.g. using a source override)
|
||||||
|
```nix
|
||||||
|
changedVBox = pkgs.virtualbox.overrideAttrs (old: {
|
||||||
|
src = path/to/vbox/sources;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- use `mkCheckpointedBuild changedVBox buildOutput`
|
||||||
|
- enjoy shorter build times
|
||||||
|
|
||||||
|
## Example {#sec-checkpoint-build-example}
|
||||||
|
```nix
|
||||||
|
{ pkgs ? import <nixpkgs> {} }: with (pkgs) checkpointBuildTools;
|
||||||
|
let
|
||||||
|
helloCheckpoint = checkpointBuildTools.prepareCheckpointBuild pkgs.hello;
|
||||||
|
changedHello = pkgs.hello.overrideAttrs (_: {
|
||||||
|
doCheck = false;
|
||||||
|
patchPhase = ''
|
||||||
|
sed -i 's/Hello, world!/Hello, Nix!/g' src/hello.c
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
in checkpointBuildTools.mkCheckpointBuild changedHello helloCheckpoint
|
||||||
|
```
|
|
@ -1,4 +1,5 @@
|
||||||
# Testers {#chap-testers}
|
# Testers {#chap-testers}
|
||||||
|
|
||||||
This chapter describes several testing builders which are available in the `testers` namespace.
|
This chapter describes several testing builders which are available in the `testers` namespace.
|
||||||
|
|
||||||
## `hasPkgConfigModules` {#tester-hasPkgConfigModules}
|
## `hasPkgConfigModules` {#tester-hasPkgConfigModules}
|
||||||
|
@ -6,19 +7,11 @@ This chapter describes several testing builders which are available in the `test
|
||||||
<!-- Old anchor name so links still work -->
|
<!-- Old anchor name so links still work -->
|
||||||
[]{#tester-hasPkgConfigModule}
|
[]{#tester-hasPkgConfigModule}
|
||||||
Checks whether a package exposes a given list of `pkg-config` modules.
|
Checks whether a package exposes a given list of `pkg-config` modules.
|
||||||
If the `moduleNames` argument is omitted, `hasPkgConfigModules` will
|
If the `moduleNames` argument is omitted, `hasPkgConfigModules` will use `meta.pkgConfigModules`.
|
||||||
use `meta.pkgConfigModules`.
|
|
||||||
|
|
||||||
Example:
|
:::{.example #ex-haspkgconfigmodules-defaultvalues}
|
||||||
|
|
||||||
```nix
|
# Check that `pkg-config` modules are exposed using default values
|
||||||
passthru.tests.pkg-config = testers.hasPkgConfigModules {
|
|
||||||
package = finalAttrs.finalPackage;
|
|
||||||
moduleNames = [ "libfoo" ];
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
If the package in question has `meta.pkgConfigModules` set, it is even simpler:
|
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
passthru.tests.pkg-config = testers.hasPkgConfigModules {
|
passthru.tests.pkg-config = testers.hasPkgConfigModules {
|
||||||
|
@ -28,40 +21,66 @@ passthru.tests.pkg-config = testers.hasPkgConfigModules {
|
||||||
meta.pkgConfigModules = [ "libfoo" ];
|
meta.pkgConfigModules = [ "libfoo" ];
|
||||||
```
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::{.example #ex-haspkgconfigmodules-explicitmodules}
|
||||||
|
|
||||||
|
# Check that `pkg-config` modules are exposed using explicit module names
|
||||||
|
|
||||||
|
```nix
|
||||||
|
passthru.tests.pkg-config = testers.hasPkgConfigModules {
|
||||||
|
package = finalAttrs.finalPackage;
|
||||||
|
moduleNames = [ "libfoo" ];
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
## `testVersion` {#tester-testVersion}
|
## `testVersion` {#tester-testVersion}
|
||||||
|
|
||||||
Checks the command output contains the specified version
|
Checks that the output from running a command contains the specified version string in it as a whole word.
|
||||||
|
|
||||||
Although simplistic, this test assures that the main program
|
Although simplistic, this test assures that the main program can run.
|
||||||
can run. While there's no substitute for a real test case,
|
While there's no substitute for a real test case, it does catch dynamic linking errors and such.
|
||||||
it does catch dynamic linking errors and such. It also provides
|
It also provides some protection against accidentally building the wrong version, for example when using an "old" hash in a fixed-output derivation.
|
||||||
some protection against accidentally building the wrong version,
|
|
||||||
for example when using an 'old' hash in a fixed-output derivation.
|
|
||||||
|
|
||||||
Examples:
|
By default, the command to be run will be inferred from the given `package` attribute:
|
||||||
|
it will check `meta.mainProgram` first, and fall back to `pname` or `name`.
|
||||||
|
The default argument to the command is `--version`, and the version to be checked will be inferred from the given `package` attribute as well.
|
||||||
|
|
||||||
|
:::{.example #ex-testversion-hello}
|
||||||
|
|
||||||
|
# Check a program version using all the default values
|
||||||
|
|
||||||
|
This example will run the command `hello --version`, and then check that the version of the `hello` package is in the output of the command.
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
passthru.tests.version = testers.testVersion { package = hello; };
|
passthru.tests.version = testers.testVersion { package = hello; };
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::{.example #ex-testversion-different-commandversion}
|
||||||
|
|
||||||
|
# Check the program version using a specified command and expected version string
|
||||||
|
|
||||||
|
This example will run the command `leetcode -V`, and then check that `leetcode 0.4.2` is in the output of the command as a whole word (separated by whitespaces).
|
||||||
|
This means that an output like "leetcode 0.4.21" would fail the tests, and an output like "You're running leetcode 0.4.2" would pass the tests.
|
||||||
|
|
||||||
|
A common usage of the `version` attribute is to specify `version = "v${version}"`.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
version = "0.4.2";
|
||||||
|
|
||||||
passthru.tests.version = testers.testVersion {
|
passthru.tests.version = testers.testVersion {
|
||||||
package = seaweedfs;
|
package = leetcode-cli;
|
||||||
command = "weed version";
|
command = "leetcode -V";
|
||||||
};
|
version = "leetcode ${version}";
|
||||||
|
|
||||||
passthru.tests.version = testers.testVersion {
|
|
||||||
package = key;
|
|
||||||
command = "KeY --help";
|
|
||||||
# Wrong '2.5' version in the code. Drop on next version.
|
|
||||||
version = "2.5";
|
|
||||||
};
|
|
||||||
|
|
||||||
passthru.tests.version = testers.testVersion {
|
|
||||||
package = ghr;
|
|
||||||
# The output needs to contain the 'version' string without any prefix or suffix.
|
|
||||||
version = "v${version}";
|
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
## `testBuildFailure` {#tester-testBuildFailure}
|
## `testBuildFailure` {#tester-testBuildFailure}
|
||||||
|
|
||||||
Make sure that a build does not succeed. This is useful for testing testers.
|
Make sure that a build does not succeed. This is useful for testing testers.
|
||||||
|
@ -72,7 +91,18 @@ This returns a derivation with an override on the builder, with the following ef
|
||||||
- Move `$out` to `$out/result`, if it exists (assuming `out` is the default output)
|
- Move `$out` to `$out/result`, if it exists (assuming `out` is the default output)
|
||||||
- Save the build log to `$out/testBuildFailure.log` (same)
|
- Save the build log to `$out/testBuildFailure.log` (same)
|
||||||
|
|
||||||
Example:
|
While `testBuildFailure` is designed to keep changes to the original builder's environment to a minimum, some small changes are inevitable:
|
||||||
|
|
||||||
|
- The file `$TMPDIR/testBuildFailure.log` is present. It should not be deleted.
|
||||||
|
- `stdout` and `stderr` are a pipe instead of a tty. This could be improved.
|
||||||
|
- One or two extra processes are present in the sandbox during the original builder's execution.
|
||||||
|
- The derivation and output hashes are different, but not unusual.
|
||||||
|
- The derivation includes a dependency on `buildPackages.bash` and `expect-failure.sh`, which is built to include a transitive dependency on `buildPackages.coreutils` and possibly more.
|
||||||
|
These are not added to `PATH` or any other environment variable, so they should be hard to observe.
|
||||||
|
|
||||||
|
:::{.example #ex-testBuildFailure-showingenvironmentchanges}
|
||||||
|
|
||||||
|
# Check that a build fails, and verify the changes made during build
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
runCommand "example" {
|
runCommand "example" {
|
||||||
|
@ -89,24 +119,15 @@ runCommand "example" {
|
||||||
'';
|
'';
|
||||||
```
|
```
|
||||||
|
|
||||||
While `testBuildFailure` is designed to keep changes to the original builder's
|
:::
|
||||||
environment to a minimum, some small changes are inevitable.
|
|
||||||
|
|
||||||
- The file `$TMPDIR/testBuildFailure.log` is present. It should not be deleted.
|
|
||||||
- `stdout` and `stderr` are a pipe instead of a tty. This could be improved.
|
|
||||||
- One or two extra processes are present in the sandbox during the original
|
|
||||||
builder's execution.
|
|
||||||
- The derivation and output hashes are different, but not unusual.
|
|
||||||
- The derivation includes a dependency on `buildPackages.bash` and
|
|
||||||
`expect-failure.sh`, which is built to include a transitive dependency on
|
|
||||||
`buildPackages.coreutils` and possibly more. These are not added to `PATH`
|
|
||||||
or any other environment variable, so they should be hard to observe.
|
|
||||||
|
|
||||||
## `testEqualContents` {#tester-equalContents}
|
## `testEqualContents` {#tester-equalContents}
|
||||||
|
|
||||||
Check that two paths have the same contents.
|
Check that two paths have the same contents.
|
||||||
|
|
||||||
Example:
|
:::{.example #ex-testEqualContents-toyexample}
|
||||||
|
|
||||||
|
# Check that two paths have the same contents
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
testers.testEqualContents {
|
testers.testEqualContents {
|
||||||
|
@ -126,17 +147,20 @@ testers.testEqualContents {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
## `testEqualDerivation` {#tester-testEqualDerivation}
|
## `testEqualDerivation` {#tester-testEqualDerivation}
|
||||||
|
|
||||||
Checks that two packages produce the exact same build instructions.
|
Checks that two packages produce the exact same build instructions.
|
||||||
|
|
||||||
This can be used to make sure that a certain difference of configuration,
|
This can be used to make sure that a certain difference of configuration, such as the presence of an overlay does not cause a cache miss.
|
||||||
such as the presence of an overlay does not cause a cache miss.
|
|
||||||
|
|
||||||
When the derivations are equal, the return value is an empty file.
|
When the derivations are equal, the return value is an empty file.
|
||||||
Otherwise, the build log explains the difference via `nix-diff`.
|
Otherwise, the build log explains the difference via `nix-diff`.
|
||||||
|
|
||||||
Example:
|
:::{.example #ex-testEqualDerivation-hello}
|
||||||
|
|
||||||
|
# Check that two packages produce the same derivation
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
testers.testEqualDerivation
|
testers.testEqualDerivation
|
||||||
|
@ -145,29 +169,28 @@ testers.testEqualDerivation
|
||||||
(hello.overrideAttrs(o: { doCheck = true; }))
|
(hello.overrideAttrs(o: { doCheck = true; }))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
## `invalidateFetcherByDrvHash` {#tester-invalidateFetcherByDrvHash}
|
## `invalidateFetcherByDrvHash` {#tester-invalidateFetcherByDrvHash}
|
||||||
|
|
||||||
Use the derivation hash to invalidate the output via name, for testing.
|
Use the derivation hash to invalidate the output via name, for testing.
|
||||||
|
|
||||||
Type: `(a@{ name, ... } -> Derivation) -> a -> Derivation`
|
Type: `(a@{ name, ... } -> Derivation) -> a -> Derivation`
|
||||||
|
|
||||||
Normally, fixed output derivations can and should be cached by their output
|
Normally, fixed output derivations can and should be cached by their output hash only, but for testing we want to re-fetch everytime the fetcher changes.
|
||||||
hash only, but for testing we want to re-fetch everytime the fetcher changes.
|
|
||||||
|
|
||||||
Changes to the fetcher become apparent in the drvPath, which is a hash of
|
Changes to the fetcher become apparent in the drvPath, which is a hash of how to fetch, rather than a fixed store path.
|
||||||
how to fetch, rather than a fixed store path.
|
By inserting this hash into the name, we can make sure to re-run the fetcher every time the fetcher changes.
|
||||||
By inserting this hash into the name, we can make sure to re-run the fetcher
|
|
||||||
every time the fetcher changes.
|
|
||||||
|
|
||||||
This relies on the assumption that Nix isn't clever enough to reuse its
|
This relies on the assumption that Nix isn't clever enough to reuse its database of local store contents to optimize fetching.
|
||||||
database of local store contents to optimize fetching.
|
|
||||||
|
|
||||||
You might notice that the "salted" name derives from the normal invocation,
|
You might notice that the "salted" name derives from the normal invocation, not the final derivation.
|
||||||
not the final derivation. `invalidateFetcherByDrvHash` has to invoke the fetcher
|
`invalidateFetcherByDrvHash` has to invoke the fetcher function twice:
|
||||||
function twice: once to get a derivation hash, and again to produce the final
|
once to get a derivation hash, and again to produce the final fixed output derivation.
|
||||||
fixed output derivation.
|
|
||||||
|
|
||||||
Example:
|
:::{.example #ex-invalidateFetcherByDrvHash-nix}
|
||||||
|
|
||||||
|
# Prevent nix from reusing the output of a fetcher
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
tests.fetchgit = testers.invalidateFetcherByDrvHash fetchgit {
|
tests.fetchgit = testers.invalidateFetcherByDrvHash fetchgit {
|
||||||
|
@ -178,13 +201,17 @@ tests.fetchgit = testers.invalidateFetcherByDrvHash fetchgit {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
## `runNixOSTest` {#tester-runNixOSTest}
|
## `runNixOSTest` {#tester-runNixOSTest}
|
||||||
|
|
||||||
A helper function that behaves exactly like the NixOS `runTest`, except it also assigns this Nixpkgs package set as the `pkgs` of the test and makes the `nixpkgs.*` options read-only.
|
A helper function that behaves exactly like the NixOS `runTest`, except it also assigns this Nixpkgs package set as the `pkgs` of the test and makes the `nixpkgs.*` options read-only.
|
||||||
|
|
||||||
If your test is part of the Nixpkgs repository, or if you need a more general entrypoint, see ["Calling a test" in the NixOS manual](https://nixos.org/manual/nixos/stable/index.html#sec-calling-nixos-tests).
|
If your test is part of the Nixpkgs repository, or if you need a more general entrypoint, see ["Calling a test" in the NixOS manual](https://nixos.org/manual/nixos/stable/index.html#sec-calling-nixos-tests).
|
||||||
|
|
||||||
Example:
|
:::{.example #ex-runNixOSTest-hello}
|
||||||
|
|
||||||
|
# Run a NixOS test using `runNixOSTest`
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
pkgs.testers.runNixOSTest ({ lib, ... }: {
|
pkgs.testers.runNixOSTest ({ lib, ... }: {
|
||||||
|
@ -198,19 +225,17 @@ pkgs.testers.runNixOSTest ({ lib, ... }: {
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
## `nixosTest` {#tester-nixosTest}
|
## `nixosTest` {#tester-nixosTest}
|
||||||
|
|
||||||
Run a NixOS VM network test using this evaluation of Nixpkgs.
|
Run a NixOS VM network test using this evaluation of Nixpkgs.
|
||||||
|
|
||||||
NOTE: This function is primarily for external use. NixOS itself uses `make-test-python.nix` directly. Packages defined in Nixpkgs [reuse NixOS tests via `nixosTests`, plural](#ssec-nixos-tests-linking).
|
NOTE: This function is primarily for external use. NixOS itself uses `make-test-python.nix` directly. Packages defined in Nixpkgs [reuse NixOS tests via `nixosTests`, plural](#ssec-nixos-tests-linking).
|
||||||
|
|
||||||
It is mostly equivalent to the function `import ./make-test-python.nix` from the
|
It is mostly equivalent to the function `import ./make-test-python.nix` from the [NixOS manual](https://nixos.org/nixos/manual/index.html#sec-nixos-tests), except that the current application of Nixpkgs (`pkgs`) will be used, instead of letting NixOS invoke Nixpkgs anew.
|
||||||
[NixOS manual](https://nixos.org/nixos/manual/index.html#sec-nixos-tests),
|
|
||||||
except that the current application of Nixpkgs (`pkgs`) will be used, instead of
|
|
||||||
letting NixOS invoke Nixpkgs anew.
|
|
||||||
|
|
||||||
If a test machine needs to set NixOS options under `nixpkgs`, it must set only the
|
If a test machine needs to set NixOS options under `nixpkgs`, it must set only the `nixpkgs.pkgs` option.
|
||||||
`nixpkgs.pkgs` option.
|
|
||||||
|
|
||||||
### Parameter {#tester-nixosTest-parameter}
|
### Parameter {#tester-nixosTest-parameter}
|
||||||
|
|
||||||
|
|
|
@ -149,4 +149,26 @@ in pkgs.stdenv.mkDerivation {
|
||||||
echo "doc manual $dest ${common.indexPath}" >> $out/nix-support/hydra-build-products
|
echo "doc manual $dest ${common.indexPath}" >> $out/nix-support/hydra-build-products
|
||||||
echo "doc manual $dest nixpkgs-manual.epub" >> $out/nix-support/hydra-build-products
|
echo "doc manual $dest nixpkgs-manual.epub" >> $out/nix-support/hydra-build-products
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
passthru.tests.manpage-urls = with pkgs; testers.invalidateFetcherByDrvHash
|
||||||
|
({ name ? "manual_check-manpage-urls"
|
||||||
|
, script
|
||||||
|
, urlsFile
|
||||||
|
}: runCommand name {
|
||||||
|
nativeBuildInputs = [
|
||||||
|
cacert
|
||||||
|
(python3.withPackages (p: with p; [
|
||||||
|
aiohttp
|
||||||
|
rich
|
||||||
|
structlog
|
||||||
|
]))
|
||||||
|
];
|
||||||
|
outputHash = "sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="; # Empty output
|
||||||
|
} ''
|
||||||
|
python3 ${script} ${urlsFile}
|
||||||
|
touch $out
|
||||||
|
'') {
|
||||||
|
script = ./tests/manpage-urls.py;
|
||||||
|
urlsFile = ./manpage-urls.json;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,16 +68,45 @@ All new projects should use the CUDA redistributables available in [`cudaPackage
|
||||||
### Updating CUDA redistributables {#updating-cuda-redistributables}
|
### Updating CUDA redistributables {#updating-cuda-redistributables}
|
||||||
|
|
||||||
1. Go to NVIDIA's index of CUDA redistributables: <https://developer.download.nvidia.com/compute/cuda/redist/>
|
1. Go to NVIDIA's index of CUDA redistributables: <https://developer.download.nvidia.com/compute/cuda/redist/>
|
||||||
2. Copy the `redistrib_*.json` corresponding to the release to `pkgs/development/compilers/cudatoolkit/redist/manifests`.
|
2. Make a note of the new version of CUDA available.
|
||||||
3. Generate the `redistrib_features_*.json` file by running:
|
3. Run
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
nix run github:ConnorBaker/cuda-redist-find-features -- <path to manifest>
|
nix run github:connorbaker/cuda-redist-find-features -- \
|
||||||
```
|
download-manifests \
|
||||||
|
--log-level DEBUG \
|
||||||
|
--version <newest CUDA version> \
|
||||||
|
https://developer.download.nvidia.com/compute/cuda/redist \
|
||||||
|
./pkgs/development/cuda-modules/cuda/manifests
|
||||||
|
```
|
||||||
|
|
||||||
That command will generate the `redistrib_features_*.json` file in the same directory as the manifest.
|
This will download a copy of the manifest for the new version of CUDA.
|
||||||
|
4. Run
|
||||||
|
|
||||||
4. Include the path to the new manifest in `pkgs/development/compilers/cudatoolkit/redist/extension.nix`.
|
```bash
|
||||||
|
nix run github:connorbaker/cuda-redist-find-features -- \
|
||||||
|
process-manifests \
|
||||||
|
--log-level DEBUG \
|
||||||
|
--version <newest CUDA version> \
|
||||||
|
https://developer.download.nvidia.com/compute/cuda/redist \
|
||||||
|
./pkgs/development/cuda-modules/cuda/manifests
|
||||||
|
```
|
||||||
|
|
||||||
|
This will generate a `redistrib_features_<newest CUDA version>.json` file in the same directory as the manifest.
|
||||||
|
5. Update the `cudaVersionMap` attribute set in `pkgs/development/cuda-modules/cuda/extension.nix`.
|
||||||
|
|
||||||
|
### Updating cuTensor {#updating-cutensor}
|
||||||
|
|
||||||
|
1. Repeat the steps present in [Updating CUDA redistributables](#updating-cuda-redistributables) with the following changes:
|
||||||
|
- Use the index of cuTensor redistributables: <https://developer.download.nvidia.com/compute/cutensor/redist>
|
||||||
|
- Use the newest version of cuTensor available instead of the newest version of CUDA.
|
||||||
|
- Use `pkgs/development/cuda-modules/cutensor/manifests` instead of `pkgs/development/cuda-modules/cuda/manifests`.
|
||||||
|
- Skip the step of updating `cudaVersionMap` in `pkgs/development/cuda-modules/cuda/extension.nix`.
|
||||||
|
|
||||||
|
### Updating supported compilers and GPUs {#updating-supported-compilers-and-gpus}
|
||||||
|
|
||||||
|
1. Update `nvcc-compatibilities.nix` in `pkgs/development/cuda-modules/` to include the newest release of NVCC, as well as any newly supported host compilers.
|
||||||
|
2. Update `gpus.nix` in `pkgs/development/cuda-modules/` to include any new GPUs supported by the new release of CUDA.
|
||||||
|
|
||||||
### Updating the CUDA Toolkit runfile installer {#updating-the-cuda-toolkit}
|
### Updating the CUDA Toolkit runfile installer {#updating-the-cuda-toolkit}
|
||||||
|
|
||||||
|
@ -99,7 +128,7 @@ All new projects should use the CUDA redistributables available in [`cudaPackage
|
||||||
nix store prefetch-file --hash-type sha256 <link>
|
nix store prefetch-file --hash-type sha256 <link>
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Update `pkgs/development/compilers/cudatoolkit/versions.toml` to include the release.
|
4. Update `pkgs/development/cuda-modules/cudatoolkit/releases.nix` to include the release.
|
||||||
|
|
||||||
### Updating the CUDA package set {#updating-the-cuda-package-set}
|
### Updating the CUDA package set {#updating-the-cuda-package-set}
|
||||||
|
|
||||||
|
@ -107,7 +136,7 @@ All new projects should use the CUDA redistributables available in [`cudaPackage
|
||||||
|
|
||||||
- NOTE: Changing the default CUDA package set should occur in a separate PR, allowing time for additional testing.
|
- NOTE: Changing the default CUDA package set should occur in a separate PR, allowing time for additional testing.
|
||||||
|
|
||||||
2. Successfully build the closure of the new package set, updating `pkgs/development/compilers/cudatoolkit/redist/overrides.nix` as needed. Below are some common failures:
|
2. Successfully build the closure of the new package set, updating `pkgs/development/cuda-modules/cuda/overrides.nix` as needed. Below are some common failures:
|
||||||
|
|
||||||
| Unable to ... | During ... | Reason | Solution | Note |
|
| Unable to ... | During ... | Reason | Solution | Note |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
|
|
|
@ -4,22 +4,21 @@
|
||||||
|
|
||||||
The function `buildDartApplication` builds Dart applications managed with pub.
|
The function `buildDartApplication` builds Dart applications managed with pub.
|
||||||
|
|
||||||
It fetches its Dart dependencies automatically through `fetchDartDeps`, and (through a series of hooks) builds and installs the executables specified in the pubspec file. The hooks can be used in other derivations, if needed. The phases can also be overridden to do something different from installing binaries.
|
It fetches its Dart dependencies automatically through `pub2nix`, and (through a series of hooks) builds and installs the executables specified in the pubspec file. The hooks can be used in other derivations, if needed. The phases can also be overridden to do something different from installing binaries.
|
||||||
|
|
||||||
If you are packaging a Flutter desktop application, use [`buildFlutterApplication`](#ssec-dart-flutter) instead.
|
If you are packaging a Flutter desktop application, use [`buildFlutterApplication`](#ssec-dart-flutter) instead.
|
||||||
|
|
||||||
`vendorHash`: is the hash of the output of the dependency fetcher derivation. To obtain it, set it to `lib.fakeHash` (or omit it) and run the build ([more details here](#sec-source-hashes)).
|
`pubspecLock` is the parsed pubspec.lock file. pub2nix uses this to download required packages.
|
||||||
|
This can be converted to JSON from YAML with something like `yq . pubspec.lock`, and then read by Nix.
|
||||||
|
|
||||||
If the upstream source is missing a `pubspec.lock` file, you'll have to vendor one and specify it using `pubspecLockFile`. If it is needed, one will be generated for you and printed when attempting to build the derivation.
|
If the package has Git package dependencies, the hashes must be provided in the `gitHashes` set. If a hash is missing, an error message prompting you to add it will be shown.
|
||||||
|
|
||||||
The `depsListFile` must always be provided when packaging in Nixpkgs. It will be generated and printed if the derivation is attempted to be built without one. Alternatively, `autoDepsList` may be set to `true` only when outside of Nixpkgs, as it relies on import-from-derivation.
|
|
||||||
|
|
||||||
The `dart` commands run can be overridden through `pubGetScript` and `dartCompileCommand`, you can also add flags using `dartCompileFlags` or `dartJitFlags`.
|
The `dart` commands run can be overridden through `pubGetScript` and `dartCompileCommand`, you can also add flags using `dartCompileFlags` or `dartJitFlags`.
|
||||||
|
|
||||||
Dart supports multiple [outputs types](https://dart.dev/tools/dart-compile#types-of-output), you can choose between them using `dartOutputType` (defaults to `exe`). If you want to override the binaries path or the source path they come from, you can use `dartEntryPoints`. Outputs that require a runtime will automatically be wrapped with the relevant runtime (`dartaotruntime` for `aot-snapshot`, `dart run` for `jit-snapshot` and `kernel`, `node` for `js`), this can be overridden through `dartRuntimeCommand`.
|
Dart supports multiple [outputs types](https://dart.dev/tools/dart-compile#types-of-output), you can choose between them using `dartOutputType` (defaults to `exe`). If you want to override the binaries path or the source path they come from, you can use `dartEntryPoints`. Outputs that require a runtime will automatically be wrapped with the relevant runtime (`dartaotruntime` for `aot-snapshot`, `dart run` for `jit-snapshot` and `kernel`, `node` for `js`), this can be overridden through `dartRuntimeCommand`.
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
{ buildDartApplication, fetchFromGitHub }:
|
{ lib, buildDartApplication, fetchFromGitHub }:
|
||||||
|
|
||||||
buildDartApplication rec {
|
buildDartApplication rec {
|
||||||
pname = "dart-sass";
|
pname = "dart-sass";
|
||||||
|
@ -32,12 +31,53 @@ buildDartApplication rec {
|
||||||
hash = "sha256-U6enz8yJcc4Wf8m54eYIAnVg/jsGi247Wy8lp1r1wg4=";
|
hash = "sha256-U6enz8yJcc4Wf8m54eYIAnVg/jsGi247Wy8lp1r1wg4=";
|
||||||
};
|
};
|
||||||
|
|
||||||
pubspecLockFile = ./pubspec.lock;
|
pubspecLock = lib.importJSON ./pubspec.lock.json;
|
||||||
depsListFile = ./deps.json;
|
|
||||||
vendorHash = "sha256-Atm7zfnDambN/BmmUf4BG0yUz/y6xWzf0reDw3Ad41s=";
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Patching dependencies {#ssec-dart-applications-patching-dependencies}
|
||||||
|
|
||||||
|
Some Dart packages require patches or build environment changes. Package derivations can be customised with the `customSourceBuilders` argument.
|
||||||
|
|
||||||
|
A collection of such customisations can be found in Nixpkgs, in the `development/compilers/dart/package-source-builders` directory.
|
||||||
|
|
||||||
|
This allows fixes for packages to be shared between all applications that use them. It is strongly recommended to add to this collection instead of including fixes in your application derivation itself.
|
||||||
|
|
||||||
|
### Running executables from dev_dependencies {#ssec-dart-applications-build-tools}
|
||||||
|
|
||||||
|
Many Dart applications require executables from the `dev_dependencies` section in `pubspec.yaml` to be run before building them.
|
||||||
|
|
||||||
|
This can be done in `preBuild`, in one of two ways:
|
||||||
|
|
||||||
|
1. Packaging the tool with `buildDartApplication`, adding it to Nixpkgs, and running it like any other application
|
||||||
|
2. Running the tool from the package cache
|
||||||
|
|
||||||
|
Of these methods, the first is recommended when using a tool that does not need
|
||||||
|
to be of a specific version.
|
||||||
|
|
||||||
|
For the second method, the `packageRun` function from the `dartConfigHook` can be used.
|
||||||
|
This is an alternative to `dart run` that does not rely on Pub.
|
||||||
|
|
||||||
|
e.g., for `build_runner`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
packageRun build_runner build
|
||||||
|
```
|
||||||
|
|
||||||
|
Do _not_ use `dart run <package_name>`, as this will attempt to download dependencies with Pub.
|
||||||
|
|
||||||
|
### Usage with nix-shell {#ssec-dart-applications-nix-shell}
|
||||||
|
|
||||||
|
As `buildDartApplication` provides dependencies instead of `pub get`, Dart needs to be explicitly told where to find them.
|
||||||
|
|
||||||
|
Run the following commands in the source directory to configure Dart appropriately.
|
||||||
|
Do not use `pub` after doing so; it will download the dependencies itself and overwrite these changes.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp --no-preserve=all "$pubspecLockFilePath" pubspec.lock
|
||||||
|
mkdir -p .dart_tool && cp --no-preserve=all "$packageConfig" .dart_tool/package_config.json
|
||||||
|
```
|
||||||
|
|
||||||
## Flutter applications {#ssec-dart-flutter}
|
## Flutter applications {#ssec-dart-flutter}
|
||||||
|
|
||||||
The function `buildFlutterApplication` builds Flutter applications.
|
The function `buildFlutterApplication` builds Flutter applications.
|
||||||
|
@ -59,8 +99,10 @@ flutter.buildFlutterApplication {
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
pubspecLockFile = ./pubspec.lock;
|
pubspecLock = lib.importJSON ./pubspec.lock.json;
|
||||||
depsListFile = ./deps.json;
|
|
||||||
vendorHash = "sha256-cdMO+tr6kYiN5xKXa+uTMAcFf2C75F3wVPrn21G4QPQ=";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
### Usage with nix-shell {#ssec-dart-flutter-nix-shell}
|
||||||
|
|
||||||
|
See the [Dart documentation](#ssec-dart-applications-nix-shell) nix-shell instructions.
|
||||||
```
|
```
|
||||||
|
|
|
@ -132,7 +132,6 @@ Arguments to pass to the Go linker tool via the `-ldflags` argument of `go build
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
ldflags = [
|
ldflags = [
|
||||||
"-s" "-w"
|
|
||||||
"-X main.Version=${version}"
|
"-X main.Version=${version}"
|
||||||
"-X main.Commit=${version}"
|
"-X main.Commit=${version}"
|
||||||
];
|
];
|
||||||
|
|
|
@ -24,6 +24,7 @@ idris.section.md
|
||||||
ios.section.md
|
ios.section.md
|
||||||
java.section.md
|
java.section.md
|
||||||
javascript.section.md
|
javascript.section.md
|
||||||
|
julia.section.md
|
||||||
lisp.section.md
|
lisp.section.md
|
||||||
lua.section.md
|
lua.section.md
|
||||||
maven.section.md
|
maven.section.md
|
||||||
|
|
69
doc/languages-frameworks/julia.section.md
Normal file
69
doc/languages-frameworks/julia.section.md
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
# Julia {#language-julia}
|
||||||
|
|
||||||
|
## Introduction {#julia-introduction}
|
||||||
|
|
||||||
|
Nixpkgs includes Julia as the `julia` derivation.
|
||||||
|
You can get specific versions by looking at the other `julia*` top-level derivations available.
|
||||||
|
For example, `julia_19` corresponds to Julia 1.9.
|
||||||
|
We also provide the current stable version as `julia-stable`, and an LTS version as `julia-lts`.
|
||||||
|
|
||||||
|
Occasionally, a Julia version has been too difficult to build from source in Nixpkgs and has been fetched prebuilt instead.
|
||||||
|
These Julia versions are differentiated with the `*-bin` suffix; for example, `julia-stable-bin`.
|
||||||
|
|
||||||
|
## julia.withPackages {#julia-withpackage}
|
||||||
|
|
||||||
|
The basic Julia derivations only provide the built-in packages that come with the distribution.
|
||||||
|
|
||||||
|
You can build Julia environments with additional packages using the `julia.withPackages` command.
|
||||||
|
This function accepts a list of strings representing Julia package names.
|
||||||
|
For example, you can build a Julia environment with the `Plots` package as follows.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
julia.withPackages ["Plots"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Arguments can be passed using `.override`.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
(julia.withPackages.override {
|
||||||
|
precompile = false; # Turn off precompilation
|
||||||
|
}) ["Plots"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Here's a nice way to run a Julia environment with a shell one-liner:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
nix-shell -p 'julia.withPackages ["Plots"]' --run julia
|
||||||
|
```
|
||||||
|
|
||||||
|
### Arguments {#julia-withpackage-arguments}
|
||||||
|
|
||||||
|
* `precompile`: Whether to run `Pkg.precompile()` on the generated environment.
|
||||||
|
|
||||||
|
This will make package imports faster, but may fail in some cases.
|
||||||
|
For example, there is an upstream issue with `Gtk.jl` that prevents precompilation from working in the Nix build sandbox, because the precompiled code tries to access a display.
|
||||||
|
Packages like this will work fine if you build with `precompile=false`, and then precompile as needed once your environment starts.
|
||||||
|
|
||||||
|
Defaults: `true`
|
||||||
|
|
||||||
|
* `extraLibs`: Extra library dependencies that will be placed on the `LD_LIBRARY_PATH` for Julia.
|
||||||
|
|
||||||
|
Should not be needed as we try to obtain library dependencies automatically using Julia's artifacts system.
|
||||||
|
|
||||||
|
* `makeWrapperArgs`: Extra arguments to pass to the `makeWrapper` call which we use to wrap the Julia binary.
|
||||||
|
* `setDefaultDepot`: Whether to automatically prepend `$HOME/.julia` to the `JULIA_DEPOT_PATH`.
|
||||||
|
|
||||||
|
This is useful because Julia expects a writable depot path as the first entry, which the one we build in Nixpkgs is not.
|
||||||
|
If there's no writable depot, then Julia will show a warning and be unable to save command history logs etc.
|
||||||
|
|
||||||
|
Default: `true`
|
||||||
|
|
||||||
|
* `packageOverrides`: Allows you to override packages by name by passing an alternative source.
|
||||||
|
|
||||||
|
For example, you can use a custom version of the `LanguageServer` package by passing `packageOverrides = { "LanguageServer" = fetchFromGitHub {...}; }`.
|
||||||
|
|
||||||
|
* `augmentedRegistry`: Allows you to change the registry from which Julia packages are drawn.
|
||||||
|
|
||||||
|
This normally points at a special augmented version of the Julia [General packages registry](https://github.com/JuliaRegistries/General).
|
||||||
|
If you want to use a bleeding-edge version to pick up the latest package updates, you can plug in a later revision than the one in Nixpkgs.
|
|
@ -50,7 +50,20 @@ $ nix build -f . ttop.src
|
||||||
$ nix run -f . nim_lk ./result | jq --sort-keys > pkgs/by-name/tt/ttop/lock.json
|
$ nix run -f . nim_lk ./result | jq --sort-keys > pkgs/by-name/tt/ttop/lock.json
|
||||||
```
|
```
|
||||||
|
|
||||||
## Lockfile dependency overrides {#nimoverrides}
|
## Overriding Nim packages {#nim-overrides}
|
||||||
|
|
||||||
|
The `buildNimPackage` function generates flags and additional build dependencies from the `lockFile` parameter passed to `buildNimPackage`. Using [`overrideAttrs`](#sec-pkg-overrideAttrs) on the final package will apply after this has already been generated, so this can't be used to override the `lockFile` in a package built with `buildNimPackage`. To be able to override parameters before flags and build dependencies are generated from the `lockFile`, use `overrideNimAttrs` instead with the same syntax as `overrideAttrs`:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
pkgs.nitter.overrideNimAttrs {
|
||||||
|
# using a different source which has different dependencies from the standard package
|
||||||
|
src = pkgs.fetchFromGithub { /* … */ };
|
||||||
|
# new lock file generated from the source
|
||||||
|
lockFile = ./custom-lock.json;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Lockfile dependency overrides {#nim-lock-overrides}
|
||||||
|
|
||||||
The `buildNimPackage` function matches the libraries specified by `lockFile` to attrset of override functions that are then applied to the package derivation.
|
The `buildNimPackage` function matches the libraries specified by `lockFile` to attrset of override functions that are then applied to the package derivation.
|
||||||
The default overrides are maintained as the top-level `nimOverrides` attrset at `pkgs/top-level/nim-overrides.nix`.
|
The default overrides are maintained as the top-level `nimOverrides` attrset at `pkgs/top-level/nim-overrides.nix`.
|
||||||
|
@ -81,7 +94,7 @@ The annotations in the `nim-overrides.nix` set are functions that take three arg
|
||||||
- finalAttrs: the final attrset passed by `buildNimPackage` to `stdenv.mkDerivation`.
|
- finalAttrs: the final attrset passed by `buildNimPackage` to `stdenv.mkDerivation`.
|
||||||
- prevAttrs: the attrset produced by initial arguments to `buildNimPackage` and any preceding lockfile overlays.
|
- prevAttrs: the attrset produced by initial arguments to `buildNimPackage` and any preceding lockfile overlays.
|
||||||
|
|
||||||
### Overriding an Nim library override {#nimoverrides-overrides}
|
### Overriding an Nim library override {#nim-lock-overrides-overrides}
|
||||||
|
|
||||||
The `nimOverrides` attrset makes it possible to modify overrides in a few different ways.
|
The `nimOverrides` attrset makes it possible to modify overrides in a few different ways.
|
||||||
|
|
||||||
|
|
|
@ -299,14 +299,13 @@ python3Packages.buildPythonApplication rec {
|
||||||
hash = "sha256-Pe229rT0aHwA98s+nTHQMEFKZPo/yw6sot8MivFDvAw=";
|
hash = "sha256-Pe229rT0aHwA98s+nTHQMEFKZPo/yw6sot8MivFDvAw=";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = with python3Packages; [
|
||||||
python3Packages.setuptools
|
setuptools
|
||||||
python3Packages.wheel
|
|
||||||
];
|
];
|
||||||
|
|
||||||
propagatedBuildInputs = [
|
propagatedBuildInputs = with python3Packages; [
|
||||||
python3Packages.tornado
|
tornado
|
||||||
python3Packages.python-daemon
|
python-daemon
|
||||||
];
|
];
|
||||||
|
|
||||||
meta = with lib; {
|
meta = with lib; {
|
||||||
|
@ -2061,7 +2060,7 @@ and create update commits, and supports the `fetchPypi`, `fetchurl` and
|
||||||
hosted on GitHub, exporting a `GITHUB_API_TOKEN` is highly recommended.
|
hosted on GitHub, exporting a `GITHUB_API_TOKEN` is highly recommended.
|
||||||
|
|
||||||
Updating packages in bulk leads to lots of breakages, which is why a
|
Updating packages in bulk leads to lots of breakages, which is why a
|
||||||
stabilization period on the `python-unstable` branch is required.
|
stabilization period on the `python-updates` branch is required.
|
||||||
|
|
||||||
If a package is fragile and often breaks during these bulks updates, it
|
If a package is fragile and often breaks during these bulks updates, it
|
||||||
may be reasonable to set `passthru.skipBulkUpdate = true` in the
|
may be reasonable to set `passthru.skipBulkUpdate = true` in the
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
## Using Ruby {#using-ruby}
|
## Using Ruby {#using-ruby}
|
||||||
|
|
||||||
Several versions of Ruby interpreters are available on Nix, as well as over 250 gems and many applications written in Ruby. The attribute `ruby` refers to the default Ruby interpreter, which is currently MRI 2.6. It's also possible to refer to specific versions, e.g. `ruby_2_y`, `jruby`, or `mruby`.
|
Several versions of Ruby interpreters are available on Nix, as well as over 250 gems and many applications written in Ruby. The attribute `ruby` refers to the default Ruby interpreter, which is currently MRI 3.1. It's also possible to refer to specific versions, e.g. `ruby_3_y`, `jruby`, or `mruby`.
|
||||||
|
|
||||||
In the Nixpkgs tree, Ruby packages can be found throughout, depending on what they do, and are called from the main package set. Ruby gems, however are separate sets, and there's one default set for each interpreter (currently MRI only).
|
In the Nixpkgs tree, Ruby packages can be found throughout, depending on what they do, and are called from the main package set. Ruby gems, however are separate sets, and there's one default set for each interpreter (currently MRI only).
|
||||||
|
|
||||||
There are two main approaches for using Ruby with gems. One is to use a specifically locked `Gemfile` for an application that has very strict dependencies. The other is to depend on the common gems, which we'll explain further down, and rely on them being updated regularly.
|
There are two main approaches for using Ruby with gems. One is to use a specifically locked `Gemfile` for an application that has very strict dependencies. The other is to depend on the common gems, which we'll explain further down, and rely on them being updated regularly.
|
||||||
|
|
||||||
The interpreters have common attributes, namely `gems`, and `withPackages`. So you can refer to `ruby.gems.nokogiri`, or `ruby_2_7.gems.nokogiri` to get the Nokogiri gem already compiled and ready to use.
|
The interpreters have common attributes, namely `gems`, and `withPackages`. So you can refer to `ruby.gems.nokogiri`, or `ruby_3_2.gems.nokogiri` to get the Nokogiri gem already compiled and ready to use.
|
||||||
|
|
||||||
Since not all gems have executables like `nokogiri`, it's usually more convenient to use the `withPackages` function like this: `ruby.withPackages (p: with p; [ nokogiri ])`. This will also make sure that the Ruby in your environment will be able to find the gem and it can be used in your Ruby code (for example via `ruby` or `irb` executables) via `require "nokogiri"` as usual.
|
Since not all gems have executables like `nokogiri`, it's usually more convenient to use the `withPackages` function like this: `ruby.withPackages (p: with p; [ nokogiri ])`. This will also make sure that the Ruby in your environment will be able to find the gem and it can be used in your Ruby code (for example via `ruby` or `irb` executables) via `require "nokogiri"` as usual.
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ Again, it's possible to launch the interpreter from the shell. The Ruby interpre
|
||||||
#### Load Ruby environment from `.nix` expression {#load-ruby-environment-from-.nix-expression}
|
#### Load Ruby environment from `.nix` expression {#load-ruby-environment-from-.nix-expression}
|
||||||
|
|
||||||
As explained [in the `nix-shell` section](https://nixos.org/manual/nix/stable/command-ref/nix-shell) of the Nix manual, `nix-shell` can also load an expression from a `.nix` file.
|
As explained [in the `nix-shell` section](https://nixos.org/manual/nix/stable/command-ref/nix-shell) of the Nix manual, `nix-shell` can also load an expression from a `.nix` file.
|
||||||
Say we want to have Ruby 2.6, `nokogori`, and `pry`. Consider a `shell.nix` file with:
|
Say we want to have Ruby, `nokogori`, and `pry`. Consider a `shell.nix` file with:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
with import <nixpkgs> {};
|
with import <nixpkgs> {};
|
||||||
|
@ -114,7 +114,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.
|
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 2.6, 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 in order to give the `bundler` from your gemset priority, it would be used like this:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
# ...
|
# ...
|
||||||
|
|
|
@ -963,7 +963,7 @@ repository:
|
||||||
lib.updateManyAttrsByPath [{
|
lib.updateManyAttrsByPath [{
|
||||||
path = [ "packages" "stable" ];
|
path = [ "packages" "stable" ];
|
||||||
update = old: old.overrideScope(final: prev: {
|
update = old: old.overrideScope(final: prev: {
|
||||||
rustc = prev.rustc.overrideAttrs (_: {
|
rustc-unwrapped = prev.rustc-unwrapped.overrideAttrs (_: {
|
||||||
src = lib.cleanSource /git/scratch/rust;
|
src = lib.cleanSource /git/scratch/rust;
|
||||||
# do *not* put passthru.isReleaseTarball=true here
|
# do *not* put passthru.isReleaseTarball=true here
|
||||||
});
|
});
|
||||||
|
@ -1003,4 +1003,3 @@ nix-build $NIXPKGS -A package-broken-by-rust-changes
|
||||||
The `git submodule update --init` and `cargo vendor` commands above
|
The `git submodule update --init` and `cargo vendor` commands above
|
||||||
require network access, so they can't be performed from within the
|
require network access, so they can't be performed from within the
|
||||||
`rustc` derivation, unfortunately.
|
`rustc` derivation, unfortunately.
|
||||||
|
|
||||||
|
|
|
@ -1,34 +1,318 @@
|
||||||
{
|
{
|
||||||
"gnunet.conf(5)": "https://docs.gnunet.org/users/configuration.html",
|
"gnunet.conf(5)": "https://docs.gnunet.org/latest/users/configuration.html",
|
||||||
"mpd(1)": "https://mpd.readthedocs.io/en/latest/mpd.1.html",
|
"mpd(1)": "https://mpd.readthedocs.io/en/latest/mpd.1.html",
|
||||||
"mpd.conf(5)": "https://mpd.readthedocs.io/en/latest/mpd.conf.5.html",
|
"mpd.conf(5)": "https://mpd.readthedocs.io/en/latest/mpd.conf.5.html",
|
||||||
"nix.conf(5)": "https://nixos.org/manual/nix/stable/command-ref/conf-file.html",
|
"nix.conf(5)": "https://nixos.org/manual/nix/stable/command-ref/conf-file.html",
|
||||||
|
|
||||||
"portals.conf(5)": "https://github.com/flatpak/xdg-desktop-portal/blob/1.18.1/doc/portals.conf.rst.in",
|
"portals.conf(5)": "https://github.com/flatpak/xdg-desktop-portal/blob/1.18.1/doc/portals.conf.rst.in",
|
||||||
|
|
||||||
|
"bootctl(1)": "https://www.freedesktop.org/software/systemd/man/bootctl.html",
|
||||||
|
"busctl(1)": "https://www.freedesktop.org/software/systemd/man/busctl.html",
|
||||||
|
"coredumpctl(1)": "https://www.freedesktop.org/software/systemd/man/coredumpctl.html",
|
||||||
|
"homectl(1)": "https://www.freedesktop.org/software/systemd/man/homectl.html",
|
||||||
|
"hostnamectl(1)": "https://www.freedesktop.org/software/systemd/man/hostnamectl.html",
|
||||||
|
"init(1)": "https://www.freedesktop.org/software/systemd/man/init.html",
|
||||||
|
"journalctl(1)": "https://www.freedesktop.org/software/systemd/man/journalctl.html",
|
||||||
|
"localectl(1)": "https://www.freedesktop.org/software/systemd/man/localectl.html",
|
||||||
|
"loginctl(1)": "https://www.freedesktop.org/software/systemd/man/loginctl.html",
|
||||||
|
"machinectl(1)": "https://www.freedesktop.org/software/systemd/man/machinectl.html",
|
||||||
|
"mount.ddi(1)": "https://www.freedesktop.org/software/systemd/man/mount.ddi.html",
|
||||||
|
"networkctl(1)": "https://www.freedesktop.org/software/systemd/man/networkctl.html",
|
||||||
|
"oomctl(1)": "https://www.freedesktop.org/software/systemd/man/oomctl.html",
|
||||||
|
"portablectl(1)": "https://www.freedesktop.org/software/systemd/man/portablectl.html",
|
||||||
|
"resolvconf(1)": "https://www.freedesktop.org/software/systemd/man/resolvconf.html",
|
||||||
|
"resolvectl(1)": "https://www.freedesktop.org/software/systemd/man/resolvectl.html",
|
||||||
|
"systemctl(1)": "https://www.freedesktop.org/software/systemd/man/systemctl.html",
|
||||||
|
"systemd-ac-power(1)": "https://www.freedesktop.org/software/systemd/man/systemd-ac-power.html",
|
||||||
|
"systemd-analyze(1)": "https://www.freedesktop.org/software/systemd/man/systemd-analyze.html",
|
||||||
|
"systemd-ask-password(1)": "https://www.freedesktop.org/software/systemd/man/systemd-ask-password.html",
|
||||||
|
"systemd-cat(1)": "https://www.freedesktop.org/software/systemd/man/systemd-cat.html",
|
||||||
|
"systemd-cgls(1)": "https://www.freedesktop.org/software/systemd/man/systemd-cgls.html",
|
||||||
|
"systemd-cgtop(1)": "https://www.freedesktop.org/software/systemd/man/systemd-cgtop.html",
|
||||||
|
"systemd-creds(1)": "https://www.freedesktop.org/software/systemd/man/systemd-creds.html",
|
||||||
|
"systemd-cryptenroll(1)": "https://www.freedesktop.org/software/systemd/man/systemd-cryptenroll.html",
|
||||||
|
"systemd-delta(1)": "https://www.freedesktop.org/software/systemd/man/systemd-delta.html",
|
||||||
|
"systemd-detect-virt(1)": "https://www.freedesktop.org/software/systemd/man/systemd-detect-virt.html",
|
||||||
|
"systemd-dissect(1)": "https://www.freedesktop.org/software/systemd/man/systemd-dissect.html",
|
||||||
|
"systemd-escape(1)": "https://www.freedesktop.org/software/systemd/man/systemd-escape.html",
|
||||||
|
"systemd-id128(1)": "https://www.freedesktop.org/software/systemd/man/systemd-id128.html",
|
||||||
|
"systemd-inhibit(1)": "https://www.freedesktop.org/software/systemd/man/systemd-inhibit.html",
|
||||||
|
"systemd-machine-id-setup(1)": "https://www.freedesktop.org/software/systemd/man/systemd-machine-id-setup.html",
|
||||||
|
"systemd-measure(1)": "https://www.freedesktop.org/software/systemd/man/systemd-measure.html",
|
||||||
|
"systemd-mount(1)": "https://www.freedesktop.org/software/systemd/man/systemd-mount.html",
|
||||||
|
"systemd-notify(1)": "https://www.freedesktop.org/software/systemd/man/systemd-notify.html",
|
||||||
|
"systemd-nspawn(1)": "https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html",
|
||||||
|
"systemd-path(1)": "https://www.freedesktop.org/software/systemd/man/systemd-path.html",
|
||||||
|
"systemd-run(1)": "https://www.freedesktop.org/software/systemd/man/systemd-run.html",
|
||||||
|
"systemd-socket-activate(1)": "https://www.freedesktop.org/software/systemd/man/systemd-socket-activate.html",
|
||||||
|
"systemd-stdio-bridge(1)": "https://www.freedesktop.org/software/systemd/man/systemd-stdio-bridge.html",
|
||||||
|
"systemd-tty-ask-password-agent(1)": "https://www.freedesktop.org/software/systemd/man/systemd-tty-ask-password-agent.html",
|
||||||
|
"systemd-umount(1)": "https://www.freedesktop.org/software/systemd/man/systemd-umount.html",
|
||||||
|
"systemd(1)": "https://www.freedesktop.org/software/systemd/man/systemd.html",
|
||||||
|
"timedatectl(1)": "https://www.freedesktop.org/software/systemd/man/timedatectl.html",
|
||||||
|
"userdbctl(1)": "https://www.freedesktop.org/software/systemd/man/userdbctl.html",
|
||||||
|
"binfmt.d(5)": "https://www.freedesktop.org/software/systemd/man/binfmt.d.html",
|
||||||
|
"coredump.conf(5)": "https://www.freedesktop.org/software/systemd/man/coredump.conf.html",
|
||||||
|
"coredump.conf.d(5)": "https://www.freedesktop.org/software/systemd/man/coredump.conf.d.html",
|
||||||
|
"crypttab(5)": "https://www.freedesktop.org/software/systemd/man/crypttab.html",
|
||||||
|
"dnssec-trust-anchors.d(5)": "https://www.freedesktop.org/software/systemd/man/dnssec-trust-anchors.d.html",
|
||||||
|
"environment.d(5)": "https://www.freedesktop.org/software/systemd/man/environment.d.html",
|
||||||
|
"extension-release(5)": "https://www.freedesktop.org/software/systemd/man/extension-release.html",
|
||||||
|
"homed.conf(5)": "https://www.freedesktop.org/software/systemd/man/homed.conf.html",
|
||||||
|
"homed.conf.d(5)": "https://www.freedesktop.org/software/systemd/man/homed.conf.d.html",
|
||||||
|
"hostname(5)": "https://www.freedesktop.org/software/systemd/man/hostname.html",
|
||||||
|
"initrd-release(5)": "https://www.freedesktop.org/software/systemd/man/initrd-release.html",
|
||||||
|
"integritytab(5)": "https://www.freedesktop.org/software/systemd/man/integritytab.html",
|
||||||
|
"iocost.conf(5)": "https://www.freedesktop.org/software/systemd/man/iocost.conf.html",
|
||||||
|
"journal-remote.conf(5)": "https://www.freedesktop.org/software/systemd/man/journal-remote.conf.html",
|
||||||
|
"journal-remote.conf.d(5)": "https://www.freedesktop.org/software/systemd/man/journal-remote.conf.d.html",
|
||||||
|
"journal-upload.conf(5)": "https://www.freedesktop.org/software/systemd/man/journal-upload.conf.html",
|
||||||
|
"journal-upload.conf.d(5)": "https://www.freedesktop.org/software/systemd/man/journal-upload.conf.d.html",
|
||||||
"journald.conf(5)": "https://www.freedesktop.org/software/systemd/man/journald.conf.html",
|
"journald.conf(5)": "https://www.freedesktop.org/software/systemd/man/journald.conf.html",
|
||||||
|
"journald.conf.d(5)": "https://www.freedesktop.org/software/systemd/man/journald.conf.d.html",
|
||||||
|
"journald@.conf(5)": "https://www.freedesktop.org/software/systemd/man/journald@.conf.html",
|
||||||
|
"loader.conf(5)": "https://www.freedesktop.org/software/systemd/man/loader.conf.html",
|
||||||
|
"locale.conf(5)": "https://www.freedesktop.org/software/systemd/man/locale.conf.html",
|
||||||
|
"localtime(5)": "https://www.freedesktop.org/software/systemd/man/localtime.html",
|
||||||
"logind.conf(5)": "https://www.freedesktop.org/software/systemd/man/logind.conf.html",
|
"logind.conf(5)": "https://www.freedesktop.org/software/systemd/man/logind.conf.html",
|
||||||
|
"logind.conf.d(5)": "https://www.freedesktop.org/software/systemd/man/logind.conf.d.html",
|
||||||
|
"machine-id(5)": "https://www.freedesktop.org/software/systemd/man/machine-id.html",
|
||||||
|
"machine-info(5)": "https://www.freedesktop.org/software/systemd/man/machine-info.html",
|
||||||
|
"modules-load.d(5)": "https://www.freedesktop.org/software/systemd/man/modules-load.d.html",
|
||||||
"networkd.conf(5)": "https://www.freedesktop.org/software/systemd/man/networkd.conf.html",
|
"networkd.conf(5)": "https://www.freedesktop.org/software/systemd/man/networkd.conf.html",
|
||||||
|
"networkd.conf.d(5)": "https://www.freedesktop.org/software/systemd/man/networkd.conf.d.html",
|
||||||
|
"oomd.conf(5)": "https://www.freedesktop.org/software/systemd/man/oomd.conf.html",
|
||||||
|
"oomd.conf.d(5)": "https://www.freedesktop.org/software/systemd/man/oomd.conf.d.html",
|
||||||
|
"org.freedesktop.LogControl1(5)": "https://www.freedesktop.org/software/systemd/man/org.freedesktop.LogControl1.html",
|
||||||
|
"org.freedesktop.home1(5)": "https://www.freedesktop.org/software/systemd/man/org.freedesktop.home1.html",
|
||||||
|
"org.freedesktop.hostname1(5)": "https://www.freedesktop.org/software/systemd/man/org.freedesktop.hostname1.html",
|
||||||
|
"org.freedesktop.import1(5)": "https://www.freedesktop.org/software/systemd/man/org.freedesktop.import1.html",
|
||||||
|
"org.freedesktop.locale1(5)": "https://www.freedesktop.org/software/systemd/man/org.freedesktop.locale1.html",
|
||||||
|
"org.freedesktop.login1(5)": "https://www.freedesktop.org/software/systemd/man/org.freedesktop.login1.html",
|
||||||
|
"org.freedesktop.machine1(5)": "https://www.freedesktop.org/software/systemd/man/org.freedesktop.machine1.html",
|
||||||
|
"org.freedesktop.network1(5)": "https://www.freedesktop.org/software/systemd/man/org.freedesktop.network1.html",
|
||||||
|
"org.freedesktop.oom1(5)": "https://www.freedesktop.org/software/systemd/man/org.freedesktop.oom1.html",
|
||||||
|
"org.freedesktop.portable1(5)": "https://www.freedesktop.org/software/systemd/man/org.freedesktop.portable1.html",
|
||||||
|
"org.freedesktop.resolve1(5)": "https://www.freedesktop.org/software/systemd/man/org.freedesktop.resolve1.html",
|
||||||
|
"org.freedesktop.systemd1(5)": "https://www.freedesktop.org/software/systemd/man/org.freedesktop.systemd1.html",
|
||||||
|
"org.freedesktop.timedate1(5)": "https://www.freedesktop.org/software/systemd/man/org.freedesktop.timedate1.html",
|
||||||
|
"os-release(5)": "https://www.freedesktop.org/software/systemd/man/os-release.html",
|
||||||
|
"pstore.conf(5)": "https://www.freedesktop.org/software/systemd/man/pstore.conf.html",
|
||||||
|
"pstore.conf.d(5)": "https://www.freedesktop.org/software/systemd/man/pstore.conf.d.html",
|
||||||
|
"repart.d(5)": "https://www.freedesktop.org/software/systemd/man/repart.d.html",
|
||||||
|
"resolved.conf(5)": "https://www.freedesktop.org/software/systemd/man/resolved.conf.html",
|
||||||
|
"resolved.conf.d(5)": "https://www.freedesktop.org/software/systemd/man/resolved.conf.d.html",
|
||||||
|
"sleep.conf.d(5)": "https://www.freedesktop.org/software/systemd/man/sleep.conf.d.html",
|
||||||
|
"sysctl.d(5)": "https://www.freedesktop.org/software/systemd/man/sysctl.d.html",
|
||||||
|
"system.conf.d(5)": "https://www.freedesktop.org/software/systemd/man/system.conf.d.html",
|
||||||
|
"systemd-sleep.conf(5)": "https://www.freedesktop.org/software/systemd/man/systemd-sleep.conf.html",
|
||||||
|
"systemd-system.conf(5)": "https://www.freedesktop.org/software/systemd/man/systemd-system.conf.html",
|
||||||
|
"systemd-user-runtime-dir(5)": "https://www.freedesktop.org/software/systemd/man/systemd-user-runtime-dir.html",
|
||||||
|
"systemd-user.conf(5)": "https://www.freedesktop.org/software/systemd/man/systemd-user.conf.html",
|
||||||
"systemd.automount(5)": "https://www.freedesktop.org/software/systemd/man/systemd.automount.html",
|
"systemd.automount(5)": "https://www.freedesktop.org/software/systemd/man/systemd.automount.html",
|
||||||
|
"systemd.device(5)": "https://www.freedesktop.org/software/systemd/man/systemd.device.html",
|
||||||
|
"systemd.dnssd(5)": "https://www.freedesktop.org/software/systemd/man/systemd.dnssd.html",
|
||||||
"systemd.exec(5)": "https://www.freedesktop.org/software/systemd/man/systemd.exec.html",
|
"systemd.exec(5)": "https://www.freedesktop.org/software/systemd/man/systemd.exec.html",
|
||||||
|
"systemd.kill(5)": "https://www.freedesktop.org/software/systemd/man/systemd.kill.html",
|
||||||
"systemd.link(5)": "https://www.freedesktop.org/software/systemd/man/systemd.link.html",
|
"systemd.link(5)": "https://www.freedesktop.org/software/systemd/man/systemd.link.html",
|
||||||
"systemd.mount(5)": "https://www.freedesktop.org/software/systemd/man/systemd.mount.html",
|
"systemd.mount(5)": "https://www.freedesktop.org/software/systemd/man/systemd.mount.html",
|
||||||
|
"systemd.negative(5)": "https://www.freedesktop.org/software/systemd/man/systemd.negative.html",
|
||||||
"systemd.netdev(5)": "https://www.freedesktop.org/software/systemd/man/systemd.netdev.html",
|
"systemd.netdev(5)": "https://www.freedesktop.org/software/systemd/man/systemd.netdev.html",
|
||||||
"systemd.network(5)": "https://www.freedesktop.org/software/systemd/man/systemd.network.html",
|
"systemd.network(5)": "https://www.freedesktop.org/software/systemd/man/systemd.network.html",
|
||||||
"systemd.nspawn(5)": "https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html",
|
"systemd.nspawn(5)": "https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html",
|
||||||
"systemd.path(5)": "https://www.freedesktop.org/software/systemd/man/systemd.path.html",
|
"systemd.path(5)": "https://www.freedesktop.org/software/systemd/man/systemd.path.html",
|
||||||
|
"systemd.positive(5)": "https://www.freedesktop.org/software/systemd/man/systemd.positive.html",
|
||||||
|
"systemd.preset(5)": "https://www.freedesktop.org/software/systemd/man/systemd.preset.html",
|
||||||
"systemd.resource-control(5)": "https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html",
|
"systemd.resource-control(5)": "https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html",
|
||||||
"systemd.scope(5)": "https://www.freedesktop.org/software/systemd/man/systemd.scope.html",
|
"systemd.scope(5)": "https://www.freedesktop.org/software/systemd/man/systemd.scope.html",
|
||||||
"systemd.service(5)": "https://www.freedesktop.org/software/systemd/man/systemd.service.html",
|
"systemd.service(5)": "https://www.freedesktop.org/software/systemd/man/systemd.service.html",
|
||||||
"systemd.slice(5)": "https://www.freedesktop.org/software/systemd/man/systemd.slice.html",
|
"systemd.slice(5)": "https://www.freedesktop.org/software/systemd/man/systemd.slice.html",
|
||||||
"systemd.socket(5)": "https://www.freedesktop.org/software/systemd/man/systemd.socket.html",
|
"systemd.socket(5)": "https://www.freedesktop.org/software/systemd/man/systemd.socket.html",
|
||||||
|
"systemd.swap(5)": "https://www.freedesktop.org/software/systemd/man/systemd.swap.html",
|
||||||
|
"systemd.target(5)": "https://www.freedesktop.org/software/systemd/man/systemd.target.html",
|
||||||
"systemd.timer(5)": "https://www.freedesktop.org/software/systemd/man/systemd.timer.html",
|
"systemd.timer(5)": "https://www.freedesktop.org/software/systemd/man/systemd.timer.html",
|
||||||
"systemd.unit(5)": "https://www.freedesktop.org/software/systemd/man/systemd.unit.html",
|
"systemd.unit(5)": "https://www.freedesktop.org/software/systemd/man/systemd.unit.html",
|
||||||
"systemd-system.conf(5)": "https://www.freedesktop.org/software/systemd/man/systemd-system.conf.html",
|
"sysupdate.d(5)": "https://www.freedesktop.org/software/systemd/man/sysupdate.d.html",
|
||||||
"systemd-user.conf(5)": "https://www.freedesktop.org/software/systemd/man/systemd-user.conf.html",
|
"sysusers.d(5)": "https://www.freedesktop.org/software/systemd/man/sysusers.d.html",
|
||||||
"timesyncd.conf(5)": "https://www.freedesktop.org/software/systemd/man/timesyncd.conf.html",
|
"timesyncd.conf(5)": "https://www.freedesktop.org/software/systemd/man/timesyncd.conf.html",
|
||||||
|
"timesyncd.conf.d(5)": "https://www.freedesktop.org/software/systemd/man/timesyncd.conf.d.html",
|
||||||
"tmpfiles.d(5)": "https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html",
|
"tmpfiles.d(5)": "https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html",
|
||||||
|
"udev.conf(5)": "https://www.freedesktop.org/software/systemd/man/udev.conf.html",
|
||||||
|
"user-runtime-dir@.service(5)": "https://www.freedesktop.org/software/systemd/man/user-runtime-dir@.service.html",
|
||||||
|
"user.conf.d(5)": "https://www.freedesktop.org/software/systemd/man/user.conf.d.html",
|
||||||
|
"user@.service(5)": "https://www.freedesktop.org/software/systemd/man/user@.service.html",
|
||||||
|
"vconsole.conf(5)": "https://www.freedesktop.org/software/systemd/man/vconsole.conf.html",
|
||||||
|
"veritytab(5)": "https://www.freedesktop.org/software/systemd/man/veritytab.html",
|
||||||
|
"bootup(7)": "https://www.freedesktop.org/software/systemd/man/bootup.html",
|
||||||
|
"daemon(7)": "https://www.freedesktop.org/software/systemd/man/daemon.html",
|
||||||
|
"file-hierarchy(7)": "https://www.freedesktop.org/software/systemd/man/file-hierarchy.html",
|
||||||
|
"hwdb(7)": "https://www.freedesktop.org/software/systemd/man/hwdb.html",
|
||||||
|
"kernel-command-line(7)": "https://www.freedesktop.org/software/systemd/man/kernel-command-line.html",
|
||||||
|
"linuxaa64.efi.stub(7)": "https://www.freedesktop.org/software/systemd/man/linuxaa64.efi.stub.html",
|
||||||
|
"linuxia32.efi.stub(7)": "https://www.freedesktop.org/software/systemd/man/linuxia32.efi.stub.html",
|
||||||
|
"linuxx64.efi.stub(7)": "https://www.freedesktop.org/software/systemd/man/linuxx64.efi.stub.html",
|
||||||
|
"sd-boot(7)": "https://www.freedesktop.org/software/systemd/man/sd-boot.html",
|
||||||
|
"sd-stub(7)": "https://www.freedesktop.org/software/systemd/man/sd-stub.html",
|
||||||
|
"smbios-type-11(7)": "https://www.freedesktop.org/software/systemd/man/smbios-type-11.html",
|
||||||
|
"systemd-boot(7)": "https://www.freedesktop.org/software/systemd/man/systemd-boot.html",
|
||||||
|
"systemd-stub(7)": "https://www.freedesktop.org/software/systemd/man/systemd-stub.html",
|
||||||
|
"systemd.directives(7)": "https://www.freedesktop.org/software/systemd/man/systemd.directives.html",
|
||||||
|
"systemd.environment-generator(7)": "https://www.freedesktop.org/software/systemd/man/systemd.environment-generator.html",
|
||||||
|
"systemd.generator(7)": "https://www.freedesktop.org/software/systemd/man/systemd.generator.html",
|
||||||
|
"systemd.image-policy(7)": "https://www.freedesktop.org/software/systemd/man/systemd.image-policy.html",
|
||||||
|
"systemd.index(7)": "https://www.freedesktop.org/software/systemd/man/systemd.index.html",
|
||||||
|
"systemd.journal-fields(7)": "https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html",
|
||||||
|
"systemd.net-naming-scheme(7)": "https://www.freedesktop.org/software/systemd/man/systemd.net-naming-scheme.html",
|
||||||
|
"systemd.offline-updates(7)": "https://www.freedesktop.org/software/systemd/man/systemd.offline-updates.html",
|
||||||
|
"systemd.special(7)": "https://www.freedesktop.org/software/systemd/man/systemd.special.html",
|
||||||
|
"systemd.syntax(7)": "https://www.freedesktop.org/software/systemd/man/systemd.syntax.html",
|
||||||
|
"systemd.system-credentials(7)": "https://www.freedesktop.org/software/systemd/man/systemd.system-credentials.html",
|
||||||
"systemd.time(7)": "https://www.freedesktop.org/software/systemd/man/systemd.time.html",
|
"systemd.time(7)": "https://www.freedesktop.org/software/systemd/man/systemd.time.html",
|
||||||
|
"udev(7)": "https://www.freedesktop.org/software/systemd/man/udev.html",
|
||||||
|
"30-systemd-environment-d-generator(8)": "https://www.freedesktop.org/software/systemd/man/30-systemd-environment-d-generator.html",
|
||||||
|
"halt(8)": "https://www.freedesktop.org/software/systemd/man/halt.html",
|
||||||
|
"kernel-install(8)": "https://www.freedesktop.org/software/systemd/man/kernel-install.html",
|
||||||
|
"libnss_myhostname.so.2(8)": "https://www.freedesktop.org/software/systemd/man/libnss_myhostname.so.2.html",
|
||||||
|
"libnss_mymachines.so.2(8)": "https://www.freedesktop.org/software/systemd/man/libnss_mymachines.so.2.html",
|
||||||
|
"libnss_resolve.so.2(8)": "https://www.freedesktop.org/software/systemd/man/libnss_resolve.so.2.html",
|
||||||
|
"libnss_systemd.so.2(8)": "https://www.freedesktop.org/software/systemd/man/libnss_systemd.so.2.html",
|
||||||
|
"nss-myhostname(8)": "https://www.freedesktop.org/software/systemd/man/nss-myhostname.html",
|
||||||
|
"nss-mymachines(8)": "https://www.freedesktop.org/software/systemd/man/nss-mymachines.html",
|
||||||
|
"nss-resolve(8)": "https://www.freedesktop.org/software/systemd/man/nss-resolve.html",
|
||||||
|
"nss-systemd(8)": "https://www.freedesktop.org/software/systemd/man/nss-systemd.html",
|
||||||
|
"pam_systemd(8)": "https://www.freedesktop.org/software/systemd/man/pam_systemd.html",
|
||||||
|
"pam_systemd_home(8)": "https://www.freedesktop.org/software/systemd/man/pam_systemd_home.html",
|
||||||
|
"poweroff(8)": "https://www.freedesktop.org/software/systemd/man/poweroff.html",
|
||||||
|
"reboot(8)": "https://www.freedesktop.org/software/systemd/man/reboot.html",
|
||||||
|
"shutdown(8)": "https://www.freedesktop.org/software/systemd/man/shutdown.html",
|
||||||
|
"systemd-ask-password-console.path(8)": "https://www.freedesktop.org/software/systemd/man/systemd-ask-password-console.path.html",
|
||||||
|
"systemd-ask-password-console.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-ask-password-console.service.html",
|
||||||
|
"systemd-ask-password-wall.path(8)": "https://www.freedesktop.org/software/systemd/man/systemd-ask-password-wall.path.html",
|
||||||
|
"systemd-ask-password-wall.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-ask-password-wall.service.html",
|
||||||
|
"systemd-backlight(8)": "https://www.freedesktop.org/software/systemd/man/systemd-backlight.html",
|
||||||
|
"systemd-backlight@.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-backlight@.service.html",
|
||||||
|
"systemd-battery-check(8)": "https://www.freedesktop.org/software/systemd/man/systemd-battery-check.html",
|
||||||
|
"systemd-binfmt(8)": "https://www.freedesktop.org/software/systemd/man/systemd-binfmt.html",
|
||||||
|
"systemd-bless-boot-generator(8)": "https://www.freedesktop.org/software/systemd/man/systemd-bless-boot-generator.html",
|
||||||
|
"systemd-bless-boot(8)": "https://www.freedesktop.org/software/systemd/man/systemd-bless-boot.html",
|
||||||
|
"systemd-boot-check-no-failures(8)": "https://www.freedesktop.org/software/systemd/man/systemd-boot-check-no-failures.html",
|
||||||
|
"systemd-boot-random-seed.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-boot-random-seed.service.html",
|
||||||
|
"systemd-confext(8)": "https://www.freedesktop.org/software/systemd/man/systemd-confext.html",
|
||||||
|
"systemd-confext.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-confext.service.html",
|
||||||
|
"systemd-coredump(8)": "https://www.freedesktop.org/software/systemd/man/systemd-coredump.html",
|
||||||
|
"systemd-coredump.socket(8)": "https://www.freedesktop.org/software/systemd/man/systemd-coredump.socket.html",
|
||||||
|
"systemd-coredump@.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-coredump@.service.html",
|
||||||
|
"systemd-cryptsetup-generator(8)": "https://www.freedesktop.org/software/systemd/man/systemd-cryptsetup-generator.html",
|
||||||
|
"systemd-cryptsetup(8)": "https://www.freedesktop.org/software/systemd/man/systemd-cryptsetup.html",
|
||||||
|
"systemd-cryptsetup@.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-cryptsetup@.service.html",
|
||||||
|
"systemd-debug-generator(8)": "https://www.freedesktop.org/software/systemd/man/systemd-debug-generator.html",
|
||||||
|
"systemd-environment-d-generator(8)": "https://www.freedesktop.org/software/systemd/man/systemd-environment-d-generator.html",
|
||||||
|
"systemd-fsck-root.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-fsck-root.service.html",
|
||||||
|
"systemd-fsck-usr.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-fsck-usr.service.html",
|
||||||
|
"systemd-fsck(8)": "https://www.freedesktop.org/software/systemd/man/systemd-fsck.html",
|
||||||
|
"systemd-fsck@.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-fsck@.service.html",
|
||||||
"systemd-fstab-generator(8)": "https://www.freedesktop.org/software/systemd/man/systemd-fstab-generator.html",
|
"systemd-fstab-generator(8)": "https://www.freedesktop.org/software/systemd/man/systemd-fstab-generator.html",
|
||||||
"systemd-networkd-wait-online.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-networkd-wait-online.service.html"
|
"systemd-getty-generator(8)": "https://www.freedesktop.org/software/systemd/man/systemd-getty-generator.html",
|
||||||
|
"systemd-gpt-auto-generator(8)": "https://www.freedesktop.org/software/systemd/man/systemd-gpt-auto-generator.html",
|
||||||
|
"systemd-growfs-root.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-growfs-root.service.html",
|
||||||
|
"systemd-growfs(8)": "https://www.freedesktop.org/software/systemd/man/systemd-growfs.html",
|
||||||
|
"systemd-growfs@.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-growfs@.service.html",
|
||||||
|
"systemd-halt.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-halt.service.html",
|
||||||
|
"systemd-hibernate-resume-generator(8)": "https://www.freedesktop.org/software/systemd/man/systemd-hibernate-resume-generator.html",
|
||||||
|
"systemd-hibernate-resume(8)": "https://www.freedesktop.org/software/systemd/man/systemd-hibernate-resume.html",
|
||||||
|
"systemd-hibernate.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-hibernate.service.html",
|
||||||
|
"systemd-homed(8)": "https://www.freedesktop.org/software/systemd/man/systemd-homed.html",
|
||||||
|
"systemd-hostnamed(8)": "https://www.freedesktop.org/software/systemd/man/systemd-hostnamed.html",
|
||||||
|
"systemd-hwdb(8)": "https://www.freedesktop.org/software/systemd/man/systemd-hwdb.html",
|
||||||
|
"systemd-hybrid-sleep.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-hybrid-sleep.service.html",
|
||||||
|
"systemd-importd(8)": "https://www.freedesktop.org/software/systemd/man/systemd-importd.html",
|
||||||
|
"systemd-integritysetup-generator(8)": "https://www.freedesktop.org/software/systemd/man/systemd-integritysetup-generator.html",
|
||||||
|
"systemd-integritysetup(8)": "https://www.freedesktop.org/software/systemd/man/systemd-integritysetup.html",
|
||||||
|
"systemd-integritysetup@.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-integritysetup@.service.html",
|
||||||
|
"systemd-journal-gatewayd(8)": "https://www.freedesktop.org/software/systemd/man/systemd-journal-gatewayd.html",
|
||||||
|
"systemd-journal-gatewayd.socket(8)": "https://www.freedesktop.org/software/systemd/man/systemd-journal-gatewayd.socket.html",
|
||||||
|
"systemd-journal-remote(8)": "https://www.freedesktop.org/software/systemd/man/systemd-journal-remote.html",
|
||||||
|
"systemd-journal-remote.socket(8)": "https://www.freedesktop.org/software/systemd/man/systemd-journal-remote.socket.html",
|
||||||
|
"systemd-journal-upload(8)": "https://www.freedesktop.org/software/systemd/man/systemd-journal-upload.html",
|
||||||
|
"systemd-journald-audit.socket(8)": "https://www.freedesktop.org/software/systemd/man/systemd-journald-audit.socket.html",
|
||||||
|
"systemd-journald-dev-log.socket(8)": "https://www.freedesktop.org/software/systemd/man/systemd-journald-dev-log.socket.html",
|
||||||
|
"systemd-journald-varlink@.socket(8)": "https://www.freedesktop.org/software/systemd/man/systemd-journald-varlink@.socket.html",
|
||||||
|
"systemd-journald(8)": "https://www.freedesktop.org/software/systemd/man/systemd-journald.html",
|
||||||
|
"systemd-journald.socket(8)": "https://www.freedesktop.org/software/systemd/man/systemd-journald.socket.html",
|
||||||
|
"systemd-journald@.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-journald@.service.html",
|
||||||
|
"systemd-journald@.socket(8)": "https://www.freedesktop.org/software/systemd/man/systemd-journald@.socket.html",
|
||||||
|
"systemd-kexec.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-kexec.service.html",
|
||||||
|
"systemd-localed(8)": "https://www.freedesktop.org/software/systemd/man/systemd-localed.html",
|
||||||
|
"systemd-logind(8)": "https://www.freedesktop.org/software/systemd/man/systemd-logind.html",
|
||||||
|
"systemd-machine-id-commit.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-machine-id-commit.service.html",
|
||||||
|
"systemd-machined(8)": "https://www.freedesktop.org/software/systemd/man/systemd-machined.html",
|
||||||
|
"systemd-makefs(8)": "https://www.freedesktop.org/software/systemd/man/systemd-makefs.html",
|
||||||
|
"systemd-makefs@.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-makefs@.service.html",
|
||||||
|
"systemd-mkswap@.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-mkswap@.service.html",
|
||||||
|
"systemd-modules-load(8)": "https://www.freedesktop.org/software/systemd/man/systemd-modules-load.html",
|
||||||
|
"systemd-network-generator(8)": "https://www.freedesktop.org/software/systemd/man/systemd-network-generator.html",
|
||||||
|
"systemd-networkd-wait-online(8)": "https://www.freedesktop.org/software/systemd/man/systemd-networkd-wait-online.html",
|
||||||
|
"systemd-networkd-wait-online@.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-networkd-wait-online@.service.html",
|
||||||
|
"systemd-networkd(8)": "https://www.freedesktop.org/software/systemd/man/systemd-networkd.html",
|
||||||
|
"systemd-oomd(8)": "https://www.freedesktop.org/software/systemd/man/systemd-oomd.html",
|
||||||
|
"systemd-pcrfs-root.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-pcrfs-root.service.html",
|
||||||
|
"systemd-pcrfs@.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-pcrfs@.service.html",
|
||||||
|
"systemd-pcrmachine.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-pcrmachine.service.html",
|
||||||
|
"systemd-pcrphase-initrd.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-pcrphase-initrd.service.html",
|
||||||
|
"systemd-pcrphase-sysinit.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-pcrphase-sysinit.service.html",
|
||||||
|
"systemd-pcrphase(8)": "https://www.freedesktop.org/software/systemd/man/systemd-pcrphase.html",
|
||||||
|
"systemd-portabled(8)": "https://www.freedesktop.org/software/systemd/man/systemd-portabled.html",
|
||||||
|
"systemd-poweroff.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-poweroff.service.html",
|
||||||
|
"systemd-pstore(8)": "https://www.freedesktop.org/software/systemd/man/systemd-pstore.html",
|
||||||
|
"systemd-random-seed(8)": "https://www.freedesktop.org/software/systemd/man/systemd-random-seed.html",
|
||||||
|
"systemd-reboot.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-reboot.service.html",
|
||||||
|
"systemd-remount-fs(8)": "https://www.freedesktop.org/software/systemd/man/systemd-remount-fs.html",
|
||||||
|
"systemd-repart(8)": "https://www.freedesktop.org/software/systemd/man/systemd-repart.html",
|
||||||
|
"systemd-repart.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-repart.service.html",
|
||||||
|
"systemd-resolved(8)": "https://www.freedesktop.org/software/systemd/man/systemd-resolved.html",
|
||||||
|
"systemd-rfkill(8)": "https://www.freedesktop.org/software/systemd/man/systemd-rfkill.html",
|
||||||
|
"systemd-rfkill.socket(8)": "https://www.freedesktop.org/software/systemd/man/systemd-rfkill.socket.html",
|
||||||
|
"systemd-run-generator(8)": "https://www.freedesktop.org/software/systemd/man/systemd-run-generator.html",
|
||||||
|
"systemd-shutdown(8)": "https://www.freedesktop.org/software/systemd/man/systemd-shutdown.html",
|
||||||
|
"systemd-sleep(8)": "https://www.freedesktop.org/software/systemd/man/systemd-sleep.html",
|
||||||
|
"systemd-socket-proxyd(8)": "https://www.freedesktop.org/software/systemd/man/systemd-socket-proxyd.html",
|
||||||
|
"systemd-soft-reboot.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-soft-reboot.service.html",
|
||||||
|
"systemd-suspend-then-hibernate.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-suspend-then-hibernate.service.html",
|
||||||
|
"systemd-suspend.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-suspend.service.html",
|
||||||
|
"systemd-sysctl(8)": "https://www.freedesktop.org/software/systemd/man/systemd-sysctl.html",
|
||||||
|
"systemd-sysext(8)": "https://www.freedesktop.org/software/systemd/man/systemd-sysext.html",
|
||||||
|
"systemd-sysext.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-sysext.service.html",
|
||||||
|
"systemd-system-update-generator(8)": "https://www.freedesktop.org/software/systemd/man/systemd-system-update-generator.html",
|
||||||
|
"systemd-sysupdate-reboot.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-sysupdate-reboot.service.html",
|
||||||
|
"systemd-sysupdate-reboot.timer(8)": "https://www.freedesktop.org/software/systemd/man/systemd-sysupdate-reboot.timer.html",
|
||||||
|
"systemd-sysupdate(8)": "https://www.freedesktop.org/software/systemd/man/systemd-sysupdate.html",
|
||||||
|
"systemd-sysupdate.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-sysupdate.service.html",
|
||||||
|
"systemd-sysupdate.timer(8)": "https://www.freedesktop.org/software/systemd/man/systemd-sysupdate.timer.html",
|
||||||
|
"systemd-sysusers(8)": "https://www.freedesktop.org/software/systemd/man/systemd-sysusers.html",
|
||||||
|
"systemd-sysusers.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-sysusers.service.html",
|
||||||
|
"systemd-time-wait-sync(8)": "https://www.freedesktop.org/software/systemd/man/systemd-time-wait-sync.html",
|
||||||
|
"systemd-timedated(8)": "https://www.freedesktop.org/software/systemd/man/systemd-timedated.html",
|
||||||
|
"systemd-timesyncd(8)": "https://www.freedesktop.org/software/systemd/man/systemd-timesyncd.html",
|
||||||
|
"systemd-tmpfiles-clean.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-tmpfiles-clean.service.html",
|
||||||
|
"systemd-tmpfiles-clean.timer(8)": "https://www.freedesktop.org/software/systemd/man/systemd-tmpfiles-clean.timer.html",
|
||||||
|
"systemd-tmpfiles-setup-dev-early.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-tmpfiles-setup-dev-early.service.html",
|
||||||
|
"systemd-tmpfiles-setup-dev.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-tmpfiles-setup-dev.service.html",
|
||||||
|
"systemd-tmpfiles-setup.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-tmpfiles-setup.service.html",
|
||||||
|
"systemd-tmpfiles(8)": "https://www.freedesktop.org/software/systemd/man/systemd-tmpfiles.html",
|
||||||
|
"systemd-udev-settle.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-udev-settle.service.html",
|
||||||
|
"systemd-udevd-control.socket(8)": "https://www.freedesktop.org/software/systemd/man/systemd-udevd-control.socket.html",
|
||||||
|
"systemd-udevd-kernel.socket(8)": "https://www.freedesktop.org/software/systemd/man/systemd-udevd-kernel.socket.html",
|
||||||
|
"systemd-udevd(8)": "https://www.freedesktop.org/software/systemd/man/systemd-udevd.html",
|
||||||
|
"systemd-update-done(8)": "https://www.freedesktop.org/software/systemd/man/systemd-update-done.html",
|
||||||
|
"systemd-update-utmp-runlevel.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-update-utmp-runlevel.service.html",
|
||||||
|
"systemd-update-utmp(8)": "https://www.freedesktop.org/software/systemd/man/systemd-update-utmp.html",
|
||||||
|
"systemd-user-sessions(8)": "https://www.freedesktop.org/software/systemd/man/systemd-user-sessions.html",
|
||||||
|
"systemd-userdbd(8)": "https://www.freedesktop.org/software/systemd/man/systemd-userdbd.html",
|
||||||
|
"systemd-vconsole-setup(8)": "https://www.freedesktop.org/software/systemd/man/systemd-vconsole-setup.html",
|
||||||
|
"systemd-veritysetup-generator(8)": "https://www.freedesktop.org/software/systemd/man/systemd-veritysetup-generator.html",
|
||||||
|
"systemd-veritysetup(8)": "https://www.freedesktop.org/software/systemd/man/systemd-veritysetup.html",
|
||||||
|
"systemd-veritysetup@.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-veritysetup@.service.html",
|
||||||
|
"systemd-volatile-root(8)": "https://www.freedesktop.org/software/systemd/man/systemd-volatile-root.html",
|
||||||
|
"systemd-xdg-autostart-generator(8)": "https://www.freedesktop.org/software/systemd/man/systemd-xdg-autostart-generator.html",
|
||||||
|
"udevadm(8)": "https://www.freedesktop.org/software/systemd/man/udevadm.html"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Nixpkgs Manual {#nixpkgs-manual}
|
# Nixpkgs Reference Manual {#nixpkgs-manual}
|
||||||
## Version @MANUAL_VERSION@
|
## Version @MANUAL_VERSION@
|
||||||
|
|
||||||
```{=include=} chapters
|
```{=include=} chapters
|
||||||
|
|
|
@ -6,11 +6,15 @@ The Nix Packages collection (Nixpkgs) is a set of thousands of packages for the
|
||||||
Packages are available for several platforms, and can be used with the Nix
|
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).
|
package manager on most GNU/Linux distributions as well as [NixOS](https://nixos.org/nixos).
|
||||||
|
|
||||||
This manual primarily describes how to write packages for the Nix Packages collection
|
This document is the user [_reference_](https://nix.dev/contributing/documentation/diataxis#reference) manual for Nixpkgs.
|
||||||
(Nixpkgs). Thus it’s mainly for packagers and developers who want to add packages to
|
It describes entire public interface of Nixpkgs in a concise and orderly manner, and all relevant behaviors, with examples and cross-references.
|
||||||
Nixpkgs. If you like to learn more about the Nix package manager and the Nix
|
|
||||||
expression language, then you are kindly referred to the [Nix manual](https://nixos.org/nix/manual/).
|
To discover other kinds of documentation:
|
||||||
The NixOS distribution is documented in the [NixOS manual](https://nixos.org/nixos/manual/).
|
- [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}
|
## Overview of Nixpkgs {#overview-of-nixpkgs}
|
||||||
|
|
||||||
|
|
|
@ -261,14 +261,50 @@ For more complex cases, like libraries linked into an executable which is then e
|
||||||
|
|
||||||
As described in the Nix manual, almost any `*.drv` store path in a derivation’s attribute set will induce a dependency on that derivation. `mkDerivation`, however, takes a few attributes intended to include all the dependencies of a package. This is done both for structure and consistency, but also so that certain other setup can take place. For example, certain dependencies need their bin directories added to the `PATH`. That is built-in, but other setup is done via a pluggable mechanism that works in conjunction with these dependency attributes. See [](#ssec-setup-hooks) for details.
|
As described in the Nix manual, almost any `*.drv` store path in a derivation’s attribute set will induce a dependency on that derivation. `mkDerivation`, however, takes a few attributes intended to include all the dependencies of a package. This is done both for structure and consistency, but also so that certain other setup can take place. For example, certain dependencies need their bin directories added to the `PATH`. That is built-in, but other setup is done via a pluggable mechanism that works in conjunction with these dependency attributes. See [](#ssec-setup-hooks) for details.
|
||||||
|
|
||||||
Dependencies can be broken down along three axes: their host and target platforms relative to the new derivation’s, and whether they are propagated. The platform distinctions are motivated by cross compilation; see [](#chap-cross) for exactly what each platform means. [^footnote-stdenv-ignored-build-platform] But even if one is not cross compiling, the platforms imply whether or not the dependency is needed at run-time or build-time, a concept that makes perfect sense outside of cross compilation. By default, the run-time/build-time distinction is just a hint for mental clarity, but with `strictDeps` set it is mostly enforced even in the native case.
|
Dependencies can be broken down along these axes: their host and target platforms relative to the new derivation’s. The platform distinctions are motivated by cross compilation; see [](#chap-cross) for exactly what each platform means. [^footnote-stdenv-ignored-build-platform] But even if one is not cross compiling, the platforms imply whether a dependency is needed at run-time or build-time.
|
||||||
|
|
||||||
The extension of `PATH` with dependencies, alluded to above, proceeds according to the relative platforms alone. The process is carried out only for dependencies whose host platform matches the new derivation’s build platform i.e. dependencies which run on the platform where the new derivation will be built. [^footnote-stdenv-native-dependencies-in-path] For each dependency \<dep\> of those dependencies, `dep/bin`, if present, is added to the `PATH` environment variable.
|
The extension of `PATH` with dependencies, alluded to above, proceeds according to the relative platforms alone. The process is carried out only for dependencies whose host platform matches the new derivation’s build platform i.e. dependencies which run on the platform where the new derivation will be built. [^footnote-stdenv-native-dependencies-in-path] For each dependency \<dep\> of those dependencies, `dep/bin`, if present, is added to the `PATH` environment variable.
|
||||||
|
|
||||||
A dependency is said to be **propagated** when some of its other-transitive (non-immediate) downstream dependencies also need it as an immediate dependency.
|
### Dependency propagation {#ssec-stdenv-dependencies-propagated}
|
||||||
[^footnote-stdenv-propagated-dependencies]
|
|
||||||
|
|
||||||
It is important to note that dependencies are not necessarily propagated as the same sort of dependency that they were before, but rather as the corresponding sort so that the platform rules still line up. To determine the exact rules for dependency propagation, we start by assigning to each dependency a couple of ternary numbers (`-1` for `build`, `0` for `host`, and `1` for `target`) representing its [dependency type](#possible-dependency-types), which captures how its host and target platforms are each "offset" from the depending derivation’s host and target platforms. The following table summarize the different combinations that can be obtained:
|
Propagated dependencies are made available to all downstream dependencies.
|
||||||
|
This is particularly useful for interpreted languages, where all transitive dependencies have to be present in the same environment.
|
||||||
|
Therefore it is used for the Python infrastructure in Nixpkgs.
|
||||||
|
|
||||||
|
:::{.note}
|
||||||
|
Propagated dependencies should be used with care, because they obscure the actual build inputs of dependent derivations and cause side effects through setup hooks.
|
||||||
|
This can lead to conflicting dependencies that cannot easily be resolved.
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::{.example}
|
||||||
|
# A propagated dependency
|
||||||
|
|
||||||
|
```nix
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
let
|
||||||
|
bar = stdenv.mkDerivation {
|
||||||
|
name = "bar";
|
||||||
|
dontUnpack = true;
|
||||||
|
# `hello` is also made available to dependents, such as `foo`
|
||||||
|
propagatedBuildInputs = [ hello ];
|
||||||
|
postInstall = "mkdir $out";
|
||||||
|
};
|
||||||
|
foo = stdenv.mkDerivation {
|
||||||
|
name = "foo";
|
||||||
|
dontUnpack = true;
|
||||||
|
# `bar` is a direct dependency, which implicitly includes the propagated `hello`
|
||||||
|
buildInputs = [ bar ];
|
||||||
|
# The `hello` binary is available!
|
||||||
|
postInstall = "hello > $out";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
foo
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
Dependency propagation takes cross compilation into account, meaning that dependencies that cross platform boundaries are properly adjusted.
|
||||||
|
|
||||||
|
To determine the exact rules for dependency propagation, we start by assigning to each dependency a couple of ternary numbers (`-1` for `build`, `0` for `host`, and `1` for `target`) representing its [dependency type](#possible-dependency-types), which captures how its host and target platforms are each "offset" from the depending derivation’s host and target platforms. The following table summarize the different combinations that can be obtained:
|
||||||
|
|
||||||
| `host → target` | attribute name | offset |
|
| `host → target` | attribute name | offset |
|
||||||
| ------------------- | ------------------- | -------- |
|
| ------------------- | ------------------- | -------- |
|
||||||
|
@ -591,7 +627,7 @@ See also the section about [`passthru.tests`](#var-meta-tests).
|
||||||
|
|
||||||
`stdenv.mkDerivation` sets the Nix [derivation](https://nixos.org/manual/nix/stable/expressions/derivations.html#derivations)'s builder to a script that loads the stdenv `setup.sh` bash library and calls `genericBuild`. Most packaging functions rely on this default builder.
|
`stdenv.mkDerivation` sets the Nix [derivation](https://nixos.org/manual/nix/stable/expressions/derivations.html#derivations)'s builder to a script that loads the stdenv `setup.sh` bash library and calls `genericBuild`. Most packaging functions rely on this default builder.
|
||||||
|
|
||||||
This generic command invokes a number of *phases*. Package builds are split into phases to make it easier to override specific parts of the build (e.g., unpacking the sources or installing the binaries).
|
This generic command either invokes a script at *buildCommandPath*, or a *buildCommand*, or a number of *phases*. Package builds are split into phases to make it easier to override specific parts of the build (e.g., unpacking the sources or installing the binaries).
|
||||||
|
|
||||||
Each phase can be overridden in its entirety either by setting the environment variable `namePhase` to a string containing some shell commands to be executed, or by redefining the shell function `namePhase`. The former is convenient to override a phase from the derivation, while the latter is convenient from a build script. However, typically one only wants to *add* some commands to a phase, e.g. by defining `postInstall` or `preFixup`, as skipping some of the default actions may have unexpected consequences. The default script for each phase is defined in the file `pkgs/stdenv/generic/setup.sh`.
|
Each phase can be overridden in its entirety either by setting the environment variable `namePhase` to a string containing some shell commands to be executed, or by redefining the shell function `namePhase`. The former is convenient to override a phase from the derivation, while the latter is convenient from a build script. However, typically one only wants to *add* some commands to a phase, e.g. by defining `postInstall` or `preFixup`, as skipping some of the default actions may have unexpected consequences. The default script for each phase is defined in the file `pkgs/stdenv/generic/setup.sh`.
|
||||||
|
|
||||||
|
@ -831,7 +867,7 @@ Note that shell arrays cannot be passed through environment variables, so you ca
|
||||||
|
|
||||||
##### `buildFlags` / `buildFlagsArray` {#var-stdenv-buildFlags}
|
##### `buildFlags` / `buildFlagsArray` {#var-stdenv-buildFlags}
|
||||||
|
|
||||||
A list of strings passed as additional flags to `make`. Like `makeFlags` and `makeFlagsArray`, but only used by the build phase.
|
A list of strings passed as additional flags to `make`. Like `makeFlags` and `makeFlagsArray`, but only used by the build phase. Any build targets should be specified as part of the `buildFlags`.
|
||||||
|
|
||||||
##### `preBuild` {#var-stdenv-preBuild}
|
##### `preBuild` {#var-stdenv-preBuild}
|
||||||
|
|
||||||
|
@ -872,7 +908,7 @@ If unset, use `check` if it exists, otherwise `test`; if neither is found, do no
|
||||||
|
|
||||||
##### `checkFlags` / `checkFlagsArray` {#var-stdenv-checkFlags}
|
##### `checkFlags` / `checkFlagsArray` {#var-stdenv-checkFlags}
|
||||||
|
|
||||||
A list of strings passed as additional flags to `make`. Like `makeFlags` and `makeFlagsArray`, but only used by the check phase.
|
A list of strings passed as additional flags to `make`. Like `makeFlags` and `makeFlagsArray`, but only used by the check phase. Unlike with `buildFlags`, the `checkTarget` is automatically added to the `make` invocation in addition to any `checkFlags` specified.
|
||||||
|
|
||||||
##### `checkInputs` {#var-stdenv-checkInputs}
|
##### `checkInputs` {#var-stdenv-checkInputs}
|
||||||
|
|
||||||
|
@ -914,7 +950,7 @@ installTargets = "install-bin install-doc";
|
||||||
|
|
||||||
##### `installFlags` / `installFlagsArray` {#var-stdenv-installFlags}
|
##### `installFlags` / `installFlagsArray` {#var-stdenv-installFlags}
|
||||||
|
|
||||||
A list of strings passed as additional flags to `make`. Like `makeFlags` and `makeFlagsArray`, but only used by the install phase.
|
A list of strings passed as additional flags to `make`. Like `makeFlags` and `makeFlagsArray`, but only used by the install phase. Unlike with `buildFlags`, the `installTargets` are automatically added to the `make` invocation in addition to any `installFlags` specified.
|
||||||
|
|
||||||
##### `preInstall` {#var-stdenv-preInstall}
|
##### `preInstall` {#var-stdenv-preInstall}
|
||||||
|
|
||||||
|
|
109
doc/tests/manpage-urls.py
Executable file
109
doc/tests/manpage-urls.py
Executable file
|
@ -0,0 +1,109 @@
|
||||||
|
#! /usr/bin/env nix-shell
|
||||||
|
#! nix-shell -i "python3 -I" -p "python3.withPackages(p: with p; [ aiohttp rich structlog ])"
|
||||||
|
|
||||||
|
from argparse import ArgumentParser, Namespace
|
||||||
|
from collections import defaultdict
|
||||||
|
from collections.abc import Mapping, Sequence
|
||||||
|
from enum import IntEnum
|
||||||
|
from http import HTTPStatus
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Optional
|
||||||
|
import asyncio, json, logging
|
||||||
|
|
||||||
|
import aiohttp, structlog
|
||||||
|
from structlog.contextvars import bound_contextvars as log_context
|
||||||
|
|
||||||
|
|
||||||
|
LogLevel = IntEnum('LogLevel', {
|
||||||
|
lvl: getattr(logging, lvl)
|
||||||
|
for lvl in ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')
|
||||||
|
})
|
||||||
|
LogLevel.__str__ = lambda self: self.name
|
||||||
|
|
||||||
|
|
||||||
|
EXPECTED_STATUS=frozenset((
|
||||||
|
HTTPStatus.OK, HTTPStatus.FOUND,
|
||||||
|
HTTPStatus.NOT_FOUND,
|
||||||
|
))
|
||||||
|
|
||||||
|
async def check(session: aiohttp.ClientSession, manpage: str, url: str) -> HTTPStatus:
|
||||||
|
with log_context(manpage=manpage, url=url):
|
||||||
|
logger.debug("Checking")
|
||||||
|
async with session.head(url) as resp:
|
||||||
|
st = HTTPStatus(resp.status)
|
||||||
|
match st:
|
||||||
|
case HTTPStatus.OK | HTTPStatus.FOUND:
|
||||||
|
logger.debug("OK!")
|
||||||
|
case HTTPStatus.NOT_FOUND:
|
||||||
|
logger.error("Broken link!")
|
||||||
|
case _ if st < 400:
|
||||||
|
logger.info("Unexpected code", status=st)
|
||||||
|
case _ if 400 <= st < 600:
|
||||||
|
logger.warn("Unexpected error", status=st)
|
||||||
|
|
||||||
|
return st
|
||||||
|
|
||||||
|
async def main(urls_path: Path) -> Mapping[HTTPStatus, int]:
|
||||||
|
logger.info(f"Parsing {urls_path}")
|
||||||
|
with urls_path.open() as urls_file:
|
||||||
|
urls = json.load(urls_file)
|
||||||
|
|
||||||
|
count: defaultdict[HTTPStatus, int] = defaultdict(lambda: 0)
|
||||||
|
|
||||||
|
logger.info(f"Checking URLs from {urls_path}")
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
for status in asyncio.as_completed([
|
||||||
|
check(session, manpage, url)
|
||||||
|
for manpage, url in urls.items()
|
||||||
|
]):
|
||||||
|
count[await status]+=1
|
||||||
|
|
||||||
|
ok = count[HTTPStatus.OK] + count[HTTPStatus.FOUND]
|
||||||
|
broken = count[HTTPStatus.NOT_FOUND]
|
||||||
|
unknown = sum(c for st, c in count.items() if st not in EXPECTED_STATUS)
|
||||||
|
logger.info(f"Done: {broken} broken links, "
|
||||||
|
f"{ok} correct links, and {unknown} unexpected status")
|
||||||
|
|
||||||
|
return count
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args(args: Optional[Sequence[str]] = None) -> Namespace:
|
||||||
|
parser = ArgumentParser(
|
||||||
|
prog = 'check-manpage-urls',
|
||||||
|
description = 'Check the validity of the manpage URLs linked in the nixpkgs manual',
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'-l', '--log-level',
|
||||||
|
default = os.getenv('LOG_LEVEL', 'INFO'),
|
||||||
|
type = lambda s: LogLevel[s],
|
||||||
|
choices = list(LogLevel),
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'file',
|
||||||
|
type = Path,
|
||||||
|
nargs = '?',
|
||||||
|
)
|
||||||
|
|
||||||
|
return parser.parse_args(args)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import os, sys
|
||||||
|
|
||||||
|
args = parse_args()
|
||||||
|
|
||||||
|
structlog.configure(
|
||||||
|
wrapper_class=structlog.make_filtering_bound_logger(args.log_level),
|
||||||
|
)
|
||||||
|
logger = structlog.getLogger("check-manpage-urls.py")
|
||||||
|
|
||||||
|
urls_path = args.file
|
||||||
|
if urls_path is None:
|
||||||
|
REPO_ROOT = Path(__file__).parent.parent.parent.parent
|
||||||
|
logger.info(f"Assuming we are in a nixpkgs repo rooted at {REPO_ROOT}")
|
||||||
|
|
||||||
|
urls_path = REPO_ROOT / 'doc' / 'manpage-urls.json'
|
||||||
|
|
||||||
|
count = asyncio.run(main(urls_path))
|
||||||
|
|
||||||
|
sys.exit(0 if count[HTTPStatus.NOT_FOUND] == 0 else 1)
|
43
flake.nix
43
flake.nix
|
@ -9,7 +9,8 @@
|
||||||
nixpkgs = self;
|
nixpkgs = self;
|
||||||
};
|
};
|
||||||
|
|
||||||
lib = import ./lib;
|
libVersionInfoOverlay = import ./lib/flake-version-info.nix self;
|
||||||
|
lib = (import ./lib).extend libVersionInfoOverlay;
|
||||||
|
|
||||||
forAllSystems = lib.genAttrs lib.systems.flakeExposed;
|
forAllSystems = lib.genAttrs lib.systems.flakeExposed;
|
||||||
in
|
in
|
||||||
|
@ -20,22 +21,38 @@
|
||||||
|
|
||||||
nixosSystem = args:
|
nixosSystem = args:
|
||||||
import ./nixos/lib/eval-config.nix (
|
import ./nixos/lib/eval-config.nix (
|
||||||
args // {
|
{
|
||||||
modules = args.modules ++ [{
|
lib = final;
|
||||||
system.nixos.versionSuffix =
|
|
||||||
".${final.substring 0 8 (self.lastModifiedDate or self.lastModified or "19700101")}.${self.shortRev or "dirty"}";
|
|
||||||
system.nixos.revision = final.mkIf (self ? rev) self.rev;
|
|
||||||
}];
|
|
||||||
} // lib.optionalAttrs (! args?system) {
|
|
||||||
# Allow system to be set modularly in nixpkgs.system.
|
# Allow system to be set modularly in nixpkgs.system.
|
||||||
# We set it to null, to remove the "legacy" entrypoint's
|
# We set it to null, to remove the "legacy" entrypoint's
|
||||||
# non-hermetic default.
|
# non-hermetic default.
|
||||||
system = null;
|
system = null;
|
||||||
}
|
} // args
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
checks.x86_64-linux.tarball = jobs.tarball;
|
checks.x86_64-linux = {
|
||||||
|
tarball = jobs.tarball;
|
||||||
|
# Test that ensures that the nixosSystem function can accept a lib argument
|
||||||
|
# Note: prefer not to extend or modify `lib`, especially if you want to share reusable modules
|
||||||
|
# alternatives include: `import` a file, or put a custom library in an option or in `_module.args.<libname>`
|
||||||
|
nixosSystemAcceptsLib = (self.lib.nixosSystem {
|
||||||
|
lib = self.lib.extend (final: prev: {
|
||||||
|
ifThisFunctionIsMissingTheTestFails = final.id;
|
||||||
|
});
|
||||||
|
modules = [
|
||||||
|
./nixos/modules/profiles/minimal.nix
|
||||||
|
({ lib, ... }: lib.ifThisFunctionIsMissingTheTestFails {
|
||||||
|
# Define a minimal config without eval warnings
|
||||||
|
nixpkgs.hostPlatform = "x86_64-linux";
|
||||||
|
boot.loader.grub.enable = false;
|
||||||
|
fileSystems."/".device = "nodev";
|
||||||
|
# See https://search.nixos.org/options?show=system.stateVersion&query=stateversion
|
||||||
|
system.stateVersion = lib.versions.majorMinor lib.version; # DON'T do this in real configs!
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}).config.system.build.toplevel;
|
||||||
|
};
|
||||||
|
|
||||||
htmlDocs = {
|
htmlDocs = {
|
||||||
nixpkgsManual = jobs.manual;
|
nixpkgsManual = jobs.manual;
|
||||||
|
@ -53,7 +70,11 @@
|
||||||
# attribute it displays `omitted` instead of evaluating all packages,
|
# attribute it displays `omitted` instead of evaluating all packages,
|
||||||
# which keeps `nix flake show` on Nixpkgs reasonably fast, though less
|
# which keeps `nix flake show` on Nixpkgs reasonably fast, though less
|
||||||
# information rich.
|
# information rich.
|
||||||
legacyPackages = forAllSystems (system: import ./. { inherit system; });
|
legacyPackages = forAllSystems (system:
|
||||||
|
(import ./. { inherit system; }).extend (final: prev: {
|
||||||
|
lib = prev.lib.extend libVersionInfoOverlay;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
nixosModules = {
|
nixosModules = {
|
||||||
notDetected = ./nixos/modules/installer/scan/not-detected.nix;
|
notDetected = ./nixos/modules/installer/scan/not-detected.nix;
|
||||||
|
|
|
@ -36,13 +36,76 @@ The [module system](https://nixos.org/manual/nixpkgs/#module-system) spans multi
|
||||||
- [`options.nix`](options.nix): `lib.options` for anything relating to option definitions
|
- [`options.nix`](options.nix): `lib.options` for anything relating to option definitions
|
||||||
- [`types.nix`](types.nix): `lib.types` for module system types
|
- [`types.nix`](types.nix): `lib.types` for module system types
|
||||||
|
|
||||||
|
## PR Guidelines
|
||||||
|
|
||||||
|
Follow these guidelines for proposing a change to the interface of `lib`.
|
||||||
|
|
||||||
|
### Provide a Motivation
|
||||||
|
|
||||||
|
Clearly describe why the change is necessary and its use cases.
|
||||||
|
|
||||||
|
Make sure that the change benefits the user more than the added mental effort of looking it up and keeping track of its definition.
|
||||||
|
If the same can reasonably be done with the existing interface,
|
||||||
|
consider just updating the documentation with more examples and links.
|
||||||
|
This is also known as the [Fairbairn Threshold](https://wiki.haskell.org/Fairbairn_threshold).
|
||||||
|
|
||||||
|
Through this principle we avoid the human cost of duplicated functionality in an overly large library.
|
||||||
|
|
||||||
|
### Make one PR for each change
|
||||||
|
|
||||||
|
Don't have multiple changes in one PR, instead split it up into multiple ones.
|
||||||
|
|
||||||
|
This keeps the conversation focused and has a higher chance of getting merged.
|
||||||
|
|
||||||
|
### Name the interface appropriately
|
||||||
|
|
||||||
|
When introducing new names to the interface, such as new function, or new function attributes,
|
||||||
|
make sure to name it appropriately.
|
||||||
|
|
||||||
|
Names should be self-explanatory and consistent with the rest of `lib`.
|
||||||
|
If there's no obvious best name, include the alternatives you considered.
|
||||||
|
|
||||||
|
### Write documentation
|
||||||
|
|
||||||
|
Update the [reference documentation](#reference-documentation) to reflect the change.
|
||||||
|
|
||||||
|
Be generous with links to related functionality.
|
||||||
|
|
||||||
|
### Write tests
|
||||||
|
|
||||||
|
Add good test coverage for the change, including:
|
||||||
|
|
||||||
|
- Tests for edge cases, such as empty values or lists.
|
||||||
|
- Tests for tricky inputs, such as a string with string context or a path that doesn't exist.
|
||||||
|
- Test all code paths, such as `if-then-else` branches and returned attributes.
|
||||||
|
- If the tests for the sub-library are written in bash,
|
||||||
|
test messages of custom errors, such as `throw` or `abortMsg`,
|
||||||
|
|
||||||
|
At the time this is only not necessary for sub-libraries tested with [`tests/misc.nix`](./tests/misc.nix).
|
||||||
|
|
||||||
|
See [running tests](#running-tests) for more details on the test suites.
|
||||||
|
|
||||||
|
### Write tidy code
|
||||||
|
|
||||||
|
Name variables well, even if they're internal.
|
||||||
|
The code should be as self-explanatory as possible.
|
||||||
|
Be generous with code comments when appropriate.
|
||||||
|
|
||||||
|
As a baseline, follow the [Nixpkgs code conventions](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md#code-conventions).
|
||||||
|
|
||||||
|
### Write efficient code
|
||||||
|
|
||||||
|
Nix generally does not have free abstractions.
|
||||||
|
Be aware that seemingly straightforward changes can cause more allocations and a decrease in performance.
|
||||||
|
That said, don't optimise prematurely, especially in new code.
|
||||||
|
|
||||||
## Reference documentation
|
## Reference documentation
|
||||||
|
|
||||||
Reference documentation for library functions is written above each function as a multi-line comment.
|
Reference documentation for library functions is written above each function as a multi-line comment.
|
||||||
These comments are processed using [nixdoc](https://github.com/nix-community/nixdoc) and [rendered in the Nixpkgs manual](https://nixos.org/manual/nixpkgs/stable/#chap-functions).
|
These comments are processed using [nixdoc](https://github.com/nix-community/nixdoc) and [rendered in the Nixpkgs manual](https://nixos.org/manual/nixpkgs/stable/#chap-functions).
|
||||||
The nixdoc README describes the [comment format](https://github.com/nix-community/nixdoc#comment-format).
|
The nixdoc README describes the [comment format](https://github.com/nix-community/nixdoc#comment-format).
|
||||||
|
|
||||||
See the [chapter on contributing to the Nixpkgs manual](https://nixos.org/manual/nixpkgs/#chap-contributing) for how to build the manual.
|
See [doc/README.md](../doc/README.md) for how to build the manual.
|
||||||
|
|
||||||
## Running tests
|
## Running tests
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,14 @@ rec {
|
||||||
|
|
||||||
/* Return an attribute from nested attribute sets.
|
/* Return an attribute from nested attribute sets.
|
||||||
|
|
||||||
|
Nix has an [attribute selection operator `. or`](https://nixos.org/manual/nix/stable/language/operators#attribute-selection) which is sufficient for such queries, as long as the number of attributes is static. For example:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
(x.a.b or 6) == attrByPath ["a" "b"] 6 x
|
||||||
|
# and
|
||||||
|
(x.${f p}."example.com" or 6) == attrByPath [ (f p) "example.com" ] 6 x
|
||||||
|
```
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
x = { a = { b = 3; }; }
|
x = { a = { b = 3; }; }
|
||||||
# ["a" "b"] is equivalent to x.a.b
|
# ["a" "b"] is equivalent to x.a.b
|
||||||
|
@ -51,12 +59,27 @@ rec {
|
||||||
|
|
||||||
/* Return if an attribute from nested attribute set exists.
|
/* Return if an attribute from nested attribute set exists.
|
||||||
|
|
||||||
|
Nix has a [has attribute operator `?`](https://nixos.org/manual/nix/stable/language/operators#has-attribute), which is sufficient for such queries, as long as the number of attributes is static. For example:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
(x?a.b) == hasAttryByPath ["a" "b"] x
|
||||||
|
# and
|
||||||
|
(x?${f p}."example.com") == hasAttryByPath [ (f p) "example.com" ] x
|
||||||
|
```
|
||||||
|
|
||||||
|
**Laws**:
|
||||||
|
1. ```nix
|
||||||
|
hasAttrByPath [] x == true
|
||||||
|
```
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
x = { a = { b = 3; }; }
|
x = { a = { b = 3; }; }
|
||||||
hasAttrByPath ["a" "b"] x
|
hasAttrByPath ["a" "b"] x
|
||||||
=> true
|
=> true
|
||||||
hasAttrByPath ["z" "z"] x
|
hasAttrByPath ["z" "z"] x
|
||||||
=> false
|
=> false
|
||||||
|
hasAttrByPath [] (throw "no need")
|
||||||
|
=> true
|
||||||
|
|
||||||
Type:
|
Type:
|
||||||
hasAttrByPath :: [String] -> AttrSet -> Bool
|
hasAttrByPath :: [String] -> AttrSet -> Bool
|
||||||
|
@ -80,6 +103,71 @@ rec {
|
||||||
in
|
in
|
||||||
hasAttrByPath' 0 e;
|
hasAttrByPath' 0 e;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Return the longest prefix of an attribute path that refers to an existing attribute in a nesting of attribute sets.
|
||||||
|
|
||||||
|
Can be used after [`mapAttrsRecursiveCond`](#function-library-lib.attrsets.mapAttrsRecursiveCond) to apply a condition,
|
||||||
|
although this will evaluate the predicate function on sibling attributes as well.
|
||||||
|
|
||||||
|
Note that the empty attribute path is valid for all values, so this function only throws an exception if any of its inputs does.
|
||||||
|
|
||||||
|
**Laws**:
|
||||||
|
1. ```nix
|
||||||
|
attrsets.longestValidPathPrefix [] x == []
|
||||||
|
```
|
||||||
|
|
||||||
|
2. ```nix
|
||||||
|
hasAttrByPath (attrsets.longestValidPathPrefix p x) x == true
|
||||||
|
```
|
||||||
|
|
||||||
|
Example:
|
||||||
|
x = { a = { b = 3; }; }
|
||||||
|
attrsets.longestValidPathPrefix ["a" "b" "c"] x
|
||||||
|
=> ["a" "b"]
|
||||||
|
attrsets.longestValidPathPrefix ["a"] x
|
||||||
|
=> ["a"]
|
||||||
|
attrsets.longestValidPathPrefix ["z" "z"] x
|
||||||
|
=> []
|
||||||
|
attrsets.longestValidPathPrefix ["z" "z"] (throw "no need")
|
||||||
|
=> []
|
||||||
|
|
||||||
|
Type:
|
||||||
|
attrsets.longestValidPathPrefix :: [String] -> Value -> [String]
|
||||||
|
*/
|
||||||
|
longestValidPathPrefix =
|
||||||
|
# A list of strings representing the longest possible path that may be returned.
|
||||||
|
attrPath:
|
||||||
|
# The nested attribute set to check.
|
||||||
|
v:
|
||||||
|
let
|
||||||
|
lenAttrPath = length attrPath;
|
||||||
|
getPrefixForSetAtIndex =
|
||||||
|
# The nested attribute set to check, if it is an attribute set, which
|
||||||
|
# is not a given.
|
||||||
|
remainingSet:
|
||||||
|
# The index of the attribute we're about to check, as well as
|
||||||
|
# the length of the prefix we've already checked.
|
||||||
|
remainingPathIndex:
|
||||||
|
|
||||||
|
if remainingPathIndex == lenAttrPath then
|
||||||
|
# All previously checked attributes exist, and no attr names left,
|
||||||
|
# so we return the whole path.
|
||||||
|
attrPath
|
||||||
|
else
|
||||||
|
let
|
||||||
|
attr = elemAt attrPath remainingPathIndex;
|
||||||
|
in
|
||||||
|
if remainingSet ? ${attr} then
|
||||||
|
getPrefixForSetAtIndex
|
||||||
|
remainingSet.${attr} # advance from the set to the attribute value
|
||||||
|
(remainingPathIndex + 1) # advance the path
|
||||||
|
else
|
||||||
|
# The attribute doesn't exist, so we return the prefix up to the
|
||||||
|
# previously checked length.
|
||||||
|
take remainingPathIndex attrPath;
|
||||||
|
in
|
||||||
|
getPrefixForSetAtIndex v 0;
|
||||||
|
|
||||||
/* Create a new attribute set with `value` set at the nested attribute location specified in `attrPath`.
|
/* Create a new attribute set with `value` set at the nested attribute location specified in `attrPath`.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
@ -105,6 +193,14 @@ rec {
|
||||||
/* Like `attrByPath`, but without a default value. If it doesn't find the
|
/* Like `attrByPath`, but without a default value. If it doesn't find the
|
||||||
path it will throw an error.
|
path it will throw an error.
|
||||||
|
|
||||||
|
Nix has an [attribute selection operator](https://nixos.org/manual/nix/stable/language/operators#attribute-selection) which is sufficient for such queries, as long as the number of attributes is static. For example:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
x.a.b == getAttrByPath ["a" "b"] x
|
||||||
|
# and
|
||||||
|
x.${f p}."example.com" == getAttrByPath [ (f p) "example.com" ] x
|
||||||
|
```
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
x = { a = { b = 3; }; }
|
x = { a = { b = 3; }; }
|
||||||
getAttrFromPath ["a" "b"] x
|
getAttrFromPath ["a" "b"] x
|
||||||
|
|
|
@ -5,7 +5,7 @@ let
|
||||||
intersectAttrs;
|
intersectAttrs;
|
||||||
inherit (lib)
|
inherit (lib)
|
||||||
functionArgs isFunction mirrorFunctionArgs isAttrs setFunctionArgs
|
functionArgs isFunction mirrorFunctionArgs isAttrs setFunctionArgs
|
||||||
optionalAttrs attrNames filter elemAt concatStringsSep sort take length
|
optionalAttrs attrNames filter elemAt concatStringsSep sortOn take length
|
||||||
filterAttrs optionalString flip pathIsDirectory head pipe isDerivation listToAttrs
|
filterAttrs optionalString flip pathIsDirectory head pipe isDerivation listToAttrs
|
||||||
mapAttrs seq flatten deepSeq warnIf isInOldestRelease extends
|
mapAttrs seq flatten deepSeq warnIf isInOldestRelease extends
|
||||||
;
|
;
|
||||||
|
@ -174,7 +174,7 @@ rec {
|
||||||
# levenshteinAtMost is only fast for 2 or less.
|
# levenshteinAtMost is only fast for 2 or less.
|
||||||
(filter (levenshteinAtMost 2 arg))
|
(filter (levenshteinAtMost 2 arg))
|
||||||
# Put strings with shorter distance first
|
# Put strings with shorter distance first
|
||||||
(sort (x: y: levenshtein x arg < levenshtein y arg))
|
(sortOn (levenshtein arg))
|
||||||
# Only take the first couple results
|
# Only take the first couple results
|
||||||
(take 3)
|
(take 3)
|
||||||
# Quote all entries
|
# Quote all entries
|
||||||
|
|
|
@ -91,7 +91,7 @@ let
|
||||||
inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1
|
inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1
|
||||||
concatMap flatten remove findSingle findFirst any all count
|
concatMap flatten remove findSingle findFirst any all count
|
||||||
optional optionals toList range replicate partition zipListsWith zipLists
|
optional optionals toList range replicate partition zipListsWith zipLists
|
||||||
reverseList listDfs toposort sort naturalSort compareLists take
|
reverseList listDfs toposort sort sortOn naturalSort compareLists take
|
||||||
drop sublist last init crossLists unique allUnique intersectLists
|
drop sublist last init crossLists unique allUnique intersectLists
|
||||||
subtractLists mutuallyExclusive groupBy groupBy';
|
subtractLists mutuallyExclusive groupBy groupBy';
|
||||||
inherit (self.strings) concatStrings concatMapStrings concatImapStrings
|
inherit (self.strings) concatStrings concatMapStrings concatImapStrings
|
||||||
|
@ -120,7 +120,8 @@ let
|
||||||
inherit (self.meta) addMetaAttrs dontDistribute setName updateName
|
inherit (self.meta) addMetaAttrs dontDistribute setName updateName
|
||||||
appendToName mapDerivationAttrset setPrio lowPrio lowPrioSet hiPrio
|
appendToName mapDerivationAttrset setPrio lowPrio lowPrioSet hiPrio
|
||||||
hiPrioSet getLicenseFromSpdxId getExe getExe';
|
hiPrioSet getLicenseFromSpdxId getExe getExe';
|
||||||
inherit (self.filesystem) pathType pathIsDirectory pathIsRegularFile;
|
inherit (self.filesystem) pathType pathIsDirectory pathIsRegularFile
|
||||||
|
packagesFromDirectoryRecursive;
|
||||||
inherit (self.sources) cleanSourceFilter
|
inherit (self.sources) cleanSourceFilter
|
||||||
cleanSource sourceByRegex sourceFilesBySuffices
|
cleanSource sourceByRegex sourceFilesBySuffices
|
||||||
commitIdFromGitRepo cleanSourceWith pathHasContext
|
commitIdFromGitRepo cleanSourceWith pathHasContext
|
||||||
|
|
|
@ -107,7 +107,7 @@ let
|
||||||
_printFileset
|
_printFileset
|
||||||
_intersection
|
_intersection
|
||||||
_difference
|
_difference
|
||||||
_mirrorStorePath
|
_fromFetchGit
|
||||||
_fetchGitSubmodulesMinver
|
_fetchGitSubmodulesMinver
|
||||||
_emptyWithoutBase
|
_emptyWithoutBase
|
||||||
;
|
;
|
||||||
|
@ -148,7 +148,6 @@ let
|
||||||
inherit (lib.trivial)
|
inherit (lib.trivial)
|
||||||
isFunction
|
isFunction
|
||||||
pipe
|
pipe
|
||||||
inPureEvalMode
|
|
||||||
;
|
;
|
||||||
|
|
||||||
in {
|
in {
|
||||||
|
@ -754,23 +753,22 @@ in {
|
||||||
This directory must contain a `.git` file or subdirectory.
|
This directory must contain a `.git` file or subdirectory.
|
||||||
*/
|
*/
|
||||||
path:
|
path:
|
||||||
# See the gitTrackedWith implementation for more explanatory comments
|
_fromFetchGit
|
||||||
let
|
"gitTracked"
|
||||||
fetchResult = builtins.fetchGit path;
|
"argument"
|
||||||
in
|
path
|
||||||
if inPureEvalMode then
|
{};
|
||||||
throw "lib.fileset.gitTracked: This function is currently not supported in pure evaluation mode, since it currently relies on `builtins.fetchGit`. See https://github.com/NixOS/nix/issues/9292."
|
|
||||||
else if ! isPath path then
|
|
||||||
throw "lib.fileset.gitTracked: Expected the argument to be a path, but it's a ${typeOf path} instead."
|
|
||||||
else if ! pathExists (path + "/.git") then
|
|
||||||
throw "lib.fileset.gitTracked: Expected the argument (${toString path}) to point to a local working tree of a Git repository, but it's not."
|
|
||||||
else
|
|
||||||
_mirrorStorePath path fetchResult.outPath;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create a file set containing all [Git-tracked files](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository) in a repository.
|
Create a file set containing all [Git-tracked files](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository) in a repository.
|
||||||
The first argument allows configuration with an attribute set,
|
The first argument allows configuration with an attribute set,
|
||||||
while the second argument is the path to the Git working tree.
|
while the second argument is the path to the Git working tree.
|
||||||
|
|
||||||
|
`gitTrackedWith` does not perform any filtering when the path is a [Nix store path](https://nixos.org/manual/nix/stable/store/store-path.html#store-path) and not a repository.
|
||||||
|
In this way, it accommodates the use case where the expression that makes the `gitTracked` call does not reside in an actual git repository anymore,
|
||||||
|
and has presumably already been fetched in a way that excludes untracked files.
|
||||||
|
Fetchers with such equivalent behavior include `builtins.fetchGit`, `builtins.fetchTree` (experimental), and `pkgs.fetchgit` when used without `leaveDotGit`.
|
||||||
|
|
||||||
If you don't need the configuration,
|
If you don't need the configuration,
|
||||||
you can use [`gitTracked`](#function-library-lib.fileset.gitTracked) instead.
|
you can use [`gitTracked`](#function-library-lib.fileset.gitTracked) instead.
|
||||||
|
|
||||||
|
@ -807,35 +805,19 @@ in {
|
||||||
This directory must contain a `.git` file or subdirectory.
|
This directory must contain a `.git` file or subdirectory.
|
||||||
*/
|
*/
|
||||||
path:
|
path:
|
||||||
let
|
if ! isBool recurseSubmodules then
|
||||||
# This imports the files unnecessarily, which currently can't be avoided
|
|
||||||
# because `builtins.fetchGit` is the only function exposing which files are tracked by Git.
|
|
||||||
# With the [lazy trees PR](https://github.com/NixOS/nix/pull/6530),
|
|
||||||
# the unnecessarily import could be avoided.
|
|
||||||
# However a simpler alternative still would be [a builtins.gitLsFiles](https://github.com/NixOS/nix/issues/2944).
|
|
||||||
fetchResult = builtins.fetchGit {
|
|
||||||
url = path;
|
|
||||||
|
|
||||||
# This is the only `fetchGit` parameter that makes sense in this context.
|
|
||||||
# We can't just pass `submodules = recurseSubmodules` here because
|
|
||||||
# this would fail for Nix versions that don't support `submodules`.
|
|
||||||
${if recurseSubmodules then "submodules" else null} = true;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
if inPureEvalMode then
|
|
||||||
throw "lib.fileset.gitTrackedWith: This function is currently not supported in pure evaluation mode, since it currently relies on `builtins.fetchGit`. See https://github.com/NixOS/nix/issues/9292."
|
|
||||||
else if ! isBool recurseSubmodules then
|
|
||||||
throw "lib.fileset.gitTrackedWith: Expected the attribute `recurseSubmodules` of the first argument to be a boolean, but it's a ${typeOf recurseSubmodules} instead."
|
throw "lib.fileset.gitTrackedWith: Expected the attribute `recurseSubmodules` of the first argument to be a boolean, but it's a ${typeOf recurseSubmodules} instead."
|
||||||
else if recurseSubmodules && versionOlder nixVersion _fetchGitSubmodulesMinver then
|
else if recurseSubmodules && versionOlder nixVersion _fetchGitSubmodulesMinver then
|
||||||
throw "lib.fileset.gitTrackedWith: Setting the attribute `recurseSubmodules` to `true` is only supported for Nix version ${_fetchGitSubmodulesMinver} and after, but Nix version ${nixVersion} is used."
|
throw "lib.fileset.gitTrackedWith: Setting the attribute `recurseSubmodules` to `true` is only supported for Nix version ${_fetchGitSubmodulesMinver} and after, but Nix version ${nixVersion} is used."
|
||||||
else if ! isPath path then
|
|
||||||
throw "lib.fileset.gitTrackedWith: Expected the second argument to be a path, but it's a ${typeOf path} instead."
|
|
||||||
# We can identify local working directories by checking for .git,
|
|
||||||
# see https://git-scm.com/docs/gitrepository-layout#_description.
|
|
||||||
# Note that `builtins.fetchGit` _does_ work for bare repositories (where there's no `.git`),
|
|
||||||
# even though `git ls-files` wouldn't return any files in that case.
|
|
||||||
else if ! pathExists (path + "/.git") then
|
|
||||||
throw "lib.fileset.gitTrackedWith: Expected the second argument (${toString path}) to point to a local working tree of a Git repository, but it's not."
|
|
||||||
else
|
else
|
||||||
_mirrorStorePath path fetchResult.outPath;
|
_fromFetchGit
|
||||||
|
"gitTrackedWith"
|
||||||
|
"second argument"
|
||||||
|
path
|
||||||
|
# This is the only `fetchGit` parameter that makes sense in this context.
|
||||||
|
# We can't just pass `submodules = recurseSubmodules` here because
|
||||||
|
# this would fail for Nix versions that don't support `submodules`.
|
||||||
|
(lib.optionalAttrs recurseSubmodules {
|
||||||
|
submodules = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ let
|
||||||
split
|
split
|
||||||
trace
|
trace
|
||||||
typeOf
|
typeOf
|
||||||
|
fetchGit
|
||||||
;
|
;
|
||||||
|
|
||||||
inherit (lib.attrsets)
|
inherit (lib.attrsets)
|
||||||
|
@ -40,6 +41,8 @@ let
|
||||||
inherit (lib.path)
|
inherit (lib.path)
|
||||||
append
|
append
|
||||||
splitRoot
|
splitRoot
|
||||||
|
hasStorePathPrefix
|
||||||
|
splitStorePath
|
||||||
;
|
;
|
||||||
|
|
||||||
inherit (lib.path.subpath)
|
inherit (lib.path.subpath)
|
||||||
|
@ -55,6 +58,9 @@ let
|
||||||
hasSuffix
|
hasSuffix
|
||||||
;
|
;
|
||||||
|
|
||||||
|
inherit (lib.trivial)
|
||||||
|
inPureEvalMode
|
||||||
|
;
|
||||||
in
|
in
|
||||||
# Rare case of justified usage of rec:
|
# Rare case of justified usage of rec:
|
||||||
# - This file is internal, so the return value doesn't matter, no need to make things overridable
|
# - This file is internal, so the return value doesn't matter, no need to make things overridable
|
||||||
|
@ -852,4 +858,61 @@ rec {
|
||||||
in
|
in
|
||||||
_create localPath
|
_create localPath
|
||||||
(recurse storePath);
|
(recurse storePath);
|
||||||
|
|
||||||
|
# Create a file set from the files included in the result of a fetchGit call
|
||||||
|
# Type: String -> String -> Path -> Attrs -> FileSet
|
||||||
|
_fromFetchGit = function: argument: path: extraFetchGitAttrs:
|
||||||
|
let
|
||||||
|
# The code path for when isStorePath is true
|
||||||
|
tryStorePath =
|
||||||
|
if pathExists (path + "/.git") then
|
||||||
|
# If there is a `.git` directory in the path,
|
||||||
|
# it means that the path was imported unfiltered into the Nix store.
|
||||||
|
# This function should throw in such a case, because
|
||||||
|
# - `fetchGit` doesn't generally work with `.git` directories in store paths
|
||||||
|
# - Importing the entire path could include Git-tracked files
|
||||||
|
throw ''
|
||||||
|
lib.fileset.${function}: The ${argument} (${toString path}) is a store path within a working tree of a Git repository.
|
||||||
|
This indicates that a source directory was imported into the store using a method such as `import "''${./.}"` or `path:.`.
|
||||||
|
This function currently does not support such a use case, since it currently relies on `builtins.fetchGit`.
|
||||||
|
You could make this work by using a fetcher such as `fetchGit` instead of copying the whole repository.
|
||||||
|
If you can't avoid copying the repo to the store, see https://github.com/NixOS/nix/issues/9292.''
|
||||||
|
else
|
||||||
|
# Otherwise we're going to assume that the path was a Git directory originally,
|
||||||
|
# but it was fetched using a method that already removed files not tracked by Git,
|
||||||
|
# such as `builtins.fetchGit`, `pkgs.fetchgit` or others.
|
||||||
|
# So we can just import the path in its entirety.
|
||||||
|
_singleton path;
|
||||||
|
|
||||||
|
# The code path for when isStorePath is false
|
||||||
|
tryFetchGit =
|
||||||
|
let
|
||||||
|
# This imports the files unnecessarily, which currently can't be avoided
|
||||||
|
# because `builtins.fetchGit` is the only function exposing which files are tracked by Git.
|
||||||
|
# With the [lazy trees PR](https://github.com/NixOS/nix/pull/6530),
|
||||||
|
# the unnecessarily import could be avoided.
|
||||||
|
# However a simpler alternative still would be [a builtins.gitLsFiles](https://github.com/NixOS/nix/issues/2944).
|
||||||
|
fetchResult = fetchGit ({
|
||||||
|
url = path;
|
||||||
|
} // extraFetchGitAttrs);
|
||||||
|
in
|
||||||
|
# We can identify local working directories by checking for .git,
|
||||||
|
# see https://git-scm.com/docs/gitrepository-layout#_description.
|
||||||
|
# Note that `builtins.fetchGit` _does_ work for bare repositories (where there's no `.git`),
|
||||||
|
# even though `git ls-files` wouldn't return any files in that case.
|
||||||
|
if ! pathExists (path + "/.git") then
|
||||||
|
throw "lib.fileset.${function}: Expected the ${argument} (${toString path}) to point to a local working tree of a Git repository, but it's not."
|
||||||
|
else
|
||||||
|
_mirrorStorePath path fetchResult.outPath;
|
||||||
|
|
||||||
|
in
|
||||||
|
if ! isPath path then
|
||||||
|
throw "lib.fileset.${function}: Expected the ${argument} to be a path, but it's a ${typeOf path} instead."
|
||||||
|
else if pathType path != "directory" then
|
||||||
|
throw "lib.fileset.${function}: Expected the ${argument} (${toString path}) to be a directory, but it's a file instead."
|
||||||
|
else if hasStorePathPrefix path then
|
||||||
|
tryStorePath
|
||||||
|
else
|
||||||
|
tryFetchGit;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,29 +43,17 @@ crudeUnquoteJSON() {
|
||||||
cut -d \" -f2
|
cut -d \" -f2
|
||||||
}
|
}
|
||||||
|
|
||||||
prefixExpression() {
|
prefixExpression='
|
||||||
echo 'let
|
let
|
||||||
lib =
|
lib = import <nixpkgs/lib>;
|
||||||
(import <nixpkgs/lib>)
|
internal = import <nixpkgs/lib/fileset/internal.nix> {
|
||||||
'
|
inherit lib;
|
||||||
if [[ "${1:-}" == "--simulate-pure-eval" ]]; then
|
};
|
||||||
echo '
|
in
|
||||||
.extend (final: prev: {
|
with lib;
|
||||||
trivial = prev.trivial // {
|
with internal;
|
||||||
inPureEvalMode = true;
|
with lib.fileset;
|
||||||
};
|
'
|
||||||
})'
|
|
||||||
fi
|
|
||||||
echo '
|
|
||||||
;
|
|
||||||
internal = import <nixpkgs/lib/fileset/internal.nix> {
|
|
||||||
inherit lib;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
with lib;
|
|
||||||
with internal;
|
|
||||||
with lib.fileset;'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check that two nix expression successfully evaluate to the same value.
|
# Check that two nix expression successfully evaluate to the same value.
|
||||||
# The expressions have `lib.fileset` in scope.
|
# The expressions have `lib.fileset` in scope.
|
||||||
|
@ -74,7 +62,7 @@ expectEqual() {
|
||||||
local actualExpr=$1
|
local actualExpr=$1
|
||||||
local expectedExpr=$2
|
local expectedExpr=$2
|
||||||
if actualResult=$(nix-instantiate --eval --strict --show-trace 2>"$tmp"/actualStderr \
|
if actualResult=$(nix-instantiate --eval --strict --show-trace 2>"$tmp"/actualStderr \
|
||||||
--expr "$(prefixExpression) ($actualExpr)"); then
|
--expr "$prefixExpression ($actualExpr)"); then
|
||||||
actualExitCode=$?
|
actualExitCode=$?
|
||||||
else
|
else
|
||||||
actualExitCode=$?
|
actualExitCode=$?
|
||||||
|
@ -82,7 +70,7 @@ expectEqual() {
|
||||||
actualStderr=$(< "$tmp"/actualStderr)
|
actualStderr=$(< "$tmp"/actualStderr)
|
||||||
|
|
||||||
if expectedResult=$(nix-instantiate --eval --strict --show-trace 2>"$tmp"/expectedStderr \
|
if expectedResult=$(nix-instantiate --eval --strict --show-trace 2>"$tmp"/expectedStderr \
|
||||||
--expr "$(prefixExpression) ($expectedExpr)"); then
|
--expr "$prefixExpression ($expectedExpr)"); then
|
||||||
expectedExitCode=$?
|
expectedExitCode=$?
|
||||||
else
|
else
|
||||||
expectedExitCode=$?
|
expectedExitCode=$?
|
||||||
|
@ -110,7 +98,7 @@ expectEqual() {
|
||||||
expectStorePath() {
|
expectStorePath() {
|
||||||
local expr=$1
|
local expr=$1
|
||||||
if ! result=$(nix-instantiate --eval --strict --json --read-write-mode --show-trace 2>"$tmp"/stderr \
|
if ! result=$(nix-instantiate --eval --strict --json --read-write-mode --show-trace 2>"$tmp"/stderr \
|
||||||
--expr "$(prefixExpression) ($expr)"); then
|
--expr "$prefixExpression ($expr)"); then
|
||||||
cat "$tmp/stderr" >&2
|
cat "$tmp/stderr" >&2
|
||||||
die "$expr failed to evaluate, but it was expected to succeed"
|
die "$expr failed to evaluate, but it was expected to succeed"
|
||||||
fi
|
fi
|
||||||
|
@ -123,16 +111,10 @@ expectStorePath() {
|
||||||
# The expression has `lib.fileset` in scope.
|
# The expression has `lib.fileset` in scope.
|
||||||
# Usage: expectFailure NIX REGEX
|
# Usage: expectFailure NIX REGEX
|
||||||
expectFailure() {
|
expectFailure() {
|
||||||
if [[ "$1" == "--simulate-pure-eval" ]]; then
|
|
||||||
maybePure="--simulate-pure-eval"
|
|
||||||
shift
|
|
||||||
else
|
|
||||||
maybePure=""
|
|
||||||
fi
|
|
||||||
local expr=$1
|
local expr=$1
|
||||||
local expectedErrorRegex=$2
|
local expectedErrorRegex=$2
|
||||||
if result=$(nix-instantiate --eval --strict --read-write-mode --show-trace 2>"$tmp/stderr" \
|
if result=$(nix-instantiate --eval --strict --read-write-mode --show-trace 2>"$tmp/stderr" \
|
||||||
--expr "$(prefixExpression $maybePure) $expr"); then
|
--expr "$prefixExpression $expr"); then
|
||||||
die "$expr evaluated successfully to $result, but it was expected to fail"
|
die "$expr evaluated successfully to $result, but it was expected to fail"
|
||||||
fi
|
fi
|
||||||
stderr=$(<"$tmp/stderr")
|
stderr=$(<"$tmp/stderr")
|
||||||
|
@ -149,12 +131,12 @@ expectTrace() {
|
||||||
local expectedTrace=$2
|
local expectedTrace=$2
|
||||||
|
|
||||||
nix-instantiate --eval --show-trace >/dev/null 2>"$tmp"/stderrTrace \
|
nix-instantiate --eval --show-trace >/dev/null 2>"$tmp"/stderrTrace \
|
||||||
--expr "$(prefixExpression) trace ($expr)" || true
|
--expr "$prefixExpression trace ($expr)" || true
|
||||||
|
|
||||||
actualTrace=$(sed -n 's/^trace: //p' "$tmp/stderrTrace")
|
actualTrace=$(sed -n 's/^trace: //p' "$tmp/stderrTrace")
|
||||||
|
|
||||||
nix-instantiate --eval --show-trace >/dev/null 2>"$tmp"/stderrTraceVal \
|
nix-instantiate --eval --show-trace >/dev/null 2>"$tmp"/stderrTraceVal \
|
||||||
--expr "$(prefixExpression) traceVal ($expr)" || true
|
--expr "$prefixExpression traceVal ($expr)" || true
|
||||||
|
|
||||||
actualTraceVal=$(sed -n 's/^trace: //p' "$tmp/stderrTraceVal")
|
actualTraceVal=$(sed -n 's/^trace: //p' "$tmp/stderrTraceVal")
|
||||||
|
|
||||||
|
@ -1317,6 +1299,12 @@ rm -rf -- *
|
||||||
expectFailure 'gitTracked null' 'lib.fileset.gitTracked: Expected the argument to be a path, but it'\''s a null instead.'
|
expectFailure 'gitTracked null' 'lib.fileset.gitTracked: Expected the argument to be a path, but it'\''s a null instead.'
|
||||||
expectFailure 'gitTrackedWith {} null' 'lib.fileset.gitTrackedWith: Expected the second argument to be a path, but it'\''s a null instead.'
|
expectFailure 'gitTrackedWith {} null' 'lib.fileset.gitTrackedWith: Expected the second argument to be a path, but it'\''s a null instead.'
|
||||||
|
|
||||||
|
# The path must be a directory
|
||||||
|
touch a
|
||||||
|
expectFailure 'gitTracked ./a' 'lib.fileset.gitTracked: Expected the argument \('"$work"'/a\) to be a directory, but it'\''s a file instead'
|
||||||
|
expectFailure 'gitTrackedWith {} ./a' 'lib.fileset.gitTrackedWith: Expected the second argument \('"$work"'/a\) to be a directory, but it'\''s a file instead'
|
||||||
|
rm -rf -- *
|
||||||
|
|
||||||
# The path has to contain a .git directory
|
# The path has to contain a .git directory
|
||||||
expectFailure 'gitTracked ./.' 'lib.fileset.gitTracked: Expected the argument \('"$work"'\) to point to a local working tree of a Git repository, but it'\''s not.'
|
expectFailure 'gitTracked ./.' 'lib.fileset.gitTracked: Expected the argument \('"$work"'\) to point to a local working tree of a Git repository, but it'\''s not.'
|
||||||
expectFailure 'gitTrackedWith {} ./.' 'lib.fileset.gitTrackedWith: Expected the second argument \('"$work"'\) to point to a local working tree of a Git repository, but it'\''s not.'
|
expectFailure 'gitTrackedWith {} ./.' 'lib.fileset.gitTrackedWith: Expected the second argument \('"$work"'\) to point to a local working tree of a Git repository, but it'\''s not.'
|
||||||
|
@ -1325,7 +1313,7 @@ expectFailure 'gitTrackedWith {} ./.' 'lib.fileset.gitTrackedWith: Expected the
|
||||||
expectFailure 'gitTrackedWith { recurseSubmodules = null; } ./.' 'lib.fileset.gitTrackedWith: Expected the attribute `recurseSubmodules` of the first argument to be a boolean, but it'\''s a null instead.'
|
expectFailure 'gitTrackedWith { recurseSubmodules = null; } ./.' 'lib.fileset.gitTrackedWith: Expected the attribute `recurseSubmodules` of the first argument to be a boolean, but it'\''s a null instead.'
|
||||||
|
|
||||||
# recurseSubmodules = true is not supported on all Nix versions
|
# recurseSubmodules = true is not supported on all Nix versions
|
||||||
if [[ "$(nix-instantiate --eval --expr "$(prefixExpression) (versionAtLeast builtins.nixVersion _fetchGitSubmodulesMinver)")" == true ]]; then
|
if [[ "$(nix-instantiate --eval --expr "$prefixExpression (versionAtLeast builtins.nixVersion _fetchGitSubmodulesMinver)")" == true ]]; then
|
||||||
fetchGitSupportsSubmodules=1
|
fetchGitSupportsSubmodules=1
|
||||||
else
|
else
|
||||||
fetchGitSupportsSubmodules=
|
fetchGitSupportsSubmodules=
|
||||||
|
@ -1395,10 +1383,60 @@ createGitRepo() {
|
||||||
git -C "$1" commit -q --allow-empty -m "Empty commit"
|
git -C "$1" commit -q --allow-empty -m "Empty commit"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check the error message for pure eval mode
|
# Check that gitTracked[With] works as expected when evaluated out-of-tree
|
||||||
|
|
||||||
|
## First we create a git repositories (and a subrepository) with `default.nix` files referring to their local paths
|
||||||
|
## Simulating how it would be used in the wild
|
||||||
createGitRepo .
|
createGitRepo .
|
||||||
expectFailure --simulate-pure-eval 'toSource { root = ./.; fileset = gitTracked ./.; }' 'lib.fileset.gitTracked: This function is currently not supported in pure evaluation mode, since it currently relies on `builtins.fetchGit`. See https://github.com/NixOS/nix/issues/9292.'
|
echo '{ fs }: fs.toSource { root = ./.; fileset = fs.gitTracked ./.; }' > default.nix
|
||||||
expectFailure --simulate-pure-eval 'toSource { root = ./.; fileset = gitTrackedWith {} ./.; }' 'lib.fileset.gitTrackedWith: This function is currently not supported in pure evaluation mode, since it currently relies on `builtins.fetchGit`. See https://github.com/NixOS/nix/issues/9292.'
|
git add .
|
||||||
|
|
||||||
|
## We can evaluate it locally just fine, `fetchGit` is used underneath to filter git-tracked files
|
||||||
|
expectEqual '(import ./. { fs = lib.fileset; }).outPath' '(builtins.fetchGit ./.).outPath'
|
||||||
|
|
||||||
|
## We can also evaluate when importing from fetched store paths
|
||||||
|
storePath=$(expectStorePath 'builtins.fetchGit ./.')
|
||||||
|
expectEqual '(import '"$storePath"' { fs = lib.fileset; }).outPath' \""$storePath"\"
|
||||||
|
|
||||||
|
## But it fails if the path is imported with a fetcher that doesn't remove .git (like just using "${./.}")
|
||||||
|
expectFailure 'import "${./.}" { fs = lib.fileset; }' 'lib.fileset.gitTracked: The argument \(.*\) is a store path within a working tree of a Git repository.
|
||||||
|
\s*This indicates that a source directory was imported into the store using a method such as `import "\$\{./.\}"` or `path:.`.
|
||||||
|
\s*This function currently does not support such a use case, since it currently relies on `builtins.fetchGit`.
|
||||||
|
\s*You could make this work by using a fetcher such as `fetchGit` instead of copying the whole repository.
|
||||||
|
\s*If you can'\''t avoid copying the repo to the store, see https://github.com/NixOS/nix/issues/9292.'
|
||||||
|
|
||||||
|
## Even with submodules
|
||||||
|
if [[ -n "$fetchGitSupportsSubmodules" ]]; then
|
||||||
|
## Both the main repo with the submodule
|
||||||
|
echo '{ fs }: fs.toSource { root = ./.; fileset = fs.gitTrackedWith { recurseSubmodules = true; } ./.; }' > default.nix
|
||||||
|
createGitRepo sub
|
||||||
|
git submodule add ./sub sub >/dev/null
|
||||||
|
## But also the submodule itself
|
||||||
|
echo '{ fs }: fs.toSource { root = ./.; fileset = fs.gitTracked ./.; }' > sub/default.nix
|
||||||
|
git -C sub add .
|
||||||
|
|
||||||
|
## We can evaluate it locally just fine, `fetchGit` is used underneath to filter git-tracked files
|
||||||
|
expectEqual '(import ./. { fs = lib.fileset; }).outPath' '(builtins.fetchGit { url = ./.; submodules = true; }).outPath'
|
||||||
|
expectEqual '(import ./sub { fs = lib.fileset; }).outPath' '(builtins.fetchGit ./sub).outPath'
|
||||||
|
|
||||||
|
## We can also evaluate when importing from fetched store paths
|
||||||
|
storePathWithSub=$(expectStorePath 'builtins.fetchGit { url = ./.; submodules = true; }')
|
||||||
|
expectEqual '(import '"$storePathWithSub"' { fs = lib.fileset; }).outPath' \""$storePathWithSub"\"
|
||||||
|
storePathSub=$(expectStorePath 'builtins.fetchGit ./sub')
|
||||||
|
expectEqual '(import '"$storePathSub"' { fs = lib.fileset; }).outPath' \""$storePathSub"\"
|
||||||
|
|
||||||
|
## But it fails if the path is imported with a fetcher that doesn't remove .git (like just using "${./.}")
|
||||||
|
expectFailure 'import "${./.}" { fs = lib.fileset; }' 'lib.fileset.gitTrackedWith: The second argument \(.*\) is a store path within a working tree of a Git repository.
|
||||||
|
\s*This indicates that a source directory was imported into the store using a method such as `import "\$\{./.\}"` or `path:.`.
|
||||||
|
\s*This function currently does not support such a use case, since it currently relies on `builtins.fetchGit`.
|
||||||
|
\s*You could make this work by using a fetcher such as `fetchGit` instead of copying the whole repository.
|
||||||
|
\s*If you can'\''t avoid copying the repo to the store, see https://github.com/NixOS/nix/issues/9292.'
|
||||||
|
expectFailure 'import "${./.}/sub" { fs = lib.fileset; }' 'lib.fileset.gitTracked: The argument \(.*/sub\) is a store path within a working tree of a Git repository.
|
||||||
|
\s*This indicates that a source directory was imported into the store using a method such as `import "\$\{./.\}"` or `path:.`.
|
||||||
|
\s*This function currently does not support such a use case, since it currently relies on `builtins.fetchGit`.
|
||||||
|
\s*You could make this work by using a fetcher such as `fetchGit` instead of copying the whole repository.
|
||||||
|
\s*If you can'\''t avoid copying the repo to the store, see https://github.com/NixOS/nix/issues/9292.'
|
||||||
|
fi
|
||||||
rm -rf -- *
|
rm -rf -- *
|
||||||
|
|
||||||
# Go through all stages of Git files
|
# Go through all stages of Git files
|
||||||
|
|
|
@ -9,11 +9,22 @@ let
|
||||||
inherit (builtins)
|
inherit (builtins)
|
||||||
readDir
|
readDir
|
||||||
pathExists
|
pathExists
|
||||||
|
toString
|
||||||
|
;
|
||||||
|
|
||||||
|
inherit (lib.attrsets)
|
||||||
|
mapAttrs'
|
||||||
|
filterAttrs
|
||||||
;
|
;
|
||||||
|
|
||||||
inherit (lib.filesystem)
|
inherit (lib.filesystem)
|
||||||
pathType
|
pathType
|
||||||
;
|
;
|
||||||
|
|
||||||
|
inherit (lib.strings)
|
||||||
|
hasSuffix
|
||||||
|
removeSuffix
|
||||||
|
;
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -154,4 +165,147 @@ in
|
||||||
dir + "/${name}"
|
dir + "/${name}"
|
||||||
) (builtins.readDir dir));
|
) (builtins.readDir dir));
|
||||||
|
|
||||||
|
/*
|
||||||
|
Transform a directory tree containing package files suitable for
|
||||||
|
`callPackage` into a matching nested attribute set of derivations.
|
||||||
|
|
||||||
|
For a directory tree like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
my-packages
|
||||||
|
├── a.nix
|
||||||
|
├── b.nix
|
||||||
|
├── c
|
||||||
|
│ ├── my-extra-feature.patch
|
||||||
|
│ ├── package.nix
|
||||||
|
│ └── support-definitions.nix
|
||||||
|
└── my-namespace
|
||||||
|
├── d.nix
|
||||||
|
├── e.nix
|
||||||
|
└── f
|
||||||
|
└── package.nix
|
||||||
|
```
|
||||||
|
|
||||||
|
`packagesFromDirectoryRecursive` will produce an attribute set like this:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# packagesFromDirectoryRecursive {
|
||||||
|
# callPackage = pkgs.callPackage;
|
||||||
|
# directory = ./my-packages;
|
||||||
|
# }
|
||||||
|
{
|
||||||
|
a = pkgs.callPackage ./my-packages/a.nix { };
|
||||||
|
b = pkgs.callPackage ./my-packages/b.nix { };
|
||||||
|
c = pkgs.callPackage ./my-packages/c/package.nix { };
|
||||||
|
my-namespace = {
|
||||||
|
d = pkgs.callPackage ./my-packages/my-namespace/d.nix { };
|
||||||
|
e = pkgs.callPackage ./my-packages/my-namespace/e.nix { };
|
||||||
|
f = pkgs.callPackage ./my-packages/my-namespace/f/package.nix { };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In particular:
|
||||||
|
- If the input directory contains a `package.nix` file, then
|
||||||
|
`callPackage <directory>/package.nix { }` is returned.
|
||||||
|
- Otherwise, the input directory's contents are listed and transformed into
|
||||||
|
an attribute set.
|
||||||
|
- If a file name has the `.nix` extension, it is turned into attribute
|
||||||
|
where:
|
||||||
|
- The attribute name is the file name without the `.nix` extension
|
||||||
|
- The attribute value is `callPackage <file path> { }`
|
||||||
|
- Other files are ignored.
|
||||||
|
- Directories are turned into an attribute where:
|
||||||
|
- The attribute name is the name of the directory
|
||||||
|
- The attribute value is the result of calling
|
||||||
|
`packagesFromDirectoryRecursive { ... }` on the directory.
|
||||||
|
|
||||||
|
As a result, directories with no `.nix` files (including empty
|
||||||
|
directories) will be transformed into empty attribute sets.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
packagesFromDirectoryRecursive {
|
||||||
|
inherit (pkgs) callPackage;
|
||||||
|
directory = ./my-packages;
|
||||||
|
}
|
||||||
|
=> { ... }
|
||||||
|
|
||||||
|
lib.makeScope pkgs.newScope (
|
||||||
|
self: packagesFromDirectoryRecursive {
|
||||||
|
callPackage = self.callPackage;
|
||||||
|
directory = ./my-packages;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
=> { ... }
|
||||||
|
|
||||||
|
Type:
|
||||||
|
packagesFromDirectoryRecursive :: AttrSet -> AttrSet
|
||||||
|
*/
|
||||||
|
packagesFromDirectoryRecursive =
|
||||||
|
# Options.
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
`pkgs.callPackage`
|
||||||
|
|
||||||
|
Type:
|
||||||
|
Path -> AttrSet -> a
|
||||||
|
*/
|
||||||
|
callPackage,
|
||||||
|
/*
|
||||||
|
The directory to read package files from
|
||||||
|
|
||||||
|
Type:
|
||||||
|
Path
|
||||||
|
*/
|
||||||
|
directory,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
# Determine if a directory entry from `readDir` indicates a package or
|
||||||
|
# directory of packages.
|
||||||
|
directoryEntryIsPackage = basename: type:
|
||||||
|
type == "directory" || hasSuffix ".nix" basename;
|
||||||
|
|
||||||
|
# List directory entries that indicate packages in the given `path`.
|
||||||
|
packageDirectoryEntries = path:
|
||||||
|
filterAttrs directoryEntryIsPackage (readDir path);
|
||||||
|
|
||||||
|
# Transform a directory entry (a `basename` and `type` pair) into a
|
||||||
|
# package.
|
||||||
|
directoryEntryToAttrPair = subdirectory: basename: type:
|
||||||
|
let
|
||||||
|
path = subdirectory + "/${basename}";
|
||||||
|
in
|
||||||
|
if type == "regular"
|
||||||
|
then
|
||||||
|
{
|
||||||
|
name = removeSuffix ".nix" basename;
|
||||||
|
value = callPackage path { };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if type == "directory"
|
||||||
|
then
|
||||||
|
{
|
||||||
|
name = basename;
|
||||||
|
value = packagesFromDirectory path;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw
|
||||||
|
''
|
||||||
|
lib.filesystem.packagesFromDirectoryRecursive: Unsupported file type ${type} at path ${toString subdirectory}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Transform a directory into a package (if there's a `package.nix`) or
|
||||||
|
# set of packages (otherwise).
|
||||||
|
packagesFromDirectory = path:
|
||||||
|
let
|
||||||
|
defaultPackagePath = path + "/package.nix";
|
||||||
|
in
|
||||||
|
if pathExists defaultPackagePath
|
||||||
|
then callPackage defaultPackagePath { }
|
||||||
|
else mapAttrs'
|
||||||
|
(directoryEntryToAttrPair path)
|
||||||
|
(packageDirectoryEntries path);
|
||||||
|
in
|
||||||
|
packagesFromDirectory directory;
|
||||||
}
|
}
|
||||||
|
|
20
lib/flake-version-info.nix
Normal file
20
lib/flake-version-info.nix
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# This function produces a lib overlay to be used by the nixpkgs
|
||||||
|
# & nixpkgs/lib flakes to provide meaningful values for
|
||||||
|
# `lib.trivial.version` et al..
|
||||||
|
#
|
||||||
|
# Internal and subject to change, don't use this anywhere else!
|
||||||
|
# Instead, consider using a public interface, such as this flake here
|
||||||
|
# in this directory, `lib/`, or use the nixpkgs flake, which applies
|
||||||
|
# this logic for you in its `lib` output attribute.
|
||||||
|
|
||||||
|
self: # from the flake
|
||||||
|
|
||||||
|
finalLib: prevLib: # lib overlay
|
||||||
|
|
||||||
|
{
|
||||||
|
trivial = prevLib.trivial // {
|
||||||
|
versionSuffix =
|
||||||
|
".${finalLib.substring 0 8 (self.lastModifiedDate or "19700101")}.${self.shortRev or "dirty"}";
|
||||||
|
revisionWithDefault = default: self.rev or default;
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,5 +1,10 @@
|
||||||
{
|
{
|
||||||
description = "Library of low-level helper functions for nix expressions.";
|
description = "Library of low-level helper functions for nix expressions.";
|
||||||
|
|
||||||
outputs = { self }: { lib = import ./.; };
|
outputs = { self }:
|
||||||
|
let
|
||||||
|
lib0 = import ./.;
|
||||||
|
in {
|
||||||
|
lib = lib0.extend (import ./flake-version-info.nix self);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -525,6 +525,8 @@ ${expr "" v}
|
||||||
"(${v.expr})"
|
"(${v.expr})"
|
||||||
else if v == { } then
|
else if v == { } then
|
||||||
"{}"
|
"{}"
|
||||||
|
else if libAttr.isDerivation v then
|
||||||
|
''"${toString v}"''
|
||||||
else
|
else
|
||||||
"{${introSpace}${concatItems (
|
"{${introSpace}${concatItems (
|
||||||
lib.attrsets.mapAttrsToList (key: value: "[${builtins.toJSON key}] = ${toLua innerArgs value}") v
|
lib.attrsets.mapAttrsToList (key: value: "[${builtins.toJSON key}] = ${toLua innerArgs value}") v
|
||||||
|
|
|
@ -104,6 +104,7 @@ in mkLicense lset) ({
|
||||||
};
|
};
|
||||||
|
|
||||||
arphicpl = {
|
arphicpl = {
|
||||||
|
spdxId = "Arphic-1999";
|
||||||
fullName = "Arphic Public License";
|
fullName = "Arphic Public License";
|
||||||
url = "https://www.freedesktop.org/wiki/Arphic_Public_License/";
|
url = "https://www.freedesktop.org/wiki/Arphic_Public_License/";
|
||||||
};
|
};
|
||||||
|
@ -236,6 +237,7 @@ in mkLicense lset) ({
|
||||||
};
|
};
|
||||||
|
|
||||||
cal10 = {
|
cal10 = {
|
||||||
|
spdxId = "CAL-1.0";
|
||||||
fullName = "Cryptographic Autonomy License version 1.0 (CAL-1.0)";
|
fullName = "Cryptographic Autonomy License version 1.0 (CAL-1.0)";
|
||||||
url = "https://opensource.org/licenses/CAL-1.0";
|
url = "https://opensource.org/licenses/CAL-1.0";
|
||||||
};
|
};
|
||||||
|
@ -429,6 +431,7 @@ in mkLicense lset) ({
|
||||||
};
|
};
|
||||||
|
|
||||||
elastic20 = {
|
elastic20 = {
|
||||||
|
spdxId = "Elastic-2.0";
|
||||||
fullName = "Elastic License 2.0";
|
fullName = "Elastic License 2.0";
|
||||||
url = "https://github.com/elastic/elasticsearch/blob/main/licenses/ELASTIC-LICENSE-2.0.txt";
|
url = "https://github.com/elastic/elasticsearch/blob/main/licenses/ELASTIC-LICENSE-2.0.txt";
|
||||||
free = false;
|
free = false;
|
||||||
|
@ -598,6 +601,7 @@ in mkLicense lset) ({
|
||||||
|
|
||||||
# Intel's license, seems free
|
# Intel's license, seems free
|
||||||
iasl = {
|
iasl = {
|
||||||
|
spdxId = "Intel-ACPI";
|
||||||
fullName = "iASL";
|
fullName = "iASL";
|
||||||
url = "https://old.calculate-linux.org/packages/licenses/iASL";
|
url = "https://old.calculate-linux.org/packages/licenses/iASL";
|
||||||
};
|
};
|
||||||
|
@ -609,7 +613,7 @@ in mkLicense lset) ({
|
||||||
|
|
||||||
imagemagick = {
|
imagemagick = {
|
||||||
fullName = "ImageMagick License";
|
fullName = "ImageMagick License";
|
||||||
spdxId = "imagemagick";
|
spdxId = "ImageMagick";
|
||||||
};
|
};
|
||||||
|
|
||||||
imlib2 = {
|
imlib2 = {
|
||||||
|
@ -803,6 +807,7 @@ in mkLicense lset) ({
|
||||||
};
|
};
|
||||||
|
|
||||||
miros = {
|
miros = {
|
||||||
|
spdxId = "MirOS";
|
||||||
fullName = "MirOS License";
|
fullName = "MirOS License";
|
||||||
url = "https://opensource.org/licenses/MirOS";
|
url = "https://opensource.org/licenses/MirOS";
|
||||||
};
|
};
|
||||||
|
@ -1138,6 +1143,7 @@ in mkLicense lset) ({
|
||||||
};
|
};
|
||||||
|
|
||||||
upl = {
|
upl = {
|
||||||
|
spdxId = "UPL-1.0";
|
||||||
fullName = "Universal Permissive License";
|
fullName = "Universal Permissive License";
|
||||||
url = "https://oss.oracle.com/licenses/upl/";
|
url = "https://oss.oracle.com/licenses/upl/";
|
||||||
};
|
};
|
||||||
|
@ -1194,6 +1200,7 @@ in mkLicense lset) ({
|
||||||
};
|
};
|
||||||
|
|
||||||
xfig = {
|
xfig = {
|
||||||
|
spdxId = "Xfig";
|
||||||
fullName = "xfig";
|
fullName = "xfig";
|
||||||
url = "https://mcj.sourceforge.net/authors.html#xfig";
|
url = "https://mcj.sourceforge.net/authors.html#xfig";
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,7 @@ let
|
||||||
inherit (lib.strings) toInt;
|
inherit (lib.strings) toInt;
|
||||||
inherit (lib.trivial) compare min id;
|
inherit (lib.trivial) compare min id;
|
||||||
inherit (lib.attrsets) mapAttrs;
|
inherit (lib.attrsets) mapAttrs;
|
||||||
|
inherit (lib.lists) sort;
|
||||||
in
|
in
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
|
@ -591,9 +592,15 @@ rec {
|
||||||
the second argument. The returned list is sorted in an increasing
|
the second argument. The returned list is sorted in an increasing
|
||||||
order. The implementation does a quick-sort.
|
order. The implementation does a quick-sort.
|
||||||
|
|
||||||
|
See also [`sortOn`](#function-library-lib.lists.sortOn), which applies the
|
||||||
|
default comparison on a function-derived property, and may be more efficient.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
sort (a: b: a < b) [ 5 3 7 ]
|
sort (p: q: p < q) [ 5 3 7 ]
|
||||||
=> [ 3 5 7 ]
|
=> [ 3 5 7 ]
|
||||||
|
|
||||||
|
Type:
|
||||||
|
sort :: (a -> a -> Bool) -> [a] -> [a]
|
||||||
*/
|
*/
|
||||||
sort = builtins.sort or (
|
sort = builtins.sort or (
|
||||||
strictLess: list:
|
strictLess: list:
|
||||||
|
@ -612,6 +619,42 @@ rec {
|
||||||
if len < 2 then list
|
if len < 2 then list
|
||||||
else (sort strictLess pivot.left) ++ [ first ] ++ (sort strictLess pivot.right));
|
else (sort strictLess pivot.left) ++ [ first ] ++ (sort strictLess pivot.right));
|
||||||
|
|
||||||
|
/*
|
||||||
|
Sort a list based on the default comparison of a derived property `b`.
|
||||||
|
|
||||||
|
The items are returned in `b`-increasing order.
|
||||||
|
|
||||||
|
**Performance**:
|
||||||
|
|
||||||
|
The passed function `f` is only evaluated once per item,
|
||||||
|
unlike an unprepared [`sort`](#function-library-lib.lists.sort) using
|
||||||
|
`f p < f q`.
|
||||||
|
|
||||||
|
**Laws**:
|
||||||
|
```nix
|
||||||
|
sortOn f == sort (p: q: f p < f q)
|
||||||
|
```
|
||||||
|
|
||||||
|
Example:
|
||||||
|
sortOn stringLength [ "aa" "b" "cccc" ]
|
||||||
|
=> [ "b" "aa" "cccc" ]
|
||||||
|
|
||||||
|
Type:
|
||||||
|
sortOn :: (a -> b) -> [a] -> [a], for comparable b
|
||||||
|
*/
|
||||||
|
sortOn = f: list:
|
||||||
|
let
|
||||||
|
# Heterogenous list as pair may be ugly, but requires minimal allocations.
|
||||||
|
pairs = map (x: [(f x) x]) list;
|
||||||
|
in
|
||||||
|
map
|
||||||
|
(x: builtins.elemAt x 1)
|
||||||
|
(sort
|
||||||
|
# Compare the first element of the pairs
|
||||||
|
# Do not factor out the `<`, to avoid calls in hot code; duplicate instead.
|
||||||
|
(a: b: head a < head b)
|
||||||
|
pairs);
|
||||||
|
|
||||||
/* Compare two lists element-by-element.
|
/* Compare two lists element-by-element.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
34
lib/meta.nix
34
lib/meta.nix
|
@ -4,8 +4,8 @@
|
||||||
{ lib }:
|
{ lib }:
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (lib) matchAttrs any all;
|
inherit (lib) matchAttrs any all isDerivation getBin assertMsg;
|
||||||
inherit (builtins) isString;
|
inherit (builtins) isString match typeOf;
|
||||||
|
|
||||||
in
|
in
|
||||||
rec {
|
rec {
|
||||||
|
@ -154,16 +154,12 @@ rec {
|
||||||
getExe pkgs.mustache-go
|
getExe pkgs.mustache-go
|
||||||
=> "/nix/store/am9ml4f4ywvivxnkiaqwr0hyxka1xjsf-mustache-go-1.3.0/bin/mustache"
|
=> "/nix/store/am9ml4f4ywvivxnkiaqwr0hyxka1xjsf-mustache-go-1.3.0/bin/mustache"
|
||||||
*/
|
*/
|
||||||
getExe = x:
|
getExe = x: getExe' x (x.meta.mainProgram or (
|
||||||
let
|
# This could be turned into an error when 23.05 is at end of life
|
||||||
y = x.meta.mainProgram or (
|
lib.warn "getExe: Package ${lib.strings.escapeNixIdentifier x.meta.name or x.pname or x.name} does not have the meta.mainProgram attribute. We'll assume that the main program has the same name for now, but this behavior is deprecated, because it leads to surprising errors when the assumption does not hold. If the package has a main program, please set `meta.mainProgram` in its definition to make this warning go away. Otherwise, if the package does not have a main program, or if you don't control its definition, use getExe' to specify the name to the program, such as lib.getExe' foo \"bar\"."
|
||||||
# This could be turned into an error when 23.05 is at end of life
|
lib.getName
|
||||||
lib.warn "getExe: Package ${lib.strings.escapeNixIdentifier x.meta.name or x.pname or x.name} does not have the meta.mainProgram attribute. We'll assume that the main program has the same name for now, but this behavior is deprecated, because it leads to surprising errors when the assumption does not hold. If the package has a main program, please set `meta.mainProgram` in its definition to make this warning go away. Otherwise, if the package does not have a main program, or if you don't control its definition, use getExe' to specify the name to the program, such as lib.getExe' foo \"bar\"."
|
x
|
||||||
lib.getName
|
));
|
||||||
x
|
|
||||||
);
|
|
||||||
in
|
|
||||||
getExe' x y;
|
|
||||||
|
|
||||||
/* Get the path of a program of a derivation.
|
/* Get the path of a program of a derivation.
|
||||||
|
|
||||||
|
@ -175,11 +171,11 @@ rec {
|
||||||
=> "/nix/store/5rs48jamq7k6sal98ymj9l4k2bnwq515-imagemagick-7.1.1-15/bin/convert"
|
=> "/nix/store/5rs48jamq7k6sal98ymj9l4k2bnwq515-imagemagick-7.1.1-15/bin/convert"
|
||||||
*/
|
*/
|
||||||
getExe' = x: y:
|
getExe' = x: y:
|
||||||
assert lib.assertMsg (lib.isDerivation x)
|
assert assertMsg (isDerivation x)
|
||||||
"lib.meta.getExe': The first argument is of type ${builtins.typeOf x}, but it should be a derivation instead.";
|
"lib.meta.getExe': The first argument is of type ${typeOf x}, but it should be a derivation instead.";
|
||||||
assert lib.assertMsg (lib.isString y)
|
assert assertMsg (isString y)
|
||||||
"lib.meta.getExe': The second argument is of type ${builtins.typeOf y}, but it should be a string instead.";
|
"lib.meta.getExe': The second argument is of type ${typeOf y}, but it should be a string instead.";
|
||||||
assert lib.assertMsg (builtins.length (lib.splitString "/" y) == 1)
|
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.";
|
"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.";
|
||||||
"${lib.getBin x}/bin/${y}";
|
"${getBin x}/bin/${y}";
|
||||||
}
|
}
|
||||||
|
|
|
@ -275,6 +275,8 @@ let
|
||||||
"The option `${optText}' does not exist. Definition values:${defText}";
|
"The option `${optText}' does not exist. Definition values:${defText}";
|
||||||
in
|
in
|
||||||
if attrNames options == [ "_module" ]
|
if attrNames options == [ "_module" ]
|
||||||
|
# No options were declared at all (`_module` is built in)
|
||||||
|
# but we do have unmatched definitions, and no freeformType (earlier conditions)
|
||||||
then
|
then
|
||||||
let
|
let
|
||||||
optionName = showOption prefix;
|
optionName = showOption prefix;
|
||||||
|
|
|
@ -9,6 +9,7 @@ let
|
||||||
split
|
split
|
||||||
match
|
match
|
||||||
typeOf
|
typeOf
|
||||||
|
storeDir
|
||||||
;
|
;
|
||||||
|
|
||||||
inherit (lib.lists)
|
inherit (lib.lists)
|
||||||
|
@ -24,6 +25,8 @@ let
|
||||||
drop
|
drop
|
||||||
;
|
;
|
||||||
|
|
||||||
|
listHasPrefix = lib.lists.hasPrefix;
|
||||||
|
|
||||||
inherit (lib.strings)
|
inherit (lib.strings)
|
||||||
concatStringsSep
|
concatStringsSep
|
||||||
substring
|
substring
|
||||||
|
@ -120,6 +123,28 @@ let
|
||||||
else recurse ([ (baseNameOf base) ] ++ components) (dirOf base);
|
else recurse ([ (baseNameOf base) ] ++ components) (dirOf base);
|
||||||
in recurse [];
|
in recurse [];
|
||||||
|
|
||||||
|
# The components of the store directory, typically [ "nix" "store" ]
|
||||||
|
storeDirComponents = splitRelPath ("./" + storeDir);
|
||||||
|
# The number of store directory components, typically 2
|
||||||
|
storeDirLength = length storeDirComponents;
|
||||||
|
|
||||||
|
# Type: [ String ] -> Bool
|
||||||
|
#
|
||||||
|
# Whether path components have a store path as a prefix, according to
|
||||||
|
# https://nixos.org/manual/nix/stable/store/store-path.html#store-path.
|
||||||
|
componentsHaveStorePathPrefix = components:
|
||||||
|
# path starts with the store directory (typically /nix/store)
|
||||||
|
listHasPrefix storeDirComponents components
|
||||||
|
# is not the store directory itself, meaning there's at least one extra component
|
||||||
|
&& storeDirComponents != components
|
||||||
|
# and the first component after the store directory has the expected format.
|
||||||
|
# NOTE: We could change the hash regex to be [0-9a-df-np-sv-z],
|
||||||
|
# because these are the actual ASCII characters used by Nix's base32 implementation,
|
||||||
|
# but this is not fully specified, so let's tie this too much to the currently implemented concept of store paths.
|
||||||
|
# Similar reasoning applies to the validity of the name part.
|
||||||
|
# We care more about discerning store path-ness on realistic values. Making it airtight would be fragile and slow.
|
||||||
|
&& match ".{32}-.+" (elemAt components storeDirLength) != null;
|
||||||
|
|
||||||
in /* No rec! Add dependencies on this file at the top. */ {
|
in /* No rec! Add dependencies on this file at the top. */ {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -321,6 +346,62 @@ in /* No rec! Add dependencies on this file at the top. */ {
|
||||||
subpath = joinRelPath deconstructed.components;
|
subpath = joinRelPath deconstructed.components;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Whether a [path](https://nixos.org/manual/nix/stable/language/values.html#type-path)
|
||||||
|
has a [store path](https://nixos.org/manual/nix/stable/store/store-path.html#store-path)
|
||||||
|
as a prefix.
|
||||||
|
|
||||||
|
:::{.note}
|
||||||
|
As with all functions of this `lib.path` library, it does not work on paths in strings,
|
||||||
|
which is how you'd typically get store paths.
|
||||||
|
|
||||||
|
Instead, this function only handles path values themselves,
|
||||||
|
which occur when Nix files in the store use relative path expressions.
|
||||||
|
:::
|
||||||
|
|
||||||
|
Type:
|
||||||
|
hasStorePathPrefix :: Path -> Bool
|
||||||
|
|
||||||
|
Example:
|
||||||
|
# Subpaths of derivation outputs have a store path as a prefix
|
||||||
|
hasStorePathPrefix /nix/store/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo/bar/baz
|
||||||
|
=> true
|
||||||
|
|
||||||
|
# The store directory itself is not a store path
|
||||||
|
hasStorePathPrefix /nix/store
|
||||||
|
=> false
|
||||||
|
|
||||||
|
# Derivation outputs are store paths themselves
|
||||||
|
hasStorePathPrefix /nix/store/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo
|
||||||
|
=> true
|
||||||
|
|
||||||
|
# Paths outside the Nix store don't have a store path prefix
|
||||||
|
hasStorePathPrefix /home/user
|
||||||
|
=> false
|
||||||
|
|
||||||
|
# Not all paths under the Nix store are store paths
|
||||||
|
hasStorePathPrefix /nix/store/.links/10gg8k3rmbw8p7gszarbk7qyd9jwxhcfq9i6s5i0qikx8alkk4hq
|
||||||
|
=> false
|
||||||
|
|
||||||
|
# Store derivations are also store paths themselves
|
||||||
|
hasStorePathPrefix /nix/store/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo.drv
|
||||||
|
=> true
|
||||||
|
*/
|
||||||
|
hasStorePathPrefix = path:
|
||||||
|
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
|
||||||
|
# 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.";
|
||||||
|
componentsHaveStorePathPrefix deconstructed.components;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Whether a value is a valid subpath string.
|
Whether a value is a valid subpath string.
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,10 @@
|
||||||
{ libpath }:
|
{ libpath }:
|
||||||
let
|
let
|
||||||
lib = import libpath;
|
lib = import libpath;
|
||||||
inherit (lib.path) hasPrefix removePrefix append splitRoot subpath;
|
inherit (lib.path) hasPrefix removePrefix append splitRoot hasStorePathPrefix subpath;
|
||||||
|
|
||||||
|
# This is not allowed generally, but we're in the tests here, so we'll allow ourselves.
|
||||||
|
storeDirPath = /. + builtins.storeDir;
|
||||||
|
|
||||||
cases = lib.runTests {
|
cases = lib.runTests {
|
||||||
# Test examples from the lib.path.append documentation
|
# Test examples from the lib.path.append documentation
|
||||||
|
@ -91,6 +94,31 @@ let
|
||||||
expected = false;
|
expected = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
testHasStorePathPrefixExample1 = {
|
||||||
|
expr = hasStorePathPrefix (storeDirPath + "/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo/bar/baz");
|
||||||
|
expected = true;
|
||||||
|
};
|
||||||
|
testHasStorePathPrefixExample2 = {
|
||||||
|
expr = hasStorePathPrefix storeDirPath;
|
||||||
|
expected = false;
|
||||||
|
};
|
||||||
|
testHasStorePathPrefixExample3 = {
|
||||||
|
expr = hasStorePathPrefix (storeDirPath + "/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo");
|
||||||
|
expected = true;
|
||||||
|
};
|
||||||
|
testHasStorePathPrefixExample4 = {
|
||||||
|
expr = hasStorePathPrefix /home/user;
|
||||||
|
expected = false;
|
||||||
|
};
|
||||||
|
testHasStorePathPrefixExample5 = {
|
||||||
|
expr = hasStorePathPrefix (storeDirPath + "/.links/10gg8k3rmbw8p7gszarbk7qyd9jwxhcfq9i6s5i0qikx8alkk4hq");
|
||||||
|
expected = false;
|
||||||
|
};
|
||||||
|
testHasStorePathPrefixExample6 = {
|
||||||
|
expr = hasStorePathPrefix (storeDirPath + "/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo.drv");
|
||||||
|
expected = true;
|
||||||
|
};
|
||||||
|
|
||||||
# Test examples from the lib.path.subpath.isValid documentation
|
# Test examples from the lib.path.subpath.isValid documentation
|
||||||
testSubpathIsValidExample1 = {
|
testSubpathIsValidExample1 = {
|
||||||
expr = subpath.isValid null;
|
expr = subpath.isValid null;
|
||||||
|
|
|
@ -715,12 +715,12 @@ rec {
|
||||||
getName pkgs.youtube-dl
|
getName pkgs.youtube-dl
|
||||||
=> "youtube-dl"
|
=> "youtube-dl"
|
||||||
*/
|
*/
|
||||||
getName = x:
|
getName = let
|
||||||
let
|
parse = drv: (parseDrvName drv).name;
|
||||||
parse = drv: (parseDrvName drv).name;
|
in x:
|
||||||
in if isString x
|
if isString x
|
||||||
then parse x
|
then parse x
|
||||||
else x.pname or (parse x.name);
|
else x.pname or (parse x.name);
|
||||||
|
|
||||||
/* This function takes an argument that's either a derivation or a
|
/* This function takes an argument that's either a derivation or a
|
||||||
derivation's "name" attribute and extracts the version part from that
|
derivation's "name" attribute and extracts the version part from that
|
||||||
|
@ -732,12 +732,12 @@ rec {
|
||||||
getVersion pkgs.youtube-dl
|
getVersion pkgs.youtube-dl
|
||||||
=> "2016.01.01"
|
=> "2016.01.01"
|
||||||
*/
|
*/
|
||||||
getVersion = x:
|
getVersion = let
|
||||||
let
|
parse = drv: (parseDrvName drv).version;
|
||||||
parse = drv: (parseDrvName drv).version;
|
in x:
|
||||||
in if isString x
|
if isString x
|
||||||
then parse x
|
then parse x
|
||||||
else x.version or (parse x.name);
|
else x.version or (parse x.name);
|
||||||
|
|
||||||
/* Extract name with version from URL. Ask for separator which is
|
/* Extract name with version from URL. Ask for separator which is
|
||||||
supposed to start extension.
|
supposed to start extension.
|
||||||
|
@ -771,12 +771,13 @@ rec {
|
||||||
cmakeOptionType "string" "ENGINE" "sdl2"
|
cmakeOptionType "string" "ENGINE" "sdl2"
|
||||||
=> "-DENGINE:STRING=sdl2"
|
=> "-DENGINE:STRING=sdl2"
|
||||||
*/
|
*/
|
||||||
cmakeOptionType = type: feature: value:
|
cmakeOptionType = let
|
||||||
assert (lib.elem (lib.toUpper type)
|
types = [ "BOOL" "FILEPATH" "PATH" "STRING" "INTERNAL" ];
|
||||||
[ "BOOL" "FILEPATH" "PATH" "STRING" "INTERNAL" ]);
|
in type: feature: value:
|
||||||
assert (lib.isString feature);
|
assert (elem (toUpper type) types);
|
||||||
assert (lib.isString value);
|
assert (isString feature);
|
||||||
"-D${feature}:${lib.toUpper type}=${value}";
|
assert (isString value);
|
||||||
|
"-D${feature}:${toUpper type}=${value}";
|
||||||
|
|
||||||
/* Create a -D<condition>={TRUE,FALSE} string that can be passed to typical
|
/* Create a -D<condition>={TRUE,FALSE} string that can be passed to typical
|
||||||
CMake invocations.
|
CMake invocations.
|
||||||
|
@ -977,9 +978,11 @@ rec {
|
||||||
Many types of value are coercible to string this way, including int, float,
|
Many types of value are coercible to string this way, including int, float,
|
||||||
null, bool, list of similarly coercible values.
|
null, bool, list of similarly coercible values.
|
||||||
*/
|
*/
|
||||||
isConvertibleWithToString = x:
|
isConvertibleWithToString = let
|
||||||
|
types = [ "null" "int" "float" "bool" ];
|
||||||
|
in x:
|
||||||
isStringLike x ||
|
isStringLike x ||
|
||||||
elem (typeOf x) [ "null" "int" "float" "bool" ] ||
|
elem (typeOf x) types ||
|
||||||
(isList x && lib.all isConvertibleWithToString x);
|
(isList x && lib.all isConvertibleWithToString x);
|
||||||
|
|
||||||
/* Check whether a value can be coerced to a string.
|
/* Check whether a value can be coerced to a string.
|
||||||
|
|
|
@ -89,6 +89,13 @@ rec {
|
||||||
# is why we use the more obscure "bfd" and not "binutils" for this
|
# is why we use the more obscure "bfd" and not "binutils" for this
|
||||||
# choice.
|
# choice.
|
||||||
else "bfd";
|
else "bfd";
|
||||||
|
# The standard lib directory name that non-nixpkgs binaries distributed
|
||||||
|
# for this platform normally assume.
|
||||||
|
libDir = if final.isLinux then
|
||||||
|
if final.isx86_64 || final.isMips64 || final.isPower64
|
||||||
|
then "lib64"
|
||||||
|
else "lib"
|
||||||
|
else null;
|
||||||
extensions = lib.optionalAttrs final.hasSharedLibraries {
|
extensions = lib.optionalAttrs final.hasSharedLibraries {
|
||||||
sharedLibrary =
|
sharedLibrary =
|
||||||
if final.isDarwin then ".dylib"
|
if final.isDarwin then ".dylib"
|
||||||
|
|
|
@ -650,6 +650,28 @@ runTests {
|
||||||
expected = [2 30 40 42];
|
expected = [2 30 40 42];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
testSortOn = {
|
||||||
|
expr = sortOn stringLength [ "aa" "b" "cccc" ];
|
||||||
|
expected = [ "b" "aa" "cccc" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testSortOnEmpty = {
|
||||||
|
expr = sortOn (throw "nope") [ ];
|
||||||
|
expected = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testSortOnIncomparable = {
|
||||||
|
expr =
|
||||||
|
map
|
||||||
|
(x: x.f x.ok)
|
||||||
|
(sortOn (x: x.ok) [
|
||||||
|
{ ok = 1; f = x: x; }
|
||||||
|
{ ok = 3; f = x: x + 3; }
|
||||||
|
{ ok = 2; f = x: x; }
|
||||||
|
]);
|
||||||
|
expected = [ 1 2 6 ];
|
||||||
|
};
|
||||||
|
|
||||||
testReplicate = {
|
testReplicate = {
|
||||||
expr = replicate 3 "a";
|
expr = replicate 3 "a";
|
||||||
expected = ["a" "a" "a"];
|
expected = ["a" "a" "a"];
|
||||||
|
@ -675,6 +697,51 @@ runTests {
|
||||||
expected = false;
|
expected = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
testHasAttrByPathNonStrict = {
|
||||||
|
expr = hasAttrByPath [] (throw "do not use");
|
||||||
|
expected = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
testLongestValidPathPrefix_empty_empty = {
|
||||||
|
expr = attrsets.longestValidPathPrefix [ ] { };
|
||||||
|
expected = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testLongestValidPathPrefix_empty_nonStrict = {
|
||||||
|
expr = attrsets.longestValidPathPrefix [ ] (throw "do not use");
|
||||||
|
expected = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testLongestValidPathPrefix_zero = {
|
||||||
|
expr = attrsets.longestValidPathPrefix [ "a" (throw "do not use") ] { d = null; };
|
||||||
|
expected = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testLongestValidPathPrefix_zero_b = {
|
||||||
|
expr = attrsets.longestValidPathPrefix [ "z" "z" ] "remarkably harmonious";
|
||||||
|
expected = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testLongestValidPathPrefix_one = {
|
||||||
|
expr = attrsets.longestValidPathPrefix [ "a" "b" "c" ] { a = null; };
|
||||||
|
expected = [ "a" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testLongestValidPathPrefix_two = {
|
||||||
|
expr = attrsets.longestValidPathPrefix [ "a" "b" "c" ] { a.b = null; };
|
||||||
|
expected = [ "a" "b" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testLongestValidPathPrefix_three = {
|
||||||
|
expr = attrsets.longestValidPathPrefix [ "a" "b" "c" ] { a.b.c = null; };
|
||||||
|
expected = [ "a" "b" "c" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testLongestValidPathPrefix_three_extra = {
|
||||||
|
expr = attrsets.longestValidPathPrefix [ "a" "b" "c" ] { a.b.c.d = throw "nope"; };
|
||||||
|
expected = [ "a" "b" "c" ];
|
||||||
|
};
|
||||||
|
|
||||||
testFindFirstIndexExample1 = {
|
testFindFirstIndexExample1 = {
|
||||||
expr = lists.findFirstIndex (x: x > 3) (abort "index found, so a default must not be evaluated") [ 1 6 4 ];
|
expr = lists.findFirstIndex (x: x > 3) (abort "index found, so a default must not be evaluated") [ 1 6 4 ];
|
||||||
expected = 1;
|
expected = 1;
|
||||||
|
@ -1892,6 +1959,18 @@ runTests {
|
||||||
expr = (with types; int).description;
|
expr = (with types; int).description;
|
||||||
expected = "signed integer";
|
expected = "signed integer";
|
||||||
};
|
};
|
||||||
|
testTypeDescriptionIntsPositive = {
|
||||||
|
expr = (with types; ints.positive).description;
|
||||||
|
expected = "positive integer, meaning >0";
|
||||||
|
};
|
||||||
|
testTypeDescriptionIntsPositiveOrEnumAuto = {
|
||||||
|
expr = (with types; either ints.positive (enum ["auto"])).description;
|
||||||
|
expected = ''positive integer, meaning >0, or value "auto" (singular enum)'';
|
||||||
|
};
|
||||||
|
testTypeDescriptionListOfPositive = {
|
||||||
|
expr = (with types; listOf ints.positive).description;
|
||||||
|
expected = "list of (positive integer, meaning >0)";
|
||||||
|
};
|
||||||
testTypeDescriptionListOfInt = {
|
testTypeDescriptionListOfInt = {
|
||||||
expr = (with types; listOf int).description;
|
expr = (with types; listOf int).description;
|
||||||
expected = "list of signed integer";
|
expected = "list of signed integer";
|
||||||
|
@ -1988,4 +2067,37 @@ runTests {
|
||||||
expr = meta.platformMatch { } "x86_64-linux";
|
expr = meta.platformMatch { } "x86_64-linux";
|
||||||
expected = false;
|
expected = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
testPackagesFromDirectoryRecursive = {
|
||||||
|
expr = packagesFromDirectoryRecursive {
|
||||||
|
callPackage = path: overrides: import path overrides;
|
||||||
|
directory = ./packages-from-directory;
|
||||||
|
};
|
||||||
|
expected = {
|
||||||
|
a = "a";
|
||||||
|
b = "b";
|
||||||
|
# Note: Other files/directories in `./test-data/c/` are ignored and can be
|
||||||
|
# used by `package.nix`.
|
||||||
|
c = "c";
|
||||||
|
my-namespace = {
|
||||||
|
d = "d";
|
||||||
|
e = "e";
|
||||||
|
f = "f";
|
||||||
|
my-sub-namespace = {
|
||||||
|
g = "g";
|
||||||
|
h = "h";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Check that `packagesFromDirectoryRecursive` can process a directory with a
|
||||||
|
# top-level `package.nix` file into a single package.
|
||||||
|
testPackagesFromDirectoryRecursiveTopLevelPackageNix = {
|
||||||
|
expr = packagesFromDirectoryRecursive {
|
||||||
|
callPackage = path: overrides: import path overrides;
|
||||||
|
directory = ./packages-from-directory/c;
|
||||||
|
};
|
||||||
|
expected = "c";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,14 +24,14 @@ evalConfig() {
|
||||||
local attr=$1
|
local attr=$1
|
||||||
shift
|
shift
|
||||||
local script="import ./default.nix { modules = [ $* ];}"
|
local script="import ./default.nix { modules = [ $* ];}"
|
||||||
nix-instantiate --timeout 1 -E "$script" -A "$attr" --eval-only --show-trace --read-write-mode
|
nix-instantiate --timeout 1 -E "$script" -A "$attr" --eval-only --show-trace --read-write-mode --json
|
||||||
}
|
}
|
||||||
|
|
||||||
reportFailure() {
|
reportFailure() {
|
||||||
local attr=$1
|
local attr=$1
|
||||||
shift
|
shift
|
||||||
local script="import ./default.nix { modules = [ $* ];}"
|
local script="import ./default.nix { modules = [ $* ];}"
|
||||||
echo 2>&1 "$ nix-instantiate -E '$script' -A '$attr' --eval-only"
|
echo 2>&1 "$ nix-instantiate -E '$script' -A '$attr' --eval-only --json"
|
||||||
evalConfig "$attr" "$@" || true
|
evalConfig "$attr" "$@" || true
|
||||||
((++fail))
|
((++fail))
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,14 @@ checkConfigOutput '^true$' config.result ./module-argument-default.nix
|
||||||
# gvariant
|
# gvariant
|
||||||
checkConfigOutput '^true$' config.assertion ./gvariant.nix
|
checkConfigOutput '^true$' config.assertion ./gvariant.nix
|
||||||
|
|
||||||
|
# https://github.com/NixOS/nixpkgs/pull/131205
|
||||||
|
# We currently throw this error already in `config`, but throwing in `config.wrong1` would be acceptable.
|
||||||
|
checkConfigError 'It seems as if you.re trying to declare an option by placing it into .config. rather than .options.' config.wrong1 ./error-mkOption-in-config.nix
|
||||||
|
# We currently throw this error already in `config`, but throwing in `config.nest.wrong2` would be acceptable.
|
||||||
|
checkConfigError 'It seems as if you.re trying to declare an option by placing it into .config. rather than .options.' config.nest.wrong2 ./error-mkOption-in-config.nix
|
||||||
|
checkConfigError 'The option .sub.wrong2. does not exist. Definition values:' config.sub ./error-mkOption-in-submodule-config.nix
|
||||||
|
checkConfigError '.*This can happen if you e.g. declared your options in .types.submodule.' config.sub ./error-mkOption-in-submodule-config.nix
|
||||||
|
|
||||||
# types.pathInStore
|
# types.pathInStore
|
||||||
checkConfigOutput '".*/store/0lz9p8xhf89kb1c1kk6jxrzskaiygnlh-bash-5.2-p15.drv"' config.pathInStore.ok1 ./types.nix
|
checkConfigOutput '".*/store/0lz9p8xhf89kb1c1kk6jxrzskaiygnlh-bash-5.2-p15.drv"' config.pathInStore.ok1 ./types.nix
|
||||||
checkConfigOutput '".*/store/0fb3ykw9r5hpayd05sr0cizwadzq1d8q-bash-5.2-p15"' config.pathInStore.ok2 ./types.nix
|
checkConfigOutput '".*/store/0fb3ykw9r5hpayd05sr0cizwadzq1d8q-bash-5.2-p15"' config.pathInStore.ok2 ./types.nix
|
||||||
|
@ -111,6 +119,12 @@ checkConfigError 'The option .* does not exist. Definition values:\n\s*- In .*'
|
||||||
checkConfigError 'while evaluating a definition from `.*/define-enable-abort.nix' config.enable ./define-enable-abort.nix
|
checkConfigError 'while evaluating a definition from `.*/define-enable-abort.nix' config.enable ./define-enable-abort.nix
|
||||||
checkConfigError 'while evaluating the error message for definitions for .enable., which is an option that does not exist' config.enable ./define-enable-abort.nix
|
checkConfigError 'while evaluating the error message for definitions for .enable., which is an option that does not exist' config.enable ./define-enable-abort.nix
|
||||||
|
|
||||||
|
# Check boolByOr type.
|
||||||
|
checkConfigOutput '^false$' config.value.falseFalse ./boolByOr.nix
|
||||||
|
checkConfigOutput '^true$' config.value.trueFalse ./boolByOr.nix
|
||||||
|
checkConfigOutput '^true$' config.value.falseTrue ./boolByOr.nix
|
||||||
|
checkConfigOutput '^true$' config.value.trueTrue ./boolByOr.nix
|
||||||
|
|
||||||
checkConfigOutput '^1$' config.bare-submodule.nested ./declare-bare-submodule.nix ./declare-bare-submodule-nested-option.nix
|
checkConfigOutput '^1$' config.bare-submodule.nested ./declare-bare-submodule.nix ./declare-bare-submodule-nested-option.nix
|
||||||
checkConfigOutput '^2$' config.bare-submodule.deep ./declare-bare-submodule.nix ./declare-bare-submodule-deep-option.nix
|
checkConfigOutput '^2$' config.bare-submodule.deep ./declare-bare-submodule.nix ./declare-bare-submodule-deep-option.nix
|
||||||
checkConfigOutput '^42$' config.bare-submodule.nested ./declare-bare-submodule.nix ./declare-bare-submodule-nested-option.nix ./declare-bare-submodule-deep-option.nix ./define-bare-submodule-values.nix
|
checkConfigOutput '^42$' config.bare-submodule.nested ./declare-bare-submodule.nix ./declare-bare-submodule-nested-option.nix ./declare-bare-submodule-deep-option.nix ./define-bare-submodule-values.nix
|
||||||
|
@ -134,7 +148,7 @@ checkConfigOutput '^42$' config.value ./declare-either.nix ./define-value-int-po
|
||||||
checkConfigOutput '^"24"$' config.value ./declare-either.nix ./define-value-string.nix
|
checkConfigOutput '^"24"$' config.value ./declare-either.nix ./define-value-string.nix
|
||||||
# types.oneOf
|
# types.oneOf
|
||||||
checkConfigOutput '^42$' config.value ./declare-oneOf.nix ./define-value-int-positive.nix
|
checkConfigOutput '^42$' config.value ./declare-oneOf.nix ./define-value-int-positive.nix
|
||||||
checkConfigOutput '^\[ \]$' config.value ./declare-oneOf.nix ./define-value-list.nix
|
checkConfigOutput '^\[\]$' config.value ./declare-oneOf.nix ./define-value-list.nix
|
||||||
checkConfigOutput '^"24"$' config.value ./declare-oneOf.nix ./define-value-string.nix
|
checkConfigOutput '^"24"$' config.value ./declare-oneOf.nix ./define-value-string.nix
|
||||||
|
|
||||||
# Check mkForce without submodules.
|
# Check mkForce without submodules.
|
||||||
|
@ -314,7 +328,7 @@ checkConfigOutput '^"24"$' config.value ./freeform-attrsOf.nix ./define-value-st
|
||||||
# Shorthand modules interpret `meta` and `class` as config items
|
# Shorthand modules interpret `meta` and `class` as config items
|
||||||
checkConfigOutput '^true$' options._module.args.value.result ./freeform-attrsOf.nix ./define-freeform-keywords-shorthand.nix
|
checkConfigOutput '^true$' options._module.args.value.result ./freeform-attrsOf.nix ./define-freeform-keywords-shorthand.nix
|
||||||
# No freeform assignments shouldn't make it error
|
# No freeform assignments shouldn't make it error
|
||||||
checkConfigOutput '^{ }$' config ./freeform-attrsOf.nix
|
checkConfigOutput '^{}$' config ./freeform-attrsOf.nix
|
||||||
# but only if the type matches
|
# but only if the type matches
|
||||||
checkConfigError 'A definition for option .* is not of type .*' config.value ./freeform-attrsOf.nix ./define-value-list.nix
|
checkConfigError 'A definition for option .* is not of type .*' config.value ./freeform-attrsOf.nix ./define-value-list.nix
|
||||||
# and properties should be applied
|
# and properties should be applied
|
||||||
|
@ -352,19 +366,19 @@ checkConfigError 'The option .* has conflicting definitions' config.value ./type
|
||||||
checkConfigOutput '^0$' config.value.int ./types-anything/equal-atoms.nix
|
checkConfigOutput '^0$' config.value.int ./types-anything/equal-atoms.nix
|
||||||
checkConfigOutput '^false$' config.value.bool ./types-anything/equal-atoms.nix
|
checkConfigOutput '^false$' config.value.bool ./types-anything/equal-atoms.nix
|
||||||
checkConfigOutput '^""$' config.value.string ./types-anything/equal-atoms.nix
|
checkConfigOutput '^""$' config.value.string ./types-anything/equal-atoms.nix
|
||||||
checkConfigOutput '^/$' config.value.path ./types-anything/equal-atoms.nix
|
checkConfigOutput '^"/[^"]+"$' config.value.path ./types-anything/equal-atoms.nix
|
||||||
checkConfigOutput '^null$' config.value.null ./types-anything/equal-atoms.nix
|
checkConfigOutput '^null$' config.value.null ./types-anything/equal-atoms.nix
|
||||||
checkConfigOutput '^0.1$' config.value.float ./types-anything/equal-atoms.nix
|
checkConfigOutput '^0.1$' config.value.float ./types-anything/equal-atoms.nix
|
||||||
# Functions can't be merged together
|
# Functions can't be merged together
|
||||||
checkConfigError "The option .value.multiple-lambdas.<function body>. has conflicting option types" config.applied.multiple-lambdas ./types-anything/functions.nix
|
checkConfigError "The option .value.multiple-lambdas.<function body>. has conflicting option types" config.applied.multiple-lambdas ./types-anything/functions.nix
|
||||||
checkConfigOutput '^<LAMBDA>$' config.value.single-lambda ./types-anything/functions.nix
|
checkConfigOutput '^true$' config.valueIsFunction.single-lambda ./types-anything/functions.nix
|
||||||
checkConfigOutput '^null$' config.applied.merging-lambdas.x ./types-anything/functions.nix
|
checkConfigOutput '^null$' config.applied.merging-lambdas.x ./types-anything/functions.nix
|
||||||
checkConfigOutput '^null$' config.applied.merging-lambdas.y ./types-anything/functions.nix
|
checkConfigOutput '^null$' config.applied.merging-lambdas.y ./types-anything/functions.nix
|
||||||
# Check that all mk* modifiers are applied
|
# Check that all mk* modifiers are applied
|
||||||
checkConfigError 'attribute .* not found' config.value.mkiffalse ./types-anything/mk-mods.nix
|
checkConfigError 'attribute .* not found' config.value.mkiffalse ./types-anything/mk-mods.nix
|
||||||
checkConfigOutput '^{ }$' config.value.mkiftrue ./types-anything/mk-mods.nix
|
checkConfigOutput '^{}$' config.value.mkiftrue ./types-anything/mk-mods.nix
|
||||||
checkConfigOutput '^1$' config.value.mkdefault ./types-anything/mk-mods.nix
|
checkConfigOutput '^1$' config.value.mkdefault ./types-anything/mk-mods.nix
|
||||||
checkConfigOutput '^{ }$' config.value.mkmerge ./types-anything/mk-mods.nix
|
checkConfigOutput '^{}$' config.value.mkmerge ./types-anything/mk-mods.nix
|
||||||
checkConfigOutput '^true$' config.value.mkbefore ./types-anything/mk-mods.nix
|
checkConfigOutput '^true$' config.value.mkbefore ./types-anything/mk-mods.nix
|
||||||
checkConfigOutput '^1$' config.value.nested.foo ./types-anything/mk-mods.nix
|
checkConfigOutput '^1$' config.value.nested.foo ./types-anything/mk-mods.nix
|
||||||
checkConfigOutput '^"baz"$' config.value.nested.bar.baz ./types-anything/mk-mods.nix
|
checkConfigOutput '^"baz"$' config.value.nested.bar.baz ./types-anything/mk-mods.nix
|
||||||
|
@ -384,16 +398,16 @@ checkConfigOutput '^"a b y z"$' config.resultFooBar ./declare-variants.nix ./def
|
||||||
checkConfigOutput '^"a b c"$' config.resultFooFoo ./declare-variants.nix ./define-variant.nix
|
checkConfigOutput '^"a b c"$' config.resultFooFoo ./declare-variants.nix ./define-variant.nix
|
||||||
|
|
||||||
## emptyValue's
|
## emptyValue's
|
||||||
checkConfigOutput "[ ]" config.list.a ./emptyValues.nix
|
checkConfigOutput "\[\]" config.list.a ./emptyValues.nix
|
||||||
checkConfigOutput "{ }" config.attrs.a ./emptyValues.nix
|
checkConfigOutput "{}" config.attrs.a ./emptyValues.nix
|
||||||
checkConfigOutput "null" config.null.a ./emptyValues.nix
|
checkConfigOutput "null" config.null.a ./emptyValues.nix
|
||||||
checkConfigOutput "{ }" config.submodule.a ./emptyValues.nix
|
checkConfigOutput "{}" config.submodule.a ./emptyValues.nix
|
||||||
# These types don't have empty values
|
# These types don't have empty values
|
||||||
checkConfigError 'The option .int.a. is used but not defined' config.int.a ./emptyValues.nix
|
checkConfigError 'The option .int.a. is used but not defined' config.int.a ./emptyValues.nix
|
||||||
checkConfigError 'The option .nonEmptyList.a. is used but not defined' config.nonEmptyList.a ./emptyValues.nix
|
checkConfigError 'The option .nonEmptyList.a. is used but not defined' config.nonEmptyList.a ./emptyValues.nix
|
||||||
|
|
||||||
## types.raw
|
## types.raw
|
||||||
checkConfigOutput "{ foo = <CODE>; }" config.unprocessedNesting ./raw.nix
|
checkConfigOutput '^true$' config.unprocessedNestingEvaluates.success ./raw.nix
|
||||||
checkConfigOutput "10" config.processedToplevel ./raw.nix
|
checkConfigOutput "10" config.processedToplevel ./raw.nix
|
||||||
checkConfigError "The option .multiple. is defined multiple times" config.multiple ./raw.nix
|
checkConfigError "The option .multiple. is defined multiple times" config.multiple ./raw.nix
|
||||||
checkConfigOutput "bar" config.priorities ./raw.nix
|
checkConfigOutput "bar" config.priorities ./raw.nix
|
||||||
|
@ -427,13 +441,13 @@ checkConfigOutput 'ok' config.freeformItems.foo.bar ./adhoc-freeformType-survive
|
||||||
checkConfigOutput '^1$' config.sub.specialisation.value ./extendModules-168767-imports.nix
|
checkConfigOutput '^1$' config.sub.specialisation.value ./extendModules-168767-imports.nix
|
||||||
|
|
||||||
# Class checks, evalModules
|
# Class checks, evalModules
|
||||||
checkConfigOutput '^{ }$' config.ok.config ./class-check.nix
|
checkConfigOutput '^{}$' config.ok.config ./class-check.nix
|
||||||
checkConfigOutput '"nixos"' config.ok.class ./class-check.nix
|
checkConfigOutput '"nixos"' config.ok.class ./class-check.nix
|
||||||
checkConfigError 'The module .*/module-class-is-darwin.nix was imported into nixos instead of darwin.' config.fail.config ./class-check.nix
|
checkConfigError 'The module .*/module-class-is-darwin.nix was imported into nixos instead of darwin.' config.fail.config ./class-check.nix
|
||||||
checkConfigError 'The module foo.nix#darwinModules.default was imported into nixos instead of darwin.' config.fail-anon.config ./class-check.nix
|
checkConfigError 'The module foo.nix#darwinModules.default was imported into nixos instead of darwin.' config.fail-anon.config ./class-check.nix
|
||||||
|
|
||||||
# Class checks, submoduleWith
|
# Class checks, submoduleWith
|
||||||
checkConfigOutput '^{ }$' config.sub.nixosOk ./class-check.nix
|
checkConfigOutput '^{}$' config.sub.nixosOk ./class-check.nix
|
||||||
checkConfigError 'The module .*/module-class-is-darwin.nix was imported into nixos instead of darwin.' config.sub.nixosFail.config ./class-check.nix
|
checkConfigError 'The module .*/module-class-is-darwin.nix was imported into nixos instead of darwin.' config.sub.nixosFail.config ./class-check.nix
|
||||||
|
|
||||||
# submoduleWith type merge with different class
|
# submoduleWith type merge with different class
|
||||||
|
|
14
lib/tests/modules/boolByOr.nix
Normal file
14
lib/tests/modules/boolByOr.nix
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{ lib, ... }: {
|
||||||
|
|
||||||
|
options.value = lib.mkOption {
|
||||||
|
type = lib.types.lazyAttrsOf lib.types.boolByOr;
|
||||||
|
};
|
||||||
|
|
||||||
|
config.value = {
|
||||||
|
falseFalse = lib.mkMerge [ false false ];
|
||||||
|
trueFalse = lib.mkMerge [ true false ];
|
||||||
|
falseTrue = lib.mkMerge [ false true ];
|
||||||
|
trueTrue = lib.mkMerge [ true true ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
14
lib/tests/modules/error-mkOption-in-config.nix
Normal file
14
lib/tests/modules/error-mkOption-in-config.nix
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{ lib, ... }:
|
||||||
|
let
|
||||||
|
inherit (lib) mkOption;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
wrong1 = mkOption {
|
||||||
|
};
|
||||||
|
# This is not actually reported separately, so could be omitted from the test
|
||||||
|
# but it makes the example more realistic.
|
||||||
|
# Making it parse this _config_ as options would too risky. What if it's not
|
||||||
|
# options but other values, that abort, throw, diverge, etc?
|
||||||
|
nest.wrong2 = mkOption {
|
||||||
|
};
|
||||||
|
}
|
12
lib/tests/modules/error-mkOption-in-submodule-config.nix
Normal file
12
lib/tests/modules/error-mkOption-in-submodule-config.nix
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{ lib, ... }:
|
||||||
|
let
|
||||||
|
inherit (lib) mkOption;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.sub = lib.mkOption {
|
||||||
|
type = lib.types.submodule {
|
||||||
|
wrong2 = mkOption {};
|
||||||
|
};
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
{ lib, ... }: {
|
{ lib, config, ... }: {
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
processedToplevel = lib.mkOption {
|
processedToplevel = lib.mkOption {
|
||||||
|
@ -13,6 +13,9 @@
|
||||||
priorities = lib.mkOption {
|
priorities = lib.mkOption {
|
||||||
type = lib.types.raw;
|
type = lib.types.raw;
|
||||||
};
|
};
|
||||||
|
unprocessedNestingEvaluates = lib.mkOption {
|
||||||
|
default = builtins.tryEval config.unprocessedNesting;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
value.int = 0;
|
value.int = 0;
|
||||||
value.bool = false;
|
value.bool = false;
|
||||||
value.string = "";
|
value.string = "";
|
||||||
value.path = /.;
|
value.path = ./.;
|
||||||
value.null = null;
|
value.null = null;
|
||||||
value.float = 0.1;
|
value.float = 0.1;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
value.int = 0;
|
value.int = 0;
|
||||||
value.bool = false;
|
value.bool = false;
|
||||||
value.string = "";
|
value.string = "";
|
||||||
value.path = /.;
|
value.path = ./.;
|
||||||
value.null = null;
|
value.null = null;
|
||||||
value.float = 0.1;
|
value.float = 0.1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
{ lib, config, ... }: {
|
{ lib, config, ... }: {
|
||||||
|
|
||||||
|
options.valueIsFunction = lib.mkOption {
|
||||||
|
default = lib.mapAttrs (name: lib.isFunction) config.value;
|
||||||
|
};
|
||||||
|
|
||||||
options.value = lib.mkOption {
|
options.value = lib.mkOption {
|
||||||
type = lib.types.anything;
|
type = lib.types.anything;
|
||||||
};
|
};
|
||||||
|
|
2
lib/tests/packages-from-directory/a.nix
Normal file
2
lib/tests/packages-from-directory/a.nix
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
{ }:
|
||||||
|
"a"
|
2
lib/tests/packages-from-directory/b.nix
Normal file
2
lib/tests/packages-from-directory/b.nix
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
{ }:
|
||||||
|
"b"
|
2
lib/tests/packages-from-directory/c/package.nix
Normal file
2
lib/tests/packages-from-directory/c/package.nix
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
{ }:
|
||||||
|
"c"
|
2
lib/tests/packages-from-directory/my-namespace/d.nix
Normal file
2
lib/tests/packages-from-directory/my-namespace/d.nix
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
{ }:
|
||||||
|
"d"
|
2
lib/tests/packages-from-directory/my-namespace/e.nix
Normal file
2
lib/tests/packages-from-directory/my-namespace/e.nix
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
{ }:
|
||||||
|
"e"
|
|
@ -0,0 +1,2 @@
|
||||||
|
{ }:
|
||||||
|
"f"
|
|
@ -0,0 +1,2 @@
|
||||||
|
{ }:
|
||||||
|
"g"
|
|
@ -0,0 +1,2 @@
|
||||||
|
{ }:
|
||||||
|
"h"
|
|
@ -67,5 +67,17 @@ let
|
||||||
in
|
in
|
||||||
pkgs.symlinkJoin {
|
pkgs.symlinkJoin {
|
||||||
name = "nixpkgs-lib-tests";
|
name = "nixpkgs-lib-tests";
|
||||||
paths = map testWithNix nixVersions;
|
paths = map testWithNix nixVersions ++
|
||||||
|
|
||||||
|
#
|
||||||
|
# TEMPORARY MIGRATION MECHANISM
|
||||||
|
#
|
||||||
|
# This comment and the expression which follows it should be
|
||||||
|
# removed as part of resolving this issue:
|
||||||
|
#
|
||||||
|
# https://github.com/NixOS/nixpkgs/issues/272591
|
||||||
|
#
|
||||||
|
[(import ../../pkgs/test/release {})]
|
||||||
|
;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,18 @@
|
||||||
{ lib }:
|
{ lib }:
|
||||||
|
|
||||||
rec {
|
let
|
||||||
|
inherit (lib.trivial)
|
||||||
|
isFunction
|
||||||
|
isInt
|
||||||
|
functionArgs
|
||||||
|
pathExists
|
||||||
|
release
|
||||||
|
setFunctionArgs
|
||||||
|
toBaseDigits
|
||||||
|
version
|
||||||
|
versionSuffix
|
||||||
|
warn;
|
||||||
|
in {
|
||||||
|
|
||||||
## Simple (higher order) functions
|
## Simple (higher order) functions
|
||||||
|
|
||||||
|
@ -58,9 +70,7 @@ rec {
|
||||||
of the next function, and the last function returns the
|
of the next function, and the last function returns the
|
||||||
final value.
|
final value.
|
||||||
*/
|
*/
|
||||||
pipe = val: functions:
|
pipe = builtins.foldl' (x: f: f x);
|
||||||
let reverseApply = x: f: f x;
|
|
||||||
in builtins.foldl' reverseApply val functions;
|
|
||||||
|
|
||||||
# note please don’t add a function like `compose = flip pipe`.
|
# note please don’t add a function like `compose = flip pipe`.
|
||||||
# This would confuse users, because the order of the functions
|
# This would confuse users, because the order of the functions
|
||||||
|
@ -439,7 +449,7 @@ rec {
|
||||||
*/
|
*/
|
||||||
functionArgs = f:
|
functionArgs = f:
|
||||||
if f ? __functor
|
if f ? __functor
|
||||||
then f.__functionArgs or (lib.functionArgs (f.__functor f))
|
then f.__functionArgs or (functionArgs (f.__functor f))
|
||||||
else builtins.functionArgs f;
|
else builtins.functionArgs f;
|
||||||
|
|
||||||
/* Check whether something is a function or something
|
/* Check whether something is a function or something
|
||||||
|
@ -510,22 +520,20 @@ rec {
|
||||||
|
|
||||||
toHexString 250 => "FA"
|
toHexString 250 => "FA"
|
||||||
*/
|
*/
|
||||||
toHexString = i:
|
toHexString = let
|
||||||
let
|
hexDigits = {
|
||||||
toHexDigit = d:
|
"10" = "A";
|
||||||
if d < 10
|
"11" = "B";
|
||||||
then toString d
|
"12" = "C";
|
||||||
else
|
"13" = "D";
|
||||||
{
|
"14" = "E";
|
||||||
"10" = "A";
|
"15" = "F";
|
||||||
"11" = "B";
|
};
|
||||||
"12" = "C";
|
toHexDigit = d:
|
||||||
"13" = "D";
|
if d < 10
|
||||||
"14" = "E";
|
then toString d
|
||||||
"15" = "F";
|
else hexDigits.${toString d};
|
||||||
}.${toString d};
|
in i: lib.concatMapStrings toHexDigit (toBaseDigits 16 i);
|
||||||
in
|
|
||||||
lib.concatMapStrings toHexDigit (toBaseDigits 16 i);
|
|
||||||
|
|
||||||
/* `toBaseDigits base i` converts the positive integer i to a list of its
|
/* `toBaseDigits base i` converts the positive integer i to a list of its
|
||||||
digits in the given base. For example:
|
digits in the given base. For example:
|
||||||
|
|
|
@ -67,6 +67,7 @@ let
|
||||||
;
|
;
|
||||||
outer_types =
|
outer_types =
|
||||||
rec {
|
rec {
|
||||||
|
__attrsFailEvaluation = true;
|
||||||
isType = type: x: (x._type or "") == type;
|
isType = type: x: (x._type or "") == type;
|
||||||
|
|
||||||
setType = typeName: value: value // {
|
setType = typeName: value: value // {
|
||||||
|
@ -112,9 +113,14 @@ rec {
|
||||||
, # Description of the type, defined recursively by embedding the wrapped type if any.
|
, # Description of the type, defined recursively by embedding the wrapped type if any.
|
||||||
description ? null
|
description ? null
|
||||||
# A hint for whether or not this description needs parentheses. Possible values:
|
# A hint for whether or not this description needs parentheses. Possible values:
|
||||||
# - "noun": a simple noun phrase such as "positive integer"
|
# - "noun": a noun phrase
|
||||||
# - "conjunction": a phrase with a potentially ambiguous "or" connective.
|
# Example description: "positive integer",
|
||||||
|
# - "conjunction": a phrase with a potentially ambiguous "or" connective
|
||||||
|
# Example description: "int or string"
|
||||||
# - "composite": a phrase with an "of" connective
|
# - "composite": a phrase with an "of" connective
|
||||||
|
# Example description: "list of string"
|
||||||
|
# - "nonRestrictiveClause": a noun followed by a comma and a clause
|
||||||
|
# Example description: "positive integer, meaning >0"
|
||||||
# See the `optionDescriptionPhrase` function.
|
# See the `optionDescriptionPhrase` function.
|
||||||
, descriptionClass ? null
|
, descriptionClass ? null
|
||||||
, # DO NOT USE WITHOUT KNOWING WHAT YOU ARE DOING!
|
, # DO NOT USE WITHOUT KNOWING WHAT YOU ARE DOING!
|
||||||
|
@ -275,6 +281,22 @@ rec {
|
||||||
merge = mergeEqualOption;
|
merge = mergeEqualOption;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
boolByOr = mkOptionType {
|
||||||
|
name = "boolByOr";
|
||||||
|
description = "boolean (merged using or)";
|
||||||
|
descriptionClass = "noun";
|
||||||
|
check = isBool;
|
||||||
|
merge = loc: defs:
|
||||||
|
foldl'
|
||||||
|
(result: def:
|
||||||
|
# Under the assumption that .check always runs before merge, we can assume that all defs.*.value
|
||||||
|
# have been forced, and therefore we assume we don't introduce order-dependent strictness here
|
||||||
|
result || def.value
|
||||||
|
)
|
||||||
|
false
|
||||||
|
defs;
|
||||||
|
};
|
||||||
|
|
||||||
int = mkOptionType {
|
int = mkOptionType {
|
||||||
name = "int";
|
name = "int";
|
||||||
description = "signed integer";
|
description = "signed integer";
|
||||||
|
@ -321,10 +343,12 @@ rec {
|
||||||
unsigned = addCheck types.int (x: x >= 0) // {
|
unsigned = addCheck types.int (x: x >= 0) // {
|
||||||
name = "unsignedInt";
|
name = "unsignedInt";
|
||||||
description = "unsigned integer, meaning >=0";
|
description = "unsigned integer, meaning >=0";
|
||||||
|
descriptionClass = "nonRestrictiveClause";
|
||||||
};
|
};
|
||||||
positive = addCheck types.int (x: x > 0) // {
|
positive = addCheck types.int (x: x > 0) // {
|
||||||
name = "positiveInt";
|
name = "positiveInt";
|
||||||
description = "positive integer, meaning >0";
|
description = "positive integer, meaning >0";
|
||||||
|
descriptionClass = "nonRestrictiveClause";
|
||||||
};
|
};
|
||||||
u8 = unsign 8 256;
|
u8 = unsign 8 256;
|
||||||
u16 = unsign 16 65536;
|
u16 = unsign 16 65536;
|
||||||
|
@ -366,10 +390,12 @@ rec {
|
||||||
nonnegative = addCheck number (x: x >= 0) // {
|
nonnegative = addCheck number (x: x >= 0) // {
|
||||||
name = "numberNonnegative";
|
name = "numberNonnegative";
|
||||||
description = "nonnegative integer or floating point number, meaning >=0";
|
description = "nonnegative integer or floating point number, meaning >=0";
|
||||||
|
descriptionClass = "nonRestrictiveClause";
|
||||||
};
|
};
|
||||||
positive = addCheck number (x: x > 0) // {
|
positive = addCheck number (x: x > 0) // {
|
||||||
name = "numberPositive";
|
name = "numberPositive";
|
||||||
description = "positive integer or floating point number, meaning >0";
|
description = "positive integer or floating point number, meaning >0";
|
||||||
|
descriptionClass = "nonRestrictiveClause";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -446,6 +472,7 @@ rec {
|
||||||
passwdEntry = entryType: addCheck entryType (str: !(hasInfix ":" str || hasInfix "\n" str)) // {
|
passwdEntry = entryType: addCheck entryType (str: !(hasInfix ":" str || hasInfix "\n" str)) // {
|
||||||
name = "passwdEntry ${entryType.name}";
|
name = "passwdEntry ${entryType.name}";
|
||||||
description = "${optionDescriptionPhrase (class: class == "noun") entryType}, not containing newlines or colons";
|
description = "${optionDescriptionPhrase (class: class == "noun") entryType}, not containing newlines or colons";
|
||||||
|
descriptionClass = "nonRestrictiveClause";
|
||||||
};
|
};
|
||||||
|
|
||||||
attrs = mkOptionType {
|
attrs = mkOptionType {
|
||||||
|
@ -853,7 +880,13 @@ rec {
|
||||||
# Either value of type `t1` or `t2`.
|
# Either value of type `t1` or `t2`.
|
||||||
either = t1: t2: mkOptionType rec {
|
either = t1: t2: mkOptionType rec {
|
||||||
name = "either";
|
name = "either";
|
||||||
description = "${optionDescriptionPhrase (class: class == "noun" || class == "conjunction") t1} or ${optionDescriptionPhrase (class: class == "noun" || class == "conjunction" || class == "composite") t2}";
|
description =
|
||||||
|
if t1.descriptionClass or null == "nonRestrictiveClause"
|
||||||
|
then
|
||||||
|
# Plain, but add comma
|
||||||
|
"${t1.description}, or ${optionDescriptionPhrase (class: class == "noun" || class == "conjunction") t2}"
|
||||||
|
else
|
||||||
|
"${optionDescriptionPhrase (class: class == "noun" || class == "conjunction") t1} or ${optionDescriptionPhrase (class: class == "noun" || class == "conjunction" || class == "composite") t2}";
|
||||||
descriptionClass = "conjunction";
|
descriptionClass = "conjunction";
|
||||||
check = x: t1.check x || t2.check x;
|
check = x: t1.check x || t2.check x;
|
||||||
merge = loc: defs:
|
merge = loc: defs:
|
||||||
|
|
|
@ -165,3 +165,10 @@ team after giving the existing members a few days to respond.
|
||||||
|
|
||||||
*Important:* If a team says it is a closed group, do not merge additions
|
*Important:* If a team says it is a closed group, do not merge additions
|
||||||
to the team without an approval by at least one existing member.
|
to the team without an approval by at least one existing member.
|
||||||
|
|
||||||
|
|
||||||
|
# Maintainer scripts
|
||||||
|
|
||||||
|
Various utility scripts, which are mainly useful for nixpkgs maintainers,
|
||||||
|
are available under `./scripts/`. See its [README](./scripts/README.md)
|
||||||
|
for further information.
|
||||||
|
|
|
@ -26,8 +26,10 @@
|
||||||
- `githubId` is your GitHub user ID, which can be found at `https://api.github.com/users/<userhandle>`,
|
- `githubId` is your GitHub user ID, which can be found at `https://api.github.com/users/<userhandle>`,
|
||||||
- `keys` is a list of your PGP/GPG key fingerprints.
|
- `keys` is a list of your PGP/GPG key fingerprints.
|
||||||
|
|
||||||
Specifying a GitHub account ensures that you automatically get a review request on
|
Specifying a GitHub account ensures that you automatically:
|
||||||
pull requests that modify a package for which you are a maintainer.
|
- get invited to the @NixOS/nixpkgs-maintainers team ;
|
||||||
|
- once you are part of the @NixOS org, OfBorg will request you review
|
||||||
|
pull requests that modify a package for which you are a maintainer.
|
||||||
|
|
||||||
`handle == github` is strongly preferred whenever `github` is an acceptable attribute name and is short and convenient.
|
`handle == github` is strongly preferred whenever `github` is an acceptable attribute name and is short and convenient.
|
||||||
|
|
||||||
|
@ -386,6 +388,12 @@
|
||||||
fingerprint = "CE85 54F7 B9BC AC0D D648 5661 AB5F C04C 3C94 443F";
|
fingerprint = "CE85 54F7 B9BC AC0D D648 5661 AB5F C04C 3C94 443F";
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
adam248 = {
|
||||||
|
email = "adamjbutler091@gmail.com";
|
||||||
|
github = "adam248";
|
||||||
|
githubId = 85082674;
|
||||||
|
name = "Adam J. Butler";
|
||||||
|
};
|
||||||
adamcstephens = {
|
adamcstephens = {
|
||||||
email = "happy.plan4249@valkor.net";
|
email = "happy.plan4249@valkor.net";
|
||||||
matrix = "@adam:valkor.net";
|
matrix = "@adam:valkor.net";
|
||||||
|
@ -526,7 +534,7 @@
|
||||||
name = "James Alexander Feldman-Crough";
|
name = "James Alexander Feldman-Crough";
|
||||||
};
|
};
|
||||||
afontain = {
|
afontain = {
|
||||||
email = "antoine.fontaine@epfl.ch";
|
email = "afontain@posteo.net";
|
||||||
github = "necessarily-equal";
|
github = "necessarily-equal";
|
||||||
githubId = 59283660;
|
githubId = 59283660;
|
||||||
name = "Antoine Fontaine";
|
name = "Antoine Fontaine";
|
||||||
|
@ -603,6 +611,12 @@
|
||||||
githubId = 4717906;
|
githubId = 4717906;
|
||||||
name = "Jakub Skokan";
|
name = "Jakub Skokan";
|
||||||
};
|
};
|
||||||
|
ajaxbits = {
|
||||||
|
email = "contact@ajaxbits.com";
|
||||||
|
github = "ajaxbits";
|
||||||
|
githubId = 45179933;
|
||||||
|
name = "Alex Jackson";
|
||||||
|
};
|
||||||
ajgrf = {
|
ajgrf = {
|
||||||
email = "a@ajgrf.com";
|
email = "a@ajgrf.com";
|
||||||
github = "ajgrf";
|
github = "ajgrf";
|
||||||
|
@ -697,6 +711,15 @@
|
||||||
githubId = 20405311;
|
githubId = 20405311;
|
||||||
name = "Aksh Gupta";
|
name = "Aksh Gupta";
|
||||||
};
|
};
|
||||||
|
al3xtjames = {
|
||||||
|
email = "nix@alextjam.es";
|
||||||
|
github = "al3xtjames";
|
||||||
|
githubId = 5672538;
|
||||||
|
name = "Alex James";
|
||||||
|
keys = [{
|
||||||
|
fingerprint = "F354 FFAB EA89 A49D 33ED 2590 4729 B829 AC5F CC72";
|
||||||
|
}];
|
||||||
|
};
|
||||||
alanpearce = {
|
alanpearce = {
|
||||||
email = "alan@alanpearce.eu";
|
email = "alan@alanpearce.eu";
|
||||||
github = "alanpearce";
|
github = "alanpearce";
|
||||||
|
@ -1267,9 +1290,11 @@
|
||||||
githubId = 6060545;
|
githubId = 6060545;
|
||||||
matrix = "@anpin:matrix.org";
|
matrix = "@anpin:matrix.org";
|
||||||
name = "Pavel Anpin";
|
name = "Pavel Anpin";
|
||||||
keys = [{
|
keys = [
|
||||||
fingerprint = "06E8 4FF6 0CCF 7AFD 5101 76C9 0FBC D3EE 6310 7407";
|
{ fingerprint = "06E8 4FF6 0CCF 7AFD 5101 76C9 0FBC D3EE 6310 7407"; }
|
||||||
}];
|
# compare with https://keybase.io/anpin/pgp_keys.asc
|
||||||
|
{ fingerprint = "DADF F3EA 06DC 8C1B 100A 24DB 312E 8F17 91C5 DA8C"; }
|
||||||
|
];
|
||||||
};
|
};
|
||||||
anpryl = {
|
anpryl = {
|
||||||
email = "anpryl@gmail.com";
|
email = "anpryl@gmail.com";
|
||||||
|
@ -2038,6 +2063,12 @@
|
||||||
githubId = 80325;
|
githubId = 80325;
|
||||||
name = "Benjamin Andresen";
|
name = "Benjamin Andresen";
|
||||||
};
|
};
|
||||||
|
barab-i = {
|
||||||
|
email = "barab_i@outlook.com";
|
||||||
|
github = "barab-i";
|
||||||
|
githubId = 92919899;
|
||||||
|
name = "Barab I";
|
||||||
|
};
|
||||||
baracoder = {
|
baracoder = {
|
||||||
email = "baracoder@googlemail.com";
|
email = "baracoder@googlemail.com";
|
||||||
github = "baracoder";
|
github = "baracoder";
|
||||||
|
@ -2266,6 +2297,15 @@
|
||||||
githubId = 16821405;
|
githubId = 16821405;
|
||||||
name = "Ben Kuhn";
|
name = "Ben Kuhn";
|
||||||
};
|
};
|
||||||
|
benlemasurier = {
|
||||||
|
email = "ben@crypt.ly";
|
||||||
|
github = "benlemasurier";
|
||||||
|
githubId = 47993;
|
||||||
|
name = "Ben LeMasurier";
|
||||||
|
keys = [{
|
||||||
|
fingerprint = "0FD4 7407 EFD4 8FD8 8BF5 87B3 248D 430A E8E7 4189";
|
||||||
|
}];
|
||||||
|
};
|
||||||
benley = {
|
benley = {
|
||||||
email = "benley@gmail.com";
|
email = "benley@gmail.com";
|
||||||
github = "benley";
|
github = "benley";
|
||||||
|
@ -2598,6 +2638,12 @@
|
||||||
fingerprint = "F549 3B7F 9372 5578 FDD3 D0B8 A1BC 8428 323E CFE8";
|
fingerprint = "F549 3B7F 9372 5578 FDD3 D0B8 A1BC 8428 323E CFE8";
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
br337 = {
|
||||||
|
email = "brian.porumb@proton.me";
|
||||||
|
github = "br337";
|
||||||
|
githubId = 49288125;
|
||||||
|
name = "Brian Porumb";
|
||||||
|
};
|
||||||
bradediger = {
|
bradediger = {
|
||||||
email = "brad@bradediger.com";
|
email = "brad@bradediger.com";
|
||||||
github = "bradediger";
|
github = "bradediger";
|
||||||
|
@ -2705,6 +2751,12 @@
|
||||||
githubId = 53131727;
|
githubId = 53131727;
|
||||||
name = "Bryan Albuquerque";
|
name = "Bryan Albuquerque";
|
||||||
};
|
};
|
||||||
|
bryango = {
|
||||||
|
name = "Bryan Lai";
|
||||||
|
email = "bryanlais@gmail.com";
|
||||||
|
github = "bryango";
|
||||||
|
githubId = 26322692;
|
||||||
|
};
|
||||||
bryanhonof = {
|
bryanhonof = {
|
||||||
name = "Bryan Honof";
|
name = "Bryan Honof";
|
||||||
email = "bryanhonof@gmail.com";
|
email = "bryanhonof@gmail.com";
|
||||||
|
@ -3726,6 +3778,12 @@
|
||||||
githubId = 1740337;
|
githubId = 1740337;
|
||||||
name = "Chris Ostrouchov";
|
name = "Chris Ostrouchov";
|
||||||
};
|
};
|
||||||
|
cottand = {
|
||||||
|
email = "nico@dcotta.eu";
|
||||||
|
github = "cottand";
|
||||||
|
githubId = 45274424;
|
||||||
|
name = "Nico D'Cotta";
|
||||||
|
};
|
||||||
couchemar = {
|
couchemar = {
|
||||||
email = "couchemar@yandex.ru";
|
email = "couchemar@yandex.ru";
|
||||||
github = "couchemar";
|
github = "couchemar";
|
||||||
|
@ -3916,6 +3974,12 @@
|
||||||
githubId = 217899;
|
githubId = 217899;
|
||||||
name = "Cyryl Płotnicki";
|
name = "Cyryl Płotnicki";
|
||||||
};
|
};
|
||||||
|
d3vil0p3r = {
|
||||||
|
name = "Antonio Voza";
|
||||||
|
email = "vozaanthony@gmail.com";
|
||||||
|
github = "D3vil0p3r";
|
||||||
|
githubId = 83867734;
|
||||||
|
};
|
||||||
dadada = {
|
dadada = {
|
||||||
name = "dadada";
|
name = "dadada";
|
||||||
email = "dadada@dadada.li";
|
email = "dadada@dadada.li";
|
||||||
|
@ -4131,7 +4195,7 @@
|
||||||
email = "davidlewis@mac.com";
|
email = "davidlewis@mac.com";
|
||||||
github = "oceanlewis";
|
github = "oceanlewis";
|
||||||
githubId = 6754950;
|
githubId = 6754950;
|
||||||
name = "David Armstrong Lewis";
|
name = "Ocean Armstrong Lewis";
|
||||||
};
|
};
|
||||||
davidcromp = {
|
davidcromp = {
|
||||||
email = "davidcrompton1192@gmail.com";
|
email = "davidcrompton1192@gmail.com";
|
||||||
|
@ -4145,6 +4209,15 @@
|
||||||
githubId = 118536343;
|
githubId = 118536343;
|
||||||
name = "David Hamelin";
|
name = "David Hamelin";
|
||||||
};
|
};
|
||||||
|
david-r-cox = {
|
||||||
|
email = "david@integrated-reasoning.com";
|
||||||
|
github = "david-r-cox";
|
||||||
|
githubId = 4259949;
|
||||||
|
name = "David Cox";
|
||||||
|
keys = [{
|
||||||
|
fingerprint = "0056 A3F6 9918 1E0D 8FF0 BCDE 65BB 07FA A4D9 4634";
|
||||||
|
}];
|
||||||
|
};
|
||||||
davidrusu = {
|
davidrusu = {
|
||||||
email = "davidrusu.me@gmail.com";
|
email = "davidrusu.me@gmail.com";
|
||||||
github = "davidrusu";
|
github = "davidrusu";
|
||||||
|
@ -4217,6 +4290,12 @@
|
||||||
fingerprint = "B26F 9AD8 DA20 3392 EF87 C61A BB99 9F83 D9A1 9A36";
|
fingerprint = "B26F 9AD8 DA20 3392 EF87 C61A BB99 9F83 D9A1 9A36";
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
dblsaiko = {
|
||||||
|
email = "me@dblsaiko.net";
|
||||||
|
github = "2xsaiko";
|
||||||
|
githubId = 3987560;
|
||||||
|
name = "Marco Rebhan";
|
||||||
|
};
|
||||||
dbohdan = {
|
dbohdan = {
|
||||||
email = "dbohdan@dbohdan.com";
|
email = "dbohdan@dbohdan.com";
|
||||||
github = "dbohdan";
|
github = "dbohdan";
|
||||||
|
@ -4609,6 +4688,15 @@
|
||||||
fingerprint = "8FD2 153F 4889 541A 54F1 E09E 71B6 C31C 8A5A 9D21";
|
fingerprint = "8FD2 153F 4889 541A 54F1 E09E 71B6 C31C 8A5A 9D21";
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
dixslyf = {
|
||||||
|
name = "Dixon Sean Low Yan Feng";
|
||||||
|
email = "dixonseanlow@protonmail.com";
|
||||||
|
github = "dixslyf";
|
||||||
|
githubId = 56017218;
|
||||||
|
keys = [{
|
||||||
|
fingerprint = "E6F4 BFB4 8DE3 893F 68FC A15F FF5F 4B30 A41B BAC8";
|
||||||
|
}];
|
||||||
|
};
|
||||||
djacu = {
|
djacu = {
|
||||||
email = "daniel.n.baker@gmail.com";
|
email = "daniel.n.baker@gmail.com";
|
||||||
github = "djacu";
|
github = "djacu";
|
||||||
|
@ -5163,6 +5251,12 @@
|
||||||
name = "Edvin Källström";
|
name = "Edvin Källström";
|
||||||
githubId = 84442052;
|
githubId = 84442052;
|
||||||
};
|
};
|
||||||
|
ekimber = {
|
||||||
|
email = "ekimber@protonmail.com";
|
||||||
|
github = "ekimber";
|
||||||
|
name = "Edward Kimber";
|
||||||
|
githubId = 99987;
|
||||||
|
};
|
||||||
ekleog = {
|
ekleog = {
|
||||||
email = "leo@gaspard.io";
|
email = "leo@gaspard.io";
|
||||||
matrix = "@leo:gaspard.ninja";
|
matrix = "@leo:gaspard.ninja";
|
||||||
|
@ -5354,6 +5448,13 @@
|
||||||
githubId = 231483;
|
githubId = 231483;
|
||||||
name = "Jack Kelly";
|
name = "Jack Kelly";
|
||||||
};
|
};
|
||||||
|
endle = {
|
||||||
|
email = "lizhenbo@yahoo.com";
|
||||||
|
github = "Endle";
|
||||||
|
githubId = 3221521;
|
||||||
|
name = "Zhenbo Li";
|
||||||
|
matrix = "@zhenbo:matrix.org";
|
||||||
|
};
|
||||||
endocrimes = {
|
endocrimes = {
|
||||||
email = "dani@builds.terrible.systems";
|
email = "dani@builds.terrible.systems";
|
||||||
github = "endocrimes";
|
github = "endocrimes";
|
||||||
|
@ -5593,6 +5694,12 @@
|
||||||
githubId = 2147649;
|
githubId = 2147649;
|
||||||
name = "Euan Kemp";
|
name = "Euan Kemp";
|
||||||
};
|
};
|
||||||
|
eureka-cpu = {
|
||||||
|
email = "github.eureka@gmail.com";
|
||||||
|
github = "eureka-cpu";
|
||||||
|
githubId = 57543709;
|
||||||
|
name = "Chris O'Brien";
|
||||||
|
};
|
||||||
evalexpr = {
|
evalexpr = {
|
||||||
name = "Jonathan Wilkins";
|
name = "Jonathan Wilkins";
|
||||||
email = "nixos@wilkins.tech";
|
email = "nixos@wilkins.tech";
|
||||||
|
@ -5659,6 +5766,12 @@
|
||||||
githubId = 454695;
|
githubId = 454695;
|
||||||
name = "Artur Taranchiev";
|
name = "Artur Taranchiev";
|
||||||
};
|
};
|
||||||
|
ewuuwe = {
|
||||||
|
email = "ewu.uweq@pm.me";
|
||||||
|
github = "ewuuwe";
|
||||||
|
githubId = 63652646;
|
||||||
|
name = "Xaver Oswald";
|
||||||
|
};
|
||||||
exarkun = {
|
exarkun = {
|
||||||
email = "exarkun@twistedmatrix.com";
|
email = "exarkun@twistedmatrix.com";
|
||||||
github = "exarkun";
|
github = "exarkun";
|
||||||
|
@ -5712,6 +5825,12 @@
|
||||||
githubId = 25955146;
|
githubId = 25955146;
|
||||||
name = "eyJhb";
|
name = "eyJhb";
|
||||||
};
|
};
|
||||||
|
eymeric = {
|
||||||
|
name = "Eymeric Dechelette";
|
||||||
|
email = "hatchchcien@protonmail.com";
|
||||||
|
github = "hatch01";
|
||||||
|
githubId = 42416805;
|
||||||
|
};
|
||||||
f2k1de = {
|
f2k1de = {
|
||||||
name = "f2k1de";
|
name = "f2k1de";
|
||||||
email = "hi@f2k1.de";
|
email = "hi@f2k1.de";
|
||||||
|
@ -6587,7 +6706,7 @@
|
||||||
};
|
};
|
||||||
getpsyched = {
|
getpsyched = {
|
||||||
name = "Priyanshu Tripathi";
|
name = "Priyanshu Tripathi";
|
||||||
email = "priyanshutr@proton.me";
|
email = "priyanshu@getpsyched.dev";
|
||||||
matrix = "@getpsyched:matrix.org";
|
matrix = "@getpsyched:matrix.org";
|
||||||
github = "getpsyched";
|
github = "getpsyched";
|
||||||
githubId = 43472218;
|
githubId = 43472218;
|
||||||
|
@ -6828,6 +6947,12 @@
|
||||||
githubId = 6893840;
|
githubId = 6893840;
|
||||||
name = "Yacine Hmito";
|
name = "Yacine Hmito";
|
||||||
};
|
};
|
||||||
|
gracicot = {
|
||||||
|
email = "gracicot42@gmail.com";
|
||||||
|
github = "gracicot";
|
||||||
|
githubId = 2906673;
|
||||||
|
name = "Guillaume Racicot";
|
||||||
|
};
|
||||||
graham33 = {
|
graham33 = {
|
||||||
email = "graham@grahambennett.org";
|
email = "graham@grahambennett.org";
|
||||||
github = "graham33";
|
github = "graham33";
|
||||||
|
@ -6933,6 +7058,11 @@
|
||||||
githubId = 21156405;
|
githubId = 21156405;
|
||||||
name = "GuangTao Zhang";
|
name = "GuangTao Zhang";
|
||||||
};
|
};
|
||||||
|
guekka = {
|
||||||
|
github = "Guekka";
|
||||||
|
githubId = 39066502;
|
||||||
|
name = "Guekka";
|
||||||
|
};
|
||||||
guibert = {
|
guibert = {
|
||||||
email = "david.guibert@gmail.com";
|
email = "david.guibert@gmail.com";
|
||||||
github = "dguibert";
|
github = "dguibert";
|
||||||
|
@ -7395,6 +7525,16 @@
|
||||||
githubId = 362833;
|
githubId = 362833;
|
||||||
name = "Hongchang Wu";
|
name = "Hongchang Wu";
|
||||||
};
|
};
|
||||||
|
honnip = {
|
||||||
|
name = "Jung seungwoo";
|
||||||
|
email = "me@honnip.page";
|
||||||
|
matrix = "@honnip:matrix.org";
|
||||||
|
github = "honnip";
|
||||||
|
githubId = 108175486;
|
||||||
|
keys = [{
|
||||||
|
fingerprint = "E4DD 51F7 FA3F DCF1 BAF6 A72C 576E 43EF 8482 E415";
|
||||||
|
}];
|
||||||
|
};
|
||||||
hoppla20 = {
|
hoppla20 = {
|
||||||
email = "privat@vincentcui.de";
|
email = "privat@vincentcui.de";
|
||||||
github = "hoppla20";
|
github = "hoppla20";
|
||||||
|
@ -7499,6 +7639,12 @@
|
||||||
githubId = 51334444;
|
githubId = 51334444;
|
||||||
name = "Akshat Agarwal";
|
name = "Akshat Agarwal";
|
||||||
};
|
};
|
||||||
|
hummeltech = {
|
||||||
|
email = "hummeltech2024@gmail.com";
|
||||||
|
github = "hummeltech";
|
||||||
|
githubId = 6109326;
|
||||||
|
name = "David Hummel";
|
||||||
|
};
|
||||||
huyngo = {
|
huyngo = {
|
||||||
email = "huyngo@disroot.org";
|
email = "huyngo@disroot.org";
|
||||||
github = "Huy-Ngo";
|
github = "Huy-Ngo";
|
||||||
|
@ -8126,12 +8272,6 @@
|
||||||
githubId = 1358764;
|
githubId = 1358764;
|
||||||
name = "Jamie Magee";
|
name = "Jamie Magee";
|
||||||
};
|
};
|
||||||
jammerful = {
|
|
||||||
email = "jammerful@gmail.com";
|
|
||||||
github = "jammerful";
|
|
||||||
githubId = 20176306;
|
|
||||||
name = "jammerful";
|
|
||||||
};
|
|
||||||
janik = {
|
janik = {
|
||||||
name = "Janik";
|
name = "Janik";
|
||||||
email = "janik@aq0.de";
|
email = "janik@aq0.de";
|
||||||
|
@ -8139,6 +8279,12 @@
|
||||||
github = "Janik-Haag";
|
github = "Janik-Haag";
|
||||||
githubId = 80165193;
|
githubId = 80165193;
|
||||||
};
|
};
|
||||||
|
jankaifer = {
|
||||||
|
name = "Jan Kaifer";
|
||||||
|
email = "jan@kaifer.cz";
|
||||||
|
github = "jankaifer";
|
||||||
|
githubId = 12820484;
|
||||||
|
};
|
||||||
jansol = {
|
jansol = {
|
||||||
email = "jan.solanti@paivola.fi";
|
email = "jan.solanti@paivola.fi";
|
||||||
github = "jansol";
|
github = "jansol";
|
||||||
|
@ -8804,6 +8950,12 @@
|
||||||
githubId = 6321578;
|
githubId = 6321578;
|
||||||
name = "John Rinehart";
|
name = "John Rinehart";
|
||||||
};
|
};
|
||||||
|
john-rodewald = {
|
||||||
|
email = "jnrodewald99@gmail.com";
|
||||||
|
github = "john-rodewald";
|
||||||
|
githubId = 51028009;
|
||||||
|
name = "John Rodewald";
|
||||||
|
};
|
||||||
john-shaffer = {
|
john-shaffer = {
|
||||||
email = "jdsha@proton.me";
|
email = "jdsha@proton.me";
|
||||||
github = "john-shaffer";
|
github = "john-shaffer";
|
||||||
|
@ -8980,6 +9132,12 @@
|
||||||
githubId = 752510;
|
githubId = 752510;
|
||||||
name = "Martin Potier";
|
name = "Martin Potier";
|
||||||
};
|
};
|
||||||
|
jpts = {
|
||||||
|
email = "james+nixpkgs@cleverley-prance.uk";
|
||||||
|
github = "jpts";
|
||||||
|
githubId = 5352661;
|
||||||
|
name = "James Cleverley-Prance";
|
||||||
|
};
|
||||||
jqqqqqqqqqq = {
|
jqqqqqqqqqq = {
|
||||||
email = "jqqqqqqqqqq@gmail.com";
|
email = "jqqqqqqqqqq@gmail.com";
|
||||||
github = "jqqqqqqqqqq";
|
github = "jqqqqqqqqqq";
|
||||||
|
@ -9150,6 +9308,12 @@
|
||||||
githubId = 5124422;
|
githubId = 5124422;
|
||||||
name = "Julien Urraca";
|
name = "Julien Urraca";
|
||||||
};
|
};
|
||||||
|
justanotherariel = {
|
||||||
|
email = "ariel@ebersberger.io";
|
||||||
|
github = "justanotherariel";
|
||||||
|
githubId = 31776703;
|
||||||
|
name = "Ariel Ebersberger";
|
||||||
|
};
|
||||||
justinas = {
|
justinas = {
|
||||||
email = "justinas@justinas.org";
|
email = "justinas@justinas.org";
|
||||||
github = "justinas";
|
github = "justinas";
|
||||||
|
@ -9336,6 +9500,7 @@
|
||||||
katexochen = {
|
katexochen = {
|
||||||
github = "katexochen";
|
github = "katexochen";
|
||||||
githubId = 49727155;
|
githubId = 49727155;
|
||||||
|
matrix = "@katexochen:matrix.org";
|
||||||
name = "Paul Meyer";
|
name = "Paul Meyer";
|
||||||
};
|
};
|
||||||
kayhide = {
|
kayhide = {
|
||||||
|
@ -10665,6 +10830,16 @@
|
||||||
githubId = 8555953;
|
githubId = 8555953;
|
||||||
name = "Laure Tavard";
|
name = "Laure Tavard";
|
||||||
};
|
};
|
||||||
|
ltstf1re = {
|
||||||
|
email = "ltstf1re@disroot.org";
|
||||||
|
github = "lsf1re";
|
||||||
|
githubId = 153414530;
|
||||||
|
matrix = "@ltstf1re:converser.eu";
|
||||||
|
name = "Little Starfire";
|
||||||
|
keys = [{
|
||||||
|
fingerprint = "FE6C C3C9 2ACF 4367 2B56 5B22 8603 2ACC 051A 873D";
|
||||||
|
}];
|
||||||
|
};
|
||||||
lu15w1r7h = {
|
lu15w1r7h = {
|
||||||
email = "lwirth2000@gmail.com";
|
email = "lwirth2000@gmail.com";
|
||||||
github = "LU15W1R7H";
|
github = "LU15W1R7H";
|
||||||
|
@ -10793,6 +10968,12 @@
|
||||||
fingerprint = "97A0 AE5E 03F3 499B 7D7A 65C6 76A4 1432 37EF 5817";
|
fingerprint = "97A0 AE5E 03F3 499B 7D7A 65C6 76A4 1432 37EF 5817";
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
lukas-heiligenbrunner = {
|
||||||
|
email = "lukas.heiligenbrunner@gmail.com";
|
||||||
|
github = "lukas-heiligenbrunner";
|
||||||
|
githubId = 30468956;
|
||||||
|
name = "Lukas Heiligenbrunner";
|
||||||
|
};
|
||||||
lukaswrz = {
|
lukaswrz = {
|
||||||
email = "lukas@wrz.one";
|
email = "lukas@wrz.one";
|
||||||
github = "lukaswrz";
|
github = "lukaswrz";
|
||||||
|
@ -10824,6 +11005,12 @@
|
||||||
githubId = 2486026;
|
githubId = 2486026;
|
||||||
name = "Luca Fulchir";
|
name = "Luca Fulchir";
|
||||||
};
|
};
|
||||||
|
luleyleo = {
|
||||||
|
email = "git@leopoldluley.de";
|
||||||
|
github = "luleyleo";
|
||||||
|
githubId = 10746692;
|
||||||
|
name = "Leopold Luley";
|
||||||
|
};
|
||||||
lumi = {
|
lumi = {
|
||||||
email = "lumi@pew.im";
|
email = "lumi@pew.im";
|
||||||
github = "lumi-me-not";
|
github = "lumi-me-not";
|
||||||
|
@ -10921,9 +11108,6 @@
|
||||||
github = "Ma27";
|
github = "Ma27";
|
||||||
githubId = 6025220;
|
githubId = 6025220;
|
||||||
name = "Maximilian Bosch";
|
name = "Maximilian Bosch";
|
||||||
keys = [{
|
|
||||||
fingerprint = "62B9 9C26 F046 721E 26B0 04F6 D006 A998 C6AB FDF1";
|
|
||||||
}];
|
|
||||||
};
|
};
|
||||||
ma9e = {
|
ma9e = {
|
||||||
email = "sean@lfo.team";
|
email = "sean@lfo.team";
|
||||||
|
@ -11173,6 +11357,12 @@
|
||||||
github = "marius851000";
|
github = "marius851000";
|
||||||
githubId = 22586596;
|
githubId = 22586596;
|
||||||
};
|
};
|
||||||
|
mariuskimmina = {
|
||||||
|
email = "mar.kimmina@gmail.com";
|
||||||
|
name = "Marius Kimmina";
|
||||||
|
github = "mariuskimmina";
|
||||||
|
githubId = 38843153;
|
||||||
|
};
|
||||||
markbeep = {
|
markbeep = {
|
||||||
email = "mrkswrn@gmail.com";
|
email = "mrkswrn@gmail.com";
|
||||||
github = "markbeep";
|
github = "markbeep";
|
||||||
|
@ -11265,6 +11455,12 @@
|
||||||
githubId = 585424;
|
githubId = 585424;
|
||||||
name = "Massimo Gengarelli";
|
name = "Massimo Gengarelli";
|
||||||
};
|
};
|
||||||
|
matdibu = {
|
||||||
|
email = "contact@mateidibu.dev";
|
||||||
|
github = "matdibu";
|
||||||
|
githubId = 24750154;
|
||||||
|
name = "Matei Dibu";
|
||||||
|
};
|
||||||
matejc = {
|
matejc = {
|
||||||
email = "cotman.matej@gmail.com";
|
email = "cotman.matej@gmail.com";
|
||||||
github = "matejc";
|
github = "matejc";
|
||||||
|
@ -11974,7 +12170,7 @@
|
||||||
};
|
};
|
||||||
milran = {
|
milran = {
|
||||||
email = "milranmike@protonmail.com";
|
email = "milranmike@protonmail.com";
|
||||||
github = "milran";
|
github = "wattmto";
|
||||||
githubId = 93639059;
|
githubId = 93639059;
|
||||||
name = "Milran Mike";
|
name = "Milran Mike";
|
||||||
};
|
};
|
||||||
|
@ -11990,6 +12186,12 @@
|
||||||
githubId = 9799623;
|
githubId = 9799623;
|
||||||
name = "Rick van Schijndel";
|
name = "Rick van Schijndel";
|
||||||
};
|
};
|
||||||
|
mindstorms6 = {
|
||||||
|
email = "breland@bdawg.org";
|
||||||
|
github = "mindstorms6";
|
||||||
|
githubId = 92937;
|
||||||
|
name = "Breland Miley";
|
||||||
|
};
|
||||||
minijackson = {
|
minijackson = {
|
||||||
email = "minijackson@riseup.net";
|
email = "minijackson@riseup.net";
|
||||||
github = "minijackson";
|
github = "minijackson";
|
||||||
|
@ -12828,6 +13030,12 @@
|
||||||
githubId = 77314501;
|
githubId = 77314501;
|
||||||
name = "Maurice Zhou";
|
name = "Maurice Zhou";
|
||||||
};
|
};
|
||||||
|
Nebucatnetzer = {
|
||||||
|
email = "andreas+nixpkgs@zweili.ch";
|
||||||
|
github = "Nebucatnetzer";
|
||||||
|
githubId = 2287221;
|
||||||
|
name = "Andreas Zweili";
|
||||||
|
};
|
||||||
Necior = {
|
Necior = {
|
||||||
email = "adrian@sadlocha.eu";
|
email = "adrian@sadlocha.eu";
|
||||||
github = "Necior";
|
github = "Necior";
|
||||||
|
@ -13048,6 +13256,15 @@
|
||||||
githubId = 8214542;
|
githubId = 8214542;
|
||||||
name = "Nicolò Balzarotti";
|
name = "Nicolò Balzarotti";
|
||||||
};
|
};
|
||||||
|
nicolas-goudry = {
|
||||||
|
email = "goudry.nicolas@gmail.com";
|
||||||
|
github = "nicolas-goudry";
|
||||||
|
githubId = 8753998;
|
||||||
|
name = "Nicolas Goudry";
|
||||||
|
keys = [{
|
||||||
|
fingerprint = "21B6 A59A 4E89 0B1B 83E3 0CDB 01C8 8C03 5450 9AA9";
|
||||||
|
}];
|
||||||
|
};
|
||||||
nicoo = {
|
nicoo = {
|
||||||
email = "nicoo@debian.org";
|
email = "nicoo@debian.org";
|
||||||
github = "nbraud";
|
github = "nbraud";
|
||||||
|
@ -13090,6 +13307,13 @@
|
||||||
githubId = 6391776;
|
githubId = 6391776;
|
||||||
name = "Nikita Voloboev";
|
name = "Nikita Voloboev";
|
||||||
};
|
};
|
||||||
|
niklaskorz = {
|
||||||
|
name = "Niklas Korz";
|
||||||
|
email = "niklas@niklaskorz.de";
|
||||||
|
matrix = "@niklaskorz:korz.dev";
|
||||||
|
github = "niklaskorz";
|
||||||
|
githubId = 590517;
|
||||||
|
};
|
||||||
NikolaMandic = {
|
NikolaMandic = {
|
||||||
email = "nikola@mandic.email";
|
email = "nikola@mandic.email";
|
||||||
github = "NikolaMandic";
|
github = "NikolaMandic";
|
||||||
|
@ -13130,6 +13354,12 @@
|
||||||
fingerprint = "9B1A 7906 5D2F 2B80 6C8A 5A1C 7D2A CDAF 4653 CF28";
|
fingerprint = "9B1A 7906 5D2F 2B80 6C8A 5A1C 7D2A CDAF 4653 CF28";
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
ninjafb = {
|
||||||
|
email = "oscar@oronberg.com";
|
||||||
|
github = "NinjaFB";
|
||||||
|
githubId = 54169044;
|
||||||
|
name = "NinjaFB";
|
||||||
|
};
|
||||||
nintron = {
|
nintron = {
|
||||||
email = "nintron@sent.com";
|
email = "nintron@sent.com";
|
||||||
github = "Nintron27";
|
github = "Nintron27";
|
||||||
|
@ -13389,6 +13619,12 @@
|
||||||
githubId = 1839979;
|
githubId = 1839979;
|
||||||
name = "Niklas Thörne";
|
name = "Niklas Thörne";
|
||||||
};
|
};
|
||||||
|
nudelsalat = {
|
||||||
|
email = "nudelsalat@clouz.de";
|
||||||
|
name = "Fabian Dreßler";
|
||||||
|
github = "Noodlesalat";
|
||||||
|
githubId = 12748782;
|
||||||
|
};
|
||||||
nukaduka = {
|
nukaduka = {
|
||||||
email = "ksgokte@gmail.com";
|
email = "ksgokte@gmail.com";
|
||||||
github = "NukaDuka";
|
github = "NukaDuka";
|
||||||
|
@ -13427,7 +13663,8 @@
|
||||||
name = "Nathan Viets";
|
name = "Nathan Viets";
|
||||||
};
|
};
|
||||||
nyanbinary = {
|
nyanbinary = {
|
||||||
email = "vextium@skiff.com";
|
email = "nyanbinary@keemail.me";
|
||||||
|
matrix = "@niko:conduit.rs";
|
||||||
github = "nyabinary";
|
github = "nyabinary";
|
||||||
githubId = 97130632;
|
githubId = 97130632;
|
||||||
name = "Niko";
|
name = "Niko";
|
||||||
|
@ -13679,10 +13916,10 @@
|
||||||
name = "Sandro Stikić";
|
name = "Sandro Stikić";
|
||||||
};
|
};
|
||||||
OPNA2608 = {
|
OPNA2608 = {
|
||||||
email = "christoph.neidahl@gmail.com";
|
email = "opna2608@protonmail.com";
|
||||||
github = "OPNA2608";
|
github = "OPNA2608";
|
||||||
githubId = 23431373;
|
githubId = 23431373;
|
||||||
name = "Christoph Neidahl";
|
name = "Cosima Neidahl";
|
||||||
};
|
};
|
||||||
orbekk = {
|
orbekk = {
|
||||||
email = "kjetil.orbekk@gmail.com";
|
email = "kjetil.orbekk@gmail.com";
|
||||||
|
@ -13827,6 +14064,12 @@
|
||||||
github = "p3psi-boo";
|
github = "p3psi-boo";
|
||||||
githubId = 43925055;
|
githubId = 43925055;
|
||||||
};
|
};
|
||||||
|
pabloaul = {
|
||||||
|
email = "contact@nojus.org";
|
||||||
|
github = "pabloaul";
|
||||||
|
githubId = 35423980;
|
||||||
|
name = "Nojus Dulskis";
|
||||||
|
};
|
||||||
pablovsky = {
|
pablovsky = {
|
||||||
email = "dealberapablo07@gmail.com";
|
email = "dealberapablo07@gmail.com";
|
||||||
github = "Pablo1107";
|
github = "Pablo1107";
|
||||||
|
@ -13982,6 +14225,12 @@
|
||||||
githubId = 15645854;
|
githubId = 15645854;
|
||||||
name = "Brad Christensen";
|
name = "Brad Christensen";
|
||||||
};
|
};
|
||||||
|
paulsmith = {
|
||||||
|
email = "paulsmith@pobox.com";
|
||||||
|
github = "paulsmith";
|
||||||
|
name = "Paul Smith";
|
||||||
|
githubId = 1210;
|
||||||
|
};
|
||||||
paumr = {
|
paumr = {
|
||||||
github = "paumr";
|
github = "paumr";
|
||||||
name = "Michael Bergmeister";
|
name = "Michael Bergmeister";
|
||||||
|
@ -14408,15 +14657,6 @@
|
||||||
fingerprint = "B00F E582 FD3F 0732 EA48 3937 F558 14E4 D687 4375";
|
fingerprint = "B00F E582 FD3F 0732 EA48 3937 F558 14E4 D687 4375";
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
PlayerNameHere = {
|
|
||||||
name = "Dixon Sean Low Yan Feng";
|
|
||||||
email = "dixonseanlow@protonmail.com";
|
|
||||||
github = "dixslyf";
|
|
||||||
githubId = 56017218;
|
|
||||||
keys = [{
|
|
||||||
fingerprint = "E6F4 BFB4 8DE3 893F 68FC A15F FF5F 4B30 A41B BAC8";
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
plchldr = {
|
plchldr = {
|
||||||
email = "mail@oddco.de";
|
email = "mail@oddco.de";
|
||||||
github = "plchldr";
|
github = "plchldr";
|
||||||
|
@ -14622,6 +14862,11 @@
|
||||||
githubId = 146413;
|
githubId = 146413;
|
||||||
name = "Tobias Poschwatta";
|
name = "Tobias Poschwatta";
|
||||||
};
|
};
|
||||||
|
poweredbypie = {
|
||||||
|
name = "poweredbypie";
|
||||||
|
github = "poweredbypie";
|
||||||
|
githubId = 67135060;
|
||||||
|
};
|
||||||
PowerUser64 = {
|
PowerUser64 = {
|
||||||
email = "blakelysnorth@gmail.com";
|
email = "blakelysnorth@gmail.com";
|
||||||
github = "PowerUser64";
|
github = "PowerUser64";
|
||||||
|
@ -15341,7 +15586,7 @@
|
||||||
revol-xut = {
|
revol-xut = {
|
||||||
email = "revol-xut@protonmail.com";
|
email = "revol-xut@protonmail.com";
|
||||||
name = "Tassilo Tanneberger";
|
name = "Tassilo Tanneberger";
|
||||||
github = "revol-xut";
|
github = "tanneberger";
|
||||||
githubId = 32239737;
|
githubId = 32239737;
|
||||||
keys = [{
|
keys = [{
|
||||||
fingerprint = "91EB E870 1639 1323 642A 6803 B966 009D 57E6 9CC6";
|
fingerprint = "91EB E870 1639 1323 642A 6803 B966 009D 57E6 9CC6";
|
||||||
|
@ -15843,6 +16088,15 @@
|
||||||
github = "rumpelsepp";
|
github = "rumpelsepp";
|
||||||
githubId = 1961699;
|
githubId = 1961699;
|
||||||
};
|
};
|
||||||
|
running-grass = {
|
||||||
|
name = "Leo Liu";
|
||||||
|
email = "hi@grass.show";
|
||||||
|
github = "running-grass";
|
||||||
|
githubId = 17241154;
|
||||||
|
keys = [{
|
||||||
|
fingerprint = "5156 0FAB FF32 83EC BC8C EA13 9344 3660 9397 0138";
|
||||||
|
}];
|
||||||
|
};
|
||||||
rushmorem = {
|
rushmorem = {
|
||||||
email = "rushmore@webenchanter.com";
|
email = "rushmore@webenchanter.com";
|
||||||
github = "rushmorem";
|
github = "rushmorem";
|
||||||
|
@ -16045,8 +16299,8 @@
|
||||||
};
|
};
|
||||||
SamirTalwar = {
|
SamirTalwar = {
|
||||||
email = "lazy.git@functional.computer";
|
email = "lazy.git@functional.computer";
|
||||||
github = "abstracte";
|
github = "SamirTalwar";
|
||||||
githubId = 47852;
|
githubId = 47582;
|
||||||
name = "Samir Talwar";
|
name = "Samir Talwar";
|
||||||
};
|
};
|
||||||
samlich = {
|
samlich = {
|
||||||
|
@ -16237,6 +16491,11 @@
|
||||||
githubId = 5104601;
|
githubId = 5104601;
|
||||||
name = "schnusch";
|
name = "schnusch";
|
||||||
};
|
};
|
||||||
|
Schweber = {
|
||||||
|
github = "Schweber";
|
||||||
|
githubId = 64630479;
|
||||||
|
name = "Schweber";
|
||||||
|
};
|
||||||
sciencentistguy = {
|
sciencentistguy = {
|
||||||
email = "jamie@quigley.xyz";
|
email = "jamie@quigley.xyz";
|
||||||
name = "Jamie Quigley";
|
name = "Jamie Quigley";
|
||||||
|
@ -16555,6 +16814,12 @@
|
||||||
}];
|
}];
|
||||||
name = "Shane Sveller";
|
name = "Shane Sveller";
|
||||||
};
|
};
|
||||||
|
shard7 = {
|
||||||
|
email = "sh7user@gmail.com";
|
||||||
|
github = "shard77";
|
||||||
|
githubId = 106669955;
|
||||||
|
name = "Léon Gessner";
|
||||||
|
};
|
||||||
shardy = {
|
shardy = {
|
||||||
email = "shardul@baral.ca";
|
email = "shardul@baral.ca";
|
||||||
github = "shardulbee";
|
github = "shardulbee";
|
||||||
|
@ -16771,6 +17036,11 @@
|
||||||
githubId = 50401154;
|
githubId = 50401154;
|
||||||
name = "Simone Ruffini";
|
name = "Simone Ruffini";
|
||||||
};
|
};
|
||||||
|
simonhammes = {
|
||||||
|
github = "simonhammes";
|
||||||
|
githubId = 10352679;
|
||||||
|
name = "Simon Hammes";
|
||||||
|
};
|
||||||
simonkampe = {
|
simonkampe = {
|
||||||
email = "simon.kampe+nix@gmail.com";
|
email = "simon.kampe+nix@gmail.com";
|
||||||
github = "simonkampe";
|
github = "simonkampe";
|
||||||
|
@ -16846,6 +17116,12 @@
|
||||||
githubId = 8017899;
|
githubId = 8017899;
|
||||||
name = "Sivaram Balakrishnan";
|
name = "Sivaram Balakrishnan";
|
||||||
};
|
};
|
||||||
|
sixstring982 = {
|
||||||
|
email = "sixstring982@gmail.com";
|
||||||
|
github = "sixstring982";
|
||||||
|
githubId = 1328977;
|
||||||
|
name = "Trent Small";
|
||||||
|
};
|
||||||
sjagoe = {
|
sjagoe = {
|
||||||
email = "simon@simonjagoe.com";
|
email = "simon@simonjagoe.com";
|
||||||
github = "sjagoe";
|
github = "sjagoe";
|
||||||
|
@ -16960,6 +17236,12 @@
|
||||||
fingerprint = "897E 6BE3 0345 B43D CADD 05B7 290F CF08 1AED B3EC";
|
fingerprint = "897E 6BE3 0345 B43D CADD 05B7 290F CF08 1AED B3EC";
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
smrehman = {
|
||||||
|
name = "Syed Moiz Ur Rehman";
|
||||||
|
email = "smrehman@proton.me";
|
||||||
|
github = "syedmoizurrehman";
|
||||||
|
githubId = 17818950;
|
||||||
|
};
|
||||||
sna = {
|
sna = {
|
||||||
email = "abouzahra.9@wright.edu";
|
email = "abouzahra.9@wright.edu";
|
||||||
github = "S-NA";
|
github = "S-NA";
|
||||||
|
@ -17080,6 +17362,13 @@
|
||||||
githubId = 151924;
|
githubId = 151924;
|
||||||
name = "John Anderson";
|
name = "John Anderson";
|
||||||
};
|
};
|
||||||
|
soopyc = {
|
||||||
|
name = "Cassie Cheung";
|
||||||
|
email = "me@soopy.moe";
|
||||||
|
github = "soopyc";
|
||||||
|
githubId = 13762043;
|
||||||
|
matrix = "@sophie:nue.soopy.moe";
|
||||||
|
};
|
||||||
sophrosyne = {
|
sophrosyne = {
|
||||||
email = "joshuaortiz@tutanota.com";
|
email = "joshuaortiz@tutanota.com";
|
||||||
github = "sophrosyne97";
|
github = "sophrosyne97";
|
||||||
|
@ -17337,13 +17626,12 @@
|
||||||
name = "Stel Abrego";
|
name = "Stel Abrego";
|
||||||
};
|
};
|
||||||
stepbrobd = {
|
stepbrobd = {
|
||||||
name = "StepBroBD";
|
name = "Yifei Sun";
|
||||||
github = "StepBroBD";
|
email = "ysun@hey.com";
|
||||||
|
github = "stepbrobd";
|
||||||
githubId = 81826728;
|
githubId = 81826728;
|
||||||
email = "Hi@StepBroBD.com";
|
|
||||||
matrix = "@stepbrobd:matrix.org";
|
|
||||||
keys = [{
|
keys = [{
|
||||||
fingerprint = "5D8B FA8B 286A C2EF 6EE4 8598 F742 B72C 8926 1A51";
|
fingerprint = "AC7C 52E6 BA2F E8DE 8F0F 5D78 D973 170F 9B86 DB70";
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
stephank = {
|
stephank = {
|
||||||
|
@ -18348,6 +18636,11 @@
|
||||||
github = "NoneTirex";
|
github = "NoneTirex";
|
||||||
githubId = 26038207;
|
githubId = 26038207;
|
||||||
};
|
};
|
||||||
|
tirimia = {
|
||||||
|
name = "Theodor-Alexandru Irimia";
|
||||||
|
github = "tirimia";
|
||||||
|
githubId = 11174371;
|
||||||
|
};
|
||||||
titanous = {
|
titanous = {
|
||||||
email = "jonathan@titanous.com";
|
email = "jonathan@titanous.com";
|
||||||
github = "titanous";
|
github = "titanous";
|
||||||
|
@ -18526,6 +18819,12 @@
|
||||||
githubId = 1486805;
|
githubId = 1486805;
|
||||||
name = "Toon Nolten";
|
name = "Toon Nolten";
|
||||||
};
|
};
|
||||||
|
tornax = {
|
||||||
|
email = "tornax@pm.me";
|
||||||
|
github = "TornaxO7";
|
||||||
|
githubId = 50843046;
|
||||||
|
name = "tornax";
|
||||||
|
};
|
||||||
toschmidt = {
|
toschmidt = {
|
||||||
email = "tobias.schmidt@in.tum.de";
|
email = "tobias.schmidt@in.tum.de";
|
||||||
github = "toschmidt";
|
github = "toschmidt";
|
||||||
|
@ -18778,6 +19077,13 @@
|
||||||
matrix = "@ty:tjll.net";
|
matrix = "@ty:tjll.net";
|
||||||
name = "Tyler Langlois";
|
name = "Tyler Langlois";
|
||||||
};
|
};
|
||||||
|
tylervick = {
|
||||||
|
email = "nix@tylervick.com";
|
||||||
|
github = "tylervick";
|
||||||
|
githubId = 1395852;
|
||||||
|
name = "Tyler Vick";
|
||||||
|
matrix = "@tylervick:matrix.org";
|
||||||
|
};
|
||||||
tymscar = {
|
tymscar = {
|
||||||
email = "oscar@tymscar.com";
|
email = "oscar@tymscar.com";
|
||||||
github = "tymscar";
|
github = "tymscar";
|
||||||
|
@ -18798,7 +19104,7 @@
|
||||||
};
|
};
|
||||||
uakci = {
|
uakci = {
|
||||||
name = "uakci";
|
name = "uakci";
|
||||||
email = "uakci@uakci.pl";
|
email = "git@uakci.space";
|
||||||
github = "uakci";
|
github = "uakci";
|
||||||
githubId = 6961268;
|
githubId = 6961268;
|
||||||
};
|
};
|
||||||
|
@ -19222,6 +19528,12 @@
|
||||||
githubId = 118959;
|
githubId = 118959;
|
||||||
name = "VinyMeuh";
|
name = "VinyMeuh";
|
||||||
};
|
};
|
||||||
|
viperML = {
|
||||||
|
email = "ayatsfer@gmail.com";
|
||||||
|
github = "viperML";
|
||||||
|
githubId = 11395853;
|
||||||
|
name = "Fernando Ayats";
|
||||||
|
};
|
||||||
viraptor = {
|
viraptor = {
|
||||||
email = "nix@viraptor.info";
|
email = "nix@viraptor.info";
|
||||||
github = "viraptor";
|
github = "viraptor";
|
||||||
|
@ -19319,6 +19631,12 @@
|
||||||
githubId = 3413119;
|
githubId = 3413119;
|
||||||
name = "Vonfry";
|
name = "Vonfry";
|
||||||
};
|
};
|
||||||
|
vonixxx = {
|
||||||
|
email = "vonixxx@tuta.io";
|
||||||
|
github = "vonixxx";
|
||||||
|
githubId = 144771550;
|
||||||
|
name = "Luca Uricariu";
|
||||||
|
};
|
||||||
votava = {
|
votava = {
|
||||||
email = "votava@gmail.com";
|
email = "votava@gmail.com";
|
||||||
github = "janvotava";
|
github = "janvotava";
|
||||||
|
@ -19951,7 +20269,7 @@
|
||||||
};
|
};
|
||||||
yana = {
|
yana = {
|
||||||
email = "yana@riseup.net";
|
email = "yana@riseup.net";
|
||||||
github = "yanalunaterra";
|
github = "yanateras";
|
||||||
githubId = 1643293;
|
githubId = 1643293;
|
||||||
name = "Yana Timoshenko";
|
name = "Yana Timoshenko";
|
||||||
};
|
};
|
||||||
|
@ -20329,6 +20647,15 @@
|
||||||
githubId = 1557253;
|
githubId = 1557253;
|
||||||
name = "Lennart Eichhorn";
|
name = "Lennart Eichhorn";
|
||||||
};
|
};
|
||||||
|
zedseven = {
|
||||||
|
name = "Zacchary Dempsey-Plante";
|
||||||
|
email = "zacc@ztdp.ca";
|
||||||
|
github = "zedseven";
|
||||||
|
githubId = 25164338;
|
||||||
|
keys = [{
|
||||||
|
fingerprint = "065A 0A98 FE61 E1C1 41B0 AFE7 64FA BC62 F457 2875";
|
||||||
|
}];
|
||||||
|
};
|
||||||
zendo = {
|
zendo = {
|
||||||
name = "zendo";
|
name = "zendo";
|
||||||
email = "linzway@qq.com";
|
email = "linzway@qq.com";
|
||||||
|
@ -20471,6 +20798,12 @@
|
||||||
githubId = 8100652;
|
githubId = 8100652;
|
||||||
name = "David Mell";
|
name = "David Mell";
|
||||||
};
|
};
|
||||||
|
zshipko = {
|
||||||
|
email = "zachshipko@gmail.com";
|
||||||
|
github = "zshipko";
|
||||||
|
githubId = 332534;
|
||||||
|
name = "Zach Shipko";
|
||||||
|
};
|
||||||
ztzg = {
|
ztzg = {
|
||||||
email = "dd@crosstwine.com";
|
email = "dd@crosstwine.com";
|
||||||
github = "ztzg";
|
github = "ztzg";
|
||||||
|
|
62
maintainers/scripts/README.md
Normal file
62
maintainers/scripts/README.md
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
# Maintainer scripts
|
||||||
|
|
||||||
|
This folder contains various executable scripts for nixpkgs maintainers,
|
||||||
|
and supporting data or nixlang files as needed.
|
||||||
|
These scripts generally aren't a stable interface and may changed or be removed.
|
||||||
|
|
||||||
|
What follows is a (very incomplete) overview of available scripts.
|
||||||
|
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
|
||||||
|
### `check-by-name.sh`
|
||||||
|
|
||||||
|
An alias for `pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh`, see [documentation](../../pkgs/test/nixpkgs-check-by-name/scripts/README.md).
|
||||||
|
|
||||||
|
### `get-maintainer.sh`
|
||||||
|
|
||||||
|
`get-maintainer.sh [selector] value` returns a JSON object describing
|
||||||
|
a given nixpkgs maintainer, equivalent to `lib.maintainers.${x} // { handle = x; }`.
|
||||||
|
|
||||||
|
This allows looking up a maintainer's attrset (including GitHub and Matrix
|
||||||
|
handles, email address etc.) based on any of their handles, more correctly and
|
||||||
|
robustly than text search through `maintainers-list.nix`.
|
||||||
|
|
||||||
|
```
|
||||||
|
❯ ./get-maintainer.sh nicoo
|
||||||
|
{
|
||||||
|
"email": "nicoo@debian.org",
|
||||||
|
"github": "nbraud",
|
||||||
|
"githubId": 1155801,
|
||||||
|
"keys": [
|
||||||
|
{
|
||||||
|
"fingerprint": "E44E 9EA5 4B8E 256A FB73 49D3 EC9D 3708 72BC 7A8C"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "nicoo",
|
||||||
|
"handle": "nicoo"
|
||||||
|
}
|
||||||
|
|
||||||
|
❯ ./get-maintainer.sh name 'Silvan Mosberger'
|
||||||
|
{
|
||||||
|
"email": "contact@infinisil.com",
|
||||||
|
"github": "infinisil",
|
||||||
|
"githubId": 20525370,
|
||||||
|
"keys": [
|
||||||
|
{
|
||||||
|
"fingerprint": "6C2B 55D4 4E04 8266 6B7D DA1A 422E 9EDA E015 7170"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matrix": "@infinisil:matrix.org",
|
||||||
|
"name": "Silvan Mosberger",
|
||||||
|
"handle": "infinisil"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The maintainer is designated by a `selector` which must be one of:
|
||||||
|
- `handle` (default): the maintainer's attribute name in `lib.maintainers`;
|
||||||
|
- `email`, `name`, `github`, `githubId`, `matrix`, `name`:
|
||||||
|
attributes of the maintainer's object, matched exactly;
|
||||||
|
see [`maintainer-list.nix`] for the fields' definition.
|
||||||
|
|
||||||
|
[`maintainer-list.nix`]: ../maintainer-list.nix
|
1
maintainers/scripts/check-by-name.sh
Symbolic link
1
maintainers/scripts/check-by-name.sh
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh
|
33
maintainers/scripts/doc/list-systemd-manpages.zsh
Executable file
33
maintainers/scripts/doc/list-systemd-manpages.zsh
Executable file
|
@ -0,0 +1,33 @@
|
||||||
|
#!/usr/bin/env nix-shell
|
||||||
|
#!nix-shell -i zsh -p zsh
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# cd into nixpkgs' root, get the store path of `systemd.man`
|
||||||
|
cd "$(dirname "$0")/../../.."
|
||||||
|
SYSTEMD_MAN_DIR="$(nix-build -A systemd.man)/share/man"
|
||||||
|
|
||||||
|
# For each manual section
|
||||||
|
for section in {1..8}; do
|
||||||
|
sec_dir="${SYSTEMD_MAN_DIR}/man${section}"
|
||||||
|
|
||||||
|
# skip section 3 (library calls)
|
||||||
|
! [[ $section -eq 3 ]] || continue
|
||||||
|
|
||||||
|
# for each manpage in that section (potentially none)
|
||||||
|
for manpage in ${sec_dir}/*(N); do
|
||||||
|
# strip the directory prefix and (compressed) manpage suffix
|
||||||
|
page="$(basename "$manpage" ".${section}.gz")"
|
||||||
|
|
||||||
|
# if this is the manpage of a service unit
|
||||||
|
if [[ "$page" =~ ".*\.service" ]]; then
|
||||||
|
# ... and a manpage exists without the `.service` suffix
|
||||||
|
potential_alias="${sec_dir}/${page%\.service}.${section}.gz"
|
||||||
|
! [[ -e "${potential_alias}" &&
|
||||||
|
# ... which points to the same file, then skip
|
||||||
|
"$(gunzip -c "${potential_alias}")" == ".so ${page}.${section}" ]] || continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# else produce a JSON fragment, with the link to the upstream manpage (as HTML)
|
||||||
|
echo " \"${page}(${section})\": \"https://www.freedesktop.org/software/systemd/man/${page}.html\","
|
||||||
|
done
|
||||||
|
done
|
73
maintainers/scripts/get-maintainer.sh
Executable file
73
maintainers/scripts/get-maintainer.sh
Executable file
|
@ -0,0 +1,73 @@
|
||||||
|
#!/usr/bin/env nix-shell
|
||||||
|
#!nix-shell -i bash -p jq ncurses
|
||||||
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
# Get a nixpkgs maintainer's metadata as a JSON object
|
||||||
|
# see HELP_MESSAGE just below, or README.md.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
declare -A SELECTORS=( [handle]= [email]= [github]= [githubId]= [matrix]= [name]= )
|
||||||
|
HELP_MESSAGE="usage: '$0' [selector] value
|
||||||
|
examples:
|
||||||
|
get-maintainer.sh nicoo
|
||||||
|
get-maintainer.sh githubId 1155801
|
||||||
|
|
||||||
|
\`selector\` defaults to 'handle', can be one of:
|
||||||
|
${!SELECTORS[*]}
|
||||||
|
"
|
||||||
|
|
||||||
|
MAINTAINERS_DIR="$(dirname "$0")/.."
|
||||||
|
|
||||||
|
die() {
|
||||||
|
tput setaf 1 # red
|
||||||
|
echo "'$0': $*"
|
||||||
|
tput setaf 0 # back to black
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
listAsJSON() {
|
||||||
|
nix-instantiate --eval --strict --json "${MAINTAINERS_DIR}/maintainer-list.nix"
|
||||||
|
}
|
||||||
|
|
||||||
|
parseArgs() {
|
||||||
|
[ $# -gt 0 -a $# -lt 3 ] || {
|
||||||
|
echo "$HELP_MESSAGE"
|
||||||
|
die "invalid number of arguments (must be 1 or 2)"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $# -eq 1 ]; then
|
||||||
|
selector=handle
|
||||||
|
else
|
||||||
|
selector="$1"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
[ -z "${SELECTORS[$selector]-n}" ] || {
|
||||||
|
echo "Valid selectors are:" "${!SELECTORS[@]}" >&2
|
||||||
|
die "invalid selector '$selector'"
|
||||||
|
}
|
||||||
|
|
||||||
|
value="$1"
|
||||||
|
shift
|
||||||
|
}
|
||||||
|
|
||||||
|
query() {
|
||||||
|
# explode { a: A, b: B, ... } into A + {handle: a}, B + {handle: b}, ...
|
||||||
|
local explode="to_entries[] | .value + { \"handle\": .key }"
|
||||||
|
|
||||||
|
# select matching items from the list
|
||||||
|
# TODO(nicoo): Support approximate matching for `name` ?
|
||||||
|
local select
|
||||||
|
case "$selector" in
|
||||||
|
githubId)
|
||||||
|
select="select(.${selector} == $value)"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
select="select(.${selector} == \"$value\")"
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "$explode | $select"
|
||||||
|
}
|
||||||
|
|
||||||
|
parseArgs "$@"
|
||||||
|
listAsJSON | jq -e "$(query)"
|
|
@ -54,8 +54,8 @@ if ! gh auth status 2>/dev/null ; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Make sure this is configured before we start doing anything
|
# Make sure this is configured before we start doing anything
|
||||||
push_remote="$(git config branch.haskell-updates.pushRemote \
|
push_remote="$(git config branch.haskell-updates.pushRemote)" \
|
||||||
|| die 'Can'\''t determine pushRemote for haskell-updates. Please set using `git config branch.haskell-updates.pushremote <remote name>`.')"
|
|| die 'Can'\''t determine pushRemote for haskell-updates. Please set using `git config branch.haskell-updates.pushremote <remote name>`.'
|
||||||
|
|
||||||
# Fetch nixpkgs to get an up-to-date origin/haskell-updates branch.
|
# Fetch nixpkgs to get an up-to-date origin/haskell-updates branch.
|
||||||
echo "Fetching origin..."
|
echo "Fetching origin..."
|
||||||
|
|
|
@ -21,6 +21,7 @@ fzy,,,,,,mrcjkb
|
||||||
gitsigns.nvim,https://github.com/lewis6991/gitsigns.nvim.git,,,,5.1,
|
gitsigns.nvim,https://github.com/lewis6991/gitsigns.nvim.git,,,,5.1,
|
||||||
haskell-tools.nvim,,,,,,
|
haskell-tools.nvim,,,,,,
|
||||||
http,,,,0.3-0,,vcunat
|
http,,,,0.3-0,,vcunat
|
||||||
|
image.nvim,,,,,,teto
|
||||||
inspect,,,,,,
|
inspect,,,,,,
|
||||||
jsregexp,,,,,,
|
jsregexp,,,,,,
|
||||||
ldbus,,,http://luarocks.org/dev,,,
|
ldbus,,,http://luarocks.org/dev,,,
|
||||||
|
@ -95,8 +96,8 @@ mediator_lua,,,,,,
|
||||||
middleclass,,,,,,
|
middleclass,,,,,,
|
||||||
mpack,,,,,,
|
mpack,,,,,,
|
||||||
moonscript,https://github.com/leafo/moonscript.git,dev-1,,,,arobyn
|
moonscript,https://github.com/leafo/moonscript.git,dev-1,,,,arobyn
|
||||||
|
nlua,,,,,,teto
|
||||||
nui.nvim,,,,,,mrcjkb
|
nui.nvim,,,,,,mrcjkb
|
||||||
nvim-client,https://github.com/neovim/lua-client.git,,,,,
|
|
||||||
nvim-cmp,https://github.com/hrsh7th/nvim-cmp,,,,,
|
nvim-cmp,https://github.com/hrsh7th/nvim-cmp,,,,,
|
||||||
penlight,https://github.com/lunarmodules/Penlight.git,,,,,alerque
|
penlight,https://github.com/lunarmodules/Penlight.git,,,,,alerque
|
||||||
plenary.nvim,https://github.com/nvim-lua/plenary.nvim.git,,,,5.1,
|
plenary.nvim,https://github.com/nvim-lua/plenary.nvim.git,,,,5.1,
|
||||||
|
|
|
|
@ -17,6 +17,7 @@ import http
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
@ -192,6 +193,11 @@ class RepoGitHub(Repo):
|
||||||
with urllib.request.urlopen(commit_req, timeout=10) as req:
|
with urllib.request.urlopen(commit_req, timeout=10) as req:
|
||||||
self._check_for_redirect(commit_url, req)
|
self._check_for_redirect(commit_url, req)
|
||||||
xml = req.read()
|
xml = req.read()
|
||||||
|
|
||||||
|
# Filter out illegal XML characters
|
||||||
|
illegal_xml_regex = re.compile(b"[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F]")
|
||||||
|
xml = illegal_xml_regex.sub(b"", xml)
|
||||||
|
|
||||||
root = ET.fromstring(xml)
|
root = ET.fromstring(xml)
|
||||||
latest_entry = root.find(ATOM_ENTRY)
|
latest_entry = root.find(ATOM_ENTRY)
|
||||||
assert latest_entry is not None, f"No commits found in repository {self}"
|
assert latest_entry is not None, f"No commits found in repository {self}"
|
||||||
|
|
|
@ -96,6 +96,16 @@ with lib.maintainers; {
|
||||||
shortName = "Blockchains";
|
shortName = "Blockchains";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
buildbot = {
|
||||||
|
members = [
|
||||||
|
lopsided98
|
||||||
|
mic92
|
||||||
|
zowoq
|
||||||
|
];
|
||||||
|
scope = "Maintain Buildbot CI framework";
|
||||||
|
shortName = "Buildbot";
|
||||||
|
};
|
||||||
|
|
||||||
c = {
|
c = {
|
||||||
members = [
|
members = [
|
||||||
matthewbauer
|
matthewbauer
|
||||||
|
@ -290,6 +300,7 @@ with lib.maintainers; {
|
||||||
members = [
|
members = [
|
||||||
theuni
|
theuni
|
||||||
dpausp
|
dpausp
|
||||||
|
frlan
|
||||||
leona
|
leona
|
||||||
];
|
];
|
||||||
scope = "Team for Flying Circus employees who collectively maintain packages.";
|
scope = "Team for Flying Circus employees who collectively maintain packages.";
|
||||||
|
@ -318,6 +329,7 @@ with lib.maintainers; {
|
||||||
imincik
|
imincik
|
||||||
nh2
|
nh2
|
||||||
nialov
|
nialov
|
||||||
|
r-burns
|
||||||
sikmir
|
sikmir
|
||||||
willcohen
|
willcohen
|
||||||
];
|
];
|
||||||
|
@ -402,6 +414,16 @@ with lib.maintainers; {
|
||||||
enableFeatureFreezePing = true;
|
enableFeatureFreezePing = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
helsinki-systems = {
|
||||||
|
# Verify additions to this team with at least one already existing member of the team.
|
||||||
|
members = [
|
||||||
|
ajs124
|
||||||
|
das_j
|
||||||
|
];
|
||||||
|
scope = "Group registration for packages maintained by Helsinki Systems";
|
||||||
|
shortName = "Helsinki Systems employees";
|
||||||
|
};
|
||||||
|
|
||||||
home-assistant = {
|
home-assistant = {
|
||||||
members = [
|
members = [
|
||||||
fab
|
fab
|
||||||
|
@ -429,6 +451,7 @@ with lib.maintainers; {
|
||||||
cleeyv
|
cleeyv
|
||||||
ryantm
|
ryantm
|
||||||
lassulus
|
lassulus
|
||||||
|
yayayayaka
|
||||||
];
|
];
|
||||||
scope = "Maintain Jitsi.";
|
scope = "Maintain Jitsi.";
|
||||||
shortName = "Jitsi";
|
shortName = "Jitsi";
|
||||||
|
@ -511,7 +534,6 @@ with lib.maintainers; {
|
||||||
dtzWill
|
dtzWill
|
||||||
ericson2314
|
ericson2314
|
||||||
lovek323
|
lovek323
|
||||||
primeos
|
|
||||||
qyliss
|
qyliss
|
||||||
raitobezarius
|
raitobezarius
|
||||||
rrbutani
|
rrbutani
|
||||||
|
@ -562,6 +584,18 @@ with lib.maintainers; {
|
||||||
enableFeatureFreezePing = true;
|
enableFeatureFreezePing = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
lxc = {
|
||||||
|
members = [
|
||||||
|
aanderse
|
||||||
|
adamcstephens
|
||||||
|
jnsgruk
|
||||||
|
megheaiulian
|
||||||
|
mkg20001
|
||||||
|
];
|
||||||
|
scope = "All things linuxcontainers. LXC, Incus, LXD and related packages.";
|
||||||
|
shortName = "lxc";
|
||||||
|
};
|
||||||
|
|
||||||
lxqt = {
|
lxqt = {
|
||||||
members = [
|
members = [
|
||||||
romildo
|
romildo
|
||||||
|
@ -742,7 +776,6 @@ with lib.maintainers; {
|
||||||
|
|
||||||
podman = {
|
podman = {
|
||||||
members = [
|
members = [
|
||||||
adisbladis
|
|
||||||
saschagrunert
|
saschagrunert
|
||||||
vdemeester
|
vdemeester
|
||||||
];
|
];
|
||||||
|
|
28
nixos/doc/manual/administration/nixos-state.section.md
Normal file
28
nixos/doc/manual/administration/nixos-state.section.md
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# NixOS {#sec-nixos-state}
|
||||||
|
|
||||||
|
## `/nix` {#sec-state-nix}
|
||||||
|
|
||||||
|
NixOS needs the entirety of `/nix` to be persistent, as it includes:
|
||||||
|
- `/nix/store`, which contains all the system's executables, libraries, and supporting data;
|
||||||
|
- `/nix/var/nix`, which contains:
|
||||||
|
- the Nix daemon's database;
|
||||||
|
- roots whose transitive closure is preserved when garbage-collecting the Nix store;
|
||||||
|
- system-wide and per-user profiles.
|
||||||
|
|
||||||
|
## `/boot` {#sec-state-boot}
|
||||||
|
|
||||||
|
`/boot` should also be persistent, as it contains:
|
||||||
|
- the kernel and initrd which the bootloader loads,
|
||||||
|
- the bootloader's configuration, including the kernel's command-line which
|
||||||
|
determines the store path to use as system environment.
|
||||||
|
|
||||||
|
|
||||||
|
## Users and groups {#sec-state-users}
|
||||||
|
|
||||||
|
- `/var/lib/nixos` should persist: it holds state needed to generate stable
|
||||||
|
uids and gids for declaratively-managed users and groups, etc.
|
||||||
|
- `users.mutableUsers` should be false, *or* the following files under `/etc`
|
||||||
|
should all persist:
|
||||||
|
- {manpage}`passwd(5)` and {manpage}`group(5)`,
|
||||||
|
- {manpage}`shadow(5)` and {manpage}`gshadow(5)`,
|
||||||
|
- {manpage}`subuid(5)` and {manpage}`subgid(5)`.
|
|
@ -8,6 +8,7 @@ rebooting.chapter.md
|
||||||
user-sessions.chapter.md
|
user-sessions.chapter.md
|
||||||
control-groups.chapter.md
|
control-groups.chapter.md
|
||||||
logging.chapter.md
|
logging.chapter.md
|
||||||
|
system-state.chapter.md
|
||||||
cleaning-store.chapter.md
|
cleaning-store.chapter.md
|
||||||
containers.chapter.md
|
containers.chapter.md
|
||||||
troubleshooting.chapter.md
|
troubleshooting.chapter.md
|
||||||
|
|
17
nixos/doc/manual/administration/system-state.chapter.md
Normal file
17
nixos/doc/manual/administration/system-state.chapter.md
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Necessary system state {#ch-system-state}
|
||||||
|
|
||||||
|
Normally — on systems with a persistent `rootfs` — system services can persist state to
|
||||||
|
the filesystem without administrator intervention.
|
||||||
|
|
||||||
|
However, it is possible and not-uncommon to create [impermanent systems], whose
|
||||||
|
`rootfs` is either a `tmpfs` or reset during boot. While NixOS itself supports
|
||||||
|
this kind of configuration, special care needs to be taken.
|
||||||
|
|
||||||
|
[impermanent systems]: https://nixos.wiki/wiki/Impermanence
|
||||||
|
|
||||||
|
|
||||||
|
```{=include=} sections
|
||||||
|
nixos-state.section.md
|
||||||
|
systemd-state.section.md
|
||||||
|
zfs-state.section.md
|
||||||
|
```
|
52
nixos/doc/manual/administration/systemd-state.section.md
Normal file
52
nixos/doc/manual/administration/systemd-state.section.md
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
# systemd {#sec-systemd-state}
|
||||||
|
|
||||||
|
## `machine-id(5)` {#sec-machine-id}
|
||||||
|
|
||||||
|
`systemd` uses per-machine identifier — {manpage}`machine-id(5)` — which must be
|
||||||
|
unique and persistent; otherwise, the system journal may fail to list earlier
|
||||||
|
boots, etc.
|
||||||
|
|
||||||
|
`systemd` generates a random `machine-id(5)` during boot if it does not already exist,
|
||||||
|
and persists it in `/etc/machine-id`. As such, it suffices to make that file persistent.
|
||||||
|
|
||||||
|
Alternatively, it is possible to generate a random `machine-id(5)`; while the
|
||||||
|
specification allows for *any* hex-encoded 128b value, systemd itself uses
|
||||||
|
[UUIDv4], *i.e.* random UUIDs, and it is thus preferable to do so as well, in
|
||||||
|
case some software assumes `machine-id(5)` to be a UUIDv4. Those can be
|
||||||
|
generated with `uuidgen -r | tr -d -` (`tr` being used to remove the dashes).
|
||||||
|
|
||||||
|
Such a `machine-id(5)` can be set by writing it to `/etc/machine-id` or through
|
||||||
|
the kernel's command-line, though NixOS' systemd maintainers [discourage] the
|
||||||
|
latter approach.
|
||||||
|
|
||||||
|
[UUIDv4]: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
|
||||||
|
[discourage]: https://github.com/NixOS/nixpkgs/pull/268995
|
||||||
|
|
||||||
|
|
||||||
|
## `/var/lib/systemd` {#sec-var-systemd}
|
||||||
|
|
||||||
|
Moreover, `systemd` expects its state directory — `/var/lib/systemd` — to persist, for:
|
||||||
|
- {manpage}`systemd-random-seed(8)`, which loads a 256b “seed” into the kernel's RNG
|
||||||
|
at boot time, and saves a fresh one during shutdown;
|
||||||
|
- {manpage}`systemd.timer(5)` with `Persistent=yes`, which are then run after boot if
|
||||||
|
the timer would have triggered during the time the system was shut down;
|
||||||
|
- {manpage}`systemd-coredump(8)` to store core dumps there by default;
|
||||||
|
(see {manpage}`coredump.conf(5)`)
|
||||||
|
- {manpage}`systemd-timesyncd(8)`;
|
||||||
|
- {manpage}`systemd-backlight(8)` and {manpage}`systemd-rfkill(8)` persist hardware-related
|
||||||
|
state;
|
||||||
|
- possibly other things, this list is not meant to be exhaustive.
|
||||||
|
|
||||||
|
In any case, making `/var/lib/systemd` persistent is recommended.
|
||||||
|
|
||||||
|
|
||||||
|
## `/var/log/journal/{machine-id}` {#sec-var-journal}
|
||||||
|
|
||||||
|
Lastly, {manpage}`systemd-journald(8)` writes the system's journal in binary
|
||||||
|
form to `/var/log/journal/{machine-id}`; if (locally) persisting the entire log
|
||||||
|
is desired, it is recommended to make all of `/var/log/journal` persistent.
|
||||||
|
|
||||||
|
If not, one can set `Storage=volatile` in {manpage}`journald.conf(5)`
|
||||||
|
([`services.journald.storage = "volatile";`](#opt-services.journald.storage)),
|
||||||
|
which disables journal persistence and causes it to be written to
|
||||||
|
`/run/log/journal`.
|
16
nixos/doc/manual/administration/zfs-state.section.md
Normal file
16
nixos/doc/manual/administration/zfs-state.section.md
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# ZFS {#sec-zfs-state}
|
||||||
|
|
||||||
|
When using ZFS, `/etc/zfs/zpool.cache` should be persistent (or a symlink to a persistent
|
||||||
|
location) as it is the default value for the `cachefile` [property](man:zpoolprops(7)).
|
||||||
|
|
||||||
|
This cachefile is used on system startup to discover ZFS pools, so ZFS pools
|
||||||
|
holding the `rootfs` and/or early-boot datasets such as `/nix` can be set to
|
||||||
|
`cachefile=none`.
|
||||||
|
|
||||||
|
In principle, if there are no other pools attached to the system, `zpool.cache`
|
||||||
|
does not need to be persisted; it is however *strongly recommended* to persist
|
||||||
|
it, in case additional pools are added later on, temporarily or permanently:
|
||||||
|
|
||||||
|
While mishandling the cachefile does not lead to data loss by itself, it may
|
||||||
|
cause zpools not to be imported during boot, and services may then write to a
|
||||||
|
location where a dataset was expected to be mounted.
|
|
@ -13,6 +13,13 @@ merging is handled.
|
||||||
`types.bool`
|
`types.bool`
|
||||||
|
|
||||||
: A boolean, its values can be `true` or `false`.
|
: A boolean, its values can be `true` or `false`.
|
||||||
|
All definitions must have the same value, after priorities. An error is thrown in case of a conflict.
|
||||||
|
|
||||||
|
`types.boolByOr`
|
||||||
|
|
||||||
|
: A boolean, its values can be `true` or `false`.
|
||||||
|
The result is `true` if _any_ of multiple definitions is `true`.
|
||||||
|
In other words, definitions are merged with the logical _OR_ operator.
|
||||||
|
|
||||||
`types.path`
|
`types.path`
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,14 @@ which causes the new configuration (and previous ones created using
|
||||||
This can be useful to separate test configurations from "stable"
|
This can be useful to separate test configurations from "stable"
|
||||||
configurations.
|
configurations.
|
||||||
|
|
||||||
|
A repl, or read-eval-print loop, is also available. You can inspect your configuration and use the Nix language with
|
||||||
|
|
||||||
|
```ShellSession
|
||||||
|
# nixos-rebuild repl
|
||||||
|
```
|
||||||
|
|
||||||
|
Your configuration is loaded into the `config` variable. Use tab for autocompletion, use the `:r` command to reload the configuration files. See `:?` or [`nix repl` in the Nix manual](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-repl.html) to learn more.
|
||||||
|
|
||||||
Finally, you can do
|
Finally, you can do
|
||||||
|
|
||||||
```ShellSession
|
```ShellSession
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
This section lists the release notes for each stable version of NixOS and current unstable revision.
|
This section lists the release notes for each stable version of NixOS and current unstable revision.
|
||||||
|
|
||||||
```{=include=} sections
|
```{=include=} sections
|
||||||
|
rl-2405.section.md
|
||||||
rl-2311.section.md
|
rl-2311.section.md
|
||||||
rl-2305.section.md
|
rl-2305.section.md
|
||||||
rl-2211.section.md
|
rl-2211.section.md
|
||||||
|
|
|
@ -100,7 +100,7 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||||
- [opensnitch](https://github.com/evilsocket/opensnitch), an application firewall. Available as [services.opensnitch](#opt-services.opensnitch.enable).
|
- [opensnitch](https://github.com/evilsocket/opensnitch), an application firewall. Available as [services.opensnitch](#opt-services.opensnitch.enable).
|
||||||
|
|
||||||
- [snapraid](https://www.snapraid.it/), a backup program for disk arrays.
|
- [snapraid](https://www.snapraid.it/), a backup program for disk arrays.
|
||||||
Available as [snapraid](#opt-snapraid.enable).
|
Available as [snapraid](#opt-services.snapraid.enable).
|
||||||
|
|
||||||
- [Hockeypuck](https://github.com/hockeypuck/hockeypuck), a OpenPGP Key Server. Available as [services.hockeypuck](#opt-services.hockeypuck.enable).
|
- [Hockeypuck](https://github.com/hockeypuck/hockeypuck), a OpenPGP Key Server. Available as [services.hockeypuck](#opt-services.hockeypuck.enable).
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ Make sure to also check the many updates in the [Nixpkgs library](#sec-release-2
|
||||||
- [Breaking Changes](#sec-release-23.11-nixos-breaking-changes)
|
- [Breaking Changes](#sec-release-23.11-nixos-breaking-changes)
|
||||||
- [New Services](#sec-release-23.11-nixos-new-services)
|
- [New Services](#sec-release-23.11-nixos-new-services)
|
||||||
- [Other Notable Changes](#sec-release-23.11-nixos-notable-changes)
|
- [Other Notable Changes](#sec-release-23.11-nixos-notable-changes)
|
||||||
- [Nixpkgs Library Changes](#sec-release-23.11-nixpkgs-lib)
|
- [Nixpkgs Library](#sec-release-23.11-nixpkgs-lib)
|
||||||
- [Breaking Changes](#sec-release-23.11-lib-breaking)
|
- [Breaking Changes](#sec-release-23.11-lib-breaking)
|
||||||
- [Additions and Improvements](#sec-release-23.11-lib-additions-improvements)
|
- [Additions and Improvements](#sec-release-23.11-lib-additions-improvements)
|
||||||
- [Deprecations](#sec-release-23.11-lib-deprecations)
|
- [Deprecations](#sec-release-23.11-lib-deprecations)
|
||||||
|
@ -1313,18 +1313,26 @@ Make sure to also check the many updates in the [Nixpkgs library](#sec-release-2
|
||||||
- When using [split parity files](https://www.snapraid.it/manual#7.1) in `snapraid`,
|
- When using [split parity files](https://www.snapraid.it/manual#7.1) in `snapraid`,
|
||||||
the snapraid-sync systemd service will no longer fail to run.
|
the snapraid-sync systemd service will no longer fail to run.
|
||||||
|
|
||||||
|
- `wpa_supplicant`'s configuration file cannot be read by non-root users, and
|
||||||
|
secrets (such as Pre-Shared Keys) can safely be passed via
|
||||||
|
`networking.wireless.environmentFile`.
|
||||||
|
|
||||||
|
The configuration file could previously be read, when `userControlled.enable` (non-default),
|
||||||
|
by users who are in both `wheel` and `userControlled.group` (defaults to `wheel`)
|
||||||
|
|
||||||
|
|
||||||
## Nixpkgs Library {#sec-release-23.11-nixpkgs-lib}
|
## Nixpkgs Library {#sec-release-23.11-nixpkgs-lib}
|
||||||
|
|
||||||
### Breaking Changes {#sec-release-23.11-lib-breaking}
|
### Breaking Changes {#sec-release-23.11-lib-breaking}
|
||||||
|
|
||||||
- [`lib.lists.foldl'`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.lists.foldl-prime)
|
- [`lib.lists.foldl'`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.lists.foldl-prime)
|
||||||
now always evaluates the initial accumulator argument first. If you depend on
|
now always evaluates the initial accumulator argument first. If you depend on
|
||||||
the lazier behavior, consider using
|
the lazier behavior, consider using
|
||||||
[`lib.lists.foldl`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.lists.foldl)
|
[`lib.lists.foldl`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.lists.foldl)
|
||||||
or
|
or
|
||||||
[`builtins.foldl'`](https://nixos.org/manual/nix/stable/language/builtins.html#builtins-foldl')
|
[`builtins.foldl'`](https://nixos.org/manual/nix/stable/language/builtins.html#builtins-foldl')
|
||||||
instead.
|
instead.
|
||||||
- [`lib.attrsets.foldlAttrs`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.attrsets.foldlAttrs)
|
- [`lib.attrsets.foldlAttrs`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.attrsets.foldlAttrs)
|
||||||
now always evaluates the initial accumulator argument first.
|
now always evaluates the initial accumulator argument first.
|
||||||
- Now that the internal NixOS transition to Markdown documentation is complete,
|
- Now that the internal NixOS transition to Markdown documentation is complete,
|
||||||
`lib.options.literalDocBook` has been removed after deprecation in 22.11.
|
`lib.options.literalDocBook` has been removed after deprecation in 22.11.
|
||||||
|
@ -1332,7 +1340,7 @@ Make sure to also check the many updates in the [Nixpkgs library](#sec-release-2
|
||||||
|
|
||||||
### Additions and Improvements {#sec-release-23.11-lib-additions-improvements}
|
### Additions and Improvements {#sec-release-23.11-lib-additions-improvements}
|
||||||
|
|
||||||
- [`lib.fileset`](https://nixos.org/manual/nixpkgs/unstable#sec-functions-library-fileset):
|
- [`lib.fileset`](https://nixos.org/manual/nixpkgs/stable#sec-functions-library-fileset):
|
||||||
A new sub-library to select local files to use for sources, designed to be
|
A new sub-library to select local files to use for sources, designed to be
|
||||||
easy and safe to use.
|
easy and safe to use.
|
||||||
|
|
||||||
|
@ -1341,7 +1349,7 @@ Make sure to also check the many updates in the [Nixpkgs library](#sec-release-2
|
||||||
post](https://www.tweag.io/blog/2023-11-28-file-sets/) or [the
|
post](https://www.tweag.io/blog/2023-11-28-file-sets/) or [the
|
||||||
tutorial](https://nix.dev/tutorials/file-sets).
|
tutorial](https://nix.dev/tutorials/file-sets).
|
||||||
|
|
||||||
- [`lib.gvariant`](https://nixos.org/manual/nixpkgs/unstable#sec-functions-library-gvariant):
|
- [`lib.gvariant`](https://nixos.org/manual/nixpkgs/stable#sec-functions-library-gvariant):
|
||||||
A partial and basic implementation of GVariant formatted strings. See
|
A partial and basic implementation of GVariant formatted strings. See
|
||||||
[GVariant Format
|
[GVariant Format
|
||||||
Strings](https://docs.gtk.org/glib/gvariant-format-strings.html) for details.
|
Strings](https://docs.gtk.org/glib/gvariant-format-strings.html) for details.
|
||||||
|
@ -1351,58 +1359,58 @@ Make sure to also check the many updates in the [Nixpkgs library](#sec-release-2
|
||||||
change in backwards incompatible ways without prior notice.
|
change in backwards incompatible ways without prior notice.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
- [`lib.asserts`](https://nixos.org/manual/nixpkgs/unstable#sec-functions-library-asserts):
|
- [`lib.asserts`](https://nixos.org/manual/nixpkgs/stable#sec-functions-library-asserts):
|
||||||
New function:
|
New function:
|
||||||
[`assertEachOneOf`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.asserts.assertEachOneOf).
|
[`assertEachOneOf`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.asserts.assertEachOneOf).
|
||||||
- [`lib.attrsets`](https://nixos.org/manual/nixpkgs/unstable#sec-functions-library-attrsets):
|
- [`lib.attrsets`](https://nixos.org/manual/nixpkgs/stable#sec-functions-library-attrsets):
|
||||||
New function:
|
New function:
|
||||||
[`attrsToList`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.attrsets.attrsToList).
|
[`attrsToList`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.attrsets.attrsToList).
|
||||||
- [`lib.customisation`](https://nixos.org/manual/nixpkgs/unstable#sec-functions-library-customisation):
|
- [`lib.customisation`](https://nixos.org/manual/nixpkgs/stable#sec-functions-library-customisation):
|
||||||
New function:
|
New function:
|
||||||
[`makeScopeWithSplicing'`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.customisation.makeScopeWithSplicing-prime).
|
[`makeScopeWithSplicing'`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.customisation.makeScopeWithSplicing-prime).
|
||||||
- [`lib.fixedPoints`](https://nixos.org/manual/nixpkgs/unstable#sec-functions-library-fixedPoints):
|
- [`lib.fixedPoints`](https://nixos.org/manual/nixpkgs/stable#sec-functions-library-fixedPoints):
|
||||||
Documentation improvements for
|
Documentation improvements for
|
||||||
[`lib.fixedPoints.fix`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.fixedPoints.fix).
|
[`lib.fixedPoints.fix`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.fixedPoints.fix).
|
||||||
- `lib.generators`: New functions:
|
- `lib.generators`: New functions:
|
||||||
[`mkDconfKeyValue`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.generators.mkDconfKeyValue),
|
[`mkDconfKeyValue`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.generators.mkDconfKeyValue),
|
||||||
[`toDconfINI`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.generators.toDconfINI).
|
[`toDconfINI`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.generators.toDconfINI).
|
||||||
|
|
||||||
`lib.generators.toKeyValue` now supports the `indent` attribute in its first
|
`lib.generators.toKeyValue` now supports the `indent` attribute in its first
|
||||||
argument.
|
argument.
|
||||||
- [`lib.lists`](https://nixos.org/manual/nixpkgs/unstable#sec-functions-library-lists):
|
- [`lib.lists`](https://nixos.org/manual/nixpkgs/stable#sec-functions-library-lists):
|
||||||
New functions:
|
New functions:
|
||||||
[`findFirstIndex`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.lists.findFirstIndex),
|
[`findFirstIndex`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.lists.findFirstIndex),
|
||||||
[`hasPrefix`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.lists.hasPrefix),
|
[`hasPrefix`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.lists.hasPrefix),
|
||||||
[`removePrefix`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.lists.removePrefix),
|
[`removePrefix`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.lists.removePrefix),
|
||||||
[`commonPrefix`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.lists.commonPrefix),
|
[`commonPrefix`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.lists.commonPrefix),
|
||||||
[`allUnique`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.lists.allUnique).
|
[`allUnique`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.lists.allUnique).
|
||||||
|
|
||||||
Documentation improvements for
|
Documentation improvements for
|
||||||
[`lib.lists.foldl'`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.lists.foldl-prime).
|
[`lib.lists.foldl'`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.lists.foldl-prime).
|
||||||
- [`lib.meta`](https://nixos.org/manual/nixpkgs/unstable#sec-functions-library-meta):
|
- [`lib.meta`](https://nixos.org/manual/nixpkgs/stable#sec-functions-library-meta):
|
||||||
Documentation of functions now gets rendered
|
Documentation of functions now gets rendered
|
||||||
- [`lib.path`](https://nixos.org/manual/nixpkgs/unstable#sec-functions-library-path):
|
- [`lib.path`](https://nixos.org/manual/nixpkgs/stable#sec-functions-library-path):
|
||||||
New functions:
|
New functions:
|
||||||
[`hasPrefix`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.path.hasPrefix),
|
[`hasPrefix`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.path.hasPrefix),
|
||||||
[`removePrefix`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.path.removePrefix),
|
[`removePrefix`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.path.removePrefix),
|
||||||
[`splitRoot`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.path.splitRoot),
|
[`splitRoot`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.path.splitRoot),
|
||||||
[`subpath.components`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.path.subpath.components).
|
[`subpath.components`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.path.subpath.components).
|
||||||
- [`lib.strings`](https://nixos.org/manual/nixpkgs/unstable#sec-functions-library-strings):
|
- [`lib.strings`](https://nixos.org/manual/nixpkgs/stable#sec-functions-library-strings):
|
||||||
New functions:
|
New functions:
|
||||||
[`replicate`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.strings.replicate),
|
[`replicate`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.strings.replicate),
|
||||||
[`cmakeOptionType`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.strings.cmakeOptionType),
|
[`cmakeOptionType`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.strings.cmakeOptionType),
|
||||||
[`cmakeBool`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.strings.cmakeBool),
|
[`cmakeBool`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.strings.cmakeBool),
|
||||||
[`cmakeFeature`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.strings.cmakeFeature).
|
[`cmakeFeature`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.strings.cmakeFeature).
|
||||||
- [`lib.trivial`](https://nixos.org/manual/nixpkgs/unstable#sec-functions-library-trivial):
|
- [`lib.trivial`](https://nixos.org/manual/nixpkgs/stable#sec-functions-library-trivial):
|
||||||
New function:
|
New function:
|
||||||
[`mirrorFunctionArgs`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.trivial.mirrorFunctionArgs).
|
[`mirrorFunctionArgs`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.trivial.mirrorFunctionArgs).
|
||||||
- `lib.systems`: New function:
|
- `lib.systems`: New function:
|
||||||
[`equals`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.systems.equals).
|
[`equals`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.systems.equals).
|
||||||
- [`lib.options`](https://nixos.org/manual/nixpkgs/unstable#sec-functions-library-options):
|
- [`lib.options`](https://nixos.org/manual/nixpkgs/stable#sec-functions-library-options):
|
||||||
Improved documentation for
|
Improved documentation for
|
||||||
[`mkPackageOption`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.options.mkPackageOption).
|
[`mkPackageOption`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.options.mkPackageOption).
|
||||||
|
|
||||||
[`mkPackageOption`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.options.mkPackageOption).
|
[`mkPackageOption`](https://nixos.org/manual/nixpkgs/stable#function-library-lib.options.mkPackageOption).
|
||||||
now also supports the `pkgsText` attribute.
|
now also supports the `pkgsText` attribute.
|
||||||
|
|
||||||
Module system:
|
Module system:
|
||||||
|
|
|
@ -12,6 +12,12 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||||
|
|
||||||
- `linuxPackages_testing_bcachefs` is now fully deprecated by `linuxPackages_testing`, and is therefore no longer available.
|
- `linuxPackages_testing_bcachefs` is now fully deprecated by `linuxPackages_testing`, and is therefore no longer available.
|
||||||
|
|
||||||
|
- NixOS now installs a stub ELF loader that prints an informative error message when users attempt to run binaries not made for NixOS.
|
||||||
|
- This can be disabled through the `environment.stub-ld.enable` option.
|
||||||
|
- If you use `programs.nix-ld.enable`, no changes are needed. The stub will be disabled automatically.
|
||||||
|
|
||||||
|
- Julia environments can now be built with arbitrary packages from the ecosystem using the `.withPackages` function. For example: `julia.withPackages ["Plots"]`.
|
||||||
|
|
||||||
## New Services {#sec-release-24.05-new-services}
|
## New Services {#sec-release-24.05-new-services}
|
||||||
|
|
||||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||||
|
@ -20,18 +26,75 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||||
|
|
||||||
- [maubot](https://github.com/maubot/maubot), a plugin-based Matrix bot framework. Available as [services.maubot](#opt-services.maubot.enable).
|
- [maubot](https://github.com/maubot/maubot), a plugin-based Matrix bot framework. Available as [services.maubot](#opt-services.maubot.enable).
|
||||||
|
|
||||||
|
- [GNS3](https://www.gns3.com/), a network software emulator. Available as [services.gns3-server](#opt-services.gns3-server.enable).
|
||||||
|
|
||||||
|
- [rspamd-trainer](https://gitlab.com/onlime/rspamd-trainer), script triggered by a helper which reads mails from a specific mail inbox and feeds them into rspamd for spam/ham training.
|
||||||
|
|
||||||
|
- [ollama](https://ollama.ai), server for running large language models locally.
|
||||||
|
|
||||||
- [Anki Sync Server](https://docs.ankiweb.net/sync-server.html), the official sync server built into recent versions of Anki. Available as [services.anki-sync-server](#opt-services.anki-sync-server.enable).
|
- [Anki Sync Server](https://docs.ankiweb.net/sync-server.html), the official sync server built into recent versions of Anki. Available as [services.anki-sync-server](#opt-services.anki-sync-server.enable).
|
||||||
The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been marked deprecated and will be dropped after 24.05 due to lack of maintenance of the anki-sync-server softwares.
|
The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been marked deprecated and will be dropped after 24.05 due to lack of maintenance of the anki-sync-server softwares.
|
||||||
|
|
||||||
|
- [ping_exporter](https://github.com/czerwonk/ping_exporter), a Prometheus exporter for ICMP echo requests. Available as [services.prometheus.exporters.ping](#opt-services.prometheus.exporters.ping.enable).
|
||||||
|
|
||||||
- [Clevis](https://github.com/latchset/clevis), a pluggable framework for automated decryption, used to unlock encrypted devices in initrd. Available as [boot.initrd.clevis.enable](#opt-boot.initrd.clevis.enable).
|
- [Clevis](https://github.com/latchset/clevis), a pluggable framework for automated decryption, used to unlock encrypted devices in initrd. Available as [boot.initrd.clevis.enable](#opt-boot.initrd.clevis.enable).
|
||||||
|
|
||||||
|
- [TuxClocker](https://github.com/Lurkki14/tuxclocker), a hardware control and monitoring program. Available as [programs.tuxclocker](#opt-programs.tuxclocker.enable).
|
||||||
|
|
||||||
## Backward Incompatibilities {#sec-release-24.05-incompatibilities}
|
## Backward Incompatibilities {#sec-release-24.05-incompatibilities}
|
||||||
|
|
||||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||||
|
|
||||||
|
- The `power.ups` module now generates `upsd.conf`, `upsd.users` and `upsmon.conf` automatically from a set of new configuration options. This breaks compatibility with existing `power.ups` setups where these files were created manually. Back up these files before upgrading NixOS.
|
||||||
|
|
||||||
|
- `k9s` was updated to v0.30. There have been various breaking changes in the config file format,
|
||||||
|
check out the changelog of [v0.29](https://github.com/derailed/k9s/releases/tag/v0.29.0) and
|
||||||
|
[v0.30](https://github.com/derailed/k9s/releases/tag/v0.30.0) for details. It is recommended
|
||||||
|
to back up your current configuration and let k9s recreate the new base configuration.
|
||||||
|
|
||||||
|
- `idris2` was updated to v0.7.0. This version introduces breaking changes. Check out the [changelog](https://github.com/idris-lang/Idris2/blob/v0.7.0/CHANGELOG.md#v070) for details.
|
||||||
|
|
||||||
|
- `nitter` requires a `guest_accounts.jsonl` to be provided as a path or loaded into the default location at `/var/lib/nitter/guest_accounts.jsonl`. See [Guest Account Branch Deployment](https://github.com/zedeus/nitter/wiki/Guest-Account-Branch-Deployment) for details.
|
||||||
|
|
||||||
|
- Invidious has changed its default database username from `kemal` to `invidious`. Setups involving an externally provisioned database (i.e. `services.invidious.database.createLocally == false`) should adjust their configuration accordingly. The old `kemal` user will not be removed automatically even when the database is provisioned automatically.(https://github.com/NixOS/nixpkgs/pull/265857)
|
||||||
|
|
||||||
|
- `paperless`' `services.paperless.extraConfig` setting has been removed and converted to the freeform type and option named `services.paperless.settings`.
|
||||||
|
|
||||||
- `mkosi` was updated to v19. Parts of the user interface have changed. Consult the
|
- `mkosi` was updated to v19. Parts of the user interface have changed. Consult the
|
||||||
[release notes](https://github.com/systemd/mkosi/releases/tag/v19) for a list of changes.
|
[release notes](https://github.com/systemd/mkosi/releases/tag/v19) for a list of changes.
|
||||||
|
|
||||||
|
- The `kanata` package has been updated to v1.5.0, which includes [breaking changes](https://github.com/jtroo/kanata/releases/tag/v1.5.0).
|
||||||
|
|
||||||
|
- The latest available version of Nextcloud is v28 (available as `pkgs.nextcloud28`). The installation logic is as follows:
|
||||||
|
- If [`services.nextcloud.package`](#opt-services.nextcloud.package) is specified explicitly, this package will be installed (**recommended**)
|
||||||
|
- If [`system.stateVersion`](#opt-system.stateVersion) is >=24.05, `pkgs.nextcloud28` will be installed by default.
|
||||||
|
- If [`system.stateVersion`](#opt-system.stateVersion) is >=23.11, `pkgs.nextcloud27` will be installed by default.
|
||||||
|
- Please note that an upgrade from v26 (or older) to v28 directly is not possible. Please upgrade to `nextcloud27` (or earlier) first. Nextcloud prohibits skipping major versions while upgrading. You can upgrade by declaring [`services.nextcloud.package = pkgs.nextcloud27;`](options.html#opt-services.nextcloud.package).
|
||||||
|
|
||||||
|
- `services.resolved.fallbackDns` can now be used to disable the upstream fallback servers entirely by setting it to an empty list. To get the previous behaviour of the upstream defaults set it to null, the new default, instead.
|
||||||
|
|
||||||
|
- `services.avahi.nssmdns` got split into `services.avahi.nssmdns4` and `services.avahi.nssmdns6` which enable the mDNS NSS switch for IPv4 and IPv6 respectively.
|
||||||
|
Since most mDNS responders only register IPv4 addresses, most users want to keep the IPv6 support disabled to avoid long timeouts.
|
||||||
|
|
||||||
|
- `networking.iproute2.enable` now does not set `environment.etc."iproute2/rt_tables".text`.
|
||||||
|
|
||||||
|
Setting `environment.etc."iproute2/{CONFIG_FILE_NAME}".text` will override the whole configuration file instead of appending it to the upstream configuration file.
|
||||||
|
|
||||||
|
`CONFIG_FILE_NAME` includes `bpf_pinning`, `ematch_map`, `group`, `nl_protos`, `rt_dsfield`, `rt_protos`, `rt_realms`, `rt_scopes`, and `rt_tables`.
|
||||||
|
|
||||||
|
- The executable file names for `firefox-devedition`, `firefox-beta`, `firefox-esr` now matches their package names, which is consistent with the `firefox-*-bin` packages. The desktop entries are also updated so that you can have multiple editions of firefox in your app launcher.
|
||||||
|
|
||||||
|
- The `systemd.oomd` module behavior is changed as:
|
||||||
|
|
||||||
|
- Raise ManagedOOMMemoryPressureLimit from 50% to 80%. This should make systemd-oomd kill things less often, and fix issues like [this](https://pagure.io/fedora-workstation/issue/358).
|
||||||
|
Reference: [commit](https://src.fedoraproject.org/rpms/systemd/c/806c95e1c70af18f81d499b24cd7acfa4c36ffd6?branch=806c95e1c70af18f81d499b24cd7acfa4c36ffd6)
|
||||||
|
|
||||||
|
- Remove swap policy. This helps prevent killing processes when user's swap is small.
|
||||||
|
|
||||||
|
- Expand the memory pressure policy to system.slice, user-.slice, and all user owned slices. Reference: [commit](https://src.fedoraproject.org/rpms/systemd/c/7665e1796f915dedbf8e014f0a78f4f576d609bb)
|
||||||
|
|
||||||
|
- `systemd.oomd.enableUserServices` is renamed to `systemd.oomd.enableUserSlices`.
|
||||||
|
|
||||||
## Other Notable Changes {#sec-release-24.05-notable-changes}
|
## Other Notable Changes {#sec-release-24.05-notable-changes}
|
||||||
|
|
||||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||||
|
@ -40,20 +103,61 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
|
||||||
|
|
||||||
- Cinnamon has been updated to 6.0. Please beware that the [Wayland session](https://blog.linuxmint.com/?p=4591) is still experimental in this release.
|
- Cinnamon has been updated to 6.0. Please beware that the [Wayland session](https://blog.linuxmint.com/?p=4591) is still experimental in this release.
|
||||||
|
|
||||||
|
- `services.postgresql.extraPlugins` changed its type from just a list of packages to also a function that returns such a list.
|
||||||
|
For example a config line like ``services.postgresql.extraPlugins = with pkgs.postgresql_11.pkgs; [ postgis ];`` is recommended to be changed to ``services.postgresql.extraPlugins = ps: with ps; [ postgis ];``;
|
||||||
|
|
||||||
- Programs written in [Nim](https://nim-lang.org/) are built with libraries selected by lockfiles.
|
- Programs written in [Nim](https://nim-lang.org/) are built with libraries selected by lockfiles.
|
||||||
The `nimPackages` and `nim2Packages` sets have been removed.
|
The `nimPackages` and `nim2Packages` sets have been removed.
|
||||||
See https://nixos.org/manual/nixpkgs/unstable#nim for more information.
|
See https://nixos.org/manual/nixpkgs/unstable#nim for more information.
|
||||||
|
|
||||||
|
- [Portunus](https://github.com/majewsky/portunus) has been updated to major version 2.
|
||||||
|
This version of Portunus supports strong password hashes, but the legacy hash SHA-256 is also still supported to ensure a smooth migration of existing user accounts.
|
||||||
|
After upgrading, follow the instructions on the [upstream release notes](https://github.com/majewsky/portunus/releases/tag/v2.0.0) to upgrade all user accounts to strong password hashes.
|
||||||
|
Support for weak password hashes will be removed in NixOS 24.11.
|
||||||
|
|
||||||
|
- `libass` now uses the native CoreText backend on Darwin, which may fix subtitle rendering issues with `mpv`, `ffmpeg`, etc.
|
||||||
|
|
||||||
|
- [Lilypond](https://lilypond.org/index.html) and [Denemo](https://www.denemo.org) are now compiled with Guile 3.0.
|
||||||
|
|
||||||
|
- The following options of the Nextcloud module were moved into [`services.nextcloud.extraOptions`](#opt-services.nextcloud.extraOptions) and renamed to match the name from Nextcloud's `config.php`:
|
||||||
|
- `logLevel` -> [`loglevel`](#opt-services.nextcloud.extraOptions.loglevel),
|
||||||
|
- `logType` -> [`log_type`](#opt-services.nextcloud.extraOptions.log_type),
|
||||||
|
- `defaultPhoneRegion` -> [`default_phone_region`](#opt-services.nextcloud.extraOptions.default_phone_region),
|
||||||
|
- `overwriteProtocol` -> [`overwriteprotocol`](#opt-services.nextcloud.extraOptions.overwriteprotocol),
|
||||||
|
- `skeletonDirectory` -> [`skeletondirectory`](#opt-services.nextcloud.extraOptions.skeletondirectory),
|
||||||
|
- `globalProfiles` -> [`profile.enabled`](#opt-services.nextcloud.extraOptions._profile.enabled_),
|
||||||
|
- `extraTrustedDomains` -> [`trusted_domains`](#opt-services.nextcloud.extraOptions.trusted_domains) and
|
||||||
|
- `trustedProxies` -> [`trusted_proxies`](#opt-services.nextcloud.extraOptions.trusted_proxies).
|
||||||
|
|
||||||
|
- The option [`services.nextcloud.config.dbport`] of the Nextcloud module was removed to match upstream.
|
||||||
|
The port can be specified in [`services.nextcloud.config.dbhost`](#opt-services.nextcloud.config.dbhost).
|
||||||
|
|
||||||
- The Yama LSM is now enabled by default in the kernel, which prevents ptracing
|
- The Yama LSM is now enabled by default in the kernel, which prevents ptracing
|
||||||
non-child processes. This means you will not be able to attach gdb to an
|
non-child processes. This means you will not be able to attach gdb to an
|
||||||
existing process, but will need to start that process from gdb (so it is a
|
existing process, but will need to start that process from gdb (so it is a
|
||||||
child). Or you can set `boot.kernel.sysctl."kernel.yama.ptrace_scope"` to 0.
|
child). Or you can set `boot.kernel.sysctl."kernel.yama.ptrace_scope"` to 0.
|
||||||
|
|
||||||
|
- [Nginx virtual hosts](#opt-services.nginx.virtualHosts) using `forceSSL` or
|
||||||
|
`globalRedirect` can now have redirect codes other than 301 through
|
||||||
|
`redirectCode`.
|
||||||
|
|
||||||
|
- The source of the `mockgen` package has changed to the [go.uber.org/mock](https://github.com/uber-go/mock) fork because [the original repository is no longer maintained](https://github.com/golang/mock#gomock).
|
||||||
|
|
||||||
|
- [](#opt-boot.kernel.sysctl._net.core.wmem_max_) changed from a string to an integer because of the addition of a custom merge option (taking the highest value defined to avoid conflicts between 2 services trying to set that value), just as [](#opt-boot.kernel.sysctl._net.core.rmem_max_) since 22.11.
|
||||||
|
|
||||||
|
- `services.zfs.zed.enableMail` now uses the global `sendmail` wrapper defined by an email module
|
||||||
|
(such as msmtp or Postfix). It no longer requires using a special ZFS build with email support.
|
||||||
|
|
||||||
- Gitea 1.21 upgrade has several breaking changes, including:
|
- Gitea 1.21 upgrade has several breaking changes, including:
|
||||||
- Custom themes and other assets that were previously stored in `custom/public/*` now belong in `custom/public/assets/*`
|
- Custom themes and other assets that were previously stored in `custom/public/*` now belong in `custom/public/assets/*`
|
||||||
- New instances of Gitea using MySQL now ignore the `[database].CHARSET` config option and always use the `utf8mb4` charset, existing instances should migrate via the `gitea doctor convert` CLI command.
|
- New instances of Gitea using MySQL now ignore the `[database].CHARSET` config option and always use the `utf8mb4` charset, existing instances should migrate via the `gitea doctor convert` CLI command.
|
||||||
|
|
||||||
- The `hardware.pulseaudio` module now sets permission of pulse user home directory to 755 when running in "systemWide" mode. It fixes [issue 114399](https://github.com/NixOS/nixpkgs/issues/114399).
|
- The `hardware.pulseaudio` module now sets permission of pulse user home directory to 755 when running in "systemWide" mode. It fixes [issue 114399](https://github.com/NixOS/nixpkgs/issues/114399).
|
||||||
|
|
||||||
|
- The `btrbk` module now automatically selects and provides required compression
|
||||||
|
program depending on the configured `stream_compress` option. Since this
|
||||||
|
replaces the need for the `extraPackages` option, this option will be
|
||||||
|
deprecated in future releases.
|
||||||
|
|
||||||
- QtMultimedia has changed its default backend to `QT_MEDIA_BACKEND=ffmpeg` (previously `gstreamer` on Linux or `darwin` on MacOS).
|
- QtMultimedia has changed its default backend to `QT_MEDIA_BACKEND=ffmpeg` (previously `gstreamer` on Linux or `darwin` on MacOS).
|
||||||
The previous native backends remain available but are now minimally maintained. Refer to [upstream documentation](https://doc.qt.io/qt-6/qtmultimedia-index.html#ffmpeg-as-the-default-backend) for further details about each platform.
|
The previous native backends remain available but are now minimally maintained. Refer to [upstream documentation](https://doc.qt.io/qt-6/qtmultimedia-index.html#ffmpeg-as-the-default-backend) for further details about each platform.
|
||||||
|
|
|
@ -522,11 +522,16 @@ let format' = format; in let
|
||||||
chmod 0644 $efiVars
|
chmod 0644 $efiVars
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
createHydraBuildProducts = ''
|
||||||
|
mkdir -p $out/nix-support
|
||||||
|
echo "file ${format}-image $out/${filename}" >> $out/nix-support/hydra-build-products
|
||||||
|
'';
|
||||||
|
|
||||||
buildImage = pkgs.vmTools.runInLinuxVM (
|
buildImage = pkgs.vmTools.runInLinuxVM (
|
||||||
pkgs.runCommand name {
|
pkgs.runCommand name {
|
||||||
preVM = prepareImage + lib.optionalString touchEFIVars createEFIVars;
|
preVM = prepareImage + lib.optionalString touchEFIVars createEFIVars;
|
||||||
buildInputs = with pkgs; [ util-linux e2fsprogs dosfstools ];
|
buildInputs = with pkgs; [ util-linux e2fsprogs dosfstools ];
|
||||||
postVM = moveOrConvertImage + postVM;
|
postVM = moveOrConvertImage + createHydraBuildProducts + postVM;
|
||||||
QEMU_OPTS =
|
QEMU_OPTS =
|
||||||
concatStringsSep " " (lib.optional useEFIBoot "-drive if=pflash,format=raw,unit=0,readonly=on,file=${efiFirmware}"
|
concatStringsSep " " (lib.optional useEFIBoot "-drive if=pflash,format=raw,unit=0,readonly=on,file=${efiFirmware}"
|
||||||
++ lib.optionals touchEFIVars [
|
++ lib.optionals touchEFIVars [
|
||||||
|
@ -616,5 +621,5 @@ let format' = format; in let
|
||||||
in
|
in
|
||||||
if onlyNixStore then
|
if onlyNixStore then
|
||||||
pkgs.runCommand name {}
|
pkgs.runCommand name {}
|
||||||
(prepareImage + moveOrConvertImage + postVM)
|
(prepareImage + moveOrConvertImage + createHydraBuildProducts + postVM)
|
||||||
else buildImage
|
else buildImage
|
||||||
|
|
|
@ -447,8 +447,7 @@ class Machine:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def check_active(_: Any) -> bool:
|
def check_active(_: Any) -> bool:
|
||||||
info = self.get_unit_info(unit, user)
|
state = self.get_unit_property(unit, "ActiveState", user)
|
||||||
state = info["ActiveState"]
|
|
||||||
if state == "failed":
|
if state == "failed":
|
||||||
raise Exception(f'unit "{unit}" reached state "{state}"')
|
raise Exception(f'unit "{unit}" reached state "{state}"')
|
||||||
|
|
||||||
|
@ -491,6 +490,35 @@ class Machine:
|
||||||
if line_pattern.match(line)
|
if line_pattern.match(line)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_unit_property(
|
||||||
|
self,
|
||||||
|
unit: str,
|
||||||
|
property: str,
|
||||||
|
user: Optional[str] = None,
|
||||||
|
) -> str:
|
||||||
|
status, lines = self.systemctl(
|
||||||
|
f'--no-pager show "{unit}" --property="{property}"',
|
||||||
|
user,
|
||||||
|
)
|
||||||
|
if status != 0:
|
||||||
|
raise Exception(
|
||||||
|
f'retrieving systemctl property "{property}" for unit "{unit}"'
|
||||||
|
+ ("" if user is None else f' under user "{user}"')
|
||||||
|
+ f" failed with exit code {status}"
|
||||||
|
)
|
||||||
|
|
||||||
|
invalid_output_message = (
|
||||||
|
f'systemctl show --property "{property}" "{unit}"'
|
||||||
|
f"produced invalid output: {lines}"
|
||||||
|
)
|
||||||
|
|
||||||
|
line_pattern = re.compile(r"^([^=]+)=(.*)$")
|
||||||
|
match = line_pattern.match(lines)
|
||||||
|
assert match is not None, invalid_output_message
|
||||||
|
|
||||||
|
assert match[1] == property, invalid_output_message
|
||||||
|
return match[2]
|
||||||
|
|
||||||
def systemctl(self, q: str, user: Optional[str] = None) -> Tuple[int, str]:
|
def systemctl(self, q: str, user: Optional[str] = None) -> Tuple[int, str]:
|
||||||
"""
|
"""
|
||||||
Runs `systemctl` commands with optional support for
|
Runs `systemctl` commands with optional support for
|
||||||
|
|
|
@ -27,31 +27,37 @@ var ${bucket:=nixos-amis}
|
||||||
var ${service_role_name:=vmimport}
|
var ${service_role_name:=vmimport}
|
||||||
|
|
||||||
# Output of the command:
|
# Output of the command:
|
||||||
# > aws ec2 describe-regions --all-regions --query "Regions[].{Name:RegionName}" --output text | sort
|
# $ nix-shell -I nixpkgs=. -p awscli --run 'aws ec2 describe-regions --region us-east-1 --all-regions --query "Regions[].{Name:RegionName}" --output text | sort | sed -e s/^/\ \ /'
|
||||||
var ${regions:=
|
var ${regions:=
|
||||||
af-south-1
|
af-south-1
|
||||||
ap-east-1
|
ap-east-1
|
||||||
ap-northeast-1
|
ap-northeast-1
|
||||||
ap-northeast-2
|
ap-northeast-2
|
||||||
ap-northeast-3
|
ap-northeast-3
|
||||||
ap-south-1
|
ap-south-1
|
||||||
ap-southeast-1
|
ap-south-2
|
||||||
ap-southeast-2
|
ap-southeast-1
|
||||||
ap-southeast-3
|
ap-southeast-2
|
||||||
ca-central-1
|
ap-southeast-3
|
||||||
eu-central-1
|
ap-southeast-4
|
||||||
eu-north-1
|
ca-central-1
|
||||||
eu-south-1
|
eu-central-1
|
||||||
eu-west-1
|
eu-central-2
|
||||||
eu-west-2
|
eu-north-1
|
||||||
eu-west-3
|
eu-south-1
|
||||||
me-south-1
|
eu-south-2
|
||||||
sa-east-1
|
eu-west-1
|
||||||
us-east-1
|
eu-west-2
|
||||||
us-east-2
|
eu-west-3
|
||||||
us-west-1
|
il-central-1
|
||||||
us-west-2
|
me-central-1
|
||||||
}
|
me-south-1
|
||||||
|
sa-east-1
|
||||||
|
us-east-1
|
||||||
|
us-east-2
|
||||||
|
us-west-1
|
||||||
|
us-west-2
|
||||||
|
}
|
||||||
|
|
||||||
regions=($regions)
|
regions=($regions)
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,9 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
environment.etc."iproute2/rt_tables" = {
|
environment.etc."iproute2/rt_tables.d/nixos.conf" = {
|
||||||
mode = "0644";
|
mode = "0644";
|
||||||
text = (fileContents "${pkgs.iproute2}/lib/iproute2/rt_tables")
|
text = cfg.rttablesExtraConfig;
|
||||||
+ (optionalString (cfg.rttablesExtraConfig != "") "\n\n${cfg.rttablesExtraConfig}");
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,18 +226,6 @@ in
|
||||||
"ldap.conf" = ldapConfig;
|
"ldap.conf" = ldapConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
system.activationScripts = mkIf (!cfg.daemon.enable) {
|
|
||||||
ldap = stringAfter [ "etc" "groups" "users" ] ''
|
|
||||||
if test -f "${cfg.bind.passwordFile}" ; then
|
|
||||||
umask 0077
|
|
||||||
conf="$(mktemp)"
|
|
||||||
printf 'bindpw %s\n' "$(cat ${cfg.bind.passwordFile})" |
|
|
||||||
cat ${ldapConfig.source} - >"$conf"
|
|
||||||
mv -fT "$conf" /etc/ldap.conf
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
system.nssModules = mkIf cfg.nsswitch (singleton (
|
system.nssModules = mkIf cfg.nsswitch (singleton (
|
||||||
if cfg.daemon.enable then nss_pam_ldapd else nss_ldap
|
if cfg.daemon.enable then nss_pam_ldapd else nss_ldap
|
||||||
));
|
));
|
||||||
|
@ -258,42 +246,63 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services = mkIf cfg.daemon.enable {
|
systemd.services = mkMerge [
|
||||||
nslcd = {
|
(mkIf (!cfg.daemon.enable) {
|
||||||
wantedBy = [ "multi-user.target" ];
|
ldap-password = {
|
||||||
|
wantedBy = [ "sysinit.target" ];
|
||||||
preStart = ''
|
before = [ "sysinit.target" "shutdown.target" ];
|
||||||
umask 0077
|
conflicts = [ "shutdown.target" ];
|
||||||
conf="$(mktemp)"
|
unitConfig.DefaultDependencies = false;
|
||||||
{
|
serviceConfig.Type = "oneshot";
|
||||||
cat ${nslcdConfig}
|
serviceConfig.RemainAfterExit = true;
|
||||||
test -z '${cfg.bind.distinguishedName}' -o ! -f '${cfg.bind.passwordFile}' ||
|
script = ''
|
||||||
printf 'bindpw %s\n' "$(cat '${cfg.bind.passwordFile}')"
|
if test -f "${cfg.bind.passwordFile}" ; then
|
||||||
test -z '${cfg.daemon.rootpwmoddn}' -o ! -f '${cfg.daemon.rootpwmodpwFile}' ||
|
umask 0077
|
||||||
printf 'rootpwmodpw %s\n' "$(cat '${cfg.daemon.rootpwmodpwFile}')"
|
conf="$(mktemp)"
|
||||||
} >"$conf"
|
printf 'bindpw %s\n' "$(cat ${cfg.bind.passwordFile})" |
|
||||||
mv -fT "$conf" /run/nslcd/nslcd.conf
|
cat ${ldapConfig.source} - >"$conf"
|
||||||
'';
|
mv -fT "$conf" /etc/ldap.conf
|
||||||
|
fi
|
||||||
restartTriggers = [
|
'';
|
||||||
nslcdConfig
|
|
||||||
cfg.bind.passwordFile
|
|
||||||
cfg.daemon.rootpwmodpwFile
|
|
||||||
];
|
|
||||||
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = "${nslcdWrapped}/bin/nslcd";
|
|
||||||
Type = "forking";
|
|
||||||
Restart = "always";
|
|
||||||
User = "nslcd";
|
|
||||||
Group = "nslcd";
|
|
||||||
RuntimeDirectory = [ "nslcd" ];
|
|
||||||
PIDFile = "/run/nslcd/nslcd.pid";
|
|
||||||
AmbientCapabilities = "CAP_SYS_RESOURCE";
|
|
||||||
};
|
};
|
||||||
};
|
})
|
||||||
|
|
||||||
};
|
(mkIf cfg.daemon.enable {
|
||||||
|
nslcd = {
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
preStart = ''
|
||||||
|
umask 0077
|
||||||
|
conf="$(mktemp)"
|
||||||
|
{
|
||||||
|
cat ${nslcdConfig}
|
||||||
|
test -z '${cfg.bind.distinguishedName}' -o ! -f '${cfg.bind.passwordFile}' ||
|
||||||
|
printf 'bindpw %s\n' "$(cat '${cfg.bind.passwordFile}')"
|
||||||
|
test -z '${cfg.daemon.rootpwmoddn}' -o ! -f '${cfg.daemon.rootpwmodpwFile}' ||
|
||||||
|
printf 'rootpwmodpw %s\n' "$(cat '${cfg.daemon.rootpwmodpwFile}')"
|
||||||
|
} >"$conf"
|
||||||
|
mv -fT "$conf" /run/nslcd/nslcd.conf
|
||||||
|
'';
|
||||||
|
|
||||||
|
restartTriggers = [
|
||||||
|
nslcdConfig
|
||||||
|
cfg.bind.passwordFile
|
||||||
|
cfg.daemon.rootpwmodpwFile
|
||||||
|
];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${nslcdWrapped}/bin/nslcd";
|
||||||
|
Type = "forking";
|
||||||
|
Restart = "always";
|
||||||
|
User = "nslcd";
|
||||||
|
Group = "nslcd";
|
||||||
|
RuntimeDirectory = [ "nslcd" ];
|
||||||
|
PIDFile = "/run/nslcd/nslcd.pid";
|
||||||
|
AmbientCapabilities = "CAP_SYS_RESOURCE";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
58
nixos/modules/config/ldso.nix
Normal file
58
nixos/modules/config/ldso.nix
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (lib) last splitString mkOption types mdDoc optionals;
|
||||||
|
|
||||||
|
libDir = pkgs.stdenv.hostPlatform.libDir;
|
||||||
|
ldsoBasename = builtins.unsafeDiscardStringContext (last (splitString "/" pkgs.stdenv.cc.bintools.dynamicLinker));
|
||||||
|
|
||||||
|
pkgs32 = pkgs.pkgsi686Linux;
|
||||||
|
libDir32 = pkgs32.stdenv.hostPlatform.libDir;
|
||||||
|
ldsoBasename32 = builtins.unsafeDiscardStringContext (last (splitString "/" pkgs32.stdenv.cc.bintools.dynamicLinker));
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
environment.ldso = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
description = mdDoc ''
|
||||||
|
The executable to link into the normal FHS location of the ELF loader.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.ldso32 = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
description = mdDoc ''
|
||||||
|
The executable to link into the normal FHS location of the 32-bit ELF loader.
|
||||||
|
|
||||||
|
This currently only works on x86_64 architectures.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
assertions = [
|
||||||
|
{ assertion = isNull config.environment.ldso32 || pkgs.stdenv.isx86_64;
|
||||||
|
message = "Option environment.ldso32 currently only works on x86_64.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = (
|
||||||
|
if isNull config.environment.ldso then [
|
||||||
|
"r /${libDir}/${ldsoBasename} - - - - -"
|
||||||
|
] else [
|
||||||
|
"d /${libDir} 0755 root root - -"
|
||||||
|
"L+ /${libDir}/${ldsoBasename} - - - - ${config.environment.ldso}"
|
||||||
|
]
|
||||||
|
) ++ optionals pkgs.stdenv.isx86_64 (
|
||||||
|
if isNull config.environment.ldso32 then [
|
||||||
|
"r /${libDir32}/${ldsoBasename32} - - - - -"
|
||||||
|
] else [
|
||||||
|
"d /${libDir32} 0755 root root - -"
|
||||||
|
"L+ /${libDir32}/${ldsoBasename32} - - - - ${config.environment.ldso32}"
|
||||||
|
]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
meta.maintainers = with lib.maintainers; [ tejing ];
|
||||||
|
}
|
|
@ -12,7 +12,6 @@ let
|
||||||
mkDefault
|
mkDefault
|
||||||
mkIf
|
mkIf
|
||||||
mkOption
|
mkOption
|
||||||
stringAfter
|
|
||||||
types
|
types
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -109,13 +109,17 @@ let
|
||||||
if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then ''
|
if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then ''
|
||||||
echo "Ignoring validation for cross-compilation"
|
echo "Ignoring validation for cross-compilation"
|
||||||
''
|
''
|
||||||
else ''
|
else
|
||||||
|
let
|
||||||
|
showCommand = if isNixAtLeast "2.20pre" then "config show" else "show-config";
|
||||||
|
in
|
||||||
|
''
|
||||||
echo "Validating generated nix.conf"
|
echo "Validating generated nix.conf"
|
||||||
ln -s $out ./nix.conf
|
ln -s $out ./nix.conf
|
||||||
set -e
|
set -e
|
||||||
set +o pipefail
|
set +o pipefail
|
||||||
NIX_CONF_DIR=$PWD \
|
NIX_CONF_DIR=$PWD \
|
||||||
${cfg.package}/bin/nix show-config ${optionalString (isNixAtLeast "2.3pre") "--no-net"} \
|
${cfg.package}/bin/nix ${showCommand} ${optionalString (isNixAtLeast "2.3pre") "--no-net"} \
|
||||||
${optionalString (isNixAtLeast "2.4pre") "--option experimental-features nix-command"} \
|
${optionalString (isNixAtLeast "2.4pre") "--option experimental-features nix-command"} \
|
||||||
|& sed -e 's/^warning:/error:/' \
|
|& sed -e 's/^warning:/error:/' \
|
||||||
| (! grep '${if cfg.checkAllErrors then "^error:" else "^error: unknown setting"}')
|
| (! grep '${if cfg.checkAllErrors then "^error:" else "^error: unknown setting"}')
|
||||||
|
|
|
@ -34,6 +34,7 @@ with lib;
|
||||||
ffmpeg_5 = super.ffmpeg_5.override { ffmpegVariant = "headless"; };
|
ffmpeg_5 = super.ffmpeg_5.override { ffmpegVariant = "headless"; };
|
||||||
# dep of graphviz, libXpm is optional for Xpm support
|
# dep of graphviz, libXpm is optional for Xpm support
|
||||||
gd = super.gd.override { withXorg = false; };
|
gd = super.gd.override { withXorg = false; };
|
||||||
|
ghostscript = super.ghostscript.override { cupsSupport = false; x11Support = false; };
|
||||||
gobject-introspection = super.gobject-introspection.override { x11Support = false; };
|
gobject-introspection = super.gobject-introspection.override { x11Support = false; };
|
||||||
gpsd = super.gpsd.override { guiSupport = false; };
|
gpsd = super.gpsd.override { guiSupport = false; };
|
||||||
graphviz = super.graphviz-nox;
|
graphviz = super.graphviz-nox;
|
||||||
|
@ -44,6 +45,7 @@ with lib;
|
||||||
};
|
};
|
||||||
imagemagick = super.imagemagick.override { libX11Support = false; libXtSupport = false; };
|
imagemagick = super.imagemagick.override { libX11Support = false; libXtSupport = false; };
|
||||||
imagemagickBig = super.imagemagickBig.override { libX11Support = false; libXtSupport = false; };
|
imagemagickBig = super.imagemagickBig.override { libX11Support = false; libXtSupport = false; };
|
||||||
|
intel-vaapi-driver = super.intel-vaapi-driver.override { enableGui = false; };
|
||||||
libdevil = super.libdevil-nox;
|
libdevil = super.libdevil-nox;
|
||||||
libextractor = super.libextractor.override { gtkSupport = false; };
|
libextractor = super.libextractor.override { gtkSupport = false; };
|
||||||
libva = super.libva-minimal;
|
libva = super.libva-minimal;
|
||||||
|
@ -51,6 +53,7 @@ with lib;
|
||||||
mc = super.mc.override { x11Support = false; };
|
mc = super.mc.override { x11Support = false; };
|
||||||
mpv-unwrapped = super.mpv-unwrapped.override { sdl2Support = false; x11Support = false; waylandSupport = false; };
|
mpv-unwrapped = super.mpv-unwrapped.override { sdl2Support = false; x11Support = false; waylandSupport = false; };
|
||||||
msmtp = super.msmtp.override { withKeyring = false; };
|
msmtp = super.msmtp.override { withKeyring = false; };
|
||||||
|
mupdf = super.mupdf.override { enableGL = false; enableX11 = false; };
|
||||||
neofetch = super.neofetch.override { x11Support = false; };
|
neofetch = super.neofetch.override { x11Support = false; };
|
||||||
networkmanager-fortisslvpn = super.networkmanager-fortisslvpn.override { withGnome = false; };
|
networkmanager-fortisslvpn = super.networkmanager-fortisslvpn.override { withGnome = false; };
|
||||||
networkmanager-iodine = super.networkmanager-iodine.override { withGnome = false; };
|
networkmanager-iodine = super.networkmanager-iodine.override { withGnome = false; };
|
||||||
|
@ -71,7 +74,7 @@ with lib;
|
||||||
qemu = super.qemu.override { gtkSupport = false; spiceSupport = false; sdlSupport = false; };
|
qemu = super.qemu.override { gtkSupport = false; spiceSupport = false; sdlSupport = false; };
|
||||||
qrencode = super.qrencode.overrideAttrs (_: { doCheck = false; });
|
qrencode = super.qrencode.overrideAttrs (_: { doCheck = false; });
|
||||||
qt5 = super.qt5.overrideScope (const (super': {
|
qt5 = super.qt5.overrideScope (const (super': {
|
||||||
qtbase = super'.qtbase.override { withGtk3 = false; };
|
qtbase = super'.qtbase.override { withGtk3 = false; withQttranslation = false; };
|
||||||
}));
|
}));
|
||||||
stoken = super.stoken.override { withGTK3 = false; };
|
stoken = super.stoken.override { withGTK3 = false; };
|
||||||
# translateManpages -> perlPackages.po4a -> texlive-combined-basic -> texlive-core-big -> libX11
|
# translateManpages -> perlPackages.po4a -> texlive-combined-basic -> texlive-core-big -> libX11
|
||||||
|
|
|
@ -8,8 +8,6 @@ let
|
||||||
cfg = config.hardware.pulseaudio;
|
cfg = config.hardware.pulseaudio;
|
||||||
alsaCfg = config.sound;
|
alsaCfg = config.sound;
|
||||||
|
|
||||||
systemWide = cfg.enable && cfg.systemWide;
|
|
||||||
nonSystemWide = cfg.enable && !cfg.systemWide;
|
|
||||||
hasZeroconf = let z = cfg.zeroconf; in z.publish.enable || z.discovery.enable;
|
hasZeroconf = let z = cfg.zeroconf; in z.publish.enable || z.discovery.enable;
|
||||||
|
|
||||||
overriddenPackage = cfg.package.override
|
overriddenPackage = cfg.package.override
|
||||||
|
@ -217,16 +215,10 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
config = mkMerge [
|
config = lib.mkIf cfg.enable (mkMerge [
|
||||||
{
|
{
|
||||||
environment.etc = {
|
environment.etc."pulse/client.conf".source = clientConf;
|
||||||
"pulse/client.conf".source = clientConf;
|
|
||||||
};
|
|
||||||
|
|
||||||
hardware.pulseaudio.configFile = mkDefault "${getBin overriddenPackage}/etc/pulse/default.pa";
|
|
||||||
}
|
|
||||||
|
|
||||||
(mkIf cfg.enable {
|
|
||||||
environment.systemPackages = [ overriddenPackage ];
|
environment.systemPackages = [ overriddenPackage ];
|
||||||
|
|
||||||
sound.enable = true;
|
sound.enable = true;
|
||||||
|
@ -242,6 +234,8 @@ in {
|
||||||
"libao.conf".source = writeText "libao.conf" "default_driver=pulse";
|
"libao.conf".source = writeText "libao.conf" "default_driver=pulse";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
hardware.pulseaudio.configFile = mkDefault "${getBin overriddenPackage}/etc/pulse/default.pa";
|
||||||
|
|
||||||
# Disable flat volumes to enable relative ones
|
# Disable flat volumes to enable relative ones
|
||||||
hardware.pulseaudio.daemon.config.flat-volumes = mkDefault "no";
|
hardware.pulseaudio.daemon.config.flat-volumes = mkDefault "no";
|
||||||
|
|
||||||
|
@ -255,7 +249,7 @@ in {
|
||||||
|
|
||||||
# PulseAudio is packaged with udev rules to handle various audio device quirks
|
# PulseAudio is packaged with udev rules to handle various audio device quirks
|
||||||
services.udev.packages = [ overriddenPackage ];
|
services.udev.packages = [ overriddenPackage ];
|
||||||
})
|
}
|
||||||
|
|
||||||
(mkIf (cfg.extraModules != []) {
|
(mkIf (cfg.extraModules != []) {
|
||||||
hardware.pulseaudio.daemon.config.dl-search-path = let
|
hardware.pulseaudio.daemon.config.dl-search-path = let
|
||||||
|
@ -277,7 +271,7 @@ in {
|
||||||
services.avahi.publish.userServices = true;
|
services.avahi.publish.userServices = true;
|
||||||
})
|
})
|
||||||
|
|
||||||
(mkIf nonSystemWide {
|
(mkIf (!cfg.systemWide) {
|
||||||
environment.etc = {
|
environment.etc = {
|
||||||
"pulse/default.pa".source = myConfigFile;
|
"pulse/default.pa".source = myConfigFile;
|
||||||
};
|
};
|
||||||
|
@ -297,7 +291,7 @@ in {
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
(mkIf systemWide {
|
(mkIf cfg.systemWide {
|
||||||
users.users.pulse = {
|
users.users.pulse = {
|
||||||
# For some reason, PulseAudio wants UID == GID.
|
# For some reason, PulseAudio wants UID == GID.
|
||||||
uid = assert uid == gid; uid;
|
uid = assert uid == gid; uid;
|
||||||
|
@ -328,6 +322,6 @@ in {
|
||||||
|
|
||||||
environment.variables.PULSE_COOKIE = "${stateDir}/.config/pulse/cookie";
|
environment.variables.PULSE_COOKIE = "${stateDir}/.config/pulse/cookie";
|
||||||
})
|
})
|
||||||
];
|
]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue