mirror of
https://github.com/CHN-beta/nixpkgs.git
synced 2026-01-12 19:00:19 +08:00
Compare commits
1 Commits
system
...
domenkozar
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c3575249a |
@@ -55,13 +55,10 @@ trim_trailing_whitespace = unset
|
||||
[*.lock]
|
||||
indent_size = unset
|
||||
|
||||
# Although Markdown/CommonMark allows using two trailing spaces to denote
|
||||
# a hard line break, we do not use that feature in nixpkgs since
|
||||
# it forces the surrounding paragraph to become a <literallayout> which
|
||||
# does not wrap reasonably.
|
||||
# Instead of a hard line break, start a new paragraph by inserting a blank line.
|
||||
# trailing whitespace is an actual syntax element of classic Markdown/
|
||||
# CommonMark to enforce a line break
|
||||
[*.md]
|
||||
trim_trailing_whitespace = true
|
||||
trim_trailing_whitespace = unset
|
||||
|
||||
# binaries
|
||||
[*.nib]
|
||||
|
||||
7
.github/CODEOWNERS
vendored
7
.github/CODEOWNERS
vendored
@@ -28,7 +28,6 @@
|
||||
/lib/cli.nix @edolstra @nbp @Profpatsch
|
||||
/lib/debug.nix @edolstra @nbp @Profpatsch
|
||||
/lib/asserts.nix @edolstra @nbp @Profpatsch
|
||||
/lib/path.* @infinisil @fricklerhandwerk
|
||||
|
||||
# Nixpkgs Internals
|
||||
/default.nix @nbp
|
||||
@@ -107,7 +106,7 @@
|
||||
/pkgs/top-level/python-packages.nix @FRidh @jonringer
|
||||
/pkgs/development/interpreters/python @FRidh
|
||||
/pkgs/development/python-modules @FRidh @jonringer
|
||||
/doc/languages-frameworks/python.section.md @FRidh @mweinelt
|
||||
/doc/languages-frameworks/python.section.md @FRidh
|
||||
/pkgs/development/tools/poetry2nix @adisbladis
|
||||
/pkgs/development/interpreters/python/hooks @FRidh @jonringer
|
||||
|
||||
@@ -134,9 +133,7 @@
|
||||
/pkgs/development/ruby-modules @marsam
|
||||
|
||||
# Rust
|
||||
/pkgs/development/compilers/rust @Mic92 @LnL7 @zowoq @winterqt @figsoda
|
||||
/pkgs/build-support/rust @zowoq @winterqt @figsoda
|
||||
/doc/languages-frameworks/rust.section.md @zowoq @winterqt @figsoda
|
||||
/pkgs/development/compilers/rust @Mic92 @LnL7 @zowoq
|
||||
|
||||
# C compilers
|
||||
/pkgs/development/compilers/gcc @matthewbauer
|
||||
|
||||
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -26,7 +26,6 @@ If applicable, add screenshots to help explain your problem.
|
||||
Add any other context about the problem here.
|
||||
|
||||
### Notify maintainers
|
||||
|
||||
<!--
|
||||
Please @ people who are in the `meta.maintainers` list of the offending package or module.
|
||||
If in doubt, check `git blame` for whoever last touched something.
|
||||
|
||||
7
.github/ISSUE_TEMPLATE/build_failure.md
vendored
7
.github/ISSUE_TEMPLATE/build_failure.md
vendored
@@ -1,36 +1,31 @@
|
||||
---
|
||||
name: Build failure
|
||||
about: Create a report to help us improve
|
||||
title: 'Build failure: PACKAGENAME'
|
||||
title: ''
|
||||
labels: '0.kind: build failure'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### Steps To Reproduce
|
||||
|
||||
Steps to reproduce the behavior:
|
||||
1. build *X*
|
||||
|
||||
### Build log
|
||||
|
||||
```
|
||||
log here if short otherwise a link to a gist
|
||||
```
|
||||
|
||||
### Additional context
|
||||
|
||||
Add any other context about the problem here.
|
||||
|
||||
### Notify maintainers
|
||||
|
||||
<!--
|
||||
Please @ people who are in the `meta.maintainers` list of the offending package or module.
|
||||
If in doubt, check `git blame` for whoever last touched something.
|
||||
-->
|
||||
|
||||
### Metadata
|
||||
|
||||
Please run `nix-shell -p nix-info --run "nix-info -m"` and paste the result.
|
||||
|
||||
```console
|
||||
|
||||
10
.github/ISSUE_TEMPLATE/missing_documentation.md
vendored
10
.github/ISSUE_TEMPLATE/missing_documentation.md
vendored
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: Missing or incorrect documentation
|
||||
about: Help us improve the Nixpkgs and NixOS reference manuals
|
||||
title: 'Documentation: '
|
||||
title: ''
|
||||
labels: '9.needs: documentation'
|
||||
assignees: ''
|
||||
|
||||
@@ -11,10 +11,6 @@ assignees: ''
|
||||
|
||||
<!-- describe your problem -->
|
||||
|
||||
## Proposal
|
||||
|
||||
<!-- propose a solution (optional) -->
|
||||
|
||||
## Checklist
|
||||
|
||||
<!-- make sure this issue is not redundant or obsolete -->
|
||||
@@ -30,3 +26,7 @@ assignees: ''
|
||||
[open documentation issues]: https://github.com/NixOS/nixpkgs/issues?q=is%3Aissue+is%3Aopen+label%3A%229.needs%3A+documentation%22
|
||||
[open documentation pull requests]: https://github.com/NixOS/nixpkgs/pulls?q=is%3Aopen+is%3Apr+label%3A%228.has%3A+documentation%22%2C%226.topic%3A+documentation%22
|
||||
|
||||
## Proposal
|
||||
|
||||
<!-- propose a solution -->
|
||||
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
---
|
||||
name: Out-of-date package reports
|
||||
about: For packages that are out-of-date
|
||||
title: 'Update request: PACKAGENAME OLDVERSION → NEWVERSION'
|
||||
title: ''
|
||||
labels: '9.needs: package (update)'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
- Package name:
|
||||
- Latest released version:
|
||||
<!-- Search your package here: https://search.nixos.org/packages?channel=unstable -->
|
||||
- Current version on the unstable channel:
|
||||
- Current version on the stable/release channel:
|
||||
|
||||
###### Checklist
|
||||
|
||||
<!-- Note that these are hard requirements -->
|
||||
|
||||
<!--
|
||||
You can use the "Go to file" functionality on GitHub to find the package
|
||||
Then you can go to the history for this package
|
||||
Find the latest "package_name: old_version -> new_version" commit
|
||||
The "new_version" is the current version of the package
|
||||
-->
|
||||
- [ ] Checked the [nixpkgs master branch](https://github.com/NixOS/nixpkgs)
|
||||
<!--
|
||||
Type the name of your package and try to find an open pull request for the package
|
||||
If you find an open pull request, you can review it!
|
||||
@@ -19,10 +26,23 @@ There's a high chance that you'll have the new version right away while helping
|
||||
-->
|
||||
- [ ] Checked the [nixpkgs pull requests](https://github.com/NixOS/nixpkgs/pulls)
|
||||
|
||||
**Notify maintainers**
|
||||
###### Project name
|
||||
`nix search` name:
|
||||
<!--
|
||||
The current version can be found easily with the same process as above for checking the master branch
|
||||
If an open PR is present for the package, take this version as the current one and link to the PR
|
||||
-->
|
||||
current version:
|
||||
desired version:
|
||||
|
||||
<!-- If the search.nixos.org result shows no maintainers, tag the person that last updated the package. -->
|
||||
###### Notify maintainers
|
||||
<!--
|
||||
Search your package here: https://search.nixos.org/packages?channel=unstable
|
||||
If no maintainer is listed for your package, tag the person that last updated the package
|
||||
-->
|
||||
|
||||
-----
|
||||
maintainers:
|
||||
|
||||
Note for maintainers: Please tag this issue in your PR.
|
||||
###### Note for maintainers
|
||||
|
||||
Please tag this issue in your PR.
|
||||
|
||||
5
.github/ISSUE_TEMPLATE/packaging_request.md
vendored
5
.github/ISSUE_TEMPLATE/packaging_request.md
vendored
@@ -1,15 +1,14 @@
|
||||
---
|
||||
name: Packaging requests
|
||||
about: For packages that are missing
|
||||
title: 'Package request: PACKAGENAME'
|
||||
title: ''
|
||||
labels: '0.kind: packaging request'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Project description**
|
||||
|
||||
<!-- Describe the project a little: -->
|
||||
_describe the project a little_
|
||||
|
||||
**Metadata**
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name: Unreproducible package
|
||||
about: A package that does not produce a bit-by-bit reproducible result each time it is built
|
||||
title: ''
|
||||
labels: [ '0.kind: enhancement', '6.topic: reproducible builds' ]
|
||||
labels: '0.kind: enhancement', '6.topic: reproducible builds'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -26,6 +26,7 @@ For new packages please briefly describe the package or provide a link to its ho
|
||||
- [ ] (Package updates) Added a release notes entry if the change is major or breaking
|
||||
- [ ] (Module updates) Added a release notes entry if the change is significant
|
||||
- [ ] (Module addition) Added a release notes entry if adding a new NixOS module
|
||||
- [ ] (Release notes changes) Ran `nixos/doc/manual/md-to-db.sh` to update generated release notes
|
||||
- [ ] Fits [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md).
|
||||
|
||||
<!--
|
||||
|
||||
18
.github/labeler.yml
vendored
18
.github/labeler.yml
vendored
@@ -19,11 +19,6 @@
|
||||
- pkgs/build-support/emacs/**/*
|
||||
- pkgs/top-level/emacs-packages.nix
|
||||
|
||||
"6.topic: Enlightenment DE":
|
||||
- nixos/modules/services/x11/desktop-managers/enlightenment.nix
|
||||
- pkgs/desktops/enlightenment/**/*
|
||||
- pkgs/development/python-modules/python-efl/*
|
||||
|
||||
"6.topic: erlang":
|
||||
- doc/languages-frameworks/beam.section.md
|
||||
- pkgs/development/beam-modules/**/*
|
||||
@@ -70,19 +65,6 @@
|
||||
- pkgs/development/lua-modules/**/*
|
||||
- pkgs/top-level/lua-packages.nix
|
||||
|
||||
"6.topic: Lumina DE":
|
||||
- nixos/modules/services/x11/desktop-managers/lumina.nix
|
||||
- pkgs/desktops/lumina/**/*
|
||||
|
||||
"6.topic: LXQt":
|
||||
- nixos/modules/services/x11/desktop-managers/lxqt.nix
|
||||
- pkgs/desktops/lxqt/**/*
|
||||
|
||||
"6.topic: mate":
|
||||
- nixos/modules/services/x11/desktop-managers/mate.nix
|
||||
- nixos/tests/mate.nix
|
||||
- pkgs/desktops/mate/**/*
|
||||
|
||||
"6.topic: nixos":
|
||||
- nixos/**/*
|
||||
- pkgs/os-specific/linux/nixos-rebuild/**/*
|
||||
|
||||
12
.github/workflows/backport.yml
vendored
12
.github/workflows/backport.yml
vendored
@@ -14,19 +14,23 @@ permissions:
|
||||
jobs:
|
||||
backport:
|
||||
permissions:
|
||||
contents: write # for korthout/backport-action to create branch
|
||||
pull-requests: write # for korthout/backport-action to create PR to backport
|
||||
contents: write # for zeebe-io/backport-action to create branch
|
||||
pull-requests: write # for zeebe-io/backport-action to create PR to backport
|
||||
name: Backport Pull Request
|
||||
if: github.repository_owner == 'NixOS' && github.event.pull_request.merged == true && (github.event_name != 'labeled' || startsWith('backport', github.event.label.name))
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
# required to find all branches
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Create backport PRs
|
||||
uses: korthout/backport-action@v1.1.0
|
||||
uses: zeebe-io/backport-action@v0.0.9
|
||||
with:
|
||||
# Config README: https://github.com/korthout/backport-action#backport-action
|
||||
# Config README: https://github.com/zeebe-io/backport-action#backport-action
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
github_workspace: ${{ github.workspace }}
|
||||
pull_description: |-
|
||||
Bot-based backport to `${target_branch}`, triggered by a label in #${pull_number}.
|
||||
|
||||
|
||||
2
.github/workflows/editorconfig.yml
vendored
2
.github/workflows/editorconfig.yml
vendored
@@ -11,7 +11,7 @@ on:
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
if: "github.repository_owner == 'NixOS' && !contains(github.event.pull_request.title, '[skip treewide]')"
|
||||
if: "github.repository_owner == 'NixOS' && !contains(github.event.pull_request.title, '[skip editorconfig]')"
|
||||
steps:
|
||||
- name: Get list of changed files from PR
|
||||
env:
|
||||
|
||||
2
.github/workflows/labels.yml
vendored
2
.github/workflows/labels.yml
vendored
@@ -16,7 +16,7 @@ permissions:
|
||||
jobs:
|
||||
labels:
|
||||
runs-on: ubuntu-latest
|
||||
if: "github.repository_owner == 'NixOS' && !contains(github.event.pull_request.title, '[skip treewide]')"
|
||||
if: github.repository_owner == 'NixOS'
|
||||
steps:
|
||||
- uses: actions/labeler@v4
|
||||
with:
|
||||
|
||||
34
.github/workflows/nixos-manual.yml
vendored
Normal file
34
.github/workflows/nixos-manual.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
name: NixOS manual checks
|
||||
|
||||
permissions: read-all
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
branches-ignore:
|
||||
- 'release-**'
|
||||
paths:
|
||||
- 'nixos/**/*.xml'
|
||||
- 'nixos/**/*.md'
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'NixOS'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
# pull_request_target checks out the base branch by default
|
||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
- uses: cachix/install-nix-action@v18
|
||||
- name: Check DocBook files generated from Markdown are consistent
|
||||
run: |
|
||||
nixos/doc/manual/md-to-db.sh
|
||||
git diff --exit-code || {
|
||||
echo
|
||||
echo 'Generated manual files are out of date.'
|
||||
echo 'Please run'
|
||||
echo
|
||||
echo ' nixos/doc/manual/md-to-db.sh'
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
4
.github/workflows/periodic-merge-24h.yml
vendored
4
.github/workflows/periodic-merge-24h.yml
vendored
@@ -38,6 +38,10 @@ jobs:
|
||||
into: staging-next-22.11
|
||||
- from: staging-next-22.11
|
||||
into: staging-22.11
|
||||
- from: release-22.05
|
||||
into: staging-next-22.05
|
||||
- from: staging-next-22.05
|
||||
into: staging-22.05
|
||||
name: ${{ matrix.pairs.from }} → ${{ matrix.pairs.into }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
@@ -11,8 +11,8 @@ permissions:
|
||||
jobs:
|
||||
tf-providers:
|
||||
permissions:
|
||||
contents: write # for peter-evans/create-pull-request to create branch
|
||||
pull-requests: write # for peter-evans/create-pull-request to create a PR, for peter-evans/create-or-update-comment to create or update comment
|
||||
contents: write # for peter-evans/create-pull-request to create branch
|
||||
pull-requests: write # for peter-evans/create-pull-request to create a PR, for peter-evans/create-or-update-comment to create or update comment
|
||||
if: github.repository_owner == 'NixOS' && github.ref == 'refs/heads/master' # ensure workflow_dispatch only runs on master
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -25,8 +25,6 @@ jobs:
|
||||
run: |
|
||||
echo "title=terraform-providers: update $(date -u +"%Y-%m-%d")" >> $GITHUB_OUTPUT
|
||||
- name: update terraform-providers
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git config user.name "github-actions[bot]"
|
||||
|
||||
@@ -38,14 +38,11 @@ Below is a short excerpt of some points in there:
|
||||
The old config generation system used impure shell scripts and could break in specific circumstances (see #1234).
|
||||
|
||||
* `meta.description` should:
|
||||
* Be short, just one sentence.
|
||||
* Be capitalized.
|
||||
* Not start with the package name.
|
||||
* More generally, it should not refer to the package name.
|
||||
* Not end with a period (or any punctuation for that matter).
|
||||
* Not have a period at the end.
|
||||
* `meta.license` must be set and fit the upstream license.
|
||||
* If there is no upstream license, `meta.license` should default to `lib.licenses.unfree`.
|
||||
* If in doubt, try to contact the upstream developers for clarification.
|
||||
* `meta.maintainers` must be set.
|
||||
|
||||
See the nixpkgs manual for more details on [standard meta-attributes](https://nixos.org/nixpkgs/manual/#sec-standard-meta-attributes).
|
||||
@@ -128,17 +125,14 @@ Anything that does not cause user or downstream dependency regressions can be ba
|
||||
- Security critical applications (E.g. `firefox`)
|
||||
|
||||
## Generating 23.05 Release Notes
|
||||
<!--
|
||||
note: title unchanged even though we don't need regeneration because extant
|
||||
PRs will link here. definitely change the title for 23.11 though.
|
||||
-->
|
||||
|
||||
Documentation in nixpkgs is transitioning to a markdown-centric workflow. In the past release notes required a translation step to convert from markdown to a compatible docbook document, but this is no longer necessary.
|
||||
Documentation in nixpkgs is transitioning to a markdown-centric workflow. Release notes now require a translation step to convert from markdown to a compatible docbook document.
|
||||
|
||||
Steps for updating 23.05 Release notes:
|
||||
|
||||
1. Edit `nixos/doc/manual/release-notes/rl-2305.section.md` with the desired changes
|
||||
2. Commit changes to `rl-2305.section.md`.
|
||||
2. Run `./nixos/doc/manual/md-to-db.sh` to render `nixos/doc/manual/from_md/release-notes/rl-2305.section.xml`
|
||||
3. Include changes to `rl-2305.section.md` and `rl-2305.section.xml` in the same commit.
|
||||
|
||||
## Reviewing contributions
|
||||
|
||||
|
||||
2
COPYING
2
COPYING
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2003-2023 Eelco Dolstra and the Nixpkgs/NixOS contributors
|
||||
Copyright (c) 2003-2022 Eelco Dolstra and the Nixpkgs/NixOS contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -3,7 +3,7 @@ MD_TARGETS=$(addsuffix .xml, $(basename $(shell find . -type f -regex '.*\.md$$'
|
||||
PANDOC ?= pandoc
|
||||
|
||||
pandoc_media_dir = media
|
||||
# NOTE: Keep in sync with conversion script (/maintainers/scripts/db-to-md.sh).
|
||||
# NOTE: Keep in sync with NixOS manual (/nixos/doc/manual/md-to-db.sh) and conversion script (/maintainers/scripts/db-to-md.sh).
|
||||
# TODO: Remove raw-attribute when we can get rid of DocBook altogether.
|
||||
pandoc_commonmark_enabled_extensions = +attributes+fenced_divs+footnotes+bracketed_spans+definition_lists+pipe_tables+raw_attribute
|
||||
# Not needed:
|
||||
@@ -11,7 +11,7 @@ pandoc_commonmark_enabled_extensions = +attributes+fenced_divs+footnotes+bracket
|
||||
pandoc_flags = --extract-media=$(pandoc_media_dir) \
|
||||
--lua-filter=$(PANDOC_LUA_FILTERS_DIR)/diagram-generator.lua \
|
||||
--lua-filter=build-aux/pandoc-filters/myst-reader/roles.lua \
|
||||
--lua-filter=$(PANDOC_LINK_MANPAGES_FILTER) \
|
||||
--lua-filter=build-aux/pandoc-filters/link-unix-man-references.lua \
|
||||
--lua-filter=build-aux/pandoc-filters/docbook-writer/rst-roles.lua \
|
||||
--lua-filter=build-aux/pandoc-filters/docbook-writer/labelless-link-is-xref.lua \
|
||||
-f commonmark$(pandoc_commonmark_enabled_extensions)+smart
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
--[[
|
||||
Converts some HTML elements commonly used in Markdown to corresponding DocBook elements.
|
||||
]]
|
||||
|
||||
function RawInline(elem)
|
||||
if elem.format == 'html' and elem.text == '<kbd>' then
|
||||
return pandoc.RawInline('docbook', '<keycap>')
|
||||
elseif elem.format == 'html' and elem.text == '</kbd>' then
|
||||
return pandoc.RawInline('docbook', '</keycap>')
|
||||
end
|
||||
end
|
||||
@@ -1,28 +0,0 @@
|
||||
{ pkgs ? import ../../.. {} }:
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
manpageURLs = builtins.fromJSON (builtins.readFile (pkgs.path + "/doc/manpage-urls.json"));
|
||||
in pkgs.writeText "link-manpages.lua" ''
|
||||
--[[
|
||||
Adds links to known man pages that aren't already in a link.
|
||||
]]
|
||||
|
||||
local manpage_urls = {
|
||||
${lib.concatStringsSep "\n" (lib.mapAttrsToList (man: url:
|
||||
" [${builtins.toJSON man}] = ${builtins.toJSON url},") manpageURLs)}
|
||||
}
|
||||
|
||||
traverse = 'topdown'
|
||||
|
||||
-- Returning false as the second value aborts processing of child elements.
|
||||
function Link(elem)
|
||||
return elem, false
|
||||
end
|
||||
|
||||
function Code(elem)
|
||||
local is_man_role = elem.classes:includes('interpreted-text') and elem.attributes['role'] == 'manpage'
|
||||
if is_man_role and manpage_urls[elem.text] ~= nil then
|
||||
return pandoc.Link(elem, manpage_urls[elem.text]), false
|
||||
end
|
||||
end
|
||||
''
|
||||
38
doc/build-aux/pandoc-filters/link-unix-man-references.lua
Normal file
38
doc/build-aux/pandoc-filters/link-unix-man-references.lua
Normal file
@@ -0,0 +1,38 @@
|
||||
--[[
|
||||
Turns a manpage reference into a link, when a mapping is defined below.
|
||||
]]
|
||||
|
||||
local man_urls = {
|
||||
["nix.conf(5)"] = "https://nixos.org/manual/nix/stable/#sec-conf-file",
|
||||
|
||||
["journald.conf(5)"] = "https://www.freedesktop.org/software/systemd/man/journald.conf.html",
|
||||
["logind.conf(5)"] = "https://www.freedesktop.org/software/systemd/man/logind.conf.html",
|
||||
["networkd.conf(5)"] = "https://www.freedesktop.org/software/systemd/man/networkd.conf.html",
|
||||
["systemd.automount(5)"] = "https://www.freedesktop.org/software/systemd/man/systemd.automount.html",
|
||||
["systemd.exec(5)"] = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html",
|
||||
["systemd.link(5)"] = "https://www.freedesktop.org/software/systemd/man/systemd.link.html",
|
||||
["systemd.mount(5)"] = "https://www.freedesktop.org/software/systemd/man/systemd.mount.html",
|
||||
["systemd.netdev(5)"] = "https://www.freedesktop.org/software/systemd/man/systemd.netdev.html",
|
||||
["systemd.network(5)"] = "https://www.freedesktop.org/software/systemd/man/systemd.network.html",
|
||||
["systemd.nspawn(5)"] = "https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html",
|
||||
["systemd.path(5)"] = "https://www.freedesktop.org/software/systemd/man/systemd.path.html",
|
||||
["systemd.resource-control(5)"] = "https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html",
|
||||
["systemd.scope(5)"] = "https://www.freedesktop.org/software/systemd/man/systemd.scope.html",
|
||||
["systemd.service(5)"] = "https://www.freedesktop.org/software/systemd/man/systemd.service.html",
|
||||
["systemd.slice(5)"] = "https://www.freedesktop.org/software/systemd/man/systemd.slice.html",
|
||||
["systemd.socket(5)"] = "https://www.freedesktop.org/software/systemd/man/systemd.socket.html",
|
||||
["systemd.timer(5)"] = "https://www.freedesktop.org/software/systemd/man/systemd.timer.html",
|
||||
["systemd.unit(5)"] = "https://www.freedesktop.org/software/systemd/man/systemd.unit.html",
|
||||
["timesyncd.conf(5)"] = "https://www.freedesktop.org/software/systemd/man/timesyncd.conf.html",
|
||||
["tmpfiles.d(5)"] = "https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html",
|
||||
["systemd.time(7)"] = "https://www.freedesktop.org/software/systemd/man/systemd.time.html",
|
||||
["systemd-fstab-generator(8)"] = "https://www.freedesktop.org/software/systemd/man/systemd-fstab-generator.html",
|
||||
["systemd-networkd-wait-online.service(8)"] = "https://www.freedesktop.org/software/systemd/man/systemd-networkd-wait-online.service.html",
|
||||
}
|
||||
|
||||
function Code(elem)
|
||||
local is_man_role = elem.classes:includes('interpreted-text') and elem.attributes['role'] == 'manpage'
|
||||
if is_man_role and man_urls[elem.text] ~= nil then
|
||||
return pandoc.Link(elem, man_urls[elem.text])
|
||||
end
|
||||
end
|
||||
@@ -17,16 +17,9 @@ function Inlines(inlines)
|
||||
if correct_tags then
|
||||
-- docutils supports alphanumeric strings separated by [-._:]
|
||||
-- We are slightly more liberal for simplicity.
|
||||
-- Allow preceding punctuation (eg '('), otherwise '({file}`...`)'
|
||||
-- does not match. Also allow anything followed by a non-breaking space
|
||||
-- since pandoc emits those after certain abbreviations (e.g. e.g.).
|
||||
local prefix, role = first.text:match('^(.*){([-._+:%w]+)}$')
|
||||
if role ~= nil and (prefix == '' or prefix:match("^.*[%p ]$") ~= nil) then
|
||||
if prefix == '' then
|
||||
inlines:remove(i)
|
||||
else
|
||||
first.text = prefix
|
||||
end
|
||||
local role = first.text:match('^{([-._+:%w]+)}$')
|
||||
if role ~= nil then
|
||||
inlines:remove(i)
|
||||
second.attributes['role'] = role
|
||||
second.classes:insert('interpreted-text')
|
||||
end
|
||||
|
||||
@@ -163,30 +163,3 @@ or "hg"), `domain` and `fetchSubmodules`.
|
||||
If `fetchSubmodules` is `true`, `fetchFromSourcehut` uses `fetchgit`
|
||||
or `fetchhg` with `fetchSubmodules` or `fetchSubrepos` set to `true`,
|
||||
respectively. Otherwise, the fetcher uses `fetchzip`.
|
||||
|
||||
## `requireFile` {#requirefile}
|
||||
|
||||
`requireFile` allows requesting files that cannot be fetched automatically, but whose content is known.
|
||||
This is a useful last-resort workaround for license restrictions that prohibit redistribution, or for downloads that are only accessible after authenticating interactively in a browser.
|
||||
If the requested file is present in the Nix store, the resulting derivation will not be built, because its expected output is already available.
|
||||
Otherwise, the builder will run, but fail with a message explaining to the user how to provide the file. The following code, for example:
|
||||
|
||||
```
|
||||
requireFile {
|
||||
name = "jdk-${version}_linux-x64_bin.tar.gz";
|
||||
url = "https://www.oracle.com/java/technologies/javase-jdk11-downloads.html";
|
||||
sha256 = "94bd34f85ee38d3ef59e5289ec7450b9443b924c55625661fffe66b03f2c8de2";
|
||||
}
|
||||
```
|
||||
results in this error message:
|
||||
```
|
||||
***
|
||||
Unfortunately, we cannot download file jdk-11.0.10_linux-x64_bin.tar.gz automatically.
|
||||
Please go to https://www.oracle.com/java/technologies/javase-jdk11-downloads.html to download it yourself, and add it to the Nix store
|
||||
using either
|
||||
nix-store --add-fixed sha256 jdk-11.0.10_linux-x64_bin.tar.gz
|
||||
or
|
||||
nix-prefetch-url --type sha256 file:///path/to/jdk-11.0.10_linux-x64_bin.tar.gz
|
||||
|
||||
***
|
||||
```
|
||||
|
||||
@@ -11,5 +11,4 @@
|
||||
<xi:include href="images/snaptools.section.xml" />
|
||||
<xi:include href="images/portableservice.section.xml" />
|
||||
<xi:include href="images/makediskimage.section.xml" />
|
||||
<xi:include href="images/binarycache.section.xml" />
|
||||
</chapter>
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
# 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.
|
||||
|
||||
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.
|
||||
|
||||
## Example
|
||||
|
||||
The following derivation will construct a flat-file binary cache containing the closure of `hello`.
|
||||
|
||||
```nix
|
||||
mkBinaryCache {
|
||||
rootPaths = [hello];
|
||||
}
|
||||
```
|
||||
|
||||
- `rootPaths` specifies a list of root derivations. The transitive closure of these derivations' outputs will be copied into the cache.
|
||||
|
||||
Here's an example of building and using the cache.
|
||||
|
||||
Build the cache on one machine, `host1`:
|
||||
|
||||
```shellSession
|
||||
nix-build -E 'with import <nixpkgs> {}; mkBinaryCache { rootPaths = [hello]; }'
|
||||
```
|
||||
|
||||
```shellSession
|
||||
/nix/store/cc0562q828rnjqjyfj23d5q162gb424g-binary-cache
|
||||
```
|
||||
|
||||
Copy the resulting directory to the other machine, `host2`:
|
||||
|
||||
```shellSession
|
||||
scp result host2:/tmp/hello-cache
|
||||
```
|
||||
|
||||
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 trusted-substituters file:///tmp/hello-cache \
|
||||
--option substituters file:///tmp/hello-cache
|
||||
```
|
||||
|
||||
```shellSession
|
||||
/nix/store/gl5a41azbpsadfkfmbilh9yk40dh5dl0-hello-2.12.1
|
||||
```
|
||||
@@ -145,7 +145,7 @@ Create a Docker image with many of the store paths being on their own layer to i
|
||||
|
||||
`architecture` is _optional_ and used to specify the image architecture, this is useful for multi-architecture builds that don't need cross compiling. If not specified it will default to `hostPlatform`.
|
||||
|
||||
: Run-time configuration of the container. A full list of the options available is in the [Docker Image Specification v1.2.0](https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions).
|
||||
: Run-time configuration of the container. A full list of the options are available at in the [Docker Image Specification v1.2.0](https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions).
|
||||
|
||||
*Default:* `{}`
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Features are separated in various sections depending on if you opt for a Nix-sto
|
||||
### Common
|
||||
|
||||
- arbitrary NixOS configuration
|
||||
- automatic or bound disk size: `diskSize` parameter, `additionalSpace` can be set when `diskSize` is `auto` to add a constant of disk space
|
||||
- automatic or bound disk size: `diskSize` parameter, `additionalSpace` can be set when `diskSize` is `auto` to add a constant of disk space
|
||||
- multiple partition table layouts: EFI, legacy, legacy + GPT, hybrid, none through `partitionTableType` parameter
|
||||
- OVMF or EFI firmwares and variables templates can be customized
|
||||
- root filesystem `fsType` can be customized to whatever `mkfs.${fsType}` exist during operations
|
||||
|
||||
@@ -4,7 +4,7 @@ The [Citrix Workspace App](https://www.citrix.com/products/workspace-app/) is a
|
||||
|
||||
## Basic usage {#sec-citrix-base}
|
||||
|
||||
The tarball archive needs to be downloaded manually, as the license agreements of the vendor for [Citrix Workspace](https://www.citrix.com/downloads/workspace-app/linux/workspace-app-for-linux-latest.html) needs to be accepted first. Then run `nix-prefetch-url file://$PWD/linuxx64-$version.tar.gz`. With the archive available in the store, the package can be built and installed with Nix.
|
||||
The tarball archive needs to be downloaded manually, as the license agreements of the vendor for [Citrix Workspace](https://www.citrix.de/downloads/workspace-app/linux/workspace-app-for-linux-latest.html) needs to be accepted first. Then run `nix-prefetch-url file://$PWD/linuxx64-$version.tar.gz`. With the archive available in the store, the package can be built and installed with Nix.
|
||||
|
||||
## Citrix Self-service {#sec-citrix-selfservice}
|
||||
|
||||
@@ -19,7 +19,7 @@ $ selfservice
|
||||
|
||||
## Custom certificates {#sec-citrix-custom-certs}
|
||||
|
||||
The `Citrix Workspace App` in `nixpkgs` trusts several certificates [from the Mozilla database](https://curl.haxx.se/docs/caextract.html) by default. However, several companies using Citrix might require their own corporate certificate. On distros with imperative packaging, these certs can be stored easily in [`$ICAROOT`](https://citrix.github.io/receiver-for-linux-command-reference/), however this directory is a store path in `nixpkgs`. In order to work around this issue, the package provides a simple mechanism to add custom certificates without rebuilding the entire package using `symlinkJoin`:
|
||||
The `Citrix Workspace App` in `nixpkgs` trusts several certificates [from the Mozilla database](https://curl.haxx.se/docs/caextract.html) by default. However, several companies using Citrix might require their own corporate certificate. On distros with imperative packaging, these certs can be stored easily in [`$ICAROOT`](https://developer-docs.citrix.com/projects/receiver-for-linux-command-reference/en/13.7/), however this directory is a store path in `nixpkgs`. In order to work around this issue, the package provides a simple mechanism to add custom certificates without rebuilding the entire package using `symlinkJoin`:
|
||||
|
||||
```nix
|
||||
with import <nixpkgs> { config.allowUnfree = true; };
|
||||
|
||||
@@ -4,7 +4,7 @@ This package is an ibus-based completion method to speed up typing.
|
||||
|
||||
## Activating the engine {#sec-ibus-typing-booster-activate}
|
||||
|
||||
IBus needs to be configured accordingly to activate `typing-booster`. The configuration depends on the desktop manager in use. For detailed instructions, please refer to the [upstream docs](https://mike-fabian.github.io/ibus-typing-booster/).
|
||||
IBus needs to be configured accordingly to activate `typing-booster`. The configuration depends on the desktop manager in use. For detailed instructions, please refer to the [upstream docs](https://mike-fabian.github.io/ibus-typing-booster/documentation.html).
|
||||
|
||||
On NixOS, you need to explicitly enable `ibus` with given engines before customizing your desktop to use `typing-booster`. This can be achieved using the `ibus` module:
|
||||
|
||||
|
||||
@@ -28,21 +28,18 @@ Password:
|
||||
```
|
||||
|
||||
… so that it can install a private key used to `ssh` into the build server.
|
||||
After that the script will launch the virtual machine and automatically log you
|
||||
in as the `builder` user:
|
||||
After that the script will launch the virtual machine:
|
||||
|
||||
```
|
||||
<<< Welcome to NixOS 22.11.20220901.1bd8d11 (aarch64) - ttyAMA0 >>>
|
||||
|
||||
Run 'nixos-help' for the NixOS manual.
|
||||
|
||||
nixos login: builder (automatic login)
|
||||
|
||||
|
||||
[builder@nixos:~]$
|
||||
nixos login:
|
||||
```
|
||||
|
||||
> Note: When you need to stop the VM, run `shutdown now` as the `builder` user.
|
||||
> Note: When you need to stop the VM, type `Ctrl`-`a` + `c` to open the `qemu`
|
||||
> prompt and then type `quit` followed by `Enter`
|
||||
|
||||
To delegate builds to the remote builder, add the following options to your
|
||||
`nix.conf` file:
|
||||
@@ -50,7 +47,7 @@ To delegate builds to the remote builder, add the following options to your
|
||||
```
|
||||
# - Replace ${ARCH} with either aarch64 or x86_64 to match your host machine
|
||||
# - Replace ${MAX_JOBS} with the maximum number of builds (pick 4 if you're not sure)
|
||||
builders = ssh-ng://builder@localhost ${ARCH}-linux /etc/nix/builder_ed25519 ${MAX_JOBS} - - - c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUpCV2N4Yi9CbGFxdDFhdU90RStGOFFVV3JVb3RpQzVxQkorVXVFV2RWQ2Igcm9vdEBuaXhvcwo=
|
||||
builders = ssh-ng://builder@localhost ${ARCH}-linux /etc/nix/builder_ed25519 ${MAX_JOBS} - - - c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUpCV2N4Yi9CbGFxdDFhdU90RStGOFFVV3JVb3RpQzVxQkorVXVFV2RWQ2Igcm9vdEBuaXhvcwo='
|
||||
|
||||
# Not strictly necessary, but this will reduce your disk utilization
|
||||
builders-use-substitutes = true
|
||||
|
||||
@@ -1,19 +1,6 @@
|
||||
# Testers {#chap-testers}
|
||||
This chapter describes several testing builders which are available in the <literal>testers</literal> namespace.
|
||||
|
||||
## `hasPkgConfigModule` {#tester-hasPkgConfigModule}
|
||||
|
||||
Checks whether a package exposes a certain `pkg-config` module.
|
||||
|
||||
Example:
|
||||
|
||||
```nix
|
||||
passthru.tests.pkg-config = testers.hasPkgConfigModule {
|
||||
package = finalAttrs.finalPackage;
|
||||
moduleName = "libfoo";
|
||||
}
|
||||
```
|
||||
|
||||
## `testVersion` {#tester-testVersion}
|
||||
|
||||
Checks the command output contains the specified version
|
||||
@@ -75,7 +62,7 @@ runCommand "example" {
|
||||
'';
|
||||
```
|
||||
|
||||
While `testBuildFailure` is designed to keep changes to the original builder's
|
||||
While `testBuildFailure` is designed to keep changes to the original builder's
|
||||
environment to a minimum, some small changes are inevitable.
|
||||
|
||||
- The file `$TMPDIR/testBuildFailure.log` is present. It should not be deleted.
|
||||
|
||||
@@ -204,13 +204,13 @@ The key words _must_, _must not_, _required_, _shall_, _shall not_, _should_, _s
|
||||
|
||||
In Nixpkgs, there are generally three different names associated with a package:
|
||||
|
||||
- The `pname` attribute of the derivation. This is what most users see, in particular when using `nix-env`.
|
||||
- The `name` attribute of the derivation (excluding the version part). This is what most users see, in particular when using `nix-env`.
|
||||
|
||||
- The variable name used for the instantiated package in `all-packages.nix`, and when passing it as a dependency to other functions. Typically this is called the _package attribute name_. This is what Nix expression authors see. It can also be used when installing using `nix-env -iA`.
|
||||
|
||||
- The filename for (the directory containing) the Nix expression.
|
||||
|
||||
Most of the time, these are the same. For instance, the package `e2fsprogs` has a `pname` attribute `"e2fsprogs"`, is bound to the variable name `e2fsprogs` in `all-packages.nix`, and the Nix expression is in `pkgs/os-specific/linux/e2fsprogs/default.nix`.
|
||||
Most of the time, these are the same. For instance, the package `e2fsprogs` has a `name` attribute `"e2fsprogs-version"`, is bound to the variable name `e2fsprogs` in `all-packages.nix`, and the Nix expression is in `pkgs/os-specific/linux/e2fsprogs/default.nix`.
|
||||
|
||||
There are a few naming guidelines:
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ If the build succeeds, the manual will be in `./result/share/doc/nixpkgs/manual.
|
||||
|
||||
As per [RFC 0072](https://github.com/NixOS/rfcs/pull/72), all new documentation content should be written in [CommonMark](https://commonmark.org/) Markdown dialect.
|
||||
|
||||
Additional syntax extensions are available, all of which can be used in NixOS option documentation. The following extensions are currently used:
|
||||
Additional syntax extensions are available, though not all extensions can be used in NixOS option documentation. The following extensions are currently used:
|
||||
|
||||
- []{#ssec-contributing-markup-anchors}
|
||||
Explicitly defined **anchors** on headings, to allow linking to sections. These should be always used, to ensure the anchors can be linked even when the heading text changes, and to prevent conflicts between [automatically assigned identifiers](https://github.com/jgm/commonmark-hs/blob/master/commonmark-extensions/test/auto_identifiers.md).
|
||||
@@ -38,10 +38,6 @@ Additional syntax extensions are available, all of which can be used in NixOS op
|
||||
## Syntax {#sec-contributing-markup}
|
||||
```
|
||||
|
||||
::: {.note}
|
||||
NixOS option documentation does not support headings in general.
|
||||
:::
|
||||
|
||||
- []{#ssec-contributing-markup-anchors-inline}
|
||||
**Inline anchors**, which allow linking arbitrary place in the text (e.g. individual list items, sentences…).
|
||||
|
||||
@@ -57,7 +53,7 @@ Additional syntax extensions are available, all of which can be used in NixOS op
|
||||
This syntax is taken from [MyST](https://myst-parser.readthedocs.io/en/latest/using/syntax.html#targets-and-cross-referencing).
|
||||
|
||||
- []{#ssec-contributing-markup-inline-roles}
|
||||
If you want to link to a man page, you can use `` {manpage}`nix.conf(5)` ``, which will turn into {manpage}`nix.conf(5)`. The references will turn into links when a mapping exists in {file}`doc/manpage-urls.json`.
|
||||
If you want to link to a man page, you can use `` {manpage}`nix.conf(5)` ``, which will turn into {manpage}`nix.conf(5)`. The references will turn into links when a mapping exists in {file}`doc/build-aux/pandoc-filters/link-unix-man-references.lua`.
|
||||
|
||||
A few markups for other kinds of literals are also available:
|
||||
|
||||
@@ -71,6 +67,10 @@ Additional syntax extensions are available, all of which can be used in NixOS op
|
||||
|
||||
This syntax is taken from [MyST](https://myst-parser.readthedocs.io/en/latest/syntax/syntax.html#roles-an-in-line-extension-point). Though, the feature originates from [reStructuredText](https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html#role-manpage) with slightly different syntax.
|
||||
|
||||
::: {.note}
|
||||
Inline roles are available for option documentation.
|
||||
:::
|
||||
|
||||
- []{#ssec-contributing-markup-admonitions}
|
||||
**Admonitions**, set off from the text to bring attention to something.
|
||||
|
||||
@@ -96,6 +96,10 @@ Additional syntax extensions are available, all of which can be used in NixOS op
|
||||
- [`tip`](https://tdg.docbook.org/tdg/5.0/tip.html)
|
||||
- [`warning`](https://tdg.docbook.org/tdg/5.0/warning.html)
|
||||
|
||||
::: {.note}
|
||||
Admonitions are available for option documentation.
|
||||
:::
|
||||
|
||||
- []{#ssec-contributing-markup-definition-lists}
|
||||
[**Definition lists**](https://github.com/jgm/commonmark-hs/blob/master/commonmark-extensions/test/definition_lists.md), for defining a group of terms:
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ To add a package to Nixpkgs:
|
||||
|
||||
- Apache HTTPD: [`pkgs/servers/http/apache-httpd/2.4.nix`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/http/apache-httpd/2.4.nix). A bunch of optional features, variable substitutions in the configure flags, a post-install hook, and miscellaneous hackery.
|
||||
|
||||
- buildMozillaMach: [`pkgs/applications/networking/browser/firefox/common.nix`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/networking/browsers/firefox/common.nix). A reusable build function for Firefox, Thunderbird and Librewolf.
|
||||
- Thunderbird: [`pkgs/applications/networking/mailreaders/thunderbird/default.nix`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/networking/mailreaders/thunderbird/default.nix). Lots of dependencies.
|
||||
|
||||
- JDiskReport, a Java utility: [`pkgs/tools/misc/jdiskreport/default.nix`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/misc/jdiskreport/default.nix). Nixpkgs doesn’t have a decent `stdenv` for Java yet so this is pretty ad-hoc.
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{ pkgs ? (import ./.. { }), nixpkgs ? { }}:
|
||||
let
|
||||
lib = pkgs.lib;
|
||||
doc-support = import ./doc-support { inherit pkgs nixpkgs; };
|
||||
in pkgs.stdenv.mkDerivation {
|
||||
name = "nixpkgs-manual";
|
||||
@@ -14,7 +15,7 @@ in pkgs.stdenv.mkDerivation {
|
||||
xmlformat
|
||||
];
|
||||
|
||||
src = pkgs.nix-gitignore.gitignoreSource [] ./.;
|
||||
src = lib.cleanSource ./.;
|
||||
|
||||
postPatch = ''
|
||||
ln -s ${doc-support} ./doc-support/result
|
||||
@@ -35,5 +36,4 @@ in pkgs.stdenv.mkDerivation {
|
||||
|
||||
# Environment variables
|
||||
PANDOC_LUA_FILTERS_DIR = "${pkgs.pandoc-lua-filters}/share/pandoc/filters";
|
||||
PANDOC_LINK_MANPAGES_FILTER = import build-aux/pandoc-filters/link-manpages.nix { inherit pkgs; };
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ let
|
||||
{ name = "lists"; description = "list manipulation functions"; }
|
||||
{ name = "debug"; description = "debugging functions"; }
|
||||
{ name = "options"; description = "NixOS / nixpkgs option handling"; }
|
||||
{ name = "path"; description = "path functions"; }
|
||||
{ name = "filesystem"; description = "filesystem functions"; }
|
||||
{ name = "sources"; description = "source filtering functions"; }
|
||||
{ name = "cli"; description = "command-line serialization functions"; }
|
||||
|
||||
@@ -10,11 +10,7 @@ with pkgs; stdenv.mkDerivation {
|
||||
installPhase = ''
|
||||
function docgen {
|
||||
# TODO: wrap lib.$1 in <literal>, make nixdoc not escape it
|
||||
if [[ -e "../lib/$1.nix" ]]; then
|
||||
nixdoc -c "$1" -d "lib.$1: $2" -f "$1.nix" > "$out/$1.xml"
|
||||
else
|
||||
nixdoc -c "$1" -d "lib.$1: $2" -f "$1/default.nix" > "$out/$1.xml"
|
||||
fi
|
||||
nixdoc -c "$1" -d "lib.$1: $2" -f "$1.nix" > "$out/$1.xml"
|
||||
echo "<xi:include href='$1.xml' />" >> "$out/index.xml"
|
||||
}
|
||||
|
||||
|
||||
@@ -2,21 +2,19 @@
|
||||
let
|
||||
revision = pkgs.lib.trivial.revisionWithDefault (nixpkgs.revision or "master");
|
||||
|
||||
libDefPos = prefix: set:
|
||||
builtins.concatMap
|
||||
(name: [{
|
||||
name = builtins.concatStringsSep "." (prefix ++ [name]);
|
||||
libDefPos = set:
|
||||
builtins.map
|
||||
(name: {
|
||||
name = name;
|
||||
location = builtins.unsafeGetAttrPos name set;
|
||||
}] ++ nixpkgsLib.optionals
|
||||
(builtins.length prefix == 0 && builtins.isAttrs set.${name})
|
||||
(libDefPos (prefix ++ [name]) set.${name})
|
||||
) (builtins.attrNames set);
|
||||
})
|
||||
(builtins.attrNames set);
|
||||
|
||||
libset = toplib:
|
||||
builtins.map
|
||||
(subsetname: {
|
||||
subsetname = subsetname;
|
||||
functions = libDefPos [] toplib.${subsetname};
|
||||
functions = libDefPos toplib.${subsetname};
|
||||
})
|
||||
(builtins.map (x: x.name) libsets);
|
||||
|
||||
|
||||
@@ -10,7 +10,9 @@ nativeBuildInputs = [ breakpointHook ];
|
||||
When a build failure happens there will be an instruction printed that shows how to attach with `cntr` to the build sandbox.
|
||||
|
||||
::: {.note}
|
||||
::: {.title}
|
||||
Caution with remote builds
|
||||
:::
|
||||
|
||||
This won’t work with remote builds as the build environment is on a different machine and can’t be accessed by `cntr`. Remote builds can be turned off by setting `--option builders ''` for `nix-build` or `--builders ''` for `nix build`.
|
||||
:::
|
||||
|
||||
@@ -9,7 +9,7 @@ stdenv.mkDerivation {
|
||||
|
||||
# ...
|
||||
|
||||
nativeCheckInputs = [
|
||||
checkInputs = [
|
||||
postgresql
|
||||
postgresqlTestHook
|
||||
];
|
||||
@@ -46,12 +46,6 @@ Bash-only variables:
|
||||
- `postgresqlEnableTCP`: set to `1` to enable TCP listening. Flaky; not recommended.
|
||||
- `postgresqlStartCommands`: defaults to `pg_ctl start`.
|
||||
|
||||
## Hooks {#sec-postgresqlTestHook-hooks}
|
||||
|
||||
A number of additional hooks are ran in postgresqlTestHook
|
||||
|
||||
- `postgresqlTestSetupPost`: ran after postgresql has been set up.
|
||||
|
||||
## TCP and the Nix sandbox {#sec-postgresqlTestHook-tcp}
|
||||
|
||||
`postgresqlEnableTCP` relies on network sandboxing, which is not available on macOS and some custom Nix installations, resulting in flaky tests.
|
||||
|
||||
@@ -13,7 +13,6 @@ with import <nixpkgs> {};
|
||||
|
||||
let
|
||||
androidComposition = androidenv.composeAndroidPackages {
|
||||
cmdLineToolsVersion = "8.0";
|
||||
toolsVersion = "26.1.1";
|
||||
platformToolsVersion = "30.0.5";
|
||||
buildToolsVersions = [ "30.0.3" ];
|
||||
@@ -43,10 +42,7 @@ exceptions are the tools, platform-tools and build-tools sub packages.
|
||||
|
||||
The following parameters are supported:
|
||||
|
||||
* `cmdLineToolsVersion `, specifies the version of the `cmdline-tools` package to use
|
||||
* `toolsVersion`, specifies the version of the `tools` package. Notice `tools` is
|
||||
obsolete, and currently only `26.1.1` is available, so there's not a lot of
|
||||
options here, however, you can set it as `null` if you don't want it.
|
||||
* `toolsVersion`, specifies the version of the tools package to use
|
||||
* `platformsToolsVersion` specifies the version of the `platform-tools` plugin
|
||||
* `buildToolsVersions` specifies the versions of the `build-tools` plugins to
|
||||
use.
|
||||
|
||||
@@ -128,7 +128,7 @@ You will need to run the build process once to fix the hash to correspond to you
|
||||
|
||||
###### FOD {#fixed-output-derivation}
|
||||
|
||||
A fixed output derivation will download mix dependencies from the internet. To ensure reproducibility, a hash will be supplied. Note that mix is relatively reproducible. An FOD generating a different hash on each run hasn't been observed (as opposed to npm where the chances are relatively high). See [elixir_ls](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/beam-modules/elixir-ls/default.nix) for a usage example of FOD.
|
||||
A fixed output derivation will download mix dependencies from the internet. To ensure reproducibility, a hash will be supplied. Note that mix is relatively reproducible. An FOD generating a different hash on each run hasn't been observed (as opposed to npm where the chances are relatively high). See [elixir_ls](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/beam-modules/elixir_ls.nix) for a usage example of FOD.
|
||||
|
||||
Practical steps
|
||||
|
||||
|
||||
@@ -28,13 +28,13 @@ mkShell {
|
||||
packages = [
|
||||
(with dotnetCorePackages; combinePackages [
|
||||
sdk_3_1
|
||||
sdk_6_0
|
||||
sdk_5_0
|
||||
])
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
This will produce a dotnet installation that has the dotnet 3.1 6.0 sdk. The first sdk listed will have it's cli utility present in the resulting environment. Example info output:
|
||||
This will produce a dotnet installation that has the dotnet 3.1, 3.0, and 2.1 sdk. The first sdk listed will have it's cli utility present in the resulting environment. Example info output:
|
||||
|
||||
```ShellSession
|
||||
$ dotnet --info
|
||||
@@ -120,7 +120,7 @@ in buildDotnetModule rec {
|
||||
projectReferences = [ referencedProject ]; # `referencedProject` must contain `nupkg` in the folder structure.
|
||||
|
||||
dotnet-sdk = dotnetCorePackages.sdk_3_1;
|
||||
dotnet-runtime = dotnetCorePackages.net_6_0;
|
||||
dotnet-runtime = dotnetCorePackages.net_5_0;
|
||||
|
||||
executables = [ "foo" ]; # This wraps "$out/lib/$pname/foo" to `$out/bin/foo`.
|
||||
executables = []; # Don't install any executables.
|
||||
|
||||
@@ -34,7 +34,7 @@ To allow software to use various virtual file systems, `gvfs` package can be als
|
||||
|
||||
### GdkPixbuf loaders {#ssec-gnome-gdk-pixbuf-loaders}
|
||||
|
||||
GTK applications typically use [GdkPixbuf](https://gitlab.gnome.org/GNOME/gdk-pixbuf/) to load images. But `gdk-pixbuf` package only supports basic bitmap formats like JPEG, PNG or TIFF, requiring to use third-party loader modules for other formats. This is especially painful since GTK itself includes SVG icons, which cannot be rendered without a loader provided by `librsvg`.
|
||||
GTK applications typically use [GdkPixbuf](https://developer.gnome.org/gdk-pixbuf/stable/) to load images. But `gdk-pixbuf` package only supports basic bitmap formats like JPEG, PNG or TIFF, requiring to use third-party loader modules for other formats. This is especially painful since GTK itself includes SVG icons, which cannot be rendered without a loader provided by `librsvg`.
|
||||
|
||||
Unlike other libraries mentioned in this section, GdkPixbuf only supports a single value in its controlling environment variable `GDK_PIXBUF_MODULE_FILE`. It is supposed to point to a cache file containing information about the available loaders. Each loader package will contain a `lib/gdk-pixbuf-2.0/2.10.0/loaders.cache` file describing the default loaders in `gdk-pixbuf` package plus the loader contained in the package itself. If you want to use multiple third-party loaders, you will need to create your own cache file manually. Fortunately, this is pretty rare as [not many loaders exist](https://gitlab.gnome.org/federico/gdk-pixbuf-survey/blob/master/src/modules.md).
|
||||
|
||||
@@ -70,7 +70,7 @@ Also make sure that `icon-theme.cache` is installed for each theme provided by t
|
||||
|
||||
### GTK Themes {#ssec-gnome-themes}
|
||||
|
||||
Previously, a GTK theme needed to be in `XDG_DATA_DIRS`. This is no longer necessary for most programs since GTK incorporated Adwaita theme. Some programs (for example, those designed for [elementary HIG](https://docs.elementary.io/hig)) might require a special theme like `pantheon.elementary-gtk-theme`.
|
||||
Previously, a GTK theme needed to be in `XDG_DATA_DIRS`. This is no longer necessary for most programs since GTK incorporated Adwaita theme. Some programs (for example, those designed for [elementary HIG](https://elementary.io/docs/human-interface-guidelines#human-interface-guidelines)) might require a special theme like `pantheon.elementary-gtk-theme`.
|
||||
|
||||
### GObject introspection typelibs {#ssec-gnome-typelibs}
|
||||
|
||||
|
||||
@@ -16,8 +16,7 @@ In the following is an example expression using `buildGoModule`, the following a
|
||||
`vendorHash` can also be set to `null`.
|
||||
In that case, rather than fetching the dependencies and vendoring them, the dependencies vendored in the source repo will be used.
|
||||
|
||||
To avoid updating this field when dependencies change, run `go mod vendor` in your source repo and set `vendorHash = null;`
|
||||
|
||||
To avoid updating this field when dependencies change, run `go mod vendor` in your source repo and set `vendorHash = null;`
|
||||
To obtain the actual hash, set `vendorHash = lib.fakeSha256;` and run the build ([more details here](#sec-source-hashes)).
|
||||
- `proxyVendor`: Fetches (go mod download) and proxies the vendor directory. This is useful if your code depends on c code and go mod tidy does not include the needed sources to build or if any dependency has case-insensitive conflicts which will produce platform dependant `vendorHash` checksums.
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -32,13 +32,11 @@
|
||||
<xi:include href="octave.section.xml" />
|
||||
<xi:include href="perl.section.xml" />
|
||||
<xi:include href="php.section.xml" />
|
||||
<xi:include href="pkg-config.section.xml" />
|
||||
<xi:include href="python.section.xml" />
|
||||
<xi:include href="qt.section.xml" />
|
||||
<xi:include href="r.section.xml" />
|
||||
<xi:include href="ruby.section.xml" />
|
||||
<xi:include href="rust.section.xml" />
|
||||
<xi:include href="swift.section.xml" />
|
||||
<xi:include href="texlive.section.xml" />
|
||||
<xi:include href="titanium.section.xml" />
|
||||
<xi:include href="vim.section.xml" />
|
||||
|
||||
@@ -175,10 +175,9 @@ buildNpmPackage rec {
|
||||
hash = "sha256-BR+ZGkBBfd0dSQqAvujsbgsEPFYw/ThrylxUbOksYxM=";
|
||||
};
|
||||
|
||||
npmDepsHash = "sha256-tuEfyePwlOy2/mOPdXbqJskO6IowvAP4DWg8xSZwbJw=";
|
||||
patches = [ ./remove-prepack-script.patch ];
|
||||
|
||||
# The prepack script runs the build script, which we'd rather do in the build phase.
|
||||
npmPackFlags = [ "--ignore-scripts" ];
|
||||
npmDepsHash = "sha256-tuEfyePwlOy2/mOPdXbqJskO6IowvAP4DWg8xSZwbJw=";
|
||||
|
||||
NODE_OPTIONS = "--openssl-legacy-provider";
|
||||
|
||||
|
||||
@@ -129,8 +129,3 @@ packaged libraries may still use the old spelling: maintainers are invited to
|
||||
fix this when updating packages. Massive renaming is strongly discouraged as it
|
||||
would be challenging to review, difficult to test, and will cause unnecessary
|
||||
rebuild.
|
||||
|
||||
The build will automatically fail if two distinct versions of the same library
|
||||
are added to `buildInputs` (which usually happens transitively because of
|
||||
`propagatedBuildInputs`). Set `dontDetectOcamlConflicts` to true to disable this
|
||||
behavior.
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
# pkg-config {#sec-pkg-config}
|
||||
|
||||
*pkg-config* is a unified interface for declaring and querying built C/C++ libraries.
|
||||
|
||||
Nixpkgs provides a couple of facilities for working with this tool.
|
||||
|
||||
## Writing packages providing pkg-config modules
|
||||
|
||||
Packages should set `meta.pkgConfigProvides` with the list of package config modules they provide.
|
||||
They should also use `testers.testMetaPkgConfig` to check that the final built package matches that list.
|
||||
Additionally, the [`validatePkgConfig` setup hook](https://nixos.org/manual/nixpkgs/stable/#validatepkgconfig), will do extra checks on to-be-installed pkg-config modules.
|
||||
|
||||
A good example of all these things is zlib:
|
||||
|
||||
```
|
||||
{ pkg-config, testers, ... }:
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
...
|
||||
|
||||
nativeBuildInputs = [ pkg-config validatePkgConfig ];
|
||||
|
||||
passthru.tests.pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage;
|
||||
|
||||
meta = {
|
||||
...
|
||||
pkgConfigModules = [ "zlib" ];
|
||||
};
|
||||
})
|
||||
```
|
||||
|
||||
## Accessing packages via pkg-config module name
|
||||
|
||||
### Within Nixpkgs
|
||||
|
||||
A [setup hook](#setup-hook-pkg-config) is bundled in the `pkg-config` package to bring a derivation's declared build inputs into the environment.
|
||||
This will populate environment variables like `PKG_CONFIG_PATH`, `PKG_CONFIG_PATH_FOR_BUILD`, and `PKG_CONFIG_PATH_HOST` based on:
|
||||
|
||||
- how `pkg-config` itself is depended upon
|
||||
|
||||
- how other dependencies are depended upon
|
||||
|
||||
For more details see the section on [specifying dependencies in general](#ssec-stdenv-dependencies).
|
||||
|
||||
Normal pkg-config commands to look up dependencies by name will then work with those environment variables defined by the hook.
|
||||
|
||||
### Externally
|
||||
|
||||
The `defaultPkgConfigPackages` package set is a set of aliases, named after the modules they provide.
|
||||
This is meant to be used by language-to-nix integrations.
|
||||
Hand-written packages should use the normal Nixpkgs attribute name instead.
|
||||
@@ -58,7 +58,7 @@ with a nix-shell that has `numpy` and `toolz` in Python 3.9; then we will create
|
||||
a re-usable environment in a single-file Python script; then we will create a
|
||||
full Python environment for development with this same environment.
|
||||
|
||||
Philosophically, this should be familiar to users who are used to a `venv` style
|
||||
Philosphically, this should be familiar to users who are used to a `venv` style
|
||||
of development: individual projects create their own Python environments without
|
||||
impacting the global environment or each other.
|
||||
|
||||
@@ -436,7 +436,7 @@ arguments `buildInputs` and `propagatedBuildInputs` to specify dependencies. If
|
||||
something is exclusively a build-time dependency, then the dependency should be
|
||||
included in `buildInputs`, but if it is (also) a runtime dependency, then it
|
||||
should be added to `propagatedBuildInputs`. Test dependencies are considered
|
||||
build-time dependencies and passed to `nativeCheckInputs`.
|
||||
build-time dependencies and passed to `checkInputs`.
|
||||
|
||||
The following example shows which arguments are given to `buildPythonPackage` in
|
||||
order to build [`datashape`](https://github.com/blaze/datashape).
|
||||
@@ -453,7 +453,7 @@ buildPythonPackage rec {
|
||||
hash = "sha256-FLLvdm1MllKrgTGC6Gb0k0deZeVYvtCCLji/B7uhong=";
|
||||
};
|
||||
|
||||
nativeCheckInputs = [ pytest ];
|
||||
checkInputs = [ pytest ];
|
||||
propagatedBuildInputs = [ numpy multipledispatch python-dateutil ];
|
||||
|
||||
meta = with lib; {
|
||||
@@ -466,7 +466,7 @@ buildPythonPackage rec {
|
||||
```
|
||||
|
||||
We can see several runtime dependencies, `numpy`, `multipledispatch`, and
|
||||
`python-dateutil`. Furthermore, we have one `nativeCheckInputs`, i.e. `pytest`. `pytest` is a
|
||||
`python-dateutil`. Furthermore, we have one `checkInputs`, i.e. `pytest`. `pytest` is a
|
||||
test runner and is only used during the `checkPhase` and is therefore not added
|
||||
to `propagatedBuildInputs`.
|
||||
|
||||
@@ -569,14 +569,8 @@ Pytest is the most common test runner for python repositories. A trivial
|
||||
test run would be:
|
||||
|
||||
```
|
||||
nativeCheckInputs = [ pytest ];
|
||||
checkPhase = ''
|
||||
runHook preCheck
|
||||
|
||||
pytest
|
||||
|
||||
runHook postCheck
|
||||
'';
|
||||
checkInputs = [ pytest ];
|
||||
checkPhase = "pytest";
|
||||
```
|
||||
|
||||
However, many repositories' test suites do not translate well to nix's build
|
||||
@@ -585,14 +579,10 @@ sandbox, and will generally need many tests to be disabled.
|
||||
To filter tests using pytest, one can do the following:
|
||||
|
||||
```
|
||||
nativeCheckInputs = [ pytest ];
|
||||
checkInputs = [ pytest ];
|
||||
# avoid tests which need additional data or touch network
|
||||
checkPhase = ''
|
||||
runHook preCheck
|
||||
|
||||
pytest tests/ --ignore=tests/integration -k 'not download and not update'
|
||||
|
||||
runHook postCheck
|
||||
'';
|
||||
```
|
||||
|
||||
@@ -618,7 +608,7 @@ when a package may need many items disabled to run the test suite.
|
||||
Using the example above, the analogous `pytestCheckHook` usage would be:
|
||||
|
||||
```
|
||||
nativeCheckInputs = [ pytestCheckHook ];
|
||||
checkInputs = [ pytestCheckHook ];
|
||||
|
||||
# requires additional data
|
||||
pytestFlagsArray = [ "tests/" "--ignore=tests/integration" ];
|
||||
@@ -744,17 +734,17 @@ work in any of the formats supported by `buildPythonPackage` currently,
|
||||
with the exception of `other` (see `format` in
|
||||
[`buildPythonPackage` parameters](#buildpythonpackage-parameters) for more details).
|
||||
|
||||
#### Using unittestCheckHook {#using-unittestcheckhook}
|
||||
### Using unittestCheckHook {#using-unittestcheckhook}
|
||||
|
||||
`unittestCheckHook` is a hook which will substitute the setuptools `test` command for a `checkPhase` which runs `python -m unittest discover`:
|
||||
|
||||
```
|
||||
nativeCheckInputs = [ unittestCheckHook ];
|
||||
checkInputs = [ unittestCheckHook ];
|
||||
|
||||
unittestFlagsArray = [ "-s" "tests" "-v" ];
|
||||
unittestFlags = [ "-s" "tests" "-v" ];
|
||||
```
|
||||
|
||||
#### Using sphinxHook {#using-sphinxhook}
|
||||
##### Using sphinxHook {#using-sphinxhook}
|
||||
|
||||
The `sphinxHook` is a helpful tool to build documentation and manpages
|
||||
using the popular Sphinx documentation generator.
|
||||
@@ -1006,7 +996,7 @@ buildPythonPackage rec {
|
||||
rm testing/test_argcomplete.py
|
||||
'';
|
||||
|
||||
nativeCheckInputs = [ hypothesis ];
|
||||
checkInputs = [ hypothesis ];
|
||||
nativeBuildInputs = [ setuptools-scm ];
|
||||
propagatedBuildInputs = [ attrs py setuptools six pluggy ];
|
||||
|
||||
@@ -1028,7 +1018,7 @@ The `buildPythonPackage` mainly does four things:
|
||||
* In the `installCheck` phase, `${python.interpreter} setup.py test` is run.
|
||||
|
||||
By default tests are run because `doCheck = true`. Test dependencies, like
|
||||
e.g. the test runner, should be added to `nativeCheckInputs`.
|
||||
e.g. the test runner, should be added to `checkInputs`.
|
||||
|
||||
By default `meta.platforms` is set to the same value
|
||||
as the interpreter unless overridden otherwise.
|
||||
@@ -1082,7 +1072,7 @@ because their behaviour is different:
|
||||
* `buildInputs ? []`: Build and/or run-time dependencies that need to be
|
||||
compiled for the host machine. Typically non-Python libraries which are being
|
||||
linked.
|
||||
* `nativeCheckInputs ? []`: Dependencies needed for running the `checkPhase`. These
|
||||
* `checkInputs ? []`: Dependencies needed for running the `checkPhase`. These
|
||||
are added to `nativeBuildInputs` when `doCheck = true`. Items listed in
|
||||
`tests_require` go here.
|
||||
* `propagatedBuildInputs ? []`: Aside from propagating dependencies,
|
||||
@@ -1416,13 +1406,9 @@ example of such a situation is when `py.test` is used.
|
||||
buildPythonPackage {
|
||||
# ...
|
||||
# assumes the tests are located in tests
|
||||
nativeCheckInputs = [ pytest ];
|
||||
checkInputs = [ pytest ];
|
||||
checkPhase = ''
|
||||
runHook preCheck
|
||||
|
||||
py.test -k 'not function_name and not other_function' tests
|
||||
|
||||
runHook postCheck
|
||||
'';
|
||||
}
|
||||
```
|
||||
@@ -1768,7 +1754,7 @@ In a `setup.py` or `setup.cfg` it is common to declare dependencies:
|
||||
|
||||
* `setup_requires` corresponds to `nativeBuildInputs`
|
||||
* `install_requires` corresponds to `propagatedBuildInputs`
|
||||
* `tests_require` corresponds to `nativeCheckInputs`
|
||||
* `tests_require` corresponds to `checkInputs`
|
||||
|
||||
## Contributing {#contributing}
|
||||
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
|
||||
Writing Nix expressions for Qt libraries and applications is largely similar as for other C++ software.
|
||||
This section assumes some knowledge of the latter.
|
||||
There are two problems that the Nixpkgs Qt infrastructure addresses,
|
||||
which are not shared by other C++ software:
|
||||
|
||||
The major caveat with Qt applications is that Qt uses a plugin system to load additional modules at runtime,
|
||||
from a list of well-known locations. In Nixpkgs, we patch QtCore to instead use an environment variable,
|
||||
and wrap Qt applications to set it to the right paths. This effectively makes the runtime dependencies
|
||||
pure and explicit at build-time, at the cost of introducing an extra indirection.
|
||||
1. There are usually multiple supported versions of Qt in Nixpkgs.
|
||||
All of a package's dependencies must be built with the same version of Qt.
|
||||
This is similar to the version constraints imposed on interpreted languages like Python.
|
||||
2. Qt makes extensive use of runtime dependency detection.
|
||||
Runtime dependencies are made into build dependencies through wrappers.
|
||||
|
||||
## Nix expression for a Qt package (default.nix) {#qt-default-nix}
|
||||
|
||||
@@ -92,3 +95,66 @@ stdenv.mkDerivation {
|
||||
This means that scripts won't be automatically wrapped so you'll need to manually wrap them as previously mentioned.
|
||||
An example of when you'd always need to do this is with Python applications that use PyQt.
|
||||
:::
|
||||
|
||||
## Adding a library to Nixpkgs {#adding-a-library-to-nixpkgs}
|
||||
|
||||
Add Qt libraries to `qt5-packages.nix` to make them available for every
|
||||
supported Qt version.
|
||||
|
||||
### Example adding a Qt library {#qt-library-all-packages-nix}
|
||||
|
||||
The following represents the contents of `qt5-packages.nix`.
|
||||
|
||||
```nix
|
||||
{
|
||||
# ...
|
||||
|
||||
mylib = callPackage ../path/to/mylib {};
|
||||
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
Libraries are built with every available version of Qt.
|
||||
Use the `meta.broken` attribute to disable the package for unsupported Qt versions:
|
||||
|
||||
```nix
|
||||
{ stdenv, lib, qtbase }:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
# ...
|
||||
# Disable this library with Qt < 5.9.0
|
||||
meta.broken = lib.versionOlder qtbase.version "5.9.0";
|
||||
}
|
||||
```
|
||||
|
||||
## Adding an application to Nixpkgs {#adding-an-application-to-nixpkgs}
|
||||
|
||||
Add Qt applications to `qt5-packages.nix`. Add an alias to `all-packages.nix`
|
||||
to select the Qt 5 version used for the application.
|
||||
|
||||
### Example adding a Qt application {#qt-application-all-packages-nix}
|
||||
|
||||
The following represents the contents of `qt5-packages.nix`.
|
||||
|
||||
```nix
|
||||
{
|
||||
# ...
|
||||
|
||||
myapp = callPackage ../path/to/myapp {};
|
||||
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
The following represents the contents of `all-packages.nix`.
|
||||
|
||||
```nix
|
||||
{
|
||||
# ...
|
||||
|
||||
myapp = libsForQt5.myapp;
|
||||
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
# Swift {#swift}
|
||||
|
||||
The Swift compiler is provided by the `swift` package:
|
||||
|
||||
```sh
|
||||
# Compile and link a simple executable.
|
||||
nix-shell -p swift --run 'swiftc -' <<< 'print("Hello world!")'
|
||||
# Run it!
|
||||
./main
|
||||
```
|
||||
|
||||
The `swift` package also provides the `swift` command, with some caveats:
|
||||
|
||||
- Swift Package Manager (SwiftPM) is packaged separately as `swiftpm`. If you
|
||||
need functionality like `swift build`, `swift run`, `swift test`, you must
|
||||
also add the `swiftpm` package to your closure.
|
||||
- On Darwin, the `swift repl` command requires an Xcode installation. This is
|
||||
because it uses the system LLDB debugserver, which has special entitlements.
|
||||
|
||||
## Module search paths {#ssec-swift-module-search-paths}
|
||||
|
||||
Like other toolchains in Nixpkgs, the Swift compiler executables are wrapped
|
||||
to help Swift find your application's dependencies in the Nix store. These
|
||||
wrappers scan the `buildInputs` of your package derivation for specific
|
||||
directories where Swift modules are placed by convention, and automatically
|
||||
add those directories to the Swift compiler search paths.
|
||||
|
||||
Swift follows different conventions depending on the platform. The wrappers
|
||||
look for the following directories:
|
||||
|
||||
- On Darwin platforms: `lib/swift/macosx`
|
||||
(If not targeting macOS, replace `macosx` with the Xcode platform name.)
|
||||
- On other platforms: `lib/swift/linux/x86_64`
|
||||
(Where `linux` and `x86_64` are from lowercase `uname -sm`.)
|
||||
- For convenience, Nixpkgs also adds simply `lib/swift` to the search path.
|
||||
This can save a bit of work packaging Swift modules, because many Nix builds
|
||||
will produce output for just one target any way.
|
||||
|
||||
## Core libraries {#ssec-swift-core-libraries}
|
||||
|
||||
In addition to the standard library, the Swift toolchain contains some
|
||||
additional 'core libraries' that, on Apple platforms, are normally distributed
|
||||
as part of the OS or Xcode. These are packaged separately in Nixpkgs, and can
|
||||
be found (for use in `buildInputs`) as:
|
||||
|
||||
- `swiftPackages.Dispatch`
|
||||
- `swiftPackages.Foundation`
|
||||
- `swiftPackages.XCTest`
|
||||
|
||||
## Packaging with SwiftPM {#ssec-swift-packaging-with-swiftpm}
|
||||
|
||||
Nixpkgs includes a small helper `swiftpm2nix` that can fetch your SwiftPM
|
||||
dependencies for you, when you need to write a Nix expression to package your
|
||||
application.
|
||||
|
||||
The first step is to run the generator:
|
||||
|
||||
```sh
|
||||
cd /path/to/my/project
|
||||
# Enter a Nix shell with the required tools.
|
||||
nix-shell -p swift swiftpm swiftpm2nix
|
||||
# First, make sure the workspace is up-to-date.
|
||||
swift package resolve
|
||||
# Now generate the Nix code.
|
||||
swiftpm2nix
|
||||
```
|
||||
|
||||
This produces some files in a directory `nix`, which will be part of your Nix
|
||||
expression. The next step is to write that expression:
|
||||
|
||||
```nix
|
||||
{ stdenv, swift, swiftpm, swiftpm2nix, fetchFromGitHub }:
|
||||
|
||||
let
|
||||
# Pass the generated files to the helper.
|
||||
generated = swiftpm2nix.helpers ./nix;
|
||||
in
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "myproject";
|
||||
version = "0.0.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "nixos";
|
||||
repo = pname;
|
||||
rev = version;
|
||||
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
|
||||
};
|
||||
|
||||
# Including SwiftPM as a nativeBuildInput provides a buildPhase for you.
|
||||
# This by default performs a release build using SwiftPM, essentially:
|
||||
# swift build -c release
|
||||
nativeBuildInputs = [ swift swiftpm ];
|
||||
|
||||
# The helper provides a configure snippet that will prepare all dependencies
|
||||
# in the correct place, where SwiftPM expects them.
|
||||
configurePhase = generated.configure;
|
||||
|
||||
installPhase = ''
|
||||
# This is a special function that invokes swiftpm to find the location
|
||||
# of the binaries it produced.
|
||||
binPath="$(swiftpmBinPath)"
|
||||
# Now perform any installation steps.
|
||||
mkdir -p $out/bin
|
||||
cp $binPath/myproject $out/bin/
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
### Custom build flags {#ssec-swiftpm-custom-build-flags}
|
||||
|
||||
If you'd like to build a different configuration than `release`:
|
||||
|
||||
```nix
|
||||
swiftpmBuildConfig = "debug";
|
||||
```
|
||||
|
||||
It is also possible to provide additional flags to `swift build`:
|
||||
|
||||
```nix
|
||||
swiftpmFlags = [ "--disable-dead-strip" ];
|
||||
```
|
||||
|
||||
The default `buildPhase` already passes `-j` for parallel building.
|
||||
|
||||
If these two customization options are insufficient, simply provide your own
|
||||
`buildPhase` that invokes `swift build`.
|
||||
|
||||
### Running tests {#ssec-swiftpm-running-tests}
|
||||
|
||||
Including `swiftpm` in your `nativeBuildInputs` also provides a default
|
||||
`checkPhase`, but it must be enabled with:
|
||||
|
||||
```nix
|
||||
doCheck = true;
|
||||
```
|
||||
|
||||
This essentially runs: `swift test -c release`
|
||||
|
||||
### Patching dependencies {#ssec-swiftpm-patching-dependencies}
|
||||
|
||||
In some cases, it may be necessary to patch a SwiftPM dependency. SwiftPM
|
||||
dependencies are located in `.build/checkouts`, but the `swiftpm2nix` helper
|
||||
provides these as symlinks to read-only `/nix/store` paths. In order to patch
|
||||
them, we need to make them writable.
|
||||
|
||||
A special function `swiftpmMakeMutable` is available to replace the symlink
|
||||
with a writable copy:
|
||||
|
||||
```
|
||||
configurePhase = generated.configure ++ ''
|
||||
# Replace the dependency symlink with a writable copy.
|
||||
swiftpmMakeMutable swift-crypto
|
||||
# Now apply a patch.
|
||||
patch -p1 -d .build/checkouts/swift-crypto -i ${./some-fix.patch}
|
||||
'';
|
||||
```
|
||||
|
||||
## Considerations for custom build tools {#ssec-swift-considerations-for-custom-build-tools}
|
||||
|
||||
### Linking the standard library {#ssec-swift-linking-the-standard-library}
|
||||
|
||||
The `swift` package has a separate `lib` output containing just the Swift
|
||||
standard library, to prevent Swift applications needing a dependency on the
|
||||
full Swift compiler at run-time. Linking with the Nixpkgs Swift toolchain
|
||||
already ensures binaries correctly reference the `lib` output.
|
||||
|
||||
Sometimes, Swift is used only to compile part of a mixed codebase, and the
|
||||
link step is manual. Custom build tools often locate the standard library
|
||||
relative to the `swift` compiler executable, and while the result will work,
|
||||
when this path ends up in the binary, it will have the Swift compiler as an
|
||||
unintended dependency.
|
||||
|
||||
In this case, you should investigate how your build process discovers the
|
||||
standard library, and override the path. The correct path will be something
|
||||
like: `"${swift.swift.lib}/${swift.swiftModuleSubdir}"`
|
||||
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"gnunet.conf(5)": "https://docs.gnunet.org/users/configuration.html",
|
||||
"mpd(1)": "https://mpd.readthedocs.io/en/latest/mpd.1.html",
|
||||
"mpd.conf(5)": "https://mpd.readthedocs.io/en/latest/mpd.conf.5.html",
|
||||
"nix.conf(5)": "https://nixos.org/manual/nix/stable/command-ref/conf-file.html",
|
||||
|
||||
"journald.conf(5)": "https://www.freedesktop.org/software/systemd/man/journald.conf.html",
|
||||
"logind.conf(5)": "https://www.freedesktop.org/software/systemd/man/logind.conf.html",
|
||||
"networkd.conf(5)": "https://www.freedesktop.org/software/systemd/man/networkd.conf.html",
|
||||
"systemd.automount(5)": "https://www.freedesktop.org/software/systemd/man/systemd.automount.html",
|
||||
"systemd.exec(5)": "https://www.freedesktop.org/software/systemd/man/systemd.exec.html",
|
||||
"systemd.link(5)": "https://www.freedesktop.org/software/systemd/man/systemd.link.html",
|
||||
"systemd.mount(5)": "https://www.freedesktop.org/software/systemd/man/systemd.mount.html",
|
||||
"systemd.netdev(5)": "https://www.freedesktop.org/software/systemd/man/systemd.netdev.html",
|
||||
"systemd.network(5)": "https://www.freedesktop.org/software/systemd/man/systemd.network.html",
|
||||
"systemd.nspawn(5)": "https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html",
|
||||
"systemd.path(5)": "https://www.freedesktop.org/software/systemd/man/systemd.path.html",
|
||||
"systemd.resource-control(5)": "https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html",
|
||||
"systemd.scope(5)": "https://www.freedesktop.org/software/systemd/man/systemd.scope.html",
|
||||
"systemd.service(5)": "https://www.freedesktop.org/software/systemd/man/systemd.service.html",
|
||||
"systemd.slice(5)": "https://www.freedesktop.org/software/systemd/man/systemd.slice.html",
|
||||
"systemd.socket(5)": "https://www.freedesktop.org/software/systemd/man/systemd.socket.html",
|
||||
"systemd.timer(5)": "https://www.freedesktop.org/software/systemd/man/systemd.timer.html",
|
||||
"systemd.unit(5)": "https://www.freedesktop.org/software/systemd/man/systemd.unit.html",
|
||||
"systemd-system.conf(5)": "https://www.freedesktop.org/software/systemd/man/systemd-system.conf.html",
|
||||
"systemd-user.conf(5)": "https://www.freedesktop.org/software/systemd/man/systemd-user.conf.html",
|
||||
"timesyncd.conf(5)": "https://www.freedesktop.org/software/systemd/man/timesyncd.conf.html",
|
||||
"tmpfiles.d(5)": "https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html",
|
||||
"systemd.time(7)": "https://www.freedesktop.org/software/systemd/man/systemd.time.html",
|
||||
"systemd-fstab-generator(8)": "https://www.freedesktop.org/software/systemd/man/systemd-fstab-generator.html",
|
||||
"systemd-networkd-wait-online.service(8)": "https://www.freedesktop.org/software/systemd/man/systemd-networkd-wait-online.service.html"
|
||||
}
|
||||
@@ -24,8 +24,8 @@ Packages, including the Nix packages collection, are distributed through
|
||||
[channels](https://nixos.org/nix/manual/#sec-channels). The collection is
|
||||
distributed for users of Nix on non-NixOS distributions through the channel
|
||||
`nixpkgs`. Users of NixOS generally use one of the `nixos-*` channels, e.g.
|
||||
`nixos-22.11`, which includes all packages and modules for the stable NixOS
|
||||
22.11. Stable NixOS releases are generally only given
|
||||
`nixos-19.09`, which includes all packages and modules for the stable NixOS
|
||||
19.09. Stable NixOS releases are generally only given
|
||||
security updates. More up to date packages and modules are available via the
|
||||
`nixos-unstable` channel.
|
||||
|
||||
@@ -43,4 +43,4 @@ The binaries are made available via a [binary cache](https://cache.nixos.org).
|
||||
|
||||
The current Nix expressions of the channels are available in the
|
||||
[`nixpkgs`](https://github.com/NixOS/nixpkgs) repository in branches
|
||||
that correspond to the channel names (e.g. `nixos-22.11-small`).
|
||||
that correspond to the channel names (e.g. `nixos-19.09-small`).
|
||||
|
||||
@@ -150,7 +150,7 @@ depsBuildBuild = [ buildPackages.stdenv.cc ];
|
||||
Add the following to your `mkDerivation` invocation.
|
||||
|
||||
```nix
|
||||
doCheck = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
|
||||
doCheck = stdenv.hostPlatform == stdenv.buildPlatform;
|
||||
```
|
||||
|
||||
#### Package using Meson needs to run binaries for the host platform during build. {#cross-meson-runs-host-code}
|
||||
|
||||
@@ -66,7 +66,7 @@ For details, see [Licenses](#sec-meta-license).
|
||||
|
||||
### `maintainers` {#var-meta-maintainers}
|
||||
|
||||
A list of the maintainers of this Nix expression. Maintainers are defined in [`nixpkgs/maintainers/maintainer-list.nix`](https://github.com/NixOS/nixpkgs/blob/master/maintainers/maintainer-list.nix). There is no restriction to becoming a maintainer, just add yourself to that list in a separate commit titled “maintainers: add alice” in the same pull request, and reference maintainers with `maintainers = with lib.maintainers; [ alice bob ]`.
|
||||
A list of the maintainers of this Nix expression. Maintainers are defined in [`nixpkgs/maintainers/maintainer-list.nix`](https://github.com/NixOS/nixpkgs/blob/master/maintainers/maintainer-list.nix). There is no restriction to becoming a maintainer, just add yourself to that list in a separate commit titled “maintainers: add alice”, and reference maintainers with `maintainers = with lib.maintainers; [ alice bob ]`.
|
||||
|
||||
### `mainProgram` {#var-meta-mainProgram}
|
||||
|
||||
|
||||
@@ -116,82 +116,6 @@ On Linux, `stdenv` also includes the `patchelf` utility.
|
||||
|
||||
## Specifying dependencies {#ssec-stdenv-dependencies}
|
||||
|
||||
Build systems often require more dependencies than just what `stdenv` provides. This section describes attributes accepted by `stdenv.mkDerivation` that can be used to make these dependencies available to the build system.
|
||||
|
||||
### Overview {#ssec-stdenv-dependencies-overview}
|
||||
|
||||
A full reference of the different kinds of dependencies is provided in [](#ssec-stdenv-dependencies-reference), but here is an overview of the most common ones.
|
||||
It should cover most use cases.
|
||||
|
||||
Add dependencies to `nativeBuildInputs` if they are executed during the build:
|
||||
- those which are needed on `$PATH` during the build, for example `cmake` and `pkg-config`
|
||||
- [setup hooks](#ssec-setup-hooks), for example [`makeWrapper`](#fun-makeWrapper)
|
||||
- interpreters needed by [`patchShebangs`](#patch-shebangs.sh) for build scripts (with the `--build` flag), which can be the case for e.g. `perl`
|
||||
|
||||
Add dependencies to `buildInputs` if they will end up copied or linked into the final output or otherwise used at runtime:
|
||||
- libraries used by compilers, for example `zlib`,
|
||||
- interpreters needed by [`patchShebangs`](#patch-shebangs.sh) for scripts which are installed, which can be the case for e.g. `perl`
|
||||
|
||||
::: {.note}
|
||||
These criteria are independent.
|
||||
|
||||
For example, software using Wayland usually needs the `wayland` library at runtime, so `wayland` should be added to `buildInputs`.
|
||||
But it also executes the `wayland-scanner` program as part of the build to generate code, so `wayland` should also be added to `nativeBuildInputs`.
|
||||
:::
|
||||
|
||||
Dependencies needed only to run tests are similarly classified between native (executed during build) and non-native (executed at runtime):
|
||||
- `nativeCheckInputs` for test tools needed on `$PATH` (such as `ctest`) and [setup hooks](#ssec-setup-hooks) (for example [`pytestCheckHook`](#python))
|
||||
- `checkInputs` for libraries linked into test executables (for example the `qcheck` OCaml package)
|
||||
|
||||
These dependencies are only injected when [`doCheck`](#var-stdenv-doCheck) is set to `true`.
|
||||
|
||||
#### Example {#ssec-stdenv-dependencies-overview-example}
|
||||
|
||||
Consider for example this simplified derivation for `solo5`, a sandboxing tool:
|
||||
```nix
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "solo5";
|
||||
version = "0.7.5";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/Solo5/solo5/releases/download/v${version}/solo5-v${version}.tar.gz";
|
||||
sha256 = "sha256-viwrS9lnaU8sTGuzK/+L/PlMM/xRRtgVuK5pixVeDEw=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ makeWrapper pkg-config ];
|
||||
buildInputs = [ libseccomp ];
|
||||
|
||||
postInstall = ''
|
||||
substituteInPlace $out/bin/solo5-virtio-mkimage \
|
||||
--replace "/usr/lib/syslinux" "${syslinux}/share/syslinux" \
|
||||
--replace "/usr/share/syslinux" "${syslinux}/share/syslinux" \
|
||||
--replace "cp " "cp --no-preserve=mode "
|
||||
|
||||
wrapProgram $out/bin/solo5-virtio-mkimage \
|
||||
--prefix PATH : ${lib.makeBinPath [ dosfstools mtools parted syslinux ]}
|
||||
'';
|
||||
|
||||
doCheck = true;
|
||||
nativeCheckInputs = [ util-linux qemu ];
|
||||
checkPhase = '' [elided] '';
|
||||
}
|
||||
```
|
||||
|
||||
- `makeWrapper` is a setup hook, i.e., a shell script sourced by the generic builder of `stdenv`.
|
||||
It is thus executed during the build and must be added to `nativeBuildInputs`.
|
||||
- `pkg-config` is a build tool which the configure script of `solo5` expects to be on `$PATH` during the build:
|
||||
therefore, it must be added to `nativeBuildInputs`.
|
||||
- `libseccomp` is a library linked into `$out/bin/solo5-elftool`.
|
||||
As it is used at runtime, it must be added to `buildInputs`.
|
||||
- Tests need `qemu` and `getopt` (from `util-linux`) on `$PATH`, these must be added to `nativeCheckInputs`.
|
||||
- Some dependencies are injected directly in the shell code of phases: `syslinux`, `dosfstools`, `mtools`, and `parted`.
|
||||
In this specific case, they will end up in the output of the derivation (`$out` here).
|
||||
As Nix marks dependencies whose absolute path is present in the output as runtime dependencies, adding them to `buildInputs` is not required.
|
||||
|
||||
For more complex cases, like libraries linked into an executable which is then executed as part of the build system, see [](#ssec-stdenv-dependencies-reference).
|
||||
|
||||
### Reference {#ssec-stdenv-dependencies-reference}
|
||||
|
||||
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.
|
||||
@@ -263,21 +187,21 @@ Because of the bounds checks, the uncommon cases are `h = t` and `h + 2 = t`. In
|
||||
|
||||
Overall, the unifying theme here is that propagation shouldn’t be introducing transitive dependencies involving platforms the depending package is unaware of. \[One can imagine the dependending package asking for dependencies with the platforms it knows about; other platforms it doesn’t know how to ask for. The platform description in that scenario is a kind of unforagable capability.\] The offset bounds checking and definition of `mapOffset` together ensure that this is the case. Discovering a new offset is discovering a new platform, and since those platforms weren’t in the derivation “spec” of the needing package, they cannot be relevant. From a capability perspective, we can imagine that the host and target platforms of a package are the capabilities a package requires, and the depending package must provide the capability to the dependency.
|
||||
|
||||
#### Variables specifying dependencies {#variables-specifying-dependencies}
|
||||
### Variables specifying dependencies {#variables-specifying-dependencies}
|
||||
|
||||
##### `depsBuildBuild` {#var-stdenv-depsBuildBuild}
|
||||
#### `depsBuildBuild` {#var-stdenv-depsBuildBuild}
|
||||
|
||||
A list of dependencies whose host and target platforms are the new derivation’s build platform. These are programs and libraries used at build time that produce programs and libraries also used at build time. If the dependency doesn’t care about the target platform (i.e. isn’t a compiler or similar tool), put it in `nativeBuildInputs` instead. The most common use of this `buildPackages.stdenv.cc`, the default C compiler for this role. That example crops up more than one might think in old commonly used C libraries.
|
||||
|
||||
Since these packages are able to be run at build-time, they are always added to the `PATH`, as described above. But since these packages are only guaranteed to be able to run then, they shouldn’t persist as run-time dependencies. This isn’t currently enforced, but could be in the future.
|
||||
|
||||
##### `nativeBuildInputs` {#var-stdenv-nativeBuildInputs}
|
||||
#### `nativeBuildInputs` {#var-stdenv-nativeBuildInputs}
|
||||
|
||||
A list of dependencies whose host platform is the new derivation’s build platform, and target platform is the new derivation’s host platform. These are programs and libraries used at build-time that, if they are a compiler or similar tool, produce code to run at run-time—i.e. tools used to build the new derivation. If the dependency doesn’t care about the target platform (i.e. isn’t a compiler or similar tool), put it here, rather than in `depsBuildBuild` or `depsBuildTarget`. This could be called `depsBuildHost` but `nativeBuildInputs` is used for historical continuity.
|
||||
|
||||
Since these packages are able to be run at build-time, they are added to the `PATH`, as described above. But since these packages are only guaranteed to be able to run then, they shouldn’t persist as run-time dependencies. This isn’t currently enforced, but could be in the future.
|
||||
|
||||
##### `depsBuildTarget` {#var-stdenv-depsBuildTarget}
|
||||
#### `depsBuildTarget` {#var-stdenv-depsBuildTarget}
|
||||
|
||||
A list of dependencies whose host platform is the new derivation’s build platform, and target platform is the new derivation’s target platform. These are programs used at build time that produce code to run with code produced by the depending package. Most commonly, these are tools used to build the runtime or standard library that the currently-being-built compiler will inject into any code it compiles. In many cases, the currently-being-built-compiler is itself employed for that task, but when that compiler won’t run (i.e. its build and host platform differ) this is not possible. Other times, the compiler relies on some other tool, like binutils, that is always built separately so that the dependency is unconditional.
|
||||
|
||||
@@ -285,41 +209,41 @@ This is a somewhat confusing concept to wrap one’s head around, and for good r
|
||||
|
||||
Since these packages are able to run at build time, they are added to the `PATH`, as described above. But since these packages are only guaranteed to be able to run then, they shouldn’t persist as run-time dependencies. This isn’t currently enforced, but could be in the future.
|
||||
|
||||
##### `depsHostHost` {#var-stdenv-depsHostHost}
|
||||
#### `depsHostHost` {#var-stdenv-depsHostHost}
|
||||
|
||||
A list of dependencies whose host and target platforms match the new derivation’s host platform. In practice, this would usually be tools used by compilers for macros or a metaprogramming system, or libraries used by the macros or metaprogramming code itself. It’s always preferable to use a `depsBuildBuild` dependency in the derivation being built over a `depsHostHost` on the tool doing the building for this purpose.
|
||||
|
||||
##### `buildInputs` {#var-stdenv-buildInputs}
|
||||
#### `buildInputs` {#var-stdenv-buildInputs}
|
||||
|
||||
A list of dependencies whose host platform and target platform match the new derivation’s. This would be called `depsHostTarget` but for historical continuity. If the dependency doesn’t care about the target platform (i.e. isn’t a compiler or similar tool), put it here, rather than in `depsBuildBuild`.
|
||||
|
||||
These are often programs and libraries used by the new derivation at *run*-time, but that isn’t always the case. For example, the machine code in a statically-linked library is only used at run-time, but the derivation containing the library is only needed at build-time. Even in the dynamic case, the library may also be needed at build-time to appease the linker.
|
||||
|
||||
##### `depsTargetTarget` {#var-stdenv-depsTargetTarget}
|
||||
#### `depsTargetTarget` {#var-stdenv-depsTargetTarget}
|
||||
|
||||
A list of dependencies whose host platform matches the new derivation’s target platform. These are packages that run on the target platform, e.g. the standard library or run-time deps of standard library that a compiler insists on knowing about. It’s poor form in almost all cases for a package to depend on another from a future stage \[future stage corresponding to positive offset\]. Do not use this attribute unless you are packaging a compiler and are sure it is needed.
|
||||
|
||||
##### `depsBuildBuildPropagated` {#var-stdenv-depsBuildBuildPropagated}
|
||||
#### `depsBuildBuildPropagated` {#var-stdenv-depsBuildBuildPropagated}
|
||||
|
||||
The propagated equivalent of `depsBuildBuild`. This perhaps never ought to be used, but it is included for consistency \[see below for the others\].
|
||||
|
||||
##### `propagatedNativeBuildInputs` {#var-stdenv-propagatedNativeBuildInputs}
|
||||
#### `propagatedNativeBuildInputs` {#var-stdenv-propagatedNativeBuildInputs}
|
||||
|
||||
The propagated equivalent of `nativeBuildInputs`. This would be called `depsBuildHostPropagated` but for historical continuity. For example, if package `Y` has `propagatedNativeBuildInputs = [X]`, and package `Z` has `buildInputs = [Y]`, then package `Z` will be built as if it included package `X` in its `nativeBuildInputs`. If instead, package `Z` has `nativeBuildInputs = [Y]`, then `Z` will be built as if it included `X` in the `depsBuildBuild` of package `Z`, because of the sum of the two `-1` host offsets.
|
||||
|
||||
##### `depsBuildTargetPropagated` {#var-stdenv-depsBuildTargetPropagated}
|
||||
#### `depsBuildTargetPropagated` {#var-stdenv-depsBuildTargetPropagated}
|
||||
|
||||
The propagated equivalent of `depsBuildTarget`. This is prefixed for the same reason of alerting potential users.
|
||||
|
||||
##### `depsHostHostPropagated` {#var-stdenv-depsHostHostPropagated}
|
||||
#### `depsHostHostPropagated` {#var-stdenv-depsHostHostPropagated}
|
||||
|
||||
The propagated equivalent of `depsHostHost`.
|
||||
|
||||
##### `propagatedBuildInputs` {#var-stdenv-propagatedBuildInputs}
|
||||
#### `propagatedBuildInputs` {#var-stdenv-propagatedBuildInputs}
|
||||
|
||||
The propagated equivalent of `buildInputs`. This would be called `depsHostTargetPropagated` but for historical continuity.
|
||||
|
||||
##### `depsTargetTargetPropagated` {#var-stdenv-depsTargetTargetPropagated}
|
||||
#### `depsTargetTargetPropagated` {#var-stdenv-depsTargetTargetPropagated}
|
||||
|
||||
The propagated equivalent of `depsTargetTarget`. This is prefixed for the same reason of alerting potential users.
|
||||
|
||||
@@ -329,7 +253,7 @@ The propagated equivalent of `depsTargetTarget`. This is prefixed for the same r
|
||||
|
||||
#### `NIX_DEBUG` {#var-stdenv-NIX_DEBUG}
|
||||
|
||||
A number between 0 and 7 indicating how much information to log. If set to 1 or higher, `stdenv` will print moderate debugging information during the build. In particular, the `gcc` and `ld` wrapper scripts will print out the complete command line passed to the wrapped tools. If set to 6 or higher, the `stdenv` setup script will be run with `set -x` tracing. If set to 7 or higher, the `gcc` and `ld` wrapper scripts will also be run with `set -x` tracing.
|
||||
A natural number indicating how much information to log. If set to 1 or higher, `stdenv` will print moderate debugging information during the build. In particular, the `gcc` and `ld` wrapper scripts will print out the complete command line passed to the wrapped tools. If set to 6 or higher, the `stdenv` setup script will be run with `set -x` tracing. If set to 7 or higher, the `gcc` and `ld` wrapper scripts will also be run with `set -x` tracing.
|
||||
|
||||
### Attributes affecting build properties {#attributes-affecting-build-properties}
|
||||
|
||||
@@ -702,7 +626,7 @@ Before and after running `make`, the hooks `preBuild` and `postBuild` are called
|
||||
|
||||
### The check phase {#ssec-check-phase}
|
||||
|
||||
The check phase checks whether the package was built correctly by running its test suite. The default `checkPhase` calls `make $checkTarget`, but only if the [`doCheck` variable](#var-stdenv-doCheck) is enabled.
|
||||
The check phase checks whether the package was built correctly by running its test suite. The default `checkPhase` calls `make check`, but only if the `doCheck` variable is enabled.
|
||||
|
||||
#### Variables controlling the check phase {#variables-controlling-the-check-phase}
|
||||
|
||||
@@ -722,8 +646,7 @@ See the [build phase](#var-stdenv-makeFlags) for details.
|
||||
|
||||
##### `checkTarget` {#var-stdenv-checkTarget}
|
||||
|
||||
The `make` target that runs the tests.
|
||||
If unset, use `check` if it exists, otherwise `test`; if neither is found, do nothing.
|
||||
The make target that runs the tests. Defaults to `check`.
|
||||
|
||||
##### `checkFlags` / `checkFlagsArray` {#var-stdenv-checkFlags}
|
||||
|
||||
@@ -731,11 +654,7 @@ A list of strings passed as additional flags to `make`. Like `makeFlags` and `ma
|
||||
|
||||
##### `checkInputs` {#var-stdenv-checkInputs}
|
||||
|
||||
A list of host dependencies used by the phase, usually libraries linked into executables built during tests. This gets included in `buildInputs` when `doCheck` is set.
|
||||
|
||||
##### `nativeCheckInputs` {#var-stdenv-nativeCheckInputs}
|
||||
|
||||
A list of native dependencies used by the phase, notably tools needed on `$PATH`. This gets included in `nativeBuildInputs` when `doCheck` is set.
|
||||
A list of dependencies used by the phase. This gets included in `nativeBuildInputs` when `doCheck` is set.
|
||||
|
||||
##### `preCheck` {#var-stdenv-preCheck}
|
||||
|
||||
@@ -902,11 +821,7 @@ A list of strings passed as additional flags to `make`. Like `makeFlags` and `ma
|
||||
|
||||
##### `installCheckInputs` {#var-stdenv-installCheckInputs}
|
||||
|
||||
A list of host dependencies used by the phase, usually libraries linked into executables built during tests. This gets included in `buildInputs` when `doInstallCheck` is set.
|
||||
|
||||
##### `nativeInstallCheckInputs` {#var-stdenv-nativeInstallCheckInputs}
|
||||
|
||||
A list of native dependencies used by the phase, notably tools needed on `$PATH`. This gets included in `nativeBuildInputs` when `doInstallCheck` is set.
|
||||
A list of dependencies used by the phase. This gets included in `nativeBuildInputs` when `doInstallCheck` is set.
|
||||
|
||||
##### `preInstallCheck` {#var-stdenv-preInstallCheck}
|
||||
|
||||
@@ -922,10 +837,6 @@ The distribution phase is intended to produce a source distribution of the packa
|
||||
|
||||
#### Variables controlling the distribution phase {#variables-controlling-the-distribution-phase}
|
||||
|
||||
##### `doDist` {#var-stdenv-doDist}
|
||||
|
||||
If set, the distribution phase is executed.
|
||||
|
||||
##### `distTarget` {#var-stdenv-distTarget}
|
||||
|
||||
The make target that produces the distribution. Defaults to `dist`.
|
||||
@@ -1079,32 +990,6 @@ Convenience function for `makeWrapper` that replaces `<\executable\>` with a wra
|
||||
|
||||
If you will apply it multiple times, it will overwrite the wrapper file and you will end up with double wrapping, which should be avoided.
|
||||
|
||||
### `prependToVar` \<variableName\> \<elements...\> {#fun-prependToVar}
|
||||
|
||||
Prepend elements to a variable.
|
||||
|
||||
Example:
|
||||
|
||||
```shellSession
|
||||
$ configureFlags="--disable-static"
|
||||
$ prependToVar configureFlags --disable-dependency-tracking --enable-foo
|
||||
$ echo $configureFlags
|
||||
--disable-dependency-tracking --enable-foo --disable-static
|
||||
```
|
||||
|
||||
### `appendToVar` \<variableName\> \<elements...\> {#fun-appendToVar}
|
||||
|
||||
Append elements to a variable.
|
||||
|
||||
Example:
|
||||
|
||||
```shellSession
|
||||
$ configureFlags="--disable-static"
|
||||
$ appendToVar configureFlags --disable-dependency-tracking --enable-foo
|
||||
$ echo $configureFlags
|
||||
--disable-static --disable-dependency-tracking --enable-foo
|
||||
```
|
||||
|
||||
## Package setup hooks {#ssec-setup-hooks}
|
||||
|
||||
Nix itself considers a build-time dependency as merely something that should previously be built and accessible at build time—packages themselves are on their own to perform any additional setup. In most cases, that is fine, and the downstream derivation can deal with its own dependencies. But for a few common tasks, that would result in almost every package doing the same sort of setup work—depending not on the package itself, but entirely on which dependencies were used.
|
||||
|
||||
@@ -63,7 +63,7 @@ You should prefer `overrideAttrs` in almost all cases, see its documentation for
|
||||
:::
|
||||
|
||||
::: {.warning}
|
||||
Do not use this function in Nixpkgs as it evaluates a derivation before modifying it, which breaks package abstraction. In addition, this evaluation-per-function application incurs a performance penalty, which can become a problem if many overrides are used. It is only intended for ad-hoc customisation, such as in `~/.config/nixpkgs/config.nix`.
|
||||
Do not use this function in Nixpkgs as it evaluates a Derivation before modifying it, which breaks package abstraction and removes error-checking of function arguments. In addition, this evaluation-per-function application incurs a performance penalty, which can become a problem if many overrides are used. It is only intended for ad-hoc customisation, such as in `~/.config/nixpkgs/config.nix`.
|
||||
:::
|
||||
|
||||
The function `overrideDerivation` creates a new derivation based on an existing one by overriding the original's attributes with the attribute set produced by the specified function. This function is available on all derivations defined using the `makeOverridable` function. Most standard derivation-producing functions, such as `stdenv.mkDerivation`, are defined using this function, which means most packages in the nixpkgs expression, `pkgs`, have this function.
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
nixos = import ./nixos/lib { lib = final; };
|
||||
|
||||
inherit forAllSystems;
|
||||
|
||||
nixosSystem = args:
|
||||
import ./nixos/lib/eval-config.nix (
|
||||
args // {
|
||||
|
||||
@@ -88,7 +88,7 @@ rec {
|
||||
else { ${elemAt attrPath n} = atDepth (n + 1); };
|
||||
in atDepth 0;
|
||||
|
||||
/* Like `attrByPath`, but without a default value. If it doesn't find the
|
||||
/* Like `attrByPath', but without a default value. If it doesn't find the
|
||||
path it will throw an error.
|
||||
|
||||
Example:
|
||||
@@ -168,7 +168,7 @@ rec {
|
||||
] { a.b.c = 0; }
|
||||
=> { a = { b = { d = 1; }; }; x = { y = "xy"; }; }
|
||||
|
||||
Type: updateManyAttrsByPath :: [{ path :: [String]; update :: (Any -> Any); }] -> AttrSet -> AttrSet
|
||||
Type: updateManyAttrsByPath :: [{ path :: [String], update :: (Any -> Any) }] -> AttrSet -> AttrSet
|
||||
*/
|
||||
updateManyAttrsByPath = let
|
||||
# When recursing into attributes, instead of updating the `path` of each
|
||||
@@ -274,7 +274,7 @@ rec {
|
||||
# The set to get the named attributes from
|
||||
attrs: genAttrs names (name: attrs.${name});
|
||||
|
||||
/* Collect each attribute named `attr` from a list of attribute
|
||||
/* Collect each attribute named `attr' from a list of attribute
|
||||
sets. Sets that don't contain the named attribute are ignored.
|
||||
|
||||
Example:
|
||||
@@ -357,8 +357,8 @@ rec {
|
||||
) {} list_of_attrs;
|
||||
|
||||
|
||||
/* Recursively collect sets that verify a given predicate named `pred`
|
||||
from the set `attrs`. The recursion is stopped when the predicate is
|
||||
/* Recursively collect sets that verify a given predicate named `pred'
|
||||
from the set `attrs'. The recursion is stopped when the predicate is
|
||||
verified.
|
||||
|
||||
Example:
|
||||
@@ -414,7 +414,7 @@ rec {
|
||||
=> { name = "some"; value = 6; }
|
||||
|
||||
Type:
|
||||
nameValuePair :: String -> Any -> { name :: String; value :: Any; }
|
||||
nameValuePair :: String -> Any -> { name :: String, value :: Any }
|
||||
*/
|
||||
nameValuePair =
|
||||
# Attribute name
|
||||
@@ -439,9 +439,9 @@ rec {
|
||||
listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set)));
|
||||
|
||||
|
||||
/* Like `mapAttrs`, but allows the name of each attribute to be
|
||||
/* Like `mapAttrs', but allows the name of each attribute to be
|
||||
changed in addition to the value. The applied function should
|
||||
return both the new name and value as a `nameValuePair`.
|
||||
return both the new name and value as a `nameValuePair'.
|
||||
|
||||
Example:
|
||||
mapAttrs' (name: value: nameValuePair ("foo_" + name) ("bar-" + value))
|
||||
@@ -449,7 +449,7 @@ rec {
|
||||
=> { foo_x = "bar-a"; foo_y = "bar-b"; }
|
||||
|
||||
Type:
|
||||
mapAttrs' :: (String -> Any -> { name :: String; value :: Any; }) -> AttrSet -> AttrSet
|
||||
mapAttrs' :: (String -> Any -> { name = String; value = Any }) -> AttrSet -> AttrSet
|
||||
*/
|
||||
mapAttrs' =
|
||||
# A function, given an attribute's name and value, returns a new `nameValuePair`.
|
||||
@@ -479,14 +479,9 @@ rec {
|
||||
map (name: f name attrs.${name}) (attrNames attrs);
|
||||
|
||||
|
||||
/* Like `mapAttrs`, except that it recursively applies itself to
|
||||
the *leaf* attributes of a potentially-nested attribute set:
|
||||
the second argument of the function will never be an attrset.
|
||||
Also, the first argument of the argument function is a *list*
|
||||
of the attribute names that form the path to the leaf attribute.
|
||||
|
||||
For a function that gives you control over what counts as a leaf,
|
||||
see `mapAttrsRecursiveCond`.
|
||||
/* Like `mapAttrs', except that it recursively applies itself to
|
||||
attribute sets. Also, the first argument of the argument
|
||||
function is a *list* of the names of the containing attributes.
|
||||
|
||||
Example:
|
||||
mapAttrsRecursive (path: value: concatStringsSep "-" (path ++ [value]))
|
||||
@@ -504,9 +499,9 @@ rec {
|
||||
mapAttrsRecursiveCond (as: true) f set;
|
||||
|
||||
|
||||
/* Like `mapAttrsRecursive`, but it takes an additional predicate
|
||||
/* Like `mapAttrsRecursive', but it takes an additional predicate
|
||||
function that tells it whether to recurse into an attribute
|
||||
set. If it returns false, `mapAttrsRecursiveCond` does not
|
||||
set. If it returns false, `mapAttrsRecursiveCond' does not
|
||||
recurse, but does apply the map function. If it returns true, it
|
||||
does recurse, and does not apply the map function.
|
||||
|
||||
@@ -649,7 +644,7 @@ rec {
|
||||
|
||||
Example:
|
||||
zipAttrsWith (name: values: values) [{a = "x";} {a = "y"; b = "z";}]
|
||||
=> { a = ["x" "y"]; b = ["z"]; }
|
||||
=> { a = ["x" "y"]; b = ["z"] }
|
||||
|
||||
Type:
|
||||
zipAttrsWith :: (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet
|
||||
@@ -660,11 +655,11 @@ rec {
|
||||
|
||||
/* Merge sets of attributes and combine each attribute value in to a list.
|
||||
|
||||
Like `lib.attrsets.zipAttrsWith` with `(name: values: values)` as the function.
|
||||
Like `lib.attrsets.zipAttrsWith' with `(name: values: values)' as the function.
|
||||
|
||||
Example:
|
||||
zipAttrs [{a = "x";} {a = "y"; b = "z";}]
|
||||
=> { a = ["x" "y"]; b = ["z"]; }
|
||||
=> { a = ["x" "y"]; b = ["z"] }
|
||||
|
||||
Type:
|
||||
zipAttrs :: [ AttrSet ] -> AttrSet
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
rec {
|
||||
|
||||
|
||||
/* `overrideDerivation drv f` takes a derivation (i.e., the result
|
||||
of a call to the builtin function `derivation`) and returns a new
|
||||
/* `overrideDerivation drv f' takes a derivation (i.e., the result
|
||||
of a call to the builtin function `derivation') and returns a new
|
||||
derivation in which the attributes of the original are overridden
|
||||
according to the function `f`. The function `f` is called with
|
||||
according to the function `f'. The function `f' is called with
|
||||
the original derivation attributes.
|
||||
|
||||
`overrideDerivation` allows certain "ad-hoc" customisation
|
||||
`overrideDerivation' allows certain "ad-hoc" customisation
|
||||
scenarios (e.g. in ~/.config/nixpkgs/config.nix). For instance,
|
||||
if you want to "patch" the derivation returned by a package
|
||||
function in Nixpkgs to build another version than what the
|
||||
@@ -27,19 +27,11 @@ rec {
|
||||
For another application, see build-support/vm, where this
|
||||
function is used to build arbitrary derivations inside a QEMU
|
||||
virtual machine.
|
||||
|
||||
Note that in order to preserve evaluation errors, the new derivation's
|
||||
outPath depends on the old one's, which means that this function cannot
|
||||
be used in circular situations when the old derivation also depends on the
|
||||
new one.
|
||||
|
||||
You should in general prefer `drv.overrideAttrs` over this function;
|
||||
see the nixpkgs manual for more information on overriding.
|
||||
*/
|
||||
overrideDerivation = drv: f:
|
||||
let
|
||||
newDrv = derivation (drv.drvAttrs // (f drv));
|
||||
in lib.flip (extendDerivation (builtins.seq drv.drvPath true)) newDrv (
|
||||
in lib.flip (extendDerivation true) newDrv (
|
||||
{ meta = drv.meta or {};
|
||||
passthru = if drv ? passthru then drv.passthru else {};
|
||||
}
|
||||
@@ -104,10 +96,10 @@ rec {
|
||||
else result;
|
||||
|
||||
|
||||
/* Call the package function in the file `fn` with the required
|
||||
/* Call the package function in the file `fn' with the required
|
||||
arguments automatically. The function is called with the
|
||||
arguments `args`, but any missing arguments are obtained from
|
||||
`autoArgs`. This function is intended to be partially
|
||||
arguments `args', but any missing arguments are obtained from
|
||||
`autoArgs'. This function is intended to be partially
|
||||
parameterised, e.g.,
|
||||
|
||||
callPackage = callPackageWith pkgs;
|
||||
@@ -116,9 +108,9 @@ rec {
|
||||
libbar = callPackage ./bar.nix { };
|
||||
};
|
||||
|
||||
If the `libbar` function expects an argument named `libfoo`, it is
|
||||
If the `libbar' function expects an argument named `libfoo', it is
|
||||
automatically passed as an argument. Overrides or missing
|
||||
arguments can be supplied in `args`, e.g.
|
||||
arguments can be supplied in `args', e.g.
|
||||
|
||||
libbar = callPackage ./bar.nix {
|
||||
libfoo = null;
|
||||
@@ -252,17 +244,16 @@ rec {
|
||||
outputsList = map makeOutput outputs;
|
||||
|
||||
drv' = (lib.head outputsList).value;
|
||||
in if drv == null then null else
|
||||
lib.deepSeq drv' drv';
|
||||
in lib.deepSeq drv' drv';
|
||||
|
||||
/* Make a set of packages with a common scope. All packages called
|
||||
with the provided `callPackage` will be evaluated with the same
|
||||
with the provided `callPackage' will be evaluated with the same
|
||||
arguments. Any package in the set may depend on any other. The
|
||||
`overrideScope'` function allows subsequent modification of the package
|
||||
set in a consistent way, i.e. all packages in the set will be
|
||||
called with the overridden packages. The package sets may be
|
||||
hierarchical: the packages in the set are called with the scope
|
||||
provided by `newScope` and the set provides a `newScope` attribute
|
||||
provided by `newScope' and the set provides a `newScope' attribute
|
||||
which can form the parent scope for later package sets. */
|
||||
makeScope = newScope: f:
|
||||
let self = f self // {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Library of low-level helper functions for nix expressions.
|
||||
*
|
||||
* Please implement (mostly) exhaustive unit tests
|
||||
* for new functions in `./tests.nix`.
|
||||
* for new functions in `./tests.nix'.
|
||||
*/
|
||||
let
|
||||
|
||||
@@ -27,6 +27,7 @@ let
|
||||
maintainers = import ../maintainers/maintainer-list.nix;
|
||||
teams = callLibs ../maintainers/team-list.nix;
|
||||
meta = callLibs ./meta.nix;
|
||||
sources = callLibs ./sources.nix;
|
||||
versions = callLibs ./versions.nix;
|
||||
|
||||
# module system
|
||||
@@ -52,9 +53,7 @@ let
|
||||
fetchers = callLibs ./fetchers.nix;
|
||||
|
||||
# Eval-time filesystem handling
|
||||
path = callLibs ./path;
|
||||
filesystem = callLibs ./filesystem.nix;
|
||||
sources = callLibs ./sources.nix;
|
||||
|
||||
# back-compat aliases
|
||||
platforms = self.systems.doubles;
|
||||
@@ -64,7 +63,7 @@ let
|
||||
|
||||
inherit (builtins) add addErrorContext attrNames concatLists
|
||||
deepSeq elem elemAt filter genericClosure genList getAttr
|
||||
hasAttr head isAttrs isBool isInt isList isPath isString length
|
||||
hasAttr head isAttrs isBool isInt isList isString length
|
||||
lessThan listToAttrs pathExists readFile replaceStrings seq
|
||||
stringLength sub substring tail trace;
|
||||
inherit (self.trivial) id const pipe concat or and bitAnd bitOr bitXor
|
||||
@@ -88,25 +87,23 @@ let
|
||||
updateManyAttrsByPath;
|
||||
inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1
|
||||
concatMap flatten remove findSingle findFirst any all count
|
||||
optional optionals toList range replicate partition zipListsWith zipLists
|
||||
optional optionals toList range partition zipListsWith zipLists
|
||||
reverseList listDfs toposort sort naturalSort compareLists take
|
||||
drop sublist last init crossLists unique intersectLists
|
||||
subtractLists mutuallyExclusive groupBy groupBy';
|
||||
inherit (self.strings) concatStrings concatMapStrings concatImapStrings
|
||||
intersperse concatStringsSep concatMapStringsSep
|
||||
concatImapStringsSep concatLines makeSearchPath makeSearchPathOutput
|
||||
concatImapStringsSep makeSearchPath makeSearchPathOutput
|
||||
makeLibraryPath makeBinPath optionalString
|
||||
hasInfix hasPrefix hasSuffix stringToCharacters stringAsChars escape
|
||||
escapeShellArg escapeShellArgs
|
||||
isStorePath isStringLike
|
||||
isValidPosixName toShellVar toShellVars
|
||||
escapeShellArg escapeShellArgs isValidPosixName toShellVar toShellVars
|
||||
escapeRegex escapeXML replaceChars lowerChars
|
||||
upperChars toLower toUpper addContextFrom splitString
|
||||
removePrefix removeSuffix versionOlder versionAtLeast
|
||||
getName getVersion
|
||||
mesonOption mesonBool mesonEnable
|
||||
nameFromURL enableFeature enableFeatureAs withFeature
|
||||
withFeatureAs fixedWidthString fixedWidthNumber
|
||||
withFeatureAs fixedWidthString fixedWidthNumber isStorePath
|
||||
toInt toIntBase10 readPathsFromFile fileContents;
|
||||
inherit (self.stringsWithDeps) textClosureList textClosureMap
|
||||
noDepEntry fullDepEntry packEntry stringAfter;
|
||||
@@ -131,15 +128,14 @@ let
|
||||
mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule
|
||||
mkRenamedOptionModule mkRenamedOptionModuleWith
|
||||
mkMergedOptionModule mkChangedOptionModule
|
||||
mkAliasOptionModule mkDerivedConfig doRename
|
||||
mkAliasOptionModuleMD;
|
||||
mkAliasOptionModule mkDerivedConfig doRename;
|
||||
inherit (self.options) isOption mkEnableOption mkSinkUndeclaredOptions
|
||||
mergeDefaultOption mergeOneOption mergeEqualOption mergeUniqueOption
|
||||
getValues getFiles
|
||||
optionAttrSetToDocList optionAttrSetToDocList'
|
||||
scrubOptionValue literalExpression literalExample literalDocBook
|
||||
showOption showOptionWithDefLocs showFiles
|
||||
unknownModule mkOption mkPackageOption mkPackageOptionMD
|
||||
unknownModule mkOption mkPackageOption
|
||||
mdDoc literalMD;
|
||||
inherit (self.types) isType setType defaultTypeMerge defaultFunctor
|
||||
isOptionType mkOptionType;
|
||||
|
||||
@@ -107,7 +107,7 @@ rec {
|
||||
# Same as `makeExtensible` but the name of the extending attribute is
|
||||
# customized.
|
||||
makeExtensibleWithCustomName = extenderName: rattrs:
|
||||
fix' (self: (rattrs self) // {
|
||||
fix' rattrs // {
|
||||
${extenderName} = f: makeExtensibleWithCustomName extenderName (extends f rattrs);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -289,9 +289,7 @@ rec {
|
||||
(This means fn is type Val -> String.) */
|
||||
allowPrettyValues ? false,
|
||||
/* If this option is true, the output is indented with newlines for attribute sets and lists */
|
||||
multiline ? true,
|
||||
/* Initial indentation level */
|
||||
indent ? ""
|
||||
multiline ? true
|
||||
}:
|
||||
let
|
||||
go = indent: v: with builtins;
|
||||
@@ -350,7 +348,7 @@ rec {
|
||||
};") v)
|
||||
+ outroSpace + "}"
|
||||
else abort "generators.toPretty: should never happen (v = ${v})";
|
||||
in go indent;
|
||||
in go "";
|
||||
|
||||
# PLIST handling
|
||||
toPlist = {}: v: let
|
||||
|
||||
@@ -114,16 +114,6 @@ in mkLicense lset) ({
|
||||
fullName = "Bitstream Vera Font License";
|
||||
};
|
||||
|
||||
bitTorrent10 = {
|
||||
spdxId = "BitTorrent-1.0";
|
||||
fullName = " BitTorrent Open Source License v1.0";
|
||||
};
|
||||
|
||||
bitTorrent11 = {
|
||||
spdxId = "BitTorrent-1.1";
|
||||
fullName = " BitTorrent Open Source License v1.1";
|
||||
};
|
||||
|
||||
bola11 = {
|
||||
url = "https://blitiri.com.ar/p/bola/";
|
||||
fullName = "Buena Onda License Agreement 1.1";
|
||||
@@ -343,13 +333,6 @@ in mkLicense lset) ({
|
||||
free = false;
|
||||
};
|
||||
|
||||
ecl20 = {
|
||||
fullName = "Educational Community License, Version 2.0";
|
||||
url = "https://opensource.org/licenses/ECL-2.0";
|
||||
shortName = "ECL 2.0";
|
||||
spdxId = "ECL-2.0";
|
||||
};
|
||||
|
||||
efl10 = {
|
||||
spdxId = "EFL-1.0";
|
||||
fullName = "Eiffel Forum License v1.0";
|
||||
@@ -575,12 +558,6 @@ in mkLicense lset) ({
|
||||
redistributable = false;
|
||||
};
|
||||
|
||||
fair = {
|
||||
fullName = "Fair License";
|
||||
spdxId = "Fair";
|
||||
free = true;
|
||||
};
|
||||
|
||||
issl = {
|
||||
fullName = "Intel Simplified Software License";
|
||||
url = "https://software.intel.com/en-us/license/intel-simplified-software-license";
|
||||
@@ -732,12 +709,7 @@ in mkLicense lset) ({
|
||||
|
||||
ncsa = {
|
||||
spdxId = "NCSA";
|
||||
fullName = "University of Illinois/NCSA Open Source License";
|
||||
};
|
||||
|
||||
nlpl = {
|
||||
spdxId = "NLPL";
|
||||
fullName = "No Limit Public License";
|
||||
fullName = "University of Illinois/NCSA Open Source License";
|
||||
};
|
||||
|
||||
nposl3 = {
|
||||
@@ -870,12 +842,6 @@ in mkLicense lset) ({
|
||||
fullName = "SGI Free Software License B v2.0";
|
||||
};
|
||||
|
||||
# Gentoo seems to treat it as a license:
|
||||
# https://gitweb.gentoo.org/repo/gentoo.git/tree/licenses/SGMLUG?id=7d999af4a47bf55e53e54713d98d145f935935c1
|
||||
sgmlug = {
|
||||
fullName = "SGML UG SGML Parser Materials license";
|
||||
};
|
||||
|
||||
sleepycat = {
|
||||
spdxId = "Sleepycat";
|
||||
fullName = "Sleepycat License";
|
||||
|
||||
@@ -242,7 +242,7 @@ rec {
|
||||
|
||||
/* Return a singleton list or an empty list, depending on a boolean
|
||||
value. Useful when building lists with optional elements
|
||||
(e.g. `++ optional (system == "i686-linux") firefox`).
|
||||
(e.g. `++ optional (system == "i686-linux") firefox').
|
||||
|
||||
Type: optional :: bool -> a -> [a]
|
||||
|
||||
@@ -283,7 +283,7 @@ rec {
|
||||
*/
|
||||
toList = x: if isList x then x else [x];
|
||||
|
||||
/* Return a list of integers from `first` up to and including `last`.
|
||||
/* Return a list of integers from `first' up to and including `last'.
|
||||
|
||||
Type: range :: int -> int -> [int]
|
||||
|
||||
@@ -303,22 +303,10 @@ rec {
|
||||
else
|
||||
genList (n: first + n) (last - first + 1);
|
||||
|
||||
/* Return a list with `n` copies of an element.
|
||||
|
||||
Type: replicate :: int -> a -> [a]
|
||||
|
||||
Example:
|
||||
replicate 3 "a"
|
||||
=> [ "a" "a" "a" ]
|
||||
replicate 2 true
|
||||
=> [ true true ]
|
||||
*/
|
||||
replicate = n: elem: genList (_: elem) n;
|
||||
|
||||
/* Splits the elements of a list in two lists, `right` and
|
||||
`wrong`, depending on the evaluation of a predicate.
|
||||
|
||||
Type: (a -> bool) -> [a] -> { right :: [a]; wrong :: [a]; }
|
||||
Type: (a -> bool) -> [a] -> { right :: [a], wrong :: [a] }
|
||||
|
||||
Example:
|
||||
partition (x: x > 2) [ 5 1 2 3 4 ]
|
||||
@@ -332,7 +320,7 @@ rec {
|
||||
) { right = []; wrong = []; });
|
||||
|
||||
/* Splits the elements of a list into many lists, using the return value of a predicate.
|
||||
Predicate should return a string which becomes keys of attrset `groupBy` returns.
|
||||
Predicate should return a string which becomes keys of attrset `groupBy' returns.
|
||||
|
||||
`groupBy'` allows to customise the combining function and initial value
|
||||
|
||||
@@ -386,7 +374,7 @@ rec {
|
||||
/* Merges two lists of the same size together. If the sizes aren't the same
|
||||
the merging stops at the shortest.
|
||||
|
||||
Type: zipLists :: [a] -> [b] -> [{ fst :: a; snd :: b; }]
|
||||
Type: zipLists :: [a] -> [b] -> [{ fst :: a, snd :: b}]
|
||||
|
||||
Example:
|
||||
zipLists [ 1 2 ] [ "a" "b" ]
|
||||
|
||||
13
lib/meta.nix
13
lib/meta.nix
@@ -27,7 +27,7 @@ rec {
|
||||
setName = name: drv: drv // {inherit name;};
|
||||
|
||||
|
||||
/* Like `setName`, but takes the previous name as an argument.
|
||||
/* Like `setName', but takes the previous name as an argument.
|
||||
|
||||
Example:
|
||||
updateName (oldName: oldName + "-experimental") somePkg
|
||||
@@ -76,9 +76,7 @@ rec {
|
||||
|
||||
1. (legacy) a system string.
|
||||
|
||||
2. (modern) a pattern for the entire platform structure (see `lib.systems.inspect.platformPatterns`).
|
||||
|
||||
3. (modern) a pattern for the platform `parsed` field (see `lib.systems.inspect.patterns`).
|
||||
2. (modern) a pattern for the platform `parsed` field.
|
||||
|
||||
We can inject these into a pattern for the whole of a structured platform,
|
||||
and then match that.
|
||||
@@ -87,8 +85,6 @@ rec {
|
||||
pattern =
|
||||
if builtins.isString elem
|
||||
then { system = elem; }
|
||||
else if elem?parsed
|
||||
then elem
|
||||
else { parsed = elem; };
|
||||
in lib.matchAttrs pattern platform;
|
||||
|
||||
@@ -96,13 +92,12 @@ rec {
|
||||
|
||||
A package is available on a platform if both
|
||||
|
||||
1. One of `meta.platforms` pattern matches the given
|
||||
platform, or `meta.platforms` is not present.
|
||||
1. One of `meta.platforms` pattern matches the given platform.
|
||||
|
||||
2. None of `meta.badPlatforms` pattern matches the given platform.
|
||||
*/
|
||||
availableOn = platform: pkg:
|
||||
((!pkg?meta.platforms) || lib.any (platformMatch platform) pkg.meta.platforms) &&
|
||||
lib.any (platformMatch platform) pkg.meta.platforms &&
|
||||
lib.all (elem: !platformMatch platform elem) (pkg.meta.badPlatforms or []);
|
||||
|
||||
/* Get the corresponding attribute in lib.licenses
|
||||
|
||||
@@ -157,11 +157,6 @@ rec {
|
||||
${if prefix == []
|
||||
then null # unset => visible
|
||||
else "internal"} = true;
|
||||
# TODO: hidden during the markdown transition to not expose downstream
|
||||
# users of the docs infra to markdown if they're not ready for it.
|
||||
# we don't make this visible conditionally because it can impact
|
||||
# performance (https://github.com/NixOS/nixpkgs/pull/208407#issuecomment-1368246192)
|
||||
visible = false;
|
||||
# TODO: Change the type of this option to a submodule with a
|
||||
# freeformType, so that individual arguments can be documented
|
||||
# separately
|
||||
@@ -1115,15 +1110,6 @@ rec {
|
||||
use = id;
|
||||
};
|
||||
|
||||
/* Transitional version of mkAliasOptionModule that uses MD docs. */
|
||||
mkAliasOptionModuleMD = from: to: doRename {
|
||||
inherit from to;
|
||||
visible = true;
|
||||
warn = false;
|
||||
use = id;
|
||||
markdown = true;
|
||||
};
|
||||
|
||||
/* mkDerivedConfig : Option a -> (a -> Definition b) -> Definition b
|
||||
|
||||
Create config definitions with the same priority as the definition of another option.
|
||||
@@ -1144,7 +1130,7 @@ rec {
|
||||
(opt.highestPrio or defaultOverridePriority)
|
||||
(f opt.value);
|
||||
|
||||
doRename = { from, to, visible, warn, use, withPriority ? true, markdown ? false }:
|
||||
doRename = { from, to, visible, warn, use, withPriority ? true }:
|
||||
{ config, options, ... }:
|
||||
let
|
||||
fromOpt = getAttrFromPath from options;
|
||||
@@ -1155,9 +1141,7 @@ rec {
|
||||
{
|
||||
options = setAttrByPath from (mkOption {
|
||||
inherit visible;
|
||||
description = if markdown
|
||||
then lib.mdDoc "Alias of {option}`${showOption to}`."
|
||||
else "Alias of <option>${showOption to}</option>.";
|
||||
description = lib.mdDoc "Alias of {option}`${showOption to}`.";
|
||||
apply = x: use (toOf config);
|
||||
} // optionalAttrs (toType != null) {
|
||||
type = toType;
|
||||
|
||||
@@ -36,9 +36,6 @@ let
|
||||
inherit (lib.types)
|
||||
mkOptionType
|
||||
;
|
||||
prioritySuggestion = ''
|
||||
Use `lib.mkForce value` or `lib.mkDefault value` to change the priority on any of these definitions.
|
||||
'';
|
||||
in
|
||||
rec {
|
||||
|
||||
@@ -117,7 +114,7 @@ rec {
|
||||
|
||||
You can omit the default path if the name of the option is also attribute path in nixpkgs.
|
||||
|
||||
Type: mkPackageOption :: pkgs -> string -> { default :: [string]; example :: null | string | [string]; } -> option
|
||||
Type: mkPackageOption :: pkgs -> string -> { default :: [string], example :: null | string | [string] } -> option
|
||||
|
||||
Example:
|
||||
mkPackageOption pkgs "hello" { }
|
||||
@@ -139,7 +136,7 @@ rec {
|
||||
let default' = if !isList default then [ default ] else default;
|
||||
in mkOption {
|
||||
type = lib.types.package;
|
||||
description = "The ${name} package to use.";
|
||||
description = lib.mdDoc "The ${name} package to use.";
|
||||
default = attrByPath default'
|
||||
(throw "${concatStringsSep "." default'} cannot be found in pkgs") pkgs;
|
||||
defaultText = literalExpression ("pkgs." + concatStringsSep "." default');
|
||||
@@ -147,11 +144,6 @@ rec {
|
||||
(if isList example then "pkgs." + concatStringsSep "." example else example);
|
||||
};
|
||||
|
||||
/* Like mkPackageOption, but emit an mdDoc description instead of DocBook. */
|
||||
mkPackageOptionMD = args: name: extra:
|
||||
let option = mkPackageOption args name extra;
|
||||
in option // { description = lib.mdDoc option.description; };
|
||||
|
||||
/* This option accepts anything, but it does not produce any result.
|
||||
|
||||
This is useful for sharing a module across different module sets
|
||||
@@ -187,7 +179,7 @@ rec {
|
||||
if length defs == 1
|
||||
then (head defs).value
|
||||
else assert length defs > 1;
|
||||
throw "The option `${showOption loc}' is defined multiple times while it's expected to be unique.\n${message}\nDefinition values:${showDefs defs}\n${prioritySuggestion}";
|
||||
throw "The option `${showOption loc}' is defined multiple times.\n${message}\nDefinition values:${showDefs defs}";
|
||||
|
||||
/* "Merge" option definitions by checking that they all have the same value. */
|
||||
mergeEqualOption = loc: defs:
|
||||
@@ -198,13 +190,13 @@ rec {
|
||||
else if length defs == 1 then (head defs).value
|
||||
else (foldl' (first: def:
|
||||
if def.value != first.value then
|
||||
throw "The option `${showOption loc}' has conflicting definition values:${showDefs [ first def ]}\n${prioritySuggestion}"
|
||||
throw "The option `${showOption loc}' has conflicting definition values:${showDefs [ first def ]}"
|
||||
else
|
||||
first) (head defs) (tail defs)).value;
|
||||
|
||||
/* Extracts values of all "value" keys of the given list.
|
||||
|
||||
Type: getValues :: [ { value :: a; } ] -> [a]
|
||||
Type: getValues :: [ { value :: a } ] -> [a]
|
||||
|
||||
Example:
|
||||
getValues [ { value = 1; } { value = 2; } ] // => [ 1 2 ]
|
||||
@@ -214,7 +206,7 @@ rec {
|
||||
|
||||
/* Extracts values of all "file" keys of the given list
|
||||
|
||||
Type: getFiles :: [ { file :: a; } ] -> [a]
|
||||
Type: getFiles :: [ { file :: a } ] -> [a]
|
||||
|
||||
Example:
|
||||
getFiles [ { file = "file1"; } { file = "file2"; } ] // => [ "file1" "file2" ]
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
# Path library
|
||||
|
||||
This document explains why the `lib.path` library is designed the way it is.
|
||||
|
||||
The purpose of this library is to process [filesystem paths]. It does not read files from the filesystem.
|
||||
It exists to support the native Nix [path value type] with extra functionality.
|
||||
|
||||
[filesystem paths]: https://en.m.wikipedia.org/wiki/Path_(computing)
|
||||
[path value type]: https://nixos.org/manual/nix/stable/language/values.html#type-path
|
||||
|
||||
As an extension of the path value type, it inherits the same intended use cases and limitations:
|
||||
- Only use paths to access files at evaluation time, such as the local project source.
|
||||
- Paths cannot point to derivations, so they are unfit to represent dependencies.
|
||||
- A path implicitly imports the referenced files into the Nix store when interpolated to a string. Therefore paths are not suitable to access files at build- or run-time, as you risk importing the path from the evaluation system instead.
|
||||
|
||||
Overall, this library works with two types of paths:
|
||||
- Absolute paths are represented with the Nix [path value type]. Nix automatically normalises these paths.
|
||||
- Subpaths are represented with the [string value type] since path value types don't support relative paths. This library normalises these paths as safely as possible. Absolute paths in strings are not supported.
|
||||
|
||||
A subpath refers to a specific file or directory within an absolute base directory.
|
||||
It is a stricter form of a relative path, notably [without support for `..` components][parents] since those could escape the base directory.
|
||||
|
||||
[string value type]: https://nixos.org/manual/nix/stable/language/values.html#type-string
|
||||
|
||||
This library is designed to be as safe and intuitive as possible, throwing errors when operations are attempted that would produce surprising results, and giving the expected result otherwise.
|
||||
|
||||
This library is designed to work well as a dependency for the `lib.filesystem` and `lib.sources` library components. Contrary to these library components, `lib.path` does not read any paths from the filesystem.
|
||||
|
||||
This library makes only these assumptions about paths and no others:
|
||||
- `dirOf path` returns the path to the parent directory of `path`, unless `path` is the filesystem root, in which case `path` is returned.
|
||||
- There can be multiple filesystem roots: `p == dirOf p` and `q == dirOf q` does not imply `p == q`.
|
||||
- While there's only a single filesystem root in stable Nix, the [lazy trees feature](https://github.com/NixOS/nix/pull/6530) introduces [additional filesystem roots](https://github.com/NixOS/nix/pull/6530#discussion_r1041442173).
|
||||
- `path + ("/" + string)` returns the path to the `string` subdirectory in `path`.
|
||||
- If `string` contains no `/` characters, then `dirOf (path + ("/" + string)) == path`.
|
||||
- If `string` contains no `/` characters, then `baseNameOf (path + ("/" + string)) == string`.
|
||||
- `path1 == path2` returns `true` only if `path1` points to the same filesystem path as `path2`.
|
||||
|
||||
Notably we do not make the assumption that we can turn paths into strings using `toString path`.
|
||||
|
||||
## Design decisions
|
||||
|
||||
Each subsection here contains a decision along with arguments and counter-arguments for (+) and against (-) that decision.
|
||||
|
||||
### Leading dots for relative paths
|
||||
[leading-dots]: #leading-dots-for-relative-paths
|
||||
|
||||
Observing: Since subpaths are a form of relative paths, they can have a leading `./` to indicate it being a relative path, this is generally not necessary for tools though.
|
||||
|
||||
Considering: Paths should be as explicit, consistent and unambiguous as possible.
|
||||
|
||||
Decision: Returned subpaths should always have a leading `./`.
|
||||
|
||||
<details>
|
||||
<summary>Arguments</summary>
|
||||
|
||||
- (+) In shells, just running `foo` as a command wouldn't execute the file `foo`, whereas `./foo` would execute the file. In contrast, `foo/bar` does execute that file without the need for `./`. This can lead to confusion about when a `./` needs to be prefixed. If a `./` is always included, this becomes a non-issue. This effectively then means that paths don't overlap with command names.
|
||||
- (+) Prepending with `./` makes the subpaths always valid as relative Nix path expressions.
|
||||
- (+) Using paths in command line arguments could give problems if not escaped properly, e.g. if a path was `--version`. This is not a problem with `./--version`. This effectively then means that paths don't overlap with GNU-style command line options.
|
||||
- (-) `./` is not required to resolve relative paths, resolution always has an implicit `./` as prefix.
|
||||
- (-) It's less noisy without the `./`, e.g. in error messages.
|
||||
- (+) But similarly, it could be confusing whether something was even a path.
|
||||
e.g. `foo` could be anything, but `./foo` is more clearly a path.
|
||||
- (+) Makes it more uniform with absolute paths (those always start with `/`).
|
||||
- (-) That is not relevant for practical purposes.
|
||||
- (+) `find` also outputs results with `./`.
|
||||
- (-) But only if you give it an argument of `.`. If you give it the argument `some-directory`, it won't prefix that.
|
||||
- (-) `realpath --relative-to` doesn't prefix relative paths with `./`.
|
||||
- (+) There is no need to return the same result as `realpath`.
|
||||
|
||||
</details>
|
||||
|
||||
### Representation of the current directory
|
||||
[curdir]: #representation-of-the-current-directory
|
||||
|
||||
Observing: The subpath that produces the base directory can be represented with `.` or `./` or `./.`.
|
||||
|
||||
Considering: Paths should be as consistent and unambiguous as possible.
|
||||
|
||||
Decision: It should be `./.`.
|
||||
|
||||
<details>
|
||||
<summary>Arguments</summary>
|
||||
|
||||
- (+) `./` would be inconsistent with [the decision to not persist trailing slashes][trailing-slashes].
|
||||
- (-) `.` is how `realpath` normalises paths.
|
||||
- (+) `.` can be interpreted as a shell command (it's a builtin for sourcing files in `bash` and `zsh`).
|
||||
- (+) `.` would be the only path without a `/`. It could not be used as a Nix path expression, since those require at least one `/` to be parsed as such.
|
||||
- (-) `./.` is rather long.
|
||||
- (-) We don't require users to type this though, as it's only output by the library.
|
||||
As inputs all three variants are supported for subpaths (and we can't do anything about absolute paths)
|
||||
- (-) `builtins.dirOf "foo" == "."`, so `.` would be consistent with that.
|
||||
- (+) `./.` is consistent with the [decision to have leading `./`][leading-dots].
|
||||
- (+) `./.` is a valid Nix path expression, although this property does not hold for every relative path or subpath.
|
||||
|
||||
</details>
|
||||
|
||||
### Subpath representation
|
||||
[relrepr]: #subpath-representation
|
||||
|
||||
Observing: Subpaths such as `foo/bar` can be represented in various ways:
|
||||
- string: `"foo/bar"`
|
||||
- list with all the components: `[ "foo" "bar" ]`
|
||||
- attribute set: `{ type = "relative-path"; components = [ "foo" "bar" ]; }`
|
||||
|
||||
Considering: Paths should be as safe to use as possible. We should generate string outputs in the library and not encourage users to do that themselves.
|
||||
|
||||
Decision: Paths are represented as strings.
|
||||
|
||||
<details>
|
||||
<summary>Arguments</summary>
|
||||
|
||||
- (+) It's simpler for the users of the library. One doesn't have to convert a path a string before it can be used.
|
||||
- (+) Naively converting the list representation to a string with `concatStringsSep "/"` would break for `[]`, requiring library users to be more careful.
|
||||
- (+) It doesn't encourage people to do their own path processing and instead use the library.
|
||||
With a list representation it would seem easy to just use `lib.lists.init` to get the parent directory, but then it breaks for `.`, which would be represented as `[ ]`.
|
||||
- (+) `+` is convenient and doesn't work on lists and attribute sets.
|
||||
- (-) Shouldn't use `+` anyways, we export safer functions for path manipulation.
|
||||
|
||||
</details>
|
||||
|
||||
### Parent directory
|
||||
[parents]: #parent-directory
|
||||
|
||||
Observing: Relative paths can have `..` components, which refer to the parent directory.
|
||||
|
||||
Considering: Paths should be as safe and unambiguous as possible.
|
||||
|
||||
Decision: `..` path components in string paths are not supported, neither as inputs nor as outputs. Hence, string paths are called subpaths, rather than relative paths.
|
||||
|
||||
<details>
|
||||
<summary>Arguments</summary>
|
||||
|
||||
- (+) If we wanted relative paths to behave according to the "physical" interpretation (as a directory tree with relations between nodes), it would require resolving symlinks, since e.g. `foo/..` would not be the same as `.` if `foo` is a symlink.
|
||||
- (-) The "logical" interpretation is also valid (treating paths as a sequence of names), and is used by some software. It is simpler, and not using symlinks at all is safer.
|
||||
- (+) Mixing both models can lead to surprises.
|
||||
- (+) We can't resolve symlinks without filesystem access.
|
||||
- (+) Nix also doesn't support reading symlinks at evaluation time.
|
||||
- (-) We could just not handle such cases, e.g. `equals "foo" "foo/bar/.. == false`. The paths are different, we don't need to check whether the paths point to the same thing.
|
||||
- (+) Assume we said `relativeTo /foo /bar == "../bar"`. If this is used like `/bar/../foo` in the end, and `bar` turns out to be a symlink to somewhere else, this won't be accurate.
|
||||
- (-) We could decide to not support such ambiguous operations, or mark them as such, e.g. the normal `relativeTo` will error on such a case, but there could be `extendedRelativeTo` supporting that.
|
||||
- (-) `..` are a part of paths, a path library should therefore support it.
|
||||
- (+) If we can convincingly argue that all such use cases are better done e.g. with runtime tools, the library not supporting it can nudge people towards using those.
|
||||
- (-) We could allow "..", but only in the prefix.
|
||||
- (+) Then we'd have to throw an error for doing `append /some/path "../foo"`, making it non-composable.
|
||||
- (+) The same is for returning paths with `..`: `relativeTo /foo /bar => "../bar"` would produce a non-composable path.
|
||||
- (+) We argue that `..` is not needed at the Nix evaluation level, since we'd always start evaluation from the project root and don't go up from there.
|
||||
- (+) `..` is supported in Nix paths, turning them into absolute paths.
|
||||
- (-) This is ambiguous in the presence of symlinks.
|
||||
- (+) If you need `..` for building or runtime, you can use build-/run-time tooling to create those (e.g. `realpath` with `--relative-to`), or use absolute paths instead.
|
||||
This also gives you the ability to correctly handle symlinks.
|
||||
|
||||
</details>
|
||||
|
||||
### Trailing slashes
|
||||
[trailing-slashes]: #trailing-slashes
|
||||
|
||||
Observing: Subpaths can contain trailing slashes, like `foo/`, indicating that the path points to a directory and not a file.
|
||||
|
||||
Considering: Paths should be as consistent as possible, there should only be a single normalisation for the same path.
|
||||
|
||||
Decision: All functions remove trailing slashes in their results.
|
||||
|
||||
<details>
|
||||
<summary>Arguments</summary>
|
||||
|
||||
- (+) It allows normalisations to be unique, in that there's only a single normalisation for the same path. If trailing slashes were preserved, both `foo/bar` and `foo/bar/` would be valid but different normalisations for the same path.
|
||||
- Comparison to other frameworks to figure out the least surprising behavior:
|
||||
- (+) Nix itself doesn't support trailing slashes when parsing and doesn't preserve them when appending paths.
|
||||
- (-) [Rust's std::path](https://doc.rust-lang.org/std/path/index.html) does preserve them during [construction](https://doc.rust-lang.org/std/path/struct.Path.html#method.new).
|
||||
- (+) Doesn't preserve them when returning individual [components](https://doc.rust-lang.org/std/path/struct.Path.html#method.components).
|
||||
- (+) Doesn't preserve them when [canonicalizing](https://doc.rust-lang.org/std/path/struct.Path.html#method.canonicalize).
|
||||
- (+) [Python 3's pathlib](https://docs.python.org/3/library/pathlib.html#module-pathlib) doesn't preserve them during [construction](https://docs.python.org/3/library/pathlib.html#pathlib.PurePath).
|
||||
- Notably it represents the individual components as a list internally.
|
||||
- (-) [Haskell's filepath](https://hackage.haskell.org/package/filepath-1.4.100.0) has [explicit support](https://hackage.haskell.org/package/filepath-1.4.100.0/docs/System-FilePath.html#g:6) for handling trailing slashes.
|
||||
- (-) Does preserve them for [normalisation](https://hackage.haskell.org/package/filepath-1.4.100.0/docs/System-FilePath.html#v:normalise).
|
||||
- (-) [NodeJS's Path library](https://nodejs.org/api/path.html) preserves trailing slashes for [normalisation](https://nodejs.org/api/path.html#pathnormalizepath).
|
||||
- (+) For [parsing a path](https://nodejs.org/api/path.html#pathparsepath) into its significant elements, trailing slashes are not preserved.
|
||||
- (+) Nix's builtin function `dirOf` gives an unexpected result for paths with trailing slashes: `dirOf "foo/bar/" == "foo/bar"`.
|
||||
Inconsistently, `baseNameOf` works correctly though: `baseNameOf "foo/bar/" == "bar"`.
|
||||
- (-) We are writing a path library to improve handling of paths though, so we shouldn't use these functions and discourage their use.
|
||||
- (-) Unexpected result when normalising intermediate paths, like `relative.normalise ("foo" + "/") + "bar" == "foobar"`.
|
||||
- (+) This is not a practical use case though.
|
||||
- (+) Don't use `+` to append paths, this library has a `join` function for that.
|
||||
- (-) Users might use `+` out of habit though.
|
||||
- (+) The `realpath` command also removes trailing slashes.
|
||||
- (+) Even with a trailing slash, the path is the same, it's only an indication that it's a directory.
|
||||
|
||||
</details>
|
||||
|
||||
## Other implementations and references
|
||||
|
||||
- [Rust](https://doc.rust-lang.org/std/path/struct.Path.html)
|
||||
- [Python](https://docs.python.org/3/library/pathlib.html)
|
||||
- [Haskell](https://hackage.haskell.org/package/filepath-1.4.100.0/docs/System-FilePath.html)
|
||||
- [Nodejs](https://nodejs.org/api/path.html)
|
||||
- [POSIX.1-2017](https://pubs.opengroup.org/onlinepubs/9699919799/nframe.html)
|
||||
@@ -1,274 +0,0 @@
|
||||
# Functions for working with paths, see ./path.md
|
||||
{ lib }:
|
||||
let
|
||||
|
||||
inherit (builtins)
|
||||
isString
|
||||
isPath
|
||||
split
|
||||
match
|
||||
;
|
||||
|
||||
inherit (lib.lists)
|
||||
length
|
||||
head
|
||||
last
|
||||
genList
|
||||
elemAt
|
||||
;
|
||||
|
||||
inherit (lib.strings)
|
||||
concatStringsSep
|
||||
substring
|
||||
;
|
||||
|
||||
inherit (lib.asserts)
|
||||
assertMsg
|
||||
;
|
||||
|
||||
inherit (lib.path.subpath)
|
||||
isValid
|
||||
;
|
||||
|
||||
# Return the reason why a subpath is invalid, or `null` if it's valid
|
||||
subpathInvalidReason = value:
|
||||
if ! isString value then
|
||||
"The given value is of type ${builtins.typeOf value}, but a string was expected"
|
||||
else if value == "" then
|
||||
"The given string is empty"
|
||||
else if substring 0 1 value == "/" then
|
||||
"The given string \"${value}\" starts with a `/`, representing an absolute path"
|
||||
# We don't support ".." components, see ./path.md#parent-directory
|
||||
else if match "(.*/)?\\.\\.(/.*)?" value != null then
|
||||
"The given string \"${value}\" contains a `..` component, which is not allowed in subpaths"
|
||||
else null;
|
||||
|
||||
# Split and normalise a relative path string into its components.
|
||||
# Error for ".." components and doesn't include "." components
|
||||
splitRelPath = path:
|
||||
let
|
||||
# Split the string into its parts using regex for efficiency. This regex
|
||||
# matches patterns like "/", "/./", "/././", with arbitrarily many "/"s
|
||||
# together. These are the main special cases:
|
||||
# - Leading "./" gets split into a leading "." part
|
||||
# - Trailing "/." or "/" get split into a trailing "." or ""
|
||||
# part respectively
|
||||
#
|
||||
# These are the only cases where "." and "" parts can occur
|
||||
parts = split "/+(\\./+)*" path;
|
||||
|
||||
# `split` creates a list of 2 * k + 1 elements, containing the k +
|
||||
# 1 parts, interleaved with k matches where k is the number of
|
||||
# (non-overlapping) matches. This calculation here gets the number of parts
|
||||
# back from the list length
|
||||
# floor( (2 * k + 1) / 2 ) + 1 == floor( k + 1/2 ) + 1 == k + 1
|
||||
partCount = length parts / 2 + 1;
|
||||
|
||||
# To assemble the final list of components we want to:
|
||||
# - Skip a potential leading ".", normalising "./foo" to "foo"
|
||||
# - Skip a potential trailing "." or "", normalising "foo/" and "foo/." to
|
||||
# "foo". See ./path.md#trailing-slashes
|
||||
skipStart = if head parts == "." then 1 else 0;
|
||||
skipEnd = if last parts == "." || last parts == "" then 1 else 0;
|
||||
|
||||
# We can now know the length of the result by removing the number of
|
||||
# skipped parts from the total number
|
||||
componentCount = partCount - skipEnd - skipStart;
|
||||
|
||||
in
|
||||
# Special case of a single "." path component. Such a case leaves a
|
||||
# componentCount of -1 due to the skipStart/skipEnd not verifying that
|
||||
# they don't refer to the same character
|
||||
if path == "." then []
|
||||
|
||||
# Generate the result list directly. This is more efficient than a
|
||||
# combination of `filter`, `init` and `tail`, because here we don't
|
||||
# allocate any intermediate lists
|
||||
else genList (index:
|
||||
# To get to the element we need to add the number of parts we skip and
|
||||
# multiply by two due to the interleaved layout of `parts`
|
||||
elemAt parts ((skipStart + index) * 2)
|
||||
) componentCount;
|
||||
|
||||
# Join relative path components together
|
||||
joinRelPath = components:
|
||||
# Always return relative paths with `./` as a prefix (./path.md#leading-dots-for-relative-paths)
|
||||
"./" +
|
||||
# An empty string is not a valid relative path, so we need to return a `.` when we have no components
|
||||
(if components == [] then "." else concatStringsSep "/" components);
|
||||
|
||||
in /* No rec! Add dependencies on this file at the top. */ {
|
||||
|
||||
/* Append a subpath string to a path.
|
||||
|
||||
Like `path + ("/" + string)` but safer, because it errors instead of returning potentially surprising results.
|
||||
More specifically, it checks that the first argument is a [path value type](https://nixos.org/manual/nix/stable/language/values.html#type-path"),
|
||||
and that the second argument is a valid subpath string (see `lib.path.subpath.isValid`).
|
||||
|
||||
Type:
|
||||
append :: Path -> String -> Path
|
||||
|
||||
Example:
|
||||
append /foo "bar/baz"
|
||||
=> /foo/bar/baz
|
||||
|
||||
# subpaths don't need to be normalised
|
||||
append /foo "./bar//baz/./"
|
||||
=> /foo/bar/baz
|
||||
|
||||
# can append to root directory
|
||||
append /. "foo/bar"
|
||||
=> /foo/bar
|
||||
|
||||
# first argument needs to be a path value type
|
||||
append "/foo" "bar"
|
||||
=> <error>
|
||||
|
||||
# second argument needs to be a valid subpath string
|
||||
append /foo /bar
|
||||
=> <error>
|
||||
append /foo ""
|
||||
=> <error>
|
||||
append /foo "/bar"
|
||||
=> <error>
|
||||
append /foo "../bar"
|
||||
=> <error>
|
||||
*/
|
||||
append =
|
||||
# The absolute path to append to
|
||||
path:
|
||||
# The subpath string to append
|
||||
subpath:
|
||||
assert assertMsg (isPath path) ''
|
||||
lib.path.append: The first argument is of type ${builtins.typeOf path}, but a path was expected'';
|
||||
assert assertMsg (isValid subpath) ''
|
||||
lib.path.append: Second argument is not a valid subpath string:
|
||||
${subpathInvalidReason subpath}'';
|
||||
path + ("/" + subpath);
|
||||
|
||||
/* Whether a value is a valid subpath string.
|
||||
|
||||
- The value is a string
|
||||
|
||||
- The string is not empty
|
||||
|
||||
- The string doesn't start with a `/`
|
||||
|
||||
- The string doesn't contain any `..` path components
|
||||
|
||||
Type:
|
||||
subpath.isValid :: String -> Bool
|
||||
|
||||
Example:
|
||||
# Not a string
|
||||
subpath.isValid null
|
||||
=> false
|
||||
|
||||
# Empty string
|
||||
subpath.isValid ""
|
||||
=> false
|
||||
|
||||
# Absolute path
|
||||
subpath.isValid "/foo"
|
||||
=> false
|
||||
|
||||
# Contains a `..` path component
|
||||
subpath.isValid "../foo"
|
||||
=> false
|
||||
|
||||
# Valid subpath
|
||||
subpath.isValid "foo/bar"
|
||||
=> true
|
||||
|
||||
# Doesn't need to be normalised
|
||||
subpath.isValid "./foo//bar/"
|
||||
=> true
|
||||
*/
|
||||
subpath.isValid =
|
||||
# The value to check
|
||||
value:
|
||||
subpathInvalidReason value == null;
|
||||
|
||||
|
||||
/* Normalise a subpath. Throw an error if the subpath isn't valid, see
|
||||
`lib.path.subpath.isValid`
|
||||
|
||||
- Limit repeating `/` to a single one
|
||||
|
||||
- Remove redundant `.` components
|
||||
|
||||
- Remove trailing `/` and `/.`
|
||||
|
||||
- Add leading `./`
|
||||
|
||||
Laws:
|
||||
|
||||
- Idempotency - normalising multiple times gives the same result:
|
||||
|
||||
subpath.normalise (subpath.normalise p) == subpath.normalise p
|
||||
|
||||
- Uniqueness - there's only a single normalisation for the paths that lead to the same file system node:
|
||||
|
||||
subpath.normalise p != subpath.normalise q -> $(realpath ${p}) != $(realpath ${q})
|
||||
|
||||
- Don't change the result when appended to a Nix path value:
|
||||
|
||||
base + ("/" + p) == base + ("/" + subpath.normalise p)
|
||||
|
||||
- Don't change the path according to `realpath`:
|
||||
|
||||
$(realpath ${p}) == $(realpath ${subpath.normalise p})
|
||||
|
||||
- Only error on invalid subpaths:
|
||||
|
||||
builtins.tryEval (subpath.normalise p)).success == subpath.isValid p
|
||||
|
||||
Type:
|
||||
subpath.normalise :: String -> String
|
||||
|
||||
Example:
|
||||
# limit repeating `/` to a single one
|
||||
subpath.normalise "foo//bar"
|
||||
=> "./foo/bar"
|
||||
|
||||
# remove redundant `.` components
|
||||
subpath.normalise "foo/./bar"
|
||||
=> "./foo/bar"
|
||||
|
||||
# add leading `./`
|
||||
subpath.normalise "foo/bar"
|
||||
=> "./foo/bar"
|
||||
|
||||
# remove trailing `/`
|
||||
subpath.normalise "foo/bar/"
|
||||
=> "./foo/bar"
|
||||
|
||||
# remove trailing `/.`
|
||||
subpath.normalise "foo/bar/."
|
||||
=> "./foo/bar"
|
||||
|
||||
# Return the current directory as `./.`
|
||||
subpath.normalise "."
|
||||
=> "./."
|
||||
|
||||
# error on `..` path components
|
||||
subpath.normalise "foo/../bar"
|
||||
=> <error>
|
||||
|
||||
# error on empty string
|
||||
subpath.normalise ""
|
||||
=> <error>
|
||||
|
||||
# error on absolute path
|
||||
subpath.normalise "/foo"
|
||||
=> <error>
|
||||
*/
|
||||
subpath.normalise =
|
||||
# The subpath string to normalise
|
||||
subpath:
|
||||
assert assertMsg (isValid subpath) ''
|
||||
lib.path.subpath.normalise: Argument is not a valid subpath string:
|
||||
${subpathInvalidReason subpath}'';
|
||||
joinRelPath (splitRelPath subpath);
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
nixpkgs ? ../../..,
|
||||
system ? builtins.currentSystem,
|
||||
pkgs ? import nixpkgs {
|
||||
config = {};
|
||||
overlays = [];
|
||||
inherit system;
|
||||
},
|
||||
libpath ? ../..,
|
||||
# Random seed
|
||||
seed ? null,
|
||||
}:
|
||||
pkgs.runCommand "lib-path-tests" {
|
||||
nativeBuildInputs = with pkgs; [
|
||||
nix
|
||||
jq
|
||||
bc
|
||||
];
|
||||
} ''
|
||||
# Needed to make Nix evaluation work
|
||||
export NIX_STATE_DIR=$(mktemp -d)
|
||||
|
||||
cp -r ${libpath} lib
|
||||
export TEST_LIB=$PWD/lib
|
||||
|
||||
echo "Running unit tests lib/path/tests/unit.nix"
|
||||
nix-instantiate --eval lib/path/tests/unit.nix \
|
||||
--argstr libpath "$TEST_LIB"
|
||||
|
||||
echo "Running property tests lib/path/tests/prop.sh"
|
||||
bash lib/path/tests/prop.sh ${toString seed}
|
||||
|
||||
touch $out
|
||||
''
|
||||
@@ -1,64 +0,0 @@
|
||||
# Generate random path-like strings, separated by null characters.
|
||||
#
|
||||
# Invocation:
|
||||
#
|
||||
# awk -f ./generate.awk -v <variable>=<value> | tr '\0' '\n'
|
||||
#
|
||||
# Customizable variables (all default to 0):
|
||||
# - seed: Deterministic random seed to use for generation
|
||||
# - count: Number of paths to generate
|
||||
# - extradotweight: Give extra weight to dots being generated
|
||||
# - extraslashweight: Give extra weight to slashes being generated
|
||||
# - extranullweight: Give extra weight to null being generated, making paths shorter
|
||||
BEGIN {
|
||||
# Random seed, passed explicitly for reproducibility
|
||||
srand(seed)
|
||||
|
||||
# Don't include special characters below 32
|
||||
minascii = 32
|
||||
# Don't include DEL at 128
|
||||
maxascii = 127
|
||||
upperascii = maxascii - minascii
|
||||
|
||||
# add extra weight for ., in addition to the one weight from the ascii range
|
||||
upperdot = upperascii + extradotweight
|
||||
|
||||
# add extra weight for /, in addition to the one weight from the ascii range
|
||||
upperslash = upperdot + extraslashweight
|
||||
|
||||
# add extra weight for null, indicating the end of the string
|
||||
# Must be at least 1 to have strings end at all
|
||||
total = upperslash + 1 + extranullweight
|
||||
|
||||
# new=1 indicates that it's a new string
|
||||
new=1
|
||||
while (count > 0) {
|
||||
|
||||
# Random integer between [0, total)
|
||||
value = int(rand() * total)
|
||||
|
||||
if (value < upperascii) {
|
||||
# Ascii range
|
||||
printf("%c", value + minascii)
|
||||
new=0
|
||||
|
||||
} else if (value < upperdot) {
|
||||
# Dot range
|
||||
printf "."
|
||||
new=0
|
||||
|
||||
} else if (value < upperslash) {
|
||||
# If it's the start of a new path, only generate a / in 10% of cases
|
||||
# This is always an invalid subpath, which is not a very interesting case
|
||||
if (new && rand() > 0.1) continue
|
||||
printf "/"
|
||||
|
||||
} else {
|
||||
# Do not generate empty strings
|
||||
if (new) continue
|
||||
printf "\x00"
|
||||
count--
|
||||
new=1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
# Given a list of path-like strings, check some properties of the path library
|
||||
# using those paths and return a list of attribute sets of the following form:
|
||||
#
|
||||
# { <string> = <lib.path.subpath.normalise string>; }
|
||||
#
|
||||
# If `normalise` fails to evaluate, the attribute value is set to `""`.
|
||||
# If not, the resulting value is normalised again and an appropriate attribute set added to the output list.
|
||||
{
|
||||
# The path to the nixpkgs lib to use
|
||||
libpath,
|
||||
# A flat directory containing files with randomly-generated
|
||||
# path-like values
|
||||
dir,
|
||||
}:
|
||||
let
|
||||
lib = import libpath;
|
||||
|
||||
# read each file into a string
|
||||
strings = map (name:
|
||||
builtins.readFile (dir + "/${name}")
|
||||
) (builtins.attrNames (builtins.readDir dir));
|
||||
|
||||
inherit (lib.path.subpath) normalise isValid;
|
||||
inherit (lib.asserts) assertMsg;
|
||||
|
||||
normaliseAndCheck = str:
|
||||
let
|
||||
originalValid = isValid str;
|
||||
|
||||
tryOnce = builtins.tryEval (normalise str);
|
||||
tryTwice = builtins.tryEval (normalise tryOnce.value);
|
||||
|
||||
absConcatOrig = /. + ("/" + str);
|
||||
absConcatNormalised = /. + ("/" + tryOnce.value);
|
||||
in
|
||||
# Check the lib.path.subpath.normalise property to only error on invalid subpaths
|
||||
assert assertMsg
|
||||
(originalValid -> tryOnce.success)
|
||||
"Even though string \"${str}\" is valid as a subpath, the normalisation for it failed";
|
||||
assert assertMsg
|
||||
(! originalValid -> ! tryOnce.success)
|
||||
"Even though string \"${str}\" is invalid as a subpath, the normalisation for it succeeded";
|
||||
|
||||
# Check normalisation idempotency
|
||||
assert assertMsg
|
||||
(originalValid -> tryTwice.success)
|
||||
"For valid subpath \"${str}\", the normalisation \"${tryOnce.value}\" was not a valid subpath";
|
||||
assert assertMsg
|
||||
(originalValid -> tryOnce.value == tryTwice.value)
|
||||
"For valid subpath \"${str}\", normalising it once gives \"${tryOnce.value}\" but normalising it twice gives a different result: \"${tryTwice.value}\"";
|
||||
|
||||
# Check that normalisation doesn't change a string when appended to an absolute Nix path value
|
||||
assert assertMsg
|
||||
(originalValid -> absConcatOrig == absConcatNormalised)
|
||||
"For valid subpath \"${str}\", appending to an absolute Nix path value gives \"${absConcatOrig}\", but appending the normalised result \"${tryOnce.value}\" gives a different value \"${absConcatNormalised}\"";
|
||||
|
||||
# Return an empty string when failed
|
||||
if tryOnce.success then tryOnce.value else "";
|
||||
|
||||
in lib.genAttrs strings normaliseAndCheck
|
||||
@@ -1,179 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Property tests for the `lib.path` library
|
||||
#
|
||||
# It generates random path-like strings and runs the functions on
|
||||
# them, checking that the expected laws of the functions hold
|
||||
|
||||
set -euo pipefail
|
||||
shopt -s inherit_errexit
|
||||
|
||||
# https://stackoverflow.com/a/246128
|
||||
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
|
||||
if test -z "${TEST_LIB:-}"; then
|
||||
TEST_LIB=$SCRIPT_DIR/../..
|
||||
fi
|
||||
|
||||
tmp="$(mktemp -d)"
|
||||
clean_up() {
|
||||
rm -rf "$tmp"
|
||||
}
|
||||
trap clean_up EXIT
|
||||
mkdir -p "$tmp/work"
|
||||
cd "$tmp/work"
|
||||
|
||||
# Defaulting to a random seed but the first argument can override this
|
||||
seed=${1:-$RANDOM}
|
||||
echo >&2 "Using seed $seed, use \`lib/path/tests/prop.sh $seed\` to reproduce this result"
|
||||
|
||||
# The number of random paths to generate. This specific number was chosen to
|
||||
# be fast enough while still generating enough variety to detect bugs.
|
||||
count=500
|
||||
|
||||
debug=0
|
||||
# debug=1 # print some extra info
|
||||
# debug=2 # print generated values
|
||||
|
||||
# Fine tuning parameters to balance the number of generated invalid paths
|
||||
# to the variance in generated paths.
|
||||
extradotweight=64 # Larger value: more dots
|
||||
extraslashweight=64 # Larger value: more slashes
|
||||
extranullweight=16 # Larger value: shorter strings
|
||||
|
||||
die() {
|
||||
echo >&2 "test case failed: " "$@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [[ "$debug" -ge 1 ]]; then
|
||||
echo >&2 "Generating $count random path-like strings"
|
||||
fi
|
||||
|
||||
# Read stream of null-terminated strings entry-by-entry into bash,
|
||||
# write it to a file and the `strings` array.
|
||||
declare -a strings=()
|
||||
mkdir -p "$tmp/strings"
|
||||
while IFS= read -r -d $'\0' str; do
|
||||
printf "%s" "$str" > "$tmp/strings/${#strings[@]}"
|
||||
strings+=("$str")
|
||||
done < <(awk \
|
||||
-f "$SCRIPT_DIR"/generate.awk \
|
||||
-v seed="$seed" \
|
||||
-v count="$count" \
|
||||
-v extradotweight="$extradotweight" \
|
||||
-v extraslashweight="$extraslashweight" \
|
||||
-v extranullweight="$extranullweight")
|
||||
|
||||
if [[ "$debug" -ge 1 ]]; then
|
||||
echo >&2 "Trying to normalise the generated path-like strings with Nix"
|
||||
fi
|
||||
|
||||
# Precalculate all normalisations with a single Nix call. Calling Nix for each
|
||||
# string individually would take way too long
|
||||
nix-instantiate --eval --strict --json \
|
||||
--argstr libpath "$TEST_LIB" \
|
||||
--argstr dir "$tmp/strings" \
|
||||
"$SCRIPT_DIR"/prop.nix \
|
||||
>"$tmp/result.json"
|
||||
|
||||
# Uses some jq magic to turn the resulting attribute set into an associative
|
||||
# bash array assignment
|
||||
declare -A normalised_result="($(jq '
|
||||
to_entries
|
||||
| map("[\(.key | @sh)]=\(.value | @sh)")
|
||||
| join(" \n")' -r < "$tmp/result.json"))"
|
||||
|
||||
# Looks up a normalisation result for a string
|
||||
# Checks that the normalisation is only failing iff it's an invalid subpath
|
||||
# For valid subpaths, returns 0 and prints the normalisation result
|
||||
# For invalid subpaths, returns 1
|
||||
normalise() {
|
||||
local str=$1
|
||||
# Uses the same check for validity as in the library implementation
|
||||
if [[ "$str" == "" || "$str" == /* || "$str" =~ ^(.*/)?\.\.(/.*)?$ ]]; then
|
||||
valid=
|
||||
else
|
||||
valid=1
|
||||
fi
|
||||
|
||||
normalised=${normalised_result[$str]}
|
||||
# An empty string indicates failure, this is encoded in ./prop.nix
|
||||
if [[ -n "$normalised" ]]; then
|
||||
if [[ -n "$valid" ]]; then
|
||||
echo "$normalised"
|
||||
else
|
||||
die "For invalid subpath \"$str\", lib.path.subpath.normalise returned this result: \"$normalised\""
|
||||
fi
|
||||
else
|
||||
if [[ -n "$valid" ]]; then
|
||||
die "For valid subpath \"$str\", lib.path.subpath.normalise failed"
|
||||
else
|
||||
if [[ "$debug" -ge 2 ]]; then
|
||||
echo >&2 "String \"$str\" is not a valid subpath"
|
||||
fi
|
||||
# Invalid and it correctly failed, we let the caller continue if they catch the exit code
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Intermediate result populated by test_idempotency_realpath
|
||||
# and used in test_normalise_uniqueness
|
||||
#
|
||||
# Contains a mapping from a normalised subpath to the realpath result it represents
|
||||
declare -A norm_to_real
|
||||
|
||||
test_idempotency_realpath() {
|
||||
if [[ "$debug" -ge 1 ]]; then
|
||||
echo >&2 "Checking idempotency of each result and making sure the realpath result isn't changed"
|
||||
fi
|
||||
|
||||
# Count invalid subpaths to display stats
|
||||
invalid=0
|
||||
for str in "${strings[@]}"; do
|
||||
if ! result=$(normalise "$str"); then
|
||||
((invalid++)) || true
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check the law that it doesn't change the result of a realpath
|
||||
mkdir -p -- "$str" "$result"
|
||||
real_orig=$(realpath -- "$str")
|
||||
real_norm=$(realpath -- "$result")
|
||||
|
||||
if [[ "$real_orig" != "$real_norm" ]]; then
|
||||
die "realpath of the original string \"$str\" (\"$real_orig\") is not the same as realpath of the normalisation \"$result\" (\"$real_norm\")"
|
||||
fi
|
||||
|
||||
if [[ "$debug" -ge 2 ]]; then
|
||||
echo >&2 "String \"$str\" gets normalised to \"$result\" and file path \"$real_orig\""
|
||||
fi
|
||||
norm_to_real["$result"]="$real_orig"
|
||||
done
|
||||
if [[ "$debug" -ge 1 ]]; then
|
||||
echo >&2 "$(bc <<< "scale=1; 100 / $count * $invalid")% of the total $count generated strings were invalid subpath strings, and were therefore ignored"
|
||||
fi
|
||||
}
|
||||
|
||||
test_normalise_uniqueness() {
|
||||
if [[ "$debug" -ge 1 ]]; then
|
||||
echo >&2 "Checking for the uniqueness law"
|
||||
fi
|
||||
|
||||
for norm_p in "${!norm_to_real[@]}"; do
|
||||
real_p=${norm_to_real["$norm_p"]}
|
||||
for norm_q in "${!norm_to_real[@]}"; do
|
||||
real_q=${norm_to_real["$norm_q"]}
|
||||
# Checks normalisation uniqueness law for each pair of values
|
||||
if [[ "$norm_p" != "$norm_q" && "$real_p" == "$real_q" ]]; then
|
||||
die "Normalisations \"$norm_p\" and \"$norm_q\" are different, but the realpath of them is the same: \"$real_p\""
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
test_idempotency_realpath
|
||||
test_normalise_uniqueness
|
||||
|
||||
echo >&2 tests ok
|
||||
@@ -1,163 +0,0 @@
|
||||
# Unit tests for lib.path functions. Use `nix-build` in this directory to
|
||||
# run these
|
||||
{ libpath }:
|
||||
let
|
||||
lib = import libpath;
|
||||
inherit (lib.path) append subpath;
|
||||
|
||||
cases = lib.runTests {
|
||||
# Test examples from the lib.path.append documentation
|
||||
testAppendExample1 = {
|
||||
expr = append /foo "bar/baz";
|
||||
expected = /foo/bar/baz;
|
||||
};
|
||||
testAppendExample2 = {
|
||||
expr = append /foo "./bar//baz/./";
|
||||
expected = /foo/bar/baz;
|
||||
};
|
||||
testAppendExample3 = {
|
||||
expr = append /. "foo/bar";
|
||||
expected = /foo/bar;
|
||||
};
|
||||
testAppendExample4 = {
|
||||
expr = (builtins.tryEval (append "/foo" "bar")).success;
|
||||
expected = false;
|
||||
};
|
||||
testAppendExample5 = {
|
||||
expr = (builtins.tryEval (append /foo /bar)).success;
|
||||
expected = false;
|
||||
};
|
||||
testAppendExample6 = {
|
||||
expr = (builtins.tryEval (append /foo "")).success;
|
||||
expected = false;
|
||||
};
|
||||
testAppendExample7 = {
|
||||
expr = (builtins.tryEval (append /foo "/bar")).success;
|
||||
expected = false;
|
||||
};
|
||||
testAppendExample8 = {
|
||||
expr = (builtins.tryEval (append /foo "../bar")).success;
|
||||
expected = false;
|
||||
};
|
||||
|
||||
# Test examples from the lib.path.subpath.isValid documentation
|
||||
testSubpathIsValidExample1 = {
|
||||
expr = subpath.isValid null;
|
||||
expected = false;
|
||||
};
|
||||
testSubpathIsValidExample2 = {
|
||||
expr = subpath.isValid "";
|
||||
expected = false;
|
||||
};
|
||||
testSubpathIsValidExample3 = {
|
||||
expr = subpath.isValid "/foo";
|
||||
expected = false;
|
||||
};
|
||||
testSubpathIsValidExample4 = {
|
||||
expr = subpath.isValid "../foo";
|
||||
expected = false;
|
||||
};
|
||||
testSubpathIsValidExample5 = {
|
||||
expr = subpath.isValid "foo/bar";
|
||||
expected = true;
|
||||
};
|
||||
testSubpathIsValidExample6 = {
|
||||
expr = subpath.isValid "./foo//bar/";
|
||||
expected = true;
|
||||
};
|
||||
# Some extra tests
|
||||
testSubpathIsValidTwoDotsEnd = {
|
||||
expr = subpath.isValid "foo/..";
|
||||
expected = false;
|
||||
};
|
||||
testSubpathIsValidTwoDotsMiddle = {
|
||||
expr = subpath.isValid "foo/../bar";
|
||||
expected = false;
|
||||
};
|
||||
testSubpathIsValidTwoDotsPrefix = {
|
||||
expr = subpath.isValid "..foo";
|
||||
expected = true;
|
||||
};
|
||||
testSubpathIsValidTwoDotsSuffix = {
|
||||
expr = subpath.isValid "foo..";
|
||||
expected = true;
|
||||
};
|
||||
testSubpathIsValidTwoDotsPrefixComponent = {
|
||||
expr = subpath.isValid "foo/..bar/baz";
|
||||
expected = true;
|
||||
};
|
||||
testSubpathIsValidTwoDotsSuffixComponent = {
|
||||
expr = subpath.isValid "foo/bar../baz";
|
||||
expected = true;
|
||||
};
|
||||
testSubpathIsValidThreeDots = {
|
||||
expr = subpath.isValid "...";
|
||||
expected = true;
|
||||
};
|
||||
testSubpathIsValidFourDots = {
|
||||
expr = subpath.isValid "....";
|
||||
expected = true;
|
||||
};
|
||||
testSubpathIsValidThreeDotsComponent = {
|
||||
expr = subpath.isValid "foo/.../bar";
|
||||
expected = true;
|
||||
};
|
||||
testSubpathIsValidFourDotsComponent = {
|
||||
expr = subpath.isValid "foo/..../bar";
|
||||
expected = true;
|
||||
};
|
||||
|
||||
# Test examples from the lib.path.subpath.normalise documentation
|
||||
testSubpathNormaliseExample1 = {
|
||||
expr = subpath.normalise "foo//bar";
|
||||
expected = "./foo/bar";
|
||||
};
|
||||
testSubpathNormaliseExample2 = {
|
||||
expr = subpath.normalise "foo/./bar";
|
||||
expected = "./foo/bar";
|
||||
};
|
||||
testSubpathNormaliseExample3 = {
|
||||
expr = subpath.normalise "foo/bar";
|
||||
expected = "./foo/bar";
|
||||
};
|
||||
testSubpathNormaliseExample4 = {
|
||||
expr = subpath.normalise "foo/bar/";
|
||||
expected = "./foo/bar";
|
||||
};
|
||||
testSubpathNormaliseExample5 = {
|
||||
expr = subpath.normalise "foo/bar/.";
|
||||
expected = "./foo/bar";
|
||||
};
|
||||
testSubpathNormaliseExample6 = {
|
||||
expr = subpath.normalise ".";
|
||||
expected = "./.";
|
||||
};
|
||||
testSubpathNormaliseExample7 = {
|
||||
expr = (builtins.tryEval (subpath.normalise "foo/../bar")).success;
|
||||
expected = false;
|
||||
};
|
||||
testSubpathNormaliseExample8 = {
|
||||
expr = (builtins.tryEval (subpath.normalise "")).success;
|
||||
expected = false;
|
||||
};
|
||||
testSubpathNormaliseExample9 = {
|
||||
expr = (builtins.tryEval (subpath.normalise "/foo")).success;
|
||||
expected = false;
|
||||
};
|
||||
# Some extra tests
|
||||
testSubpathNormaliseIsValidDots = {
|
||||
expr = subpath.normalise "./foo/.bar/.../baz...qux";
|
||||
expected = "./foo/.bar/.../baz...qux";
|
||||
};
|
||||
testSubpathNormaliseWrongType = {
|
||||
expr = (builtins.tryEval (subpath.normalise null)).success;
|
||||
expected = false;
|
||||
};
|
||||
testSubpathNormaliseTwoDots = {
|
||||
expr = (builtins.tryEval (subpath.normalise "..")).success;
|
||||
expected = false;
|
||||
};
|
||||
};
|
||||
in
|
||||
if cases == [] then "Unit tests successful"
|
||||
else throw "Path unit tests failed: ${lib.generators.toPretty {} cases}"
|
||||
@@ -18,7 +18,6 @@ rec {
|
||||
isInt
|
||||
isList
|
||||
isAttrs
|
||||
isPath
|
||||
isString
|
||||
match
|
||||
parseDrvName
|
||||
@@ -128,17 +127,6 @@ rec {
|
||||
# List of input strings
|
||||
list: concatStringsSep sep (lib.imap1 f list);
|
||||
|
||||
/* Concatenate a list of strings, adding a newline at the end of each one.
|
||||
Defined as `concatMapStrings (s: s + "\n")`.
|
||||
|
||||
Type: concatLines :: [string] -> string
|
||||
|
||||
Example:
|
||||
concatLines [ "foo" "bar" ]
|
||||
=> "foo\nbar\n"
|
||||
*/
|
||||
concatLines = concatMapStrings (s: s + "\n");
|
||||
|
||||
/* Construct a Unix-style, colon-separated search path consisting of
|
||||
the given `subDir` appended to each of the given paths.
|
||||
|
||||
@@ -407,7 +395,7 @@ rec {
|
||||
*/
|
||||
toShellVar = name: value:
|
||||
lib.throwIfNot (isValidPosixName name) "toShellVar: ${name} is not a valid shell variable name" (
|
||||
if isAttrs value && ! isStringLike value then
|
||||
if isAttrs value && ! isCoercibleToString value then
|
||||
"declare -A ${name}=(${
|
||||
concatStringsSep " " (lib.mapAttrsToList (n: v:
|
||||
"[${escapeShellArg n}]=${escapeShellArg v}"
|
||||
@@ -810,31 +798,10 @@ rec {
|
||||
in lib.warnIf (!precise) "Imprecise conversion from float to string ${result}"
|
||||
result;
|
||||
|
||||
/* Soft-deprecated function. While the original implementation is available as
|
||||
isConvertibleWithToString, consider using isStringLike instead, if suitable. */
|
||||
isCoercibleToString = lib.warnIf (lib.isInOldestRelease 2305)
|
||||
"lib.strings.isCoercibleToString is deprecated in favor of either isStringLike or isConvertibleWithToString. Only use the latter if it needs to return true for null, numbers, booleans and list of similarly coercibles."
|
||||
isConvertibleWithToString;
|
||||
|
||||
/* Check whether a list or other value can be passed to toString.
|
||||
|
||||
Many types of value are coercible to string this way, including int, float,
|
||||
null, bool, list of similarly coercible values.
|
||||
*/
|
||||
isConvertibleWithToString = x:
|
||||
isStringLike x ||
|
||||
elem (typeOf x) [ "null" "int" "float" "bool" ] ||
|
||||
(isList x && lib.all isConvertibleWithToString x);
|
||||
|
||||
/* Check whether a value can be coerced to a string.
|
||||
The value must be a string, path, or attribute set.
|
||||
|
||||
String-like values can be used without explicit conversion in
|
||||
string interpolations and in most functions that expect a string.
|
||||
*/
|
||||
isStringLike = x:
|
||||
isString x ||
|
||||
isPath x ||
|
||||
/* Check whether a value can be coerced to a string */
|
||||
isCoercibleToString = x:
|
||||
elem (typeOf x) [ "path" "string" "null" "int" "float" "bool" ] ||
|
||||
(isList x && lib.all isCoercibleToString x) ||
|
||||
x ? outPath ||
|
||||
x ? __toString;
|
||||
|
||||
@@ -851,7 +818,7 @@ rec {
|
||||
=> false
|
||||
*/
|
||||
isStorePath = x:
|
||||
if isStringLike x then
|
||||
if !(isList x) && isCoercibleToString x then
|
||||
let str = toString x; in
|
||||
substring 0 1 str == "/"
|
||||
&& dirOf str == storeDir
|
||||
|
||||
@@ -101,14 +101,7 @@ rec {
|
||||
}.${final.parsed.kernel.name} or null;
|
||||
|
||||
# uname -m
|
||||
processor =
|
||||
if final.isPower64
|
||||
then "ppc64${lib.optionalString final.isLittleEndian "le"}"
|
||||
else if final.isPower
|
||||
then "ppc${lib.optionalString final.isLittleEndian "le"}"
|
||||
else if final.isMips64
|
||||
then "mips64" # endianness is *not* included on mips64
|
||||
else final.parsed.cpu.name;
|
||||
processor = final.parsed.cpu.name;
|
||||
|
||||
# uname -r
|
||||
release = null;
|
||||
@@ -142,7 +135,12 @@ rec {
|
||||
if final.isAarch32 then "arm"
|
||||
else if final.isx86_64 then "x86_64"
|
||||
else if final.isx86 then "i386"
|
||||
else final.uname.processor;
|
||||
else {
|
||||
powerpc = "ppc";
|
||||
powerpcle = "ppc";
|
||||
powerpc64 = "ppc64";
|
||||
powerpc64le = "ppc64le";
|
||||
}.${final.parsed.cpu.name} or final.parsed.cpu.name;
|
||||
|
||||
# Name used by UEFI for architectures.
|
||||
efiArch =
|
||||
|
||||
@@ -68,7 +68,6 @@ in {
|
||||
none = [];
|
||||
|
||||
arm = filterDoubles predicates.isAarch32;
|
||||
armv7 = filterDoubles predicates.isArmv7;
|
||||
aarch64 = filterDoubles predicates.isAarch64;
|
||||
x86 = filterDoubles predicates.isx86;
|
||||
i686 = filterDoubles predicates.isi686;
|
||||
@@ -76,7 +75,6 @@ in {
|
||||
microblaze = filterDoubles predicates.isMicroBlaze;
|
||||
mips = filterDoubles predicates.isMips;
|
||||
mmix = filterDoubles predicates.isMmix;
|
||||
power = filterDoubles predicates.isPower;
|
||||
riscv = filterDoubles predicates.isRiscV;
|
||||
riscv32 = filterDoubles predicates.isRiscV32;
|
||||
riscv64 = filterDoubles predicates.isRiscV64;
|
||||
@@ -85,7 +83,6 @@ in {
|
||||
or1k = filterDoubles predicates.isOr1k;
|
||||
m68k = filterDoubles predicates.isM68k;
|
||||
s390 = filterDoubles predicates.isS390;
|
||||
s390x = filterDoubles predicates.isS390x;
|
||||
js = filterDoubles predicates.isJavaScript;
|
||||
|
||||
bigEndian = filterDoubles predicates.isBigEndian;
|
||||
|
||||
@@ -7,7 +7,6 @@ let abis_ = abis; in
|
||||
let abis = lib.mapAttrs (_: abi: builtins.removeAttrs abi [ "assertions" ]) abis_; in
|
||||
|
||||
rec {
|
||||
# these patterns are to be matched against {host,build,target}Platform.parsed
|
||||
patterns = rec {
|
||||
isi686 = { cpu = cpuTypes.i686; };
|
||||
isx86_32 = { cpu = { family = "x86"; bits = 32; }; };
|
||||
@@ -23,9 +22,6 @@ rec {
|
||||
];
|
||||
isx86 = { cpu = { family = "x86"; }; };
|
||||
isAarch32 = { cpu = { family = "arm"; bits = 32; }; };
|
||||
isArmv7 = map ({ arch, ... }: { cpu = { inherit arch; }; })
|
||||
(lib.filter (cpu: lib.hasPrefix "armv7" cpu.arch or "")
|
||||
(lib.attrValues cpuTypes));
|
||||
isAarch64 = { cpu = { family = "arm"; bits = 64; }; };
|
||||
isAarch = { cpu = { family = "arm"; }; };
|
||||
isMicroBlaze = { cpu = { family = "microblaze"; }; };
|
||||
@@ -48,12 +44,10 @@ rec {
|
||||
isOr1k = { cpu = { family = "or1k"; }; };
|
||||
isM68k = { cpu = { family = "m68k"; }; };
|
||||
isS390 = { cpu = { family = "s390"; }; };
|
||||
isS390x = { cpu = { family = "s390"; bits = 64; }; };
|
||||
isJavaScript = { cpu = cpuTypes.js; };
|
||||
|
||||
is32bit = { cpu = { bits = 32; }; };
|
||||
is64bit = { cpu = { bits = 64; }; };
|
||||
isILP32 = map (a: { abi = { abi = a; }; }) [ "n32" "ilp32" "x32" ];
|
||||
isBigEndian = { cpu = { significantByte = significantBytes.bigEndian; }; };
|
||||
isLittleEndian = { cpu = { significantByte = significantBytes.littleEndian; }; };
|
||||
|
||||
@@ -82,13 +76,8 @@ rec {
|
||||
isMusl = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf muslabin32 muslabi64 ];
|
||||
isUClibc = with abis; map (a: { abi = a; }) [ uclibc uclibceabi uclibceabihf ];
|
||||
|
||||
isEfi = [
|
||||
{ cpu = { family = "arm"; version = "6"; }; }
|
||||
{ cpu = { family = "arm"; version = "7"; }; }
|
||||
{ cpu = { family = "arm"; version = "8"; }; }
|
||||
{ cpu = { family = "riscv"; }; }
|
||||
{ cpu = { family = "x86"; }; }
|
||||
];
|
||||
isEfi = map (family: { cpu.family = family; })
|
||||
[ "x86" "arm" "aarch64" ];
|
||||
};
|
||||
|
||||
matchAnyAttrs = patterns:
|
||||
@@ -96,13 +85,4 @@ rec {
|
||||
else matchAttrs patterns;
|
||||
|
||||
predicates = mapAttrs (_: matchAnyAttrs) patterns;
|
||||
|
||||
# these patterns are to be matched against the entire
|
||||
# {host,build,target}Platform structure; they include a `parsed={}` marker so
|
||||
# that `lib.meta.availableOn` can distinguish them from the patterns which
|
||||
# apply only to the `parsed` field.
|
||||
|
||||
platformPatterns = mapAttrs (_: p: { parsed = {}; } // p) {
|
||||
isStatic = { isStatic = true; };
|
||||
};
|
||||
}
|
||||
|
||||
@@ -91,14 +91,10 @@ rec {
|
||||
microblaze = { bits = 32; significantByte = bigEndian; family = "microblaze"; };
|
||||
microblazeel = { bits = 32; significantByte = littleEndian; family = "microblaze"; };
|
||||
|
||||
mips = { bits = 32; significantByte = bigEndian; family = "mips"; };
|
||||
mipsel = { bits = 32; significantByte = littleEndian; family = "mips"; };
|
||||
mipsisa32r6 = { bits = 32; significantByte = bigEndian; family = "mips"; };
|
||||
mipsisa32r6el = { bits = 32; significantByte = littleEndian; family = "mips"; };
|
||||
mips64 = { bits = 64; significantByte = bigEndian; family = "mips"; };
|
||||
mips64el = { bits = 64; significantByte = littleEndian; family = "mips"; };
|
||||
mipsisa64r6 = { bits = 64; significantByte = bigEndian; family = "mips"; };
|
||||
mipsisa64r6el = { bits = 64; significantByte = littleEndian; family = "mips"; };
|
||||
mips = { bits = 32; significantByte = bigEndian; family = "mips"; };
|
||||
mipsel = { bits = 32; significantByte = littleEndian; family = "mips"; };
|
||||
mips64 = { bits = 64; significantByte = bigEndian; family = "mips"; };
|
||||
mips64el = { bits = 64; significantByte = littleEndian; family = "mips"; };
|
||||
|
||||
mmix = { bits = 64; significantByte = bigEndian; family = "mmix"; };
|
||||
|
||||
|
||||
@@ -7,8 +7,7 @@ in {
|
||||
type = types.str;
|
||||
};
|
||||
email = lib.mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
type = types.str;
|
||||
};
|
||||
matrix = lib.mkOption {
|
||||
type = types.nullOr types.str;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# to run these tests (and the others)
|
||||
# nix-build nixpkgs/lib/tests/release.nix
|
||||
# These tests should stay in sync with the comment in maintainers/maintainers-list.nix
|
||||
{ # The pkgs used for dependencies for the testing itself
|
||||
pkgs ? import ../.. {}
|
||||
, lib ? pkgs.lib
|
||||
@@ -21,7 +20,7 @@ let
|
||||
];
|
||||
}).config;
|
||||
|
||||
checks = lib.optional (checkedAttrs.github != null && checkedAttrs.githubId == null) ''
|
||||
checkGithubId = lib.optional (checkedAttrs.github != null && checkedAttrs.githubId == null) ''
|
||||
echo ${lib.escapeShellArg (lib.showOption prefix)}': If `github` is specified, `githubId` must be too.'
|
||||
# Calling this too often would hit non-authenticated API limits, but this
|
||||
# shouldn't happen since such errors will get fixed rather quickly
|
||||
@@ -29,12 +28,8 @@ let
|
||||
id=$(jq -r '.id' <<< "$info")
|
||||
echo "The GitHub ID for GitHub user ${checkedAttrs.github} is $id:"
|
||||
echo -e " githubId = $id;\n"
|
||||
'' ++ lib.optional (checkedAttrs.email == null && checkedAttrs.github == null && checkedAttrs.matrix == null) ''
|
||||
echo ${lib.escapeShellArg (lib.showOption prefix)}': At least one of `email`, `github` or `matrix` must be specified, so that users know how to reach you.'
|
||||
'' ++ lib.optional (checkedAttrs.email != null && lib.hasSuffix "noreply.github.com" checkedAttrs.email) ''
|
||||
echo ${lib.escapeShellArg (lib.showOption prefix)}': If an email address is given, it should allow people to reach you. If you do not want that, you can just provide `github` or `matrix` instead.'
|
||||
'';
|
||||
in lib.deepSeq checkedAttrs checks;
|
||||
in lib.deepSeq checkedAttrs checkGithubId;
|
||||
|
||||
missingGithubIds = lib.concatLists (lib.mapAttrsToList checkMaintainer lib.maintainers);
|
||||
|
||||
|
||||
@@ -153,11 +153,6 @@ runTests {
|
||||
expected = "a,b,c";
|
||||
};
|
||||
|
||||
testConcatLines = {
|
||||
expr = concatLines ["a" "b" "c"];
|
||||
expected = "a\nb\nc\n";
|
||||
};
|
||||
|
||||
testSplitStringsSimple = {
|
||||
expr = strings.splitString "." "a.b.c.d";
|
||||
expected = [ "a" "b" "c" "d" ];
|
||||
@@ -479,11 +474,6 @@ runTests {
|
||||
expected = [2 30 40 42];
|
||||
};
|
||||
|
||||
testReplicate = {
|
||||
expr = replicate 3 "a";
|
||||
expected = ["a" "a" "a"];
|
||||
};
|
||||
|
||||
testToIntShouldConvertStringToInt = {
|
||||
expr = toInt "27";
|
||||
expected = 27;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{ # The pkgs used for dependencies for the testing itself
|
||||
# Don't test properties of pkgs.lib, but rather the lib in the parent directory
|
||||
pkgs ? import ../.. {} // { lib = throw "pkgs.lib accessed, but the lib tests should use nixpkgs' lib path directly!"; },
|
||||
nix ? pkgs.nix,
|
||||
pkgs ? import ../.. {} // { lib = throw "pkgs.lib accessed, but the lib tests should use nixpkgs' lib path directly!"; }
|
||||
}:
|
||||
|
||||
pkgs.runCommand "nixpkgs-lib-tests" {
|
||||
buildInputs = [
|
||||
pkgs.nix
|
||||
(import ./check-eval.nix)
|
||||
(import ./maintainers.nix {
|
||||
inherit pkgs;
|
||||
@@ -15,16 +15,9 @@ pkgs.runCommand "nixpkgs-lib-tests" {
|
||||
inherit pkgs;
|
||||
lib = import ../.;
|
||||
})
|
||||
(import ../path/tests {
|
||||
inherit pkgs;
|
||||
})
|
||||
];
|
||||
nativeBuildInputs = [
|
||||
nix
|
||||
];
|
||||
strictDeps = true;
|
||||
} ''
|
||||
datadir="${nix}/share"
|
||||
datadir="${pkgs.nix}/share"
|
||||
export TEST_ROOT=$(pwd)/test-tmp
|
||||
export NIX_BUILD_HOOK=
|
||||
export NIX_CONF_DIR=$TEST_ROOT/etc
|
||||
|
||||
@@ -16,15 +16,12 @@ with lib.systems.doubles; lib.runTests {
|
||||
testall = mseteq all (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos ++ wasi ++ windows ++ embedded ++ mmix ++ js ++ genode ++ redox);
|
||||
|
||||
testarm = mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv6l-netbsd" "armv6l-none" "armv7a-linux" "armv7a-netbsd" "armv7l-linux" "armv7l-netbsd" "arm-none" "armv7a-darwin" ];
|
||||
testarmv7 = mseteq armv7 [ "armv7a-darwin" "armv7a-linux" "armv7l-linux" "armv7a-netbsd" "armv7l-netbsd" ];
|
||||
testi686 = mseteq i686 [ "i686-linux" "i686-freebsd13" "i686-genode" "i686-netbsd" "i686-openbsd" "i686-cygwin" "i686-windows" "i686-none" "i686-darwin" ];
|
||||
testmips = mseteq mips [ "mips64el-linux" "mipsel-linux" "mipsel-netbsd" ];
|
||||
testmmix = mseteq mmix [ "mmix-mmixware" ];
|
||||
testpower = mseteq power [ "powerpc-netbsd" "powerpc-none" "powerpc64-linux" "powerpc64le-linux" "powerpcle-none" ];
|
||||
testriscv = mseteq riscv [ "riscv32-linux" "riscv64-linux" "riscv32-netbsd" "riscv64-netbsd" "riscv32-none" "riscv64-none" ];
|
||||
testriscv32 = mseteq riscv32 [ "riscv32-linux" "riscv32-netbsd" "riscv32-none" ];
|
||||
testriscv64 = mseteq riscv64 [ "riscv64-linux" "riscv64-netbsd" "riscv64-none" ];
|
||||
tests390x = mseteq s390x [ "s390x-linux" "s390x-none" ];
|
||||
testx86_64 = mseteq x86_64 [ "x86_64-linux" "x86_64-darwin" "x86_64-freebsd13" "x86_64-genode" "x86_64-redox" "x86_64-openbsd" "x86_64-netbsd" "x86_64-cygwin" "x86_64-solaris" "x86_64-windows" "x86_64-none" ];
|
||||
|
||||
testcygwin = mseteq cygwin [ "i686-cygwin" "x86_64-cygwin" ];
|
||||
|
||||
@@ -179,7 +179,7 @@ rec {
|
||||
they take effect as soon as the oldest release reaches end of life. */
|
||||
oldestSupportedRelease =
|
||||
# Update on master only. Do not backport.
|
||||
2211;
|
||||
2205;
|
||||
|
||||
/* Whether a feature is supported in all supported releases (at the time of
|
||||
release branch-off, if applicable). See `oldestSupportedRelease`. */
|
||||
|
||||
@@ -54,7 +54,7 @@ let
|
||||
concatStringsSep
|
||||
escapeNixString
|
||||
hasInfix
|
||||
isStringLike
|
||||
isCoercibleToString
|
||||
;
|
||||
inherit (lib.trivial)
|
||||
boolToString
|
||||
@@ -227,7 +227,7 @@ rec {
|
||||
merge = loc: defs:
|
||||
let
|
||||
getType = value:
|
||||
if isAttrs value && isStringLike value
|
||||
if isAttrs value && isCoercibleToString value
|
||||
then "stringCoercibleSet"
|
||||
else builtins.typeOf value;
|
||||
|
||||
@@ -479,7 +479,7 @@ rec {
|
||||
path = mkOptionType {
|
||||
name = "path";
|
||||
descriptionClass = "noun";
|
||||
check = x: isStringLike x && builtins.substring 0 1 (toString x) == "/";
|
||||
check = x: isCoercibleToString x && builtins.substring 0 1 (toString x) == "/";
|
||||
merge = mergeEqualOption;
|
||||
};
|
||||
|
||||
@@ -558,15 +558,6 @@ rec {
|
||||
nestedTypes.elemType = elemType;
|
||||
};
|
||||
|
||||
# TODO: deprecate this in the future:
|
||||
loaOf = elemType: types.attrsOf elemType // {
|
||||
name = "loaOf";
|
||||
deprecationMessage = "Mixing lists with attribute values is no longer"
|
||||
+ " possible; please use `types.attrsOf` instead. See"
|
||||
+ " https://github.com/NixOS/nixpkgs/issues/1800 for the motivation.";
|
||||
nestedTypes.elemType = elemType;
|
||||
};
|
||||
|
||||
# Value of given type but with no merging (i.e. `uniq list`s are not concatenated).
|
||||
uniq = elemType: mkOptionType rec {
|
||||
name = "uniq";
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -41,7 +41,7 @@ pandoc_flags=(
|
||||
# - diagram-generator.lua (we do not support that in NixOS manual to limit dependencies)
|
||||
# - media extraction (was only required for diagram generator)
|
||||
# - myst-reader/roles.lua (only relevant for MyST → DocBook)
|
||||
# - link-manpages.lua (links should only be added to display output)
|
||||
# - link-unix-man-references.lua (links should only be added to display output)
|
||||
# - docbook-writer/rst-roles.lua (only relevant for → DocBook)
|
||||
# - docbook-writer/labelless-link-is-xref.lua (only relevant for → DocBook)
|
||||
"--lua-filter=$DIR/../../doc/build-aux/pandoc-filters/docbook-reader/citerefentry-to-rst-role.lua"
|
||||
|
||||
@@ -17,7 +17,6 @@ let
|
||||
if (builtins.tryEval attrs.drvPath).success
|
||||
then { inherit (attrs) name drvPath; }
|
||||
else { failed = true; }
|
||||
else if attrs == null then {}
|
||||
else { recurseForDerivations = true; } //
|
||||
mapAttrs (n: v: let path' = path ++ [n]; in trace path' (recurse path' v)) attrs
|
||||
else { };
|
||||
|
||||
@@ -112,8 +112,7 @@ main = do
|
||||
["get-report"] -> getBuildReports
|
||||
["ping-maintainers"] -> printMaintainerPing
|
||||
["mark-broken-list"] -> printMarkBrokenList
|
||||
["eval-info"] -> printEvalInfo
|
||||
_ -> putStrLn "Usage: get-report | ping-maintainers | mark-broken-list | eval-info"
|
||||
_ -> putStrLn "Usage: get-report | ping-maintainers | mark-broken-list"
|
||||
|
||||
reportFileName :: IO FilePath
|
||||
reportFileName = getXdgDirectory XdgCache "haskell-updates-build-report.json"
|
||||
@@ -397,22 +396,12 @@ jobTotals (summaryBuilds -> Table mapping) = getSum <$> Table (Map.foldMapWithKe
|
||||
details :: Text -> [Text] -> [Text]
|
||||
details summary content = ["<details><summary>" <> summary <> " </summary>", ""] <> content <> ["</details>", ""]
|
||||
|
||||
evalLine :: Eval -> UTCTime -> Text
|
||||
evalLine Eval{id, jobsetevalinputs = JobsetEvalInputs{nixpkgs = Nixpkgs{revision}}} fetchTime =
|
||||
"*evaluation ["
|
||||
<> showT id
|
||||
<> "](https://hydra.nixos.org/eval/"
|
||||
<> showT id
|
||||
<> ") of nixpkgs commit ["
|
||||
<> Text.take 7 revision
|
||||
<> "](https://github.com/NixOS/nixpkgs/commits/"
|
||||
<> revision
|
||||
<> ") as of "
|
||||
<> Text.pack (formatTime defaultTimeLocale "%Y-%m-%d %H:%M UTC" fetchTime)
|
||||
<> "*"
|
||||
|
||||
printBuildSummary :: Eval -> UTCTime -> StatusSummary -> [(Text, Int)] -> Text
|
||||
printBuildSummary eval@Eval{id} fetchTime summary topBrokenRdeps =
|
||||
printBuildSummary
|
||||
Eval{id, jobsetevalinputs = JobsetEvalInputs{nixpkgs = Nixpkgs{revision}}}
|
||||
fetchTime
|
||||
summary
|
||||
topBrokenRdeps =
|
||||
Text.unlines $
|
||||
headline <> [""] <> tldr <> ((" * "<>) <$> (errors <> warnings)) <> [""]
|
||||
<> totals
|
||||
@@ -427,14 +416,25 @@ printBuildSummary eval@Eval{id} fetchTime summary topBrokenRdeps =
|
||||
<> footer
|
||||
where
|
||||
footer = ["*Report generated with [maintainers/scripts/haskell/hydra-report.hs](https://github.com/NixOS/nixpkgs/blob/haskell-updates/maintainers/scripts/haskell/hydra-report.hs)*"]
|
||||
headline =
|
||||
[ "### [haskell-updates build report from hydra](https://hydra.nixos.org/jobset/nixpkgs/haskell-updates)"
|
||||
, evalLine eval fetchTime ]
|
||||
totals =
|
||||
[ "#### Build summary"
|
||||
, ""
|
||||
]
|
||||
<> printTable "Platform" (\x -> makeSearchLink id (platform x <> " " <> platformIcon x) ("." <> platform x)) (\x -> showT x <> " " <> icon x) showT numSummary
|
||||
headline =
|
||||
[ "### [haskell-updates build report from hydra](https://hydra.nixos.org/jobset/nixpkgs/haskell-updates)"
|
||||
, "*evaluation ["
|
||||
<> showT id
|
||||
<> "](https://hydra.nixos.org/eval/"
|
||||
<> showT id
|
||||
<> ") of nixpkgs commit ["
|
||||
<> Text.take 7 revision
|
||||
<> "](https://github.com/NixOS/nixpkgs/commits/"
|
||||
<> revision
|
||||
<> ") as of "
|
||||
<> Text.pack (formatTime defaultTimeLocale "%Y-%m-%d %H:%M UTC" fetchTime)
|
||||
<> "*"
|
||||
]
|
||||
brokenLine (name, rdeps) = "[" <> name <> "](https://packdeps.haskellers.com/reverse/" <> name <> ") :arrow_heading_up: " <> Text.pack (show rdeps) <> " "
|
||||
numSummary = statusToNumSummary summary
|
||||
jobsByState predicate = Map.filter (predicate . worstState) summary
|
||||
@@ -469,11 +469,6 @@ printBuildSummary eval@Eval{id} fetchTime summary topBrokenRdeps =
|
||||
maintainedJob = Map.lookup "maintained" summary
|
||||
mergeableJob = Map.lookup "mergeable" summary
|
||||
|
||||
printEvalInfo :: IO ()
|
||||
printEvalInfo = do
|
||||
(eval, fetchTime, _) <- readBuildReports
|
||||
putStrLn (Text.unpack $ evalLine eval fetchTime)
|
||||
|
||||
printMaintainerPing :: IO ()
|
||||
printMaintainerPing = do
|
||||
(maintainerMap, (reverseDependencyMap, topBrokenRdeps)) <- concurrently getMaintainerMap do
|
||||
|
||||
@@ -1,21 +1,7 @@
|
||||
# Nix script to lookup maintainer github handles from their email address. Used by ./hydra-report.hs.
|
||||
#
|
||||
# This script produces an attr set mapping of email addresses to GitHub handles:
|
||||
#
|
||||
# ```nix
|
||||
# > import ./maintainer-handles.nix
|
||||
# { "cdep.illabout@gmail.com" = "cdepillabout"; "john@smith.com" = "johnsmith"; ... }
|
||||
# ```
|
||||
#
|
||||
# This mapping contains all maintainers in ../../mainatainer-list.nix, but it
|
||||
# ignores maintainers who don't have a GitHub account or an email address.
|
||||
let
|
||||
pkgs = import ../../.. {};
|
||||
maintainers = import ../../maintainer-list.nix;
|
||||
inherit (pkgs) lib;
|
||||
mkMailGithubPair = _: maintainer:
|
||||
if (maintainer ? email) && (maintainer ? github) then
|
||||
{ "${maintainer.email}" = maintainer.github; }
|
||||
else
|
||||
{};
|
||||
mkMailGithubPair = _: maintainer: if maintainer ? github then { "${maintainer.email}" = maintainer.github; } else {};
|
||||
in lib.zipAttrsWith (_: builtins.head) (lib.mapAttrsToList mkMailGithubPair maintainers)
|
||||
|
||||
@@ -34,7 +34,6 @@ clear="env -u HOME -u NIXPKGS_CONFIG"
|
||||
$clear maintainers/scripts/haskell/regenerate-hackage-packages.sh
|
||||
$clear maintainers/scripts/haskell/regenerate-transitive-broken-packages.sh
|
||||
$clear maintainers/scripts/haskell/regenerate-hackage-packages.sh
|
||||
evalline=$(maintainers/scripts/haskell/hydra-report.hs eval-info)
|
||||
|
||||
if [[ "${1:-}" == "--do-commit" ]]; then
|
||||
git add $broken_config
|
||||
@@ -43,8 +42,6 @@ git add pkgs/development/haskell-modules/hackage-packages.nix
|
||||
git commit -F - << EOF
|
||||
haskellPackages: mark builds failing on hydra as broken
|
||||
|
||||
This commit has been generated by maintainers/scripts/haskell/mark-broken.sh based on
|
||||
$evalline
|
||||
from the haskell-updates jobset on hydra under https://hydra.nixos.org/jobset/nixpkgs/haskell-updates
|
||||
This commit has been generated by maintainers/scripts/haskell/mark-broken.sh
|
||||
EOF
|
||||
fi
|
||||
|
||||
@@ -62,12 +62,10 @@ sed -r \
|
||||
-e '/ lsp-types /d' \
|
||||
-e '/ lsp-test /d' \
|
||||
-e '/ hie-bios /d' \
|
||||
-e '/ ShellCheck /d' \
|
||||
< "${tmpfile_new}" >> $stackage_config
|
||||
# Explanations:
|
||||
# cabal2nix, distribution-nixpkgs, jailbreak-cabal, language-nix: These are our packages and we know what we are doing.
|
||||
# lsp, lsp-types, lsp-test, hie-bios: These are tightly coupled to hls which is not in stackage. They have no rdeps in stackage.
|
||||
# ShellCheck: latest version of command-line dev tool.
|
||||
|
||||
if [[ "${1:-}" == "--do-commit" ]]; then
|
||||
git add $stackage_config
|
||||
|
||||
@@ -65,7 +65,6 @@ luaevent,,,,,,
|
||||
luaexpat,,,,1.4.1-1,,arobyn flosse
|
||||
luaffi,,,http://luarocks.org/dev,,,
|
||||
luafilesystem,,,,1.8.0-1,,flosse
|
||||
lualdap,,,,,,aanderse
|
||||
lualogging,,,,,,
|
||||
luaossl,,,,,5.1,
|
||||
luaposix,,,,34.1.1-1,,vyp lblasc
|
||||
|
||||
|
@@ -9,14 +9,15 @@ stdenv.mkDerivation {
|
||||
perl GetoptLongDescriptive CPANPLUS Readonly LogLog4perl
|
||||
];
|
||||
|
||||
dontUnpack = true;
|
||||
phases = [ "installPhase" ];
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
cp ${./nix-generate-from-cpan.pl} $out/bin/nix-generate-from-cpan
|
||||
patchShebangs $out/bin/nix-generate-from-cpan
|
||||
wrapProgram $out/bin/nix-generate-from-cpan --set PERL5LIB $PERL5LIB
|
||||
'';
|
||||
installPhase =
|
||||
''
|
||||
mkdir -p $out/bin
|
||||
cp ${./nix-generate-from-cpan.pl} $out/bin/nix-generate-from-cpan
|
||||
patchShebangs $out/bin/nix-generate-from-cpan
|
||||
wrapProgram $out/bin/nix-generate-from-cpan --set PERL5LIB $PERL5LIB
|
||||
'';
|
||||
|
||||
meta = {
|
||||
maintainers = with lib.maintainers; [ eelco ];
|
||||
|
||||
@@ -168,15 +168,6 @@ with lib.maintainers; {
|
||||
shortName = "Cosmopolitan";
|
||||
};
|
||||
|
||||
deepin = {
|
||||
members = [
|
||||
rewine
|
||||
];
|
||||
scope = "Maintain deepin desktop environment and related packages.";
|
||||
shortName = "DDE";
|
||||
enableFeatureFreezePing = true;
|
||||
};
|
||||
|
||||
deshaw = {
|
||||
# Verify additions to this team with at least one already existing member of the team.
|
||||
members = [
|
||||
@@ -289,7 +280,6 @@ with lib.maintainers; {
|
||||
kalbasit
|
||||
mic92
|
||||
zowoq
|
||||
qbit
|
||||
];
|
||||
scope = "Maintain Golang compilers.";
|
||||
shortName = "Go";
|
||||
@@ -312,19 +302,6 @@ with lib.maintainers; {
|
||||
enableFeatureFreezePing = true;
|
||||
};
|
||||
|
||||
graalvm-ce = {
|
||||
members = [
|
||||
bandresen
|
||||
hlolli
|
||||
glittershark
|
||||
babariviere
|
||||
ericdallo
|
||||
thiagokokada
|
||||
];
|
||||
scope = "Maintain GraalVM Community Edition packages.";
|
||||
shortName = "GraalVM-CE";
|
||||
};
|
||||
|
||||
haskell = {
|
||||
members = [
|
||||
cdepillabout
|
||||
@@ -420,19 +397,6 @@ with lib.maintainers; {
|
||||
shortName = "Linux Kernel";
|
||||
};
|
||||
|
||||
llvm = {
|
||||
members = [
|
||||
ericson2314
|
||||
sternenseemann
|
||||
lovek323
|
||||
dtzWill
|
||||
primeos
|
||||
];
|
||||
scope = "Maintain LLVM package sets and related packages";
|
||||
shortName = "LLVM";
|
||||
enableFeatureFreezePing = true;
|
||||
};
|
||||
|
||||
lumiguide = {
|
||||
# Verify additions by approval of an already existing member of the team.
|
||||
members = [
|
||||
@@ -711,11 +675,9 @@ with lib.maintainers; {
|
||||
|
||||
rust = {
|
||||
members = [
|
||||
figsoda
|
||||
andir
|
||||
lnl7
|
||||
mic92
|
||||
tjni
|
||||
winter
|
||||
zowoq
|
||||
];
|
||||
scope = "Maintain the Rust compiler toolchain and nixpkgs integration.";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user