Compare commits

..

1 Commits

Author SHA1 Message Date
DavHau
032122400b enable nixos tests for fetchGit and remote builds 2024-11-20 15:16:23 -05:00
342 changed files with 1738 additions and 3825 deletions

View File

@@ -1,54 +1,36 @@
---
name: Bug report
about: Report unexpected or incorrect behaviour
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
## Describe the bug
**Describe the bug**
<!--
A clear and concise description of what the bug is.
A clear and concise description of what the bug is.
If you have a problem with a specific package or NixOS,
you probably want to file an issue at https://github.com/NixOS/nixpkgs/issues.
-->
If you have a problem with a specific package or NixOS,
you probably want to file an issue at https://github.com/NixOS/nixpkgs/issues.
## Steps To Reproduce
**Steps To Reproduce**
<!--
Example:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
1. Clone this repository: ...
2. Run `nix-... ...`
3. Observe unexpected behaviour
-->
**Expected behavior**
## Expected behavior
A clear and concise description of what you expected to happen.
<!-- A clear and concise description of what you expected to happen. -->
**`nix-env --version` output**
## Metadata
**Additional context**
<!-- Please insert the output of running `nix-env --version` below this line -->
Add any other context about the problem here.
## Additional context
<!-- Add any other context about the problem here. -->
## Checklist
<!-- make sure this issue is not redundant or obsolete -->
- [ ] checked [latest Nix manual] \([source])
- [ ] checked [open bug issues and pull requests] for possible duplicates
[latest Nix manual]: https://nixos.org/manual/nix/unstable/
[source]: https://github.com/NixOS/nix/tree/master/doc/manual/source
[open bug issues and pull requests]: https://github.com/NixOS/nix/labels/bug
---
**Priorities**
Add :+1: to [issues you find important](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).

View File

@@ -1,39 +1,24 @@
---
name: Feature request
about: Suggest a new feature
about: Suggest an idea for this project
title: ''
labels: feature
assignees: ''
---
## Is your feature request related to a problem?
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
## Proposed solution
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
<!-- A clear and concise description of what you want to happen. -->
**Additional context**
Add any other context or screenshots about the feature request here.
## Alternative solutions
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
## Additional context
<!-- Add any other context or screenshots about the feature request here. -->
## Checklist
<!-- make sure this issue is not redundant or obsolete -->
- [ ] checked [latest Nix manual] \([source])
- [ ] checked [open feature issues and pull requests] for possible duplicates
[latest Nix manual]: https://nixos.org/manual/nix/unstable/
[source]: https://github.com/NixOS/nix/tree/master/doc/manual/source
[open feature issues and pull requests]: https://github.com/NixOS/nix/labels/feature
---
**Priorities**
Add :+1: to [issues you find important](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).

View File

@@ -23,25 +23,14 @@ assignees: ''
<details><summary>Output</summary>
<!-- paste console output inside the below code block -->
```log
<!-- paste console output here and remove this comment -->
```
</details>
## Checklist
<!-- make sure this issue is not redundant or obsolete -->
- [ ] checked [latest Nix manual] \([source])
- [ ] checked [open installer issues and pull requests] for possible duplicates
[latest Nix manual]: https://nixos.org/manual/nix/unstable/
[source]: https://github.com/NixOS/nix/tree/master/doc/manual/source
[open installer issues and pull requests]: https://github.com/NixOS/nix/labels/installer
---
## Priorities
Add :+1: to [issues you find important](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).

View File

@@ -26,6 +26,6 @@ assignees: ''
[source]: https://github.com/NixOS/nix/tree/master/doc/manual/source
[open documentation issues and pull requests]: https://github.com/NixOS/nix/labels/documentation
---
## Priorities
Add :+1: to [issues you find important](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).

View File

@@ -17,12 +17,10 @@ so you understand the process and the expectations.
-->
## Motivation
# Motivation
<!-- Briefly explain what the change is about and why it is desirable. -->
## Context
# Context
<!-- Provide context. Reference open issues if available. -->
<!-- Non-trivial change: Briefly outline the implementation strategy. -->
@@ -31,7 +29,7 @@ so you understand the process and the expectations.
<!-- Large change: Provide instructions to reviewers how to read the diff. -->
---
# Priorities and Process
Add :+1: to [pull requests you find important](https://github.com/NixOS/nix/pulls?q=is%3Aopen+sort%3Areactions-%2B1-desc).

View File

@@ -23,9 +23,7 @@ jobs:
- uses: cachix/install-nix-action@v30
with:
# The sandbox would otherwise be disabled by default on Darwin
extra_nix_config: |
sandbox = true
max-jobs = 1
extra_nix_config: "sandbox = true"
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
- uses: cachix/cachix-action@v15
if: needs.check_secrets.outputs.cachix == 'true'
@@ -130,7 +128,7 @@ jobs:
- run: exec bash -c "nix-channel --update && nix-env -iA nixpkgs.hello && hello"
docker_push_image:
needs: [check_secrets, tests, vm_tests]
needs: [check_secrets, tests]
permissions:
contents: read
packages: write
@@ -196,13 +194,7 @@ jobs:
- uses: actions/checkout@v4
- uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- run: |
nix build -L \
.#hydraJobs.tests.functional_user \
.#hydraJobs.tests.githubFlakes \
.#hydraJobs.tests.nix-docker \
.#hydraJobs.tests.tarballFlakes \
;
- run: nix build -L .#hydraJobs.tests.githubFlakes .#hydraJobs.tests.tarballFlakes .#hydraJobs.tests.functional_user
flake_regressions:
needs: vm_tests
@@ -222,4 +214,4 @@ jobs:
path: flake-regressions/tests
- uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- run: nix build -L --out-link ./new-nix && PATH=$(pwd)/new-nix/bin:$PATH MAX_FLAKES=25 flake-regressions/eval-all.sh
- run: nix build --out-link ./new-nix && PATH=$(pwd)/new-nix/bin:$PATH MAX_FLAKES=25 flake-regressions/eval-all.sh

View File

@@ -2,6 +2,9 @@ queue_rules:
- name: default
# all required tests need to go here
merge_conditions:
- check-success=installer
- check-success=installer_test (macos-latest)
- check-success=installer_test (ubuntu-latest)
- check-success=tests (macos-latest)
- check-success=tests (ubuntu-latest)
- check-success=vm_tests
@@ -87,13 +90,3 @@ pull_request_rules:
- "2.24-maintenance"
labels:
- merge-queue
- name: backport patches to 2.25
conditions:
- label=backport 2.25-maintenance
actions:
backport:
branches:
- "2.25-maintenance"
labels:
- merge-queue

View File

@@ -1 +1 @@
2.26.0
2.25.0

View File

@@ -0,0 +1,11 @@
add_project_arguments(
'-Wdeprecated-copy',
'-Werror=suggest-override',
'-Werror=switch',
'-Werror=switch-enum',
'-Werror=unused-result',
'-Wignored-qualifiers',
'-Wimplicit-fallthrough',
'-Wno-deprecated-declarations',
language : 'cpp',
)

View File

@@ -0,0 +1,6 @@
# This is only conditional to work around
# https://github.com/mesonbuild/meson/issues/13293. It should be
# unconditional.
if not (host_machine.system() == 'windows' and cxx.get_id() == 'gcc')
deps_private += dependency('threads')
endif

View File

@@ -199,7 +199,6 @@ nix3_manpages = [
'nix3-build',
'nix3-bundle',
'nix3-config',
'nix3-config-check',
'nix3-config-show',
'nix3-copy',
'nix3-daemon',
@@ -207,8 +206,8 @@ nix3_manpages = [
'nix3-derivation',
'nix3-derivation-show',
'nix3-develop',
#'nix3-doctor',
'nix3-edit',
'nix3-env-shell',
'nix3-eval',
'nix3-flake-archive',
'nix3-flake-check',
@@ -225,7 +224,6 @@ nix3_manpages = [
'nix3-fmt',
'nix3-hash-file',
'nix3-hash',
'nix3-hash-convert',
'nix3-hash-path',
'nix3-hash-to-base16',
'nix3-hash-to-base32',
@@ -240,7 +238,6 @@ nix3_manpages = [
'nix3-nar-cat',
'nix3-nar-dump-path',
'nix3-nar-ls',
'nix3-nar-pack',
'nix3-nar',
'nix3-path-info',
'nix3-print-dev-env',
@@ -263,7 +260,7 @@ nix3_manpages = [
'nix3-repl',
'nix3-run',
'nix3-search',
'nix3-store-add',
#'nix3-shell',
'nix3-store-add-file',
'nix3-store-add-path',
'nix3-store-cat',
@@ -273,7 +270,6 @@ nix3_manpages = [
'nix3-store-diff-closures',
'nix3-store-dump-path',
'nix3-store-gc',
'nix3-store-info',
'nix3-store-ls',
'nix3-store-make-content-addressed',
'nix3-store',

View File

@@ -0,0 +1,14 @@
---
synopsis: Use envvars NIX_CACHE_HOME, NIX_CONFIG_HOME, NIX_DATA_HOME, NIX_STATE_HOME if defined
prs: [11351]
---
Added new environment variables:
- `NIX_CACHE_HOME`
- `NIX_CONFIG_HOME`
- `NIX_DATA_HOME`
- `NIX_STATE_HOME`
Each, if defined, takes precedence over the corresponding [XDG environment variable](@docroot@/command-ref/env-common.md#xdg-base-directories).
This provides more fine-grained control over where Nix looks for files, and allows to have a stand-alone Nix environment, which only uses files in a specific directory, and doesn't interfere with the user environment.

View File

@@ -0,0 +1,21 @@
---
synopsis: Define integer overflow in the Nix language as an error
issues: [10968]
prs: [11188]
---
Previously, integer overflow in the Nix language invoked C++ level signed overflow, which was undefined behaviour, but *usually* manifested as wrapping around on overflow.
Since prior to the public release of Lix, Lix had C++ signed overflow defined to crash the process and nobody noticed this having accidentally removed overflow from the Nix language for three months until it was caught by fiddling around.
Given the significant body of actual Nix code that has been evaluated by Lix in that time, it does not appear that nixpkgs or much of importance depends on integer overflow, so it appears safe to turn into an error.
Some other overflows were fixed:
- `builtins.fromJSON` of values greater than the maximum representable value in a signed 64-bit integer will generate an error.
- `nixConfig` in flakes will no longer accept negative values for configuration options.
Integer overflow now looks like the following:
```
$ nix eval --expr '9223372036854775807 + 1'
error: integer overflow in adding 9223372036854775807 + 1
```

View File

@@ -0,0 +1,22 @@
---
synopsis: |-
The `build-hook` setting's default is less useful when using `libnixstore` as a library
prs:
- 11178
---
*This is an obscure issue that only affects usage of the `libnixstore` library outside of the Nix executable.*
As part the ongoing [rewrite of the build system](https://github.com/NixOS/nix/issues/2503) to use [Meson](https://mesonbuild.com/), we are also switching to packaging individual Nix components separately (and building them in separate derivations).
This means that when building `libnixstore` we do not know where the Nix binaries will be installed --- `libnixstore` doesn't know about downstream consumers like the Nix binaries at all.
*This is also unrelated to the _`post`_-`build-hook`*, which is often used for pushing to a cache.*
This has a small adverse affect on remote building --- the `build-remote` executable that is specified from the [`build-hook`](@docroot@/command-ref/conf-file.md#conf-build-hook) setting will not be gotten from the (presumed) installation location, but instead looked up on the `PATH`.
This means that other applications linking `libnixstore` that wish to use remote building must arrange for the `nix` command to be on the PATH (or manually overriding `build-hook`) in order for that to work.
Long term we don't envision this being a downside, because we plan to [get rid of `build-remote` and the build hook setting entirely](https://github.com/NixOS/nix/issues/1221).
There should simply be no need to have an extra, intermediate layer of remote-procedure-calling when we want to connect to a remote builder.
The build hook protocol did in principle support custom ways of remote building, but that can also be accomplished with a custom service for the ssh or daemon/ssh-ng protocols, or with a custom [store type](@docroot@/store/types/index.md) i.e. `Store` subclass. <!-- we normally don't mention classes, but consider that this release note is about a library use case -->
The Perl bindings no longer expose `getBinDir` either, since the underlying C++ libraries those bindings wrap no longer know the location of installed binaries as described above.

View File

@@ -0,0 +1,14 @@
---
synopsis: wrap filesystem exceptions more correctly
issues: []
prs: [11378]
---
With the switch to `std::filesystem` in different places, Nix started to throw `std::filesystem::filesystem_error` in many places instead of its own exceptions.
This lead to no longer generating error traces, for example when listing a non-existing directory, and can also lead to crashes inside the Nix REPL.
This version catches these types of exception correctly and wrap them into Nix's own exeception type.
Author: [**@Mic92**](https://github.com/Mic92)

View File

@@ -0,0 +1,9 @@
---
synopsis: Add setting `fsync-store-paths`
issues: [1218]
prs: [7126]
---
Nix now has a setting `fsync-store-paths` that ensures that new store paths are durably written to disk before they are registered as "valid" in Nix's database. This can prevent Nix store corruption if the system crashes or there is a power loss. This setting defaults to `false`.
Author: [**@squalus**](https://github.com/squalus)

View File

@@ -1,18 +0,0 @@
---
synopsis: "`nix copy` supports `--profile` and `--out-link`"
prs: [11657]
---
The `nix copy` command now has flags `--profile` and `--out-link`, similar to `nix build`. `--profile` makes a profile point to the
top-level store path, while `--out-link` create symlinks to the top-level store paths.
For example, when updating the local NixOS system profile from a NixOS system closure on a remote machine, instead of
```
# nix copy --from ssh://server $path
# nix build --profile /nix/var/nix/profiles/system $path
```
you can now do
```
# nix copy --from ssh://server --profile /nix/var/nix/profiles/system $path
```
The advantage is that this avoids a time window where *path* is not a garbage collector root, and so could be deleted by a concurrent `nix store gc` process.

View File

@@ -0,0 +1,17 @@
---
synopsis: Removing the default argument passed to the `nix fmt` formatter
issues: []
prs: [11438]
---
The underlying formatter no longer receives the ". " default argument when `nix fmt` is called with no arguments.
This change was necessary as the formatter wasn't able to distinguish between
a user wanting to format the current folder with `nix fmt .` or the generic
`nix fmt`.
The default behaviour is now the responsibility of the formatter itself, and
allows tools such as treefmt to format the whole tree instead of only the
current directory and below.
Author: [**@zimbatm**](https://github.com/zimbatm)

View File

@@ -0,0 +1,8 @@
---
synopsis: Flakes are no longer substituted
prs: [10612]
---
Nix will no longer attempt to substitute the source code of flakes from a binary cache. This functionality was broken because it could lead to different evaluation results depending on whether the flake was available in the binary cache, or even depending on whether the flake was already in the local store.
Author: [**@edolstra**](https://github.com/edolstra)

View File

@@ -0,0 +1,8 @@
---
synopsis: "`<nix/fetchurl.nix>` uses TLS verification"
prs: [11585]
---
Previously `<nix/fetchurl.nix>` did not do TLS verification. This was because the Nix sandbox in the past did not have access to TLS certificates, and Nix checks the hash of the fetched file anyway. However, this can expose authentication data from `netrc` and URLs to man-in-the-middle attackers. In addition, Nix now in some cases (such as when using impure derivations) does *not* check the hash. Therefore we have now enabled TLS verification. This means that downloads by `<nix/fetchurl.nix>` will now fail if you're fetching from a HTTPS server that does not have a valid certificate.
`<nix/fetchurl.nix>` is also known as the builtin derivation builder `builtin:fetchurl`. It's not to be confused with the evaluation-time function `builtins.fetchurl`, which was not affected by this issue.

View File

@@ -130,7 +130,6 @@
- [Contributing](development/contributing.md)
- [Releases](release-notes/index.md)
{{#include ./SUMMARY-rl-next.md}}
- [Release 2.25 (2024-11-07)](release-notes/rl-2.25.md)
- [Release 2.24 (2024-07-31)](release-notes/rl-2.24.md)
- [Release 2.23 (2024-06-03)](release-notes/rl-2.23.md)
- [Release 2.22 (2024-04-23)](release-notes/rl-2.22.md)

View File

@@ -36,7 +36,7 @@ Instead, it looks in a few locations, and acts on all profiles it finds there:
>
> Not stable; subject to change
>
> Do not rely on this functionality; it just exists for migration purposes and may change in the future.
> Do not rely on this functionality; it just exists for migration purposes and is may change in the future.
> These deprecated paths remain a private implementation detail of Nix.
`$NIX_STATE_DIR/profiles` and `$NIX_STATE_DIR/profiles/per-user`.

View File

@@ -88,9 +88,7 @@ All options not listed here are passed to `nix-store
cleared before the interactive shell is started, so you get an
environment that more closely corresponds to the “real” Nix build. A
few variables, in particular `HOME`, `USER` and `DISPLAY`, are
retained. Note that the shell used to run commands is obtained from
[`NIX_BUILD_SHELL`](#env-NIX_BUILD_SHELL) / `<nixpkgs>` from
`NIX_PATH`, and therefore not affected by `--pure`.
retained.
- `--packages` / `-p` *packages*
@@ -114,30 +112,11 @@ All options not listed here are passed to `nix-store
# Environment variables
- <span id="env-NIX_BUILD_SHELL">[`NIX_BUILD_SHELL`](#env-NIX_BUILD_SHELL)</span>
- `NIX_BUILD_SHELL`
Shell used to start the interactive environment.
Defaults to the `bash` from `bashInteractive` found in `<nixpkgs>`, falling back to the `bash` found in `PATH` if not found.
> **Note**
>
> The shell obtained using this method may not necessarily be the same as any shells requested in *path*.
<!-- -->
> **Example
>
> Despite `--pure`, this invocation will not result in a fully reproducible shell environment:
>
> ```nix
> #!/usr/bin/env -S nix-shell --pure
> let
> pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/854fdc68881791812eddd33b2fed94b954979a8e.tar.gz") {};
> in
> pkgs.mkShell {
> buildInputs = pkgs.bashInteractive;
> }
> ```
Shell used to start the interactive environment. Defaults to the
`bash` found in `<nixpkgs>`, falling back to the `bash` found in
`PATH` if not found.
{{#include ./env-common.md}}

View File

@@ -35,20 +35,20 @@ To build Nix itself in this shell:
```console
[nix-shell]$ mesonFlags+=" --prefix=$(pwd)/outputs/out"
[nix-shell]$ dontAddPrefix=1 configurePhase
[nix-shell]$ buildPhase
[nix-shell]$ dontAddPrefix=1 mesonConfigurePhase
[nix-shell]$ ninjaBuildPhase
```
To test it:
```console
[nix-shell]$ checkPhase
[nix-shell]$ mesonCheckPhase
```
To install it in `$(pwd)/outputs`:
```console
[nix-shell]$ installPhase
[nix-shell]$ ninjaInstallPhase
[nix-shell]$ ./outputs/out/bin/nix --version
nix (Nix) 2.12
```
@@ -90,20 +90,20 @@ $ nix develop .#native-clangStdenvPackages
To build Nix itself in this shell:
```console
[nix-shell]$ configurePhase
[nix-shell]$ buildPhase
[nix-shell]$ mesonConfigurePhase
[nix-shell]$ ninjaBuildPhase
```
To test it:
```console
[nix-shell]$ checkPhase
[nix-shell]$ mesonCheckPhase
```
To install it in `$(pwd)/outputs`:
```console
[nix-shell]$ installPhase
[nix-shell]$ ninjaInstallPhase
[nix-shell]$ nix --version
nix (Nix) 2.12
```
@@ -167,7 +167,7 @@ It is useful to perform multiple cross and native builds on the same source tree
for example to ensure that better support for one platform doesn't break the build for another.
Meson thankfully makes this very easy by confining all build products to the build directory --- one simple shares the source directory between multiple build directories, each of which contains the build for Nix to a different platform.
Nixpkgs's `configurePhase` always chooses `build` in the current directory as the name and location of the build.
Nixpkgs's `mesonConfigurePhase` always chooses `build` in the current directory as the name and location of the build.
This makes having multiple build directories slightly more inconvenient.
The good news is that Meson/Ninja seem to cope well with relocating the build directory after it is created.
@@ -176,13 +176,13 @@ Here's how to do that
1. Configure as usual
```bash
configurePhase
mesonConfigurePhase
```
2. Rename the build directory
```bash
cd .. # since `configurePhase` cd'd inside
cd .. # since `mesonConfigurePhase` cd'd inside
mv build build-linux # or whatever name we want
cd build-linux
```
@@ -190,7 +190,7 @@ Here's how to do that
3. Build as usual
```bash
buildPhase
ninjaBuildPhase
```
> **N.B.**

View File

@@ -203,7 +203,7 @@ $ xdg-open ./result/share/doc/nix/internal-api/html/index.html
or inside `nix-shell` or `nix develop`:
```console
$ configurePhase
$ mesonConfigurePhase
$ ninja src/internal-api-docs/html
$ xdg-open src/internal-api-docs/html/index.html
```
@@ -224,7 +224,7 @@ $ xdg-open ./result/share/doc/nix/external-api/html/index.html
or inside `nix-shell` or `nix develop`:
```
$ configurePhase
$ mesonConfigurePhase
$ ninja src/external-api-docs/html
$ xdg-open src/external-api-docs/html/index.html
```

View File

@@ -137,7 +137,7 @@ Functional tests are run during `installCheck` in the `nix` package build, as we
The whole test suite (functional and unit tests) can be run with:
```shell-session
$ checkPhase
$ mesonCheckPhase
```
### Grouping tests

View File

@@ -57,21 +57,3 @@ $ nix build ./\#hydraJobs.dockerImage.x86_64-linux
$ docker load -i ./result/image.tar.gz
$ docker run -ti nix:2.5pre20211105
```
# Docker image with non-root Nix
If you would like to run Nix in a container under a user other than `root`,
you can build an image with a non-root single-user installation of Nix
by specifying the `uid`, `gid`, `uname`, and `gname` arguments to `docker.nix`:
```console
$ nix build --file docker.nix \
--arg uid 1000 \
--arg gid 1000 \
--argstr uname user \
--argstr gname user \
--argstr name nix-user \
--out-link nix-user.tar.gz
$ docker load -i nix-user.tar.gz
$ docker run -ti nix-user
```

View File

@@ -1,144 +0,0 @@
# Release 2.25.0 (2024-11-07)
- New environment variables to override XDG locations [#11351](https://github.com/NixOS/nix/pull/11351)
Added new environment variables:
- `NIX_CACHE_HOME`
- `NIX_CONFIG_HOME`
- `NIX_DATA_HOME`
- `NIX_STATE_HOME`
Each, if defined, takes precedence over the corresponding [XDG environment variable](@docroot@/command-ref/env-common.md#xdg-base-directories).
This provides more fine-grained control over where Nix looks for files. It allows having a stand-alone Nix environment that only uses files in a specific directory and that doesn't interfere with the user environment.
- Define integer overflow in the Nix language as an error [#10968](https://github.com/NixOS/nix/issues/10968) [#11188](https://github.com/NixOS/nix/pull/11188)
Previously, integer overflow in the Nix language invoked C++ level signed overflow, which manifested as wrapping around on overflow. It now looks like this:
```
$ nix eval --expr '9223372036854775807 + 1'
error: integer overflow in adding 9223372036854775807 + 1
```
Some other overflows were fixed:
- `builtins.fromJSON` of values greater than the maximum representable value in a signed 64-bit integer will generate an error.
- `nixConfig` in flakes will no longer accept negative values for configuration options.
- The `build-hook` setting no longer has a useful default when using `libnixstore` as a library [#11178](https://github.com/NixOS/nix/pull/11178)
*This is an obscure issue that only affects usage of the `libnixstore` library outside of the Nix executable. It is unrelated to the `post-build-hook` settings, which is often used for pushing to a cache.*
As part the ongoing [rewrite of the build system](https://github.com/NixOS/nix/issues/2503) to use [Meson](https://mesonbuild.com/), we are also switching to packaging individual Nix components separately (and building them in separate derivations).
This means that when building `libnixstore` we do not know where the Nix binaries will be installed --- `libnixstore` doesn't know about downstream consumers like the Nix binaries at all.
This has a small adverse affect on remote building --- the `build-remote` executable that is specified from the [`build-hook`](@docroot@/command-ref/conf-file.md#conf-build-hook) setting will not be gotten from the (presumed) installation location, but instead looked up on the `PATH`.
This means that other applications linking `libnixstore` that wish to use remote building must arrange for the `nix` command to be on the PATH (or manually overriding `build-hook`) in order for that to work.
Long term we don't envision this being a downside, because we plan to [get rid of `build-remote` and the build hook setting entirely](https://github.com/NixOS/nix/issues/1221).
There should simply be no need to have an extra, intermediate layer of remote-procedure-calling when we want to connect to a remote builder.
The build hook protocol did in principle support custom ways of remote building, but that can also be accomplished with a custom service for the ssh or daemon/ssh-ng protocols, or with a custom [store type](@docroot@/store/types/index.md) i.e. `Store` subclass. <!-- we normally don't mention classes, but consider that this release note is about a library use case -->
The Perl bindings no longer expose `getBinDir` either, since the underlying C++ libraries those bindings wrap no longer know the location of installed binaries as described above.
- Wrap filesystem exceptions more correctly [#11378](https://github.com/NixOS/nix/pull/11378)
With the switch to `std::filesystem` in different places, Nix started to throw `std::filesystem::filesystem_error` in many places instead of its own exceptions.
As a result, Nix no longer generated error traces when (for example) listing a non-existing directory. It could also lead to crashes inside the Nix REPL.
This version catches these types of exception correctly and wraps them into Nix's own exception type.
Author: [**@Mic92**](https://github.com/Mic92)
- Add setting `fsync-store-paths` [#1218](https://github.com/NixOS/nix/issues/1218) [#7126](https://github.com/NixOS/nix/pull/7126)
Nix now has a setting `fsync-store-paths` that ensures that new store paths are durably written to disk before they are registered as "valid" in Nix's database. This can prevent Nix store corruption if the system crashes or there is a power loss. This setting defaults to `false`.
Author: [**@squalus**](https://github.com/squalus)
- Removing the default argument passed to the `nix fmt` formatter [#11438](https://github.com/NixOS/nix/pull/11438)
The underlying formatter no longer receives the "." default argument when `nix fmt` is called with no arguments.
This change was necessary as the formatter wasn't able to distinguish between
a user wanting to format the current folder with `nix fmt .` or the generic
`nix fmt`.
The default behavior is now the responsibility of the formatter itself, and
allows tools such as `treefmt` to format the whole tree instead of only the
current directory and below.
Author: [**@zimbatm**](https://github.com/zimbatm)
- `<nix/fetchurl.nix>` uses TLS verification [#11585](https://github.com/NixOS/nix/pull/11585)
Previously `<nix/fetchurl.nix>` did not do TLS verification. This was because the Nix sandbox in the past did not have access to TLS certificates, and Nix checks the hash of the fetched file anyway. However, this can expose authentication data from `netrc` and URLs to man-in-the-middle attackers. In addition, Nix now in some cases (such as when using impure derivations) does *not* check the hash. Therefore we have now enabled TLS verification. This means that downloads by `<nix/fetchurl.nix>` will now fail if you're fetching from a HTTPS server that does not have a valid certificate.
`<nix/fetchurl.nix>` is also known as the builtin derivation builder `builtin:fetchurl`. It's not to be confused with the evaluation-time function `builtins.fetchurl`, which was not affected by this issue.
# Contributors
This release was made possible by the following 58 contributors:
- 1444 [**(@0x5a4)**](https://github.com/0x5a4)
- Adrian Hesketh [**(@a-h)**](https://github.com/a-h)
- Aleksana [**(@Aleksanaa)**](https://github.com/Aleksanaa)
- Alyssa Ross [**(@alyssais)**](https://github.com/alyssais)
- Andrew Marshall [**(@amarshall)**](https://github.com/amarshall)
- Artemis Tosini [**(@artemist)**](https://github.com/artemist)
- Artturin [**(@Artturin)**](https://github.com/Artturin)
- Bjørn Forsman [**(@bjornfor)**](https://github.com/bjornfor)
- Brian McGee [**(@brianmcgee)**](https://github.com/brianmcgee)
- Brian McKenna [**(@puffnfresh)**](https://github.com/puffnfresh)
- Bryan Honof [**(@bryanhonof)**](https://github.com/bryanhonof)
- Cole Helbling [**(@cole-h)**](https://github.com/cole-h)
- Eelco Dolstra [**(@edolstra)**](https://github.com/edolstra)
- Eman Resu [**(@llakala)**](https://github.com/llakala)
- Emery Hemingway [**(@ehmry)**](https://github.com/ehmry)
- Emil Petersen [**(@leetemil)**](https://github.com/leetemil)
- Emily [**(@emilazy)**](https://github.com/emilazy)
- Geoffrey Thomas [**(@geofft)**](https://github.com/geofft)
- Gerg-L [**(@Gerg-L)**](https://github.com/Gerg-L)
- Ivan Tkachev
- Jacek Galowicz [**(@tfc)**](https://github.com/tfc)
- Jan Hrcek [**(@jhrcek)**](https://github.com/jhrcek)
- Jason Yundt [**(@Jayman2000)**](https://github.com/Jayman2000)
- Jeremy Kerfs [**(@jkerfs)**](https://github.com/jkerfs)
- Jeremy Kolb [**(@kjeremy)**](https://github.com/kjeremy)
- John Ericson [**(@Ericson2314)**](https://github.com/Ericson2314)
- Jonas Chevalier [**(@zimbatm)**](https://github.com/zimbatm)
- Jordan Justen [**(@jljusten)**](https://github.com/jljusten)
- Josh Heinrichs [**(@joshheinrichs-shopify)**](https://github.com/joshheinrichs-shopify)
- Jörg Thalheim [**(@Mic92)**](https://github.com/Mic92)
- Kevin Cox [**(@kevincox)**](https://github.com/kevincox)
- Michael Gallagher [**(@mjgallag)**](https://github.com/mjgallag)
- Michael [**(@michaelvanstraten)**](https://github.com/michaelvanstraten)
- Nikodem Rabuliński [**(@nrabulinski)**](https://github.com/nrabulinski)
- Noam Yorav-Raphael [**(@noamraph)**](https://github.com/noamraph)
- Onni Hakala [**(@onnimonni)**](https://github.com/onnimonni)
- Parker Hoyes [**(@parkerhoyes)**](https://github.com/parkerhoyes)
- Philipp Otterbein
- Pol Dellaiera [**(@drupol)**](https://github.com/drupol)
- Robert Hensing [**(@roberth)**](https://github.com/roberth)
- Ryan Hendrickson [**(@rhendric)**](https://github.com/rhendric)
- Sandro [**(@SuperSandro2000)**](https://github.com/SuperSandro2000)
- Seggy Umboh [**(@secobarbital)**](https://github.com/secobarbital)
- Sergei Zimmerman [**(@xokdvium)**](https://github.com/xokdvium)
- Shivaraj B H [**(@shivaraj-bh)**](https://github.com/shivaraj-bh)
- Siddhant Kumar [**(@siddhantk232)**](https://github.com/siddhantk232)
- Tim [**(@Jaculabilis)**](https://github.com/Jaculabilis)
- Tom Bereknyei
- Travis A. Everett [**(@abathur)**](https://github.com/abathur)
- Valentin Gagarin [**(@fricklerhandwerk)**](https://github.com/fricklerhandwerk)
- Vinayak Kaushik [**(@VinayakKaushikDH)**](https://github.com/VinayakKaushikDH)
- Yann Hamdaoui [**(@yannham)**](https://github.com/yannham)
- Yuriy Taraday [**(@YorikSar)**](https://github.com/YorikSar)
- bryango [**(@bryango)**](https://github.com/bryango)
- emhamm [**(@emhamm)**](https://github.com/emhamm)
- jade [**(@lf-)**](https://github.com/lf-)
- kenji [**(@a-kenji)**](https://github.com/a-kenji)
- pennae [**(@pennae)**](https://github.com/pennae)
- puckipedia [**(@puckipedia)**](https://github.com/puckipedia)
- squalus [**(@squalus)**](https://github.com/squalus)
- tomberek [**(@tomberek)**](https://github.com/tomberek)

View File

@@ -9,10 +9,6 @@
, maxLayers ? 100
, nixConf ? {}
, flake-registry ? null
, uid ? 0
, gid ? 0
, uname ? "root"
, gname ? "root"
}:
let
defaultPkgs = with pkgs; [
@@ -54,15 +50,6 @@ let
description = "Unprivileged account (don't use!)";
};
} // lib.optionalAttrs (uid != 0) {
"${uname}" = {
uid = uid;
shell = "${pkgs.bashInteractive}/bin/bash";
home = "/home/${uname}";
gid = gid;
groups = [ "${gname}" ];
description = "Nix user";
};
} // lib.listToAttrs (
map
(
@@ -83,8 +70,6 @@ let
root.gid = 0;
nixbld.gid = 30000;
nobody.gid = 65534;
} // lib.optionalAttrs (gid != 0) {
"${gname}".gid = gid;
};
userToPasswd = (
@@ -165,8 +150,6 @@ let
in
"${n} = ${vStr}") (defaultNixConf // nixConf))) + "\n";
userHome = if uid == 0 then "/root" else "/home/${uname}";
baseSystem =
let
nixpkgs = pkgs.path;
@@ -254,26 +237,26 @@ let
mkdir -p $out/etc/nix
cat $nixConfContentsPath > $out/etc/nix/nix.conf
mkdir -p $out${userHome}
mkdir -p $out/nix/var/nix/profiles/per-user/${uname}
mkdir -p $out/root
mkdir -p $out/nix/var/nix/profiles/per-user/root
ln -s ${profile} $out/nix/var/nix/profiles/default-1-link
ln -s /nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default
ln -s /nix/var/nix/profiles/default $out${userHome}/.nix-profile
ln -s $out/nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default
ln -s /nix/var/nix/profiles/default $out/root/.nix-profile
ln -s ${channel} $out/nix/var/nix/profiles/per-user/${uname}/channels-1-link
ln -s /nix/var/nix/profiles/per-user/${uname}/channels-1-link $out/nix/var/nix/profiles/per-user/${uname}/channels
ln -s ${channel} $out/nix/var/nix/profiles/per-user/root/channels-1-link
ln -s $out/nix/var/nix/profiles/per-user/root/channels-1-link $out/nix/var/nix/profiles/per-user/root/channels
mkdir -p $out${userHome}/.nix-defexpr
ln -s /nix/var/nix/profiles/per-user/${uname}/channels $out${userHome}/.nix-defexpr/channels
echo "${channelURL} ${channelName}" > $out${userHome}/.nix-channels
mkdir -p $out/root/.nix-defexpr
ln -s $out/nix/var/nix/profiles/per-user/root/channels $out/root/.nix-defexpr/channels
echo "${channelURL} ${channelName}" > $out/root/.nix-channels
mkdir -p $out/bin $out/usr/bin
ln -s ${pkgs.coreutils}/bin/env $out/usr/bin/env
ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/sh
'' + (lib.optionalString (flake-registry-path != null) ''
nixCacheDir="${userHome}/.cache/nix"
nixCacheDir="/root/.cache/nix"
mkdir -p $out$nixCacheDir
globalFlakeRegistryPath="$nixCacheDir/flake-registry.json"
ln -s ${flake-registry-path} $out$globalFlakeRegistryPath
@@ -285,7 +268,7 @@ let
in
pkgs.dockerTools.buildLayeredImageWithNixDb {
inherit name tag maxLayers uid gid uname gname;
inherit name tag maxLayers;
contents = [ baseSystem ];
@@ -296,28 +279,25 @@ pkgs.dockerTools.buildLayeredImageWithNixDb {
fakeRootCommands = ''
chmod 1777 tmp
chmod 1777 var/tmp
chown -R ${toString uid}:${toString gid} .${userHome}
chown -R ${toString uid}:${toString gid} nix
'';
config = {
Cmd = [ "${userHome}/.nix-profile/bin/bash" ];
User = "${toString uid}:${toString gid}";
Cmd = [ "/root/.nix-profile/bin/bash" ];
Env = [
"USER=${uname}"
"USER=root"
"PATH=${lib.concatStringsSep ":" [
"${userHome}/.nix-profile/bin"
"/root/.nix-profile/bin"
"/nix/var/nix/profiles/default/bin"
"/nix/var/nix/profiles/default/sbin"
]}"
"MANPATH=${lib.concatStringsSep ":" [
"${userHome}/.nix-profile/share/man"
"/root/.nix-profile/share/man"
"/nix/var/nix/profiles/default/share/man"
]}"
"SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
"GIT_SSL_CAINFO=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
"NIX_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
"NIX_PATH=/nix/var/nix/profiles/per-user/${uname}/channels:${userHome}/.nix-defexpr/channels"
"NIX_PATH=/nix/var/nix/profiles/per-user/root/channels:/root/.nix-defexpr/channels"
];
};

View File

@@ -124,36 +124,18 @@
# without "polluting" the top level "`pkgs`" attrset.
# This also has the benefit of providing us with a distinct set of packages
# we can iterate over.
nixComponents =
lib.makeScopeWithSplicing'
{
inherit (final) splicePackages;
inherit (final.nixDependencies) newScope;
}
{
otherSplices = final.generateSplicesForMkScope "nixComponents";
f = import ./packaging/components.nix {
inherit (final) lib;
inherit officialRelease;
src = self;
};
};
nixComponents = lib.makeScope final.nixDependencies.newScope (import ./packaging/components.nix {
inherit (final) lib;
inherit officialRelease;
src = self;
});
# The dependencies are in their own scope, so that they don't have to be
# in Nixpkgs top level `pkgs` or `nixComponents`.
nixDependencies =
lib.makeScopeWithSplicing'
{
inherit (final) splicePackages;
inherit (final) newScope; # layered directly on pkgs, unlike nixComponents above
}
{
otherSplices = final.generateSplicesForMkScope "nixDependencies";
f = import ./packaging/dependencies.nix {
inherit inputs stdenv;
pkgs = final;
};
};
nixDependencies = lib.makeScope final.newScope (import ./packaging/dependencies.nix {
inherit inputs stdenv;
pkgs = final;
});
nix = final.nixComponents.nix-cli;
@@ -197,6 +179,7 @@
repl-completion = nixpkgsFor.${system}.native.callPackage ./tests/repl-completion.nix { };
} // (lib.optionalAttrs (builtins.elem system linux64BitSystems)) {
dockerImage = self.hydraJobs.dockerImage.${system};
fetch-git = self.hydraJobs.tests.fetch-git;
} // (lib.optionalAttrs (!(builtins.elem system linux32BitSystems))) {
# Some perl dependencies are broken on i686-linux.
# Since the support is only best-effort there, disable the perl
@@ -236,9 +219,8 @@
# for which we don't apply the full build matrix such as cross or static.
inherit (nixpkgsFor.${system}.native)
changelog-d;
default = self.packages.${system}.nix;
# TODO probably should be `nix-cli`
nix = self.packages.${system}.nix-everything;
default = self.packages.${system}.nix-everything;
nix-manual = nixpkgsFor.${system}.native.nixComponents.nix-manual;
nix-internal-api-docs = nixpkgsFor.${system}.native.nixComponents.nix-internal-api-docs;
nix-external-api-docs = nixpkgsFor.${system}.native.nixComponents.nix-external-api-docs;

View File

@@ -48,55 +48,5 @@
"delroth@gmail.com": "delroth",
"enno@nerdworks.de": "elohmeier",
"mjbauer95@gmail.com": "matthewbauer",
"MostAwesomeDude@gmail.com": "MostAwesomeDude",
"145775305+xokdvium@users.noreply.github.com": "xokdvium",
"bryanhonof@gmail.com": "bryanhonof",
"50352631+michaelvanstraten@users.noreply.github.com": "michaelvanstraten",
"bjorn.forsman@gmail.com": "bjornfor",
"pol.dellaiera@protonmail.com": "drupol",
"tim.vanbaak@gmail.com": "Jaculabilis",
"leetemil@users.noreply.github.com": "leetemil",
"a-h@users.noreply.github.com": "a-h",
"me@artem.ist": "artemist",
"puck@puckipedia.com": "puckipedia",
"marian.hammer@meetwise.com": "emhamm",
"78693624+llakala@users.noreply.github.com": "llakala",
"itkachev@hyperad.tech": null,
"geofft@ldpreload.com": "geofft",
"onni@flaky.build": "onnimonni",
"jacek@galowicz.de": "tfc",
"potterbein@blockstream.com": null,
"49699333+dependabot[bot]@users.noreply.github.com": "dependabot[bot]",
"112626461+VinayakKaushikDH@users.noreply.github.com": "VinayakKaushikDH",
"kevincox@kevincox.ca": "kevincox",
"yann.hamdaoui@tweag.io": "yannham",
"GregLeyda@proton.me": "Gerg-L",
"jljusten@gmail.com": "jljusten",
"josh.heinrichs@shopify.com": "joshheinrichs-shopify",
"jason@jasonyundt.email": "Jayman2000",
"noamraph@gmail.com": "noamraph",
"nikodem@rabulinski.com": "nrabulinski",
"78693624+quatquatt@users.noreply.github.com": "llakala",
"yuriy.taraday@tweag.io": "YorikSar",
"travis.a.everett@gmail.com": "abathur",
"Artturin@artturin.com": "Artturin",
"zimbatm@zimbatm.com": "zimbatm",
"contact@parkerhoyes.com": "parkerhoyes",
"kjeremy@gmail.com": "kjeremy",
"jkerfs@users.noreply.github.com": "jkerfs",
"sandro.jaeckel@gmail.com": "SuperSandro2000",
"hi@alyssa.is": "alyssais",
"2716069+jhrcek@users.noreply.github.com": "jhrcek",
"seggy.umboh@coupa.com": "secobarbital",
"hello@emily.moe": "emilazy",
"ehmry@posteo.net": "ehmry",
"me@aleksana.moe": "Aleksanaa",
"tom@floxdev.com": null,
"sbh69840@gmail.com": "shivaraj-bh",
"mjgallag@gmail.com": "mjgallag",
"bryango@users.noreply.github.com": "bryango",
"aks.kenji@protonmail.com": "a-kenji",
"54070204+0x5a4@users.noreply.github.com": "0x5a4",
"brian@bmcgee.ie": "brianmcgee",
"squalus@squalus.net": "squalus"
"MostAwesomeDude@gmail.com": "MostAwesomeDude"
}

View File

@@ -41,50 +41,5 @@
"winterqt": "Winter",
"GoldsteinE": "Max \u201cGoldstein\u201d Siling",
"pennae": null,
"MostAwesomeDude": "Corbin Simpson",
"VinayakKaushikDH": "Vinayak Kaushik",
"leetemil": "Emil Petersen",
"michaelvanstraten": "Michael",
"parkerhoyes": "Parker Hoyes",
"a-h": "Adrian Hesketh",
"a-kenji": "kenji",
"geofft": "Geoffrey Thomas",
"bryango": null,
"tfc": "Jacek Galowicz",
"brianmcgee": "Brian McGee",
"Gerg-L": null,
"secobarbital": "Seggy Umboh",
"bjornfor": "Bj\u00f8rn Forsman",
"dependabot[bot]": null,
"xokdvium": "Sergei Zimmerman",
"kevincox": "Kevin Cox",
"Jayman2000": "Jason Yundt",
"Artturin": "Artturin",
"0x5a4": "1444",
"llakala": "Eman Resu",
"nrabulinski": "Nikodem Rabuli\u0144ski",
"shivaraj-bh": "Shivaraj B H",
"yannham": "Yann Hamdaoui",
"jkerfs": "Jeremy Kerfs",
"drupol": "Pol Dellaiera",
"onnimonni": "Onni Hakala",
"joshheinrichs-shopify": "Josh Heinrichs",
"puckipedia": null,
"abathur": "Travis A. Everett",
"alyssais": "Alyssa Ross",
"noamraph": "Noam Yorav-Raphael",
"squalus": null,
"emhamm": null,
"mjgallag": "Michael Gallagher",
"jljusten": "Jordan Justen",
"ehmry": "Emery Hemingway",
"jhrcek": "Jan Hrcek",
"Jaculabilis": "Tim",
"bryanhonof": "Bryan Honof",
"zimbatm": "Jonas Chevalier",
"SuperSandro2000": "Sandro",
"Aleksanaa": "Aleksana",
"YorikSar": "Yuriy Taraday",
"kjeremy": "Jeremy Kolb",
"artemist": "Artemis Tosini"
"MostAwesomeDude": "Corbin Simpson"
}

View File

@@ -496,6 +496,7 @@
''^scripts/create-darwin-volume\.sh$''
''^scripts/install-darwin-multi-user\.sh$''
''^scripts/install-multi-user\.sh$''
''^scripts/install-nix-from-closure\.sh$''
''^scripts/install-systemd-multi-user\.sh$''
''^src/nix/get-env\.sh$''
''^tests/functional/ca/build-dry\.sh$''

View File

@@ -4,4 +4,3 @@
- https://github.com/NixOS/nixos-homepage/
- https://github.com/orgs/NixOS/teams/nix-team
- Matrix room
- Team member should subscribe to notifications for the [Nix development category on Discourse](https://discourse.nixos.org/c/dev/nix/50)

View File

@@ -34,7 +34,6 @@ endif
subproject('libutil-c')
subproject('libstore-c')
subproject('libexpr-c')
subproject('libflake-c')
subproject('libmain-c')
# Language Bindings

View File

@@ -1,6 +1,6 @@
# vim: filetype=meson
option('doc-gen', type : 'boolean', value : false,
option('doc-gen', type : 'boolean', value : true,
description : 'Generate documentation',
)

View File

@@ -1,13 +0,0 @@
configure_file(
input : 'org.nixos.nix-daemon.plist.in',
output : 'org.nixos.nix-daemon.plist',
install : true,
install_dir : get_option('prefix') / 'Library/LaunchDaemons',
install_mode : 'rw-r--r--',
configuration : {
# TODO: unhardcode paths with something like:
# 'storedir' : store_dir,
# 'localstatedir' : localstatedir,
# 'bindir' : bindir,
},
)

View File

@@ -2,10 +2,4 @@ subdir('bash')
subdir('fish')
subdir('zsh')
if host_machine.system() == 'linux'
subdir('systemd')
endif
if host_machine.system() == 'darwin'
subdir('launchd')
endif
subdir('systemd')

View File

@@ -1,22 +0,0 @@
# This is only conditional to work around
# https://github.com/mesonbuild/meson/issues/13293. It should be
# unconditional.
if not (host_machine.system() == 'windows' and cxx.get_id() == 'gcc')
deps_private += dependency('threads')
endif
add_project_arguments(
'-Wdeprecated-copy',
'-Werror=suggest-override',
'-Werror=switch',
'-Werror=switch-enum',
'-Werror=unused-result',
'-Wignored-qualifiers',
'-Wimplicit-fallthrough',
'-Wno-deprecated-declarations',
language : 'cpp',
)
if get_option('buildtype') not in ['debug']
add_project_arguments('-O3', language : 'cpp')
endif

View File

@@ -44,7 +44,6 @@ in
nix-expr-tests = callPackage ../src/libexpr-tests/package.nix { };
nix-flake = callPackage ../src/libflake/package.nix { };
nix-flake-c = callPackage ../src/libflake-c/package.nix { };
nix-flake-tests = callPackage ../src/libflake-tests/package.nix { };
nix-main = callPackage ../src/libmain/package.nix { };

View File

@@ -70,9 +70,6 @@ let
pkgs.buildPackages.meson
pkgs.buildPackages.ninja
] ++ prevAttrs.nativeBuildInputs or [];
mesonCheckFlags = prevAttrs.mesonCheckFlags or [] ++ [
"--print-errorlogs"
];
};
mesonBuildLayer = finalAttrs: prevAttrs:

View File

@@ -31,35 +31,6 @@ in {
# Make bash completion work.
XDG_DATA_DIRS+=:$out/share
# Make the default phases do the right thing.
# FIXME: this wouldn't be needed if the ninja package set buildPhase() instead of $buildPhase.
# FIXME: mesonConfigurePhase shouldn't cd to the build directory. It would be better to pass '-C <dir>' to ninja.
cdToBuildDir() {
if [[ ! -e build.ninja ]]; then
cd build
fi
}
configurePhase() {
mesonConfigurePhase
}
buildPhase() {
cdToBuildDir
ninjaBuildPhase
}
checkPhase() {
cdToBuildDir
mesonCheckPhase
}
installPhase() {
cdToBuildDir
ninjaInstallPhase
}
'';
# We use this shell with the local checkout, not unpackPhase.

View File

@@ -5,10 +5,12 @@
nix-util,
nix-util-c,
nix-util-test-support,
nix-util-tests,
nix-store,
nix-store-c,
nix-store-test-support,
nix-store-tests,
nix-fetchers,
@@ -16,10 +18,10 @@
nix-expr,
nix-expr-c,
nix-expr-test-support,
nix-expr-tests,
nix-flake,
nix-flake-c,
nix-flake-tests,
nix-main,
@@ -36,82 +38,45 @@
nix-external-api-docs,
nix-perl-bindings,
testers,
runCommand,
}:
let
dev = stdenv.mkDerivation (finalAttrs: {
name = "nix-${nix-cli.version}-dev";
pname = "nix";
version = nix-cli.version;
dontUnpack = true;
dontBuild = true;
libs = map lib.getDev [
nix-cmd
nix-expr
nix-expr-c
nix-fetchers
nix-flake
nix-flake-c
nix-main
nix-main-c
nix-store
nix-store-c
nix-util
nix-util-c
nix-perl-bindings
];
installPhase = ''
mkdir -p $out/nix-support
echo $libs >> $out/nix-support/propagated-build-inputs
'';
passthru = {
tests = {
pkg-config =
testers.hasPkgConfigModules {
package = finalAttrs.finalPackage;
};
};
# If we were to fully emulate output selection here, we'd confuse the Nix CLIs,
# because they rely on `drvPath`.
dev = finalAttrs.finalPackage.out;
libs = throw "`nix.dev.libs` is not meant to be used; use `nix.libs` instead.";
};
meta = {
pkgConfigModules = [
"nix-cmd"
"nix-expr"
"nix-expr-c"
"nix-fetchers"
"nix-flake"
"nix-flake-c"
"nix-main"
"nix-main-c"
"nix-store"
"nix-store-c"
"nix-util"
"nix-util-c"
];
};
});
devdoc = buildEnv {
name = "nix-${nix-cli.version}-devdoc";
paths = [
nix-internal-api-docs
nix-external-api-docs
];
};
in
(buildEnv {
name = "nix-${nix-cli.version}";
paths = [
nix-util
nix-util-c
nix-util-test-support
nix-util-tests
nix-store
nix-store-c
nix-store-test-support
nix-store-tests
nix-fetchers
nix-fetchers-tests
nix-expr
nix-expr-c
nix-expr-test-support
nix-expr-tests
nix-flake
nix-flake-tests
nix-main
nix-main-c
nix-cmd
nix-cli
nix-manual.man
nix-manual
nix-internal-api-docs
nix-external-api-docs
] ++ lib.optionals (stdenv.buildPlatform.canExecute stdenv.hostPlatform) [
nix-perl-bindings
];
meta.mainProgram = "nix";
@@ -120,31 +85,16 @@ in
doInstallCheck = true;
checkInputs = [
# Make sure the unit tests have passed
# Actually run the unit tests too
nix-util-tests.tests.run
nix-store-tests.tests.run
nix-expr-tests.tests.run
nix-fetchers-tests.tests.run
nix-flake-tests.tests.run
# dev bundle is ok
# (checkInputs must be empty paths??)
(runCommand "check-pkg-config" { checked = dev.tests.pkg-config; } "mkdir $out")
] ++
(if stdenv.buildPlatform.canExecute stdenv.hostPlatform
then [
# TODO: add perl.tests
nix-perl-bindings
]
else [
nix-perl-bindings
]);
];
installCheckInputs = [
nix-functional-tests
];
passthru = prevAttrs.passthru // {
inherit (nix-cli) version;
/**
These are the libraries that are part of the Nix project. They are used
by the Nix CLI and other tools.
@@ -172,31 +122,9 @@ in
nix-expr
nix-expr-c
nix-flake
nix-flake-c
nix-main
nix-main-c
;
};
tests = prevAttrs.passthru.tests or {} // {
# TODO: create a proper fixpoint and:
# pkg-config =
# testers.hasPkgConfigModules {
# package = finalPackage;
# };
};
/**
A derivation referencing the `dev` outputs of the Nix libraries.
*/
inherit dev;
inherit devdoc;
doc = nix-manual;
outputs = [ "out" "dev" "devdoc" "doc" ];
all = lib.attrValues (lib.genAttrs finalAttrs.passthru.outputs (outName: finalAttrs.finalPackage.${outName}));
};
meta = prevAttrs.meta // {
description = "The Nix package manager";
pkgConfigModules = dev.meta.pkgConfigModules;
};
})

View File

@@ -18,8 +18,12 @@ let
testNixVersions = pkgs: daemon:
pkgs.nixComponents.nix-functional-tests.override {
pname = "nix-daemon-compat-tests";
version = "${pkgs.nix.version}-with-daemon-${daemon.version}";
pname =
"nix-tests"
+ lib.optionalString
(lib.versionAtLeast daemon.version "2.4pre20211005" &&
lib.versionAtLeast pkgs.nix.version "2.4pre20211005")
"-${pkgs.nix.version}-against-${daemon.version}";
test-daemon = daemon;
};
@@ -57,9 +61,7 @@ in
build = forAllPackages (pkgName:
forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.${pkgName}));
shellInputs = removeAttrs
(forAllSystems (system: self.devShells.${system}.default.inputDerivation))
[ "i686-linux" ];
shellInputs = forAllSystems (system: self.devShells.${system}.default.inputDerivation);
buildStatic = forAllPackages (pkgName:
lib.genAttrs linux64BitSystems (system: nixpkgsFor.${system}.static.nixComponents.${pkgName}));

View File

@@ -23,7 +23,7 @@ in
runCommand "nix-binary-tarball-${version}" env ''
cp ${installerClosureInfo}/registration $TMPDIR/reginfo
cp ${./create-darwin-volume.sh} $TMPDIR/create-darwin-volume.sh
substitute ${./install-nix-from-tarball.sh} $TMPDIR/install \
substitute ${./install-nix-from-closure.sh} $TMPDIR/install \
--subst-var-by nix ${nix} \
--subst-var-by cacert ${cacert}

View File

@@ -463,7 +463,7 @@ EOF
EDITOR="$SCRATCH/ex_cleanroom_wrapper" _sudo "to add nix to fstab" "$@" <<EOF
:a
UUID=$uuid $escaped_mountpoint apfs rw,noauto,nobrowse,nosuid,noatime,owners
UUID=$uuid $escaped_mountpoint apfs rw,noauto,nobrowse,suid,owners
.
:x
EOF

View File

@@ -690,7 +690,7 @@ place_channel_configuration() {
if [ -z "${NIX_INSTALLER_NO_CHANNEL_ADD:-}" ]; then
echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > "$SCRATCH/.nix-channels"
_sudo "to set up the default system channel (part 1)" \
install -m 0644 "$SCRATCH/.nix-channels" "$ROOT_HOME/.nix-channels"
install -m 0664 "$SCRATCH/.nix-channels" "$ROOT_HOME/.nix-channels"
fi
}
@@ -964,7 +964,7 @@ $NIX_EXTRA_CONF
build-users-group = $NIX_BUILD_GROUP_NAME
EOF
_sudo "to place the default nix daemon configuration (part 2)" \
install -m 0644 "$SCRATCH/nix.conf" /etc/nix/nix.conf
install -m 0664 "$SCRATCH/nix.conf" /etc/nix/nix.conf
}

View File

@@ -48,14 +48,15 @@ case "$(uname -s)" in
INSTALL_MODE=no-daemon;;
esac
ACTION=
# space-separated string
ACTIONS=
# handle the command line flags
while [ $# -gt 0 ]; do
case $1 in
--daemon)
INSTALL_MODE=daemon
ACTION=install
ACTIONS="${ACTIONS}install "
;;
--no-daemon)
if [ "$(uname -s)" = "Darwin" ]; then
@@ -64,14 +65,18 @@ while [ $# -gt 0 ]; do
fi
INSTALL_MODE=no-daemon
# intentional tail space
ACTION=install
ACTIONS="${ACTIONS}install "
;;
# --uninstall)
# # intentional tail space
# ACTIONS="${ACTIONS}uninstall "
# ;;
--yes)
export NIX_INSTALLER_YES=1;;
--no-channel-add)
export NIX_INSTALLER_NO_CHANNEL_ADD=1;;
--daemon-user-count)
export NIX_USER_COUNT="$2"
export NIX_USER_COUNT=$2
shift;;
--no-modify-profile)
NIX_INSTALLER_NO_MODIFY_PROFILE=1;;
@@ -123,7 +128,7 @@ done
if [ "$INSTALL_MODE" = "daemon" ]; then
printf '\e[1;31mSwitching to the Multi-user Installer\e[0m\n'
exec "$self/install-multi-user" $ACTION
exec "$self/install-multi-user" $ACTIONS # let ACTIONS split
exit 0
fi

View File

@@ -40,9 +40,8 @@ GENERATE_LATEX = NO
INPUT = \
@src@/src/libutil-c \
@src@/src/libexpr-c \
@src@/src/libflake-c \
@src@/src/libstore-c \
@src@/src/external-api-docs/README.md
@src@/doc/external-api/README.md
FILE_PATTERNS = nix_api_*.h *.md
@@ -56,8 +55,6 @@ EXCLUDE_PATTERNS = *_internal.h
GENERATE_TREEVIEW = YES
OPTIMIZE_OUTPUT_FOR_C = YES
USE_MDFILE_AS_MAINPAGE = @src@/src/external-api-docs/README.md
USE_MDFILE_AS_MAINPAGE = doc/external-api/README.md
WARN_IF_UNDOCUMENTED = NO
WARN_IF_INCOMPLETE_DOC = NO
QUIET = YES

View File

@@ -30,7 +30,6 @@ mkMesonDerivation (finalAttrs: {
# Source is not compiled, but still must be available for Doxygen
# to gather comments.
(cpp ../libexpr-c)
(cpp ../libflake-c)
(cpp ../libstore-c)
(cpp ../libutil-c)
];

View File

@@ -43,8 +43,8 @@ INPUT = \
@src@/libexpr/flake \
@src@/libexpr-tests \
@src@/libexpr-tests/value \
@src@/libexpr-test-support/tests \
@src@/libexpr-test-support/tests/value \
@src@/libexpr-test-support/test \
@src@/libexpr-test-support/test/value \
@src@/libexpr/value \
@src@/libfetchers \
@src@/libmain \
@@ -52,11 +52,10 @@ INPUT = \
@src@/libstore/build \
@src@/libstore/builtins \
@src@/libstore-tests \
@src@/libstore-test-support/tests \
@src@/libstore-test-support/test \
@src@/libutil \
@src@/libutil/args \
@src@/libutil-tests \
@src@/libutil-test-support/tests \
@src@/libutil-test-support/test \
@src@/nix \
@src@/nix-env \
@src@/nix-store
@@ -84,9 +83,7 @@ EXPAND_ONLY_PREDEF = YES
# RECURSIVE has no effect here.
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
INCLUDE_PATH = \
@BUILD_ROOT@/src/libexpr/libnixexpr.so.p \
@BUILD_ROOT@/src/nix/nix.p \
INCLUDE_PATH =
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
@@ -99,18 +96,7 @@ EXPAND_AS_DEFINED = \
DECLARE_COMMON_SERIALISER \
DECLARE_WORKER_SERIALISER \
DECLARE_SERVE_SERIALISER \
LENGTH_PREFIXED_PROTO_HELPER \
LENGTH_PREFIXED_PROTO_HELPER_X \
WORKER_USE_LENGTH_PREFIX_SERIALISER \
WORKER_USE_LENGTH_PREFIX_SERIALISER_COMMA \
SERVE_USE_LENGTH_PREFIX_SERIALISER \
SERVE_USE_LENGTH_PREFIX_SERIALISER_COMMA \
COMMON_METHODS \
JSON_IMPL \
MakeBinOp
PREDEFINED = DOXYGEN_SKIP
LENGTH_PREFIXED_PROTO_HELPER
WARN_IF_UNDOCUMENTED = NO
WARN_IF_INCOMPLETE_DOC = NO
QUIET = YES

View File

@@ -12,7 +12,6 @@ doxygen_cfg = configure_file(
configuration : {
'PROJECT_NUMBER': meson.project_version(),
'OUTPUT_DIRECTORY' : meson.current_build_dir(),
'BUILD_ROOT' : meson.build_root(),
'src' : fs.parent(fs.parent(meson.project_source_root())) / 'src',
},
)

View File

@@ -0,0 +1 @@
../../build-utils-meson

View File

@@ -179,34 +179,30 @@ BuiltPathsCommand::BuiltPathsCommand(bool recursive)
void BuiltPathsCommand::run(ref<Store> store, Installables && installables)
{
BuiltPaths rootPaths, allPaths;
BuiltPaths paths;
if (all) {
if (installables.size())
throw UsageError("'--all' does not expect arguments");
// XXX: Only uses opaque paths, ignores all the realisations
for (auto & p : store->queryAllValidPaths())
rootPaths.emplace_back(BuiltPath::Opaque{p});
allPaths = rootPaths;
paths.emplace_back(BuiltPath::Opaque{p});
} else {
rootPaths = Installable::toBuiltPaths(getEvalStore(), store, realiseMode, operateOn, installables);
allPaths = rootPaths;
paths = Installable::toBuiltPaths(getEvalStore(), store, realiseMode, operateOn, installables);
if (recursive) {
// XXX: This only computes the store path closure, ignoring
// intermediate realisations
StorePathSet pathsRoots, pathsClosure;
for (auto & root : rootPaths) {
for (auto & root : paths) {
auto rootFromThis = root.outPaths();
pathsRoots.insert(rootFromThis.begin(), rootFromThis.end());
}
store->computeFSClosure(pathsRoots, pathsClosure);
for (auto & path : pathsClosure)
allPaths.emplace_back(BuiltPath::Opaque{path});
paths.emplace_back(BuiltPath::Opaque{path});
}
}
run(store, std::move(allPaths), std::move(rootPaths));
run(store, std::move(paths));
}
StorePathsCommand::StorePathsCommand(bool recursive)
@@ -214,10 +210,10 @@ StorePathsCommand::StorePathsCommand(bool recursive)
{
}
void StorePathsCommand::run(ref<Store> store, BuiltPaths && allPaths, BuiltPaths && rootPaths)
void StorePathsCommand::run(ref<Store> store, BuiltPaths && paths)
{
StorePathSet storePaths;
for (auto & builtPath : allPaths)
for (auto & builtPath : paths)
for (auto & p : builtPath.outPaths())
storePaths.insert(p);
@@ -249,7 +245,7 @@ void MixProfile::updateProfile(const StorePath & storePath)
{
if (!profile)
return;
auto store = getDstStore().dynamic_pointer_cast<LocalFSStore>();
auto store = getStore().dynamic_pointer_cast<LocalFSStore>();
if (!store)
throw Error("'--profile' is not supported for this Nix store");
auto profile2 = absPath(*profile);
@@ -369,37 +365,4 @@ void MixEnvironment::setEnviron()
return;
}
void createOutLinks(
const std::filesystem::path & outLink,
const BuiltPaths & buildables,
LocalFSStore & store,
PathSet & symlinks)
{
for (const auto & [_i, buildable] : enumerate(buildables)) {
auto i = _i;
std::visit(
overloaded{
[&](const BuiltPath::Opaque & bo) {
auto symlink = outLink;
if (i)
symlink += fmt("-%d", i);
store.addPermRoot(bo.path, absPath(symlink.string()));
symlinks.insert(symlink);
},
[&](const BuiltPath::Built & bfd) {
for (auto & output : bfd.outputs) {
auto symlink = outLink;
if (i)
symlink += fmt("-%d", i);
if (output.first != "out")
symlink += fmt("-%s", output.first);
store.addPermRoot(output.second, absPath(symlink.string()));
symlinks.insert(symlink);
}
},
},
buildable.raw());
}
}
}

View File

@@ -18,7 +18,6 @@ extern char ** savedArgv;
class EvalState;
struct Pos;
class Store;
class LocalFSStore;
static constexpr Command::Category catHelp = -1;
static constexpr Command::Category catSecondary = 100;
@@ -47,20 +46,7 @@ struct StoreCommand : virtual Command
{
StoreCommand();
void run() override;
/**
* Return the default Nix store.
*/
ref<Store> getStore();
/**
* Return the destination Nix store.
*/
virtual ref<Store> getDstStore()
{
return getStore();
}
virtual ref<Store> createStore();
/**
* Main entry point, with a `Store` provided
@@ -83,7 +69,7 @@ struct CopyCommand : virtual StoreCommand
ref<Store> createStore() override;
ref<Store> getDstStore() override;
ref<Store> getDstStore();
};
/**
@@ -253,7 +239,7 @@ public:
BuiltPathsCommand(bool recursive = false);
virtual void run(ref<Store> store, BuiltPaths && allPaths, BuiltPaths && rootPaths) = 0;
virtual void run(ref<Store> store, BuiltPaths && paths) = 0;
void run(ref<Store> store, Installables && installables) override;
@@ -266,7 +252,7 @@ struct StorePathsCommand : public BuiltPathsCommand
virtual void run(ref<Store> store, StorePaths && storePaths) = 0;
void run(ref<Store> store, BuiltPaths && allPaths, BuiltPaths && rootPaths) override;
void run(ref<Store> store, BuiltPaths && paths) override;
};
/**
@@ -368,14 +354,4 @@ std::string showVersions(const std::set<std::string> & versions);
void printClosureDiff(
ref<Store> store, const StorePath & beforePath, const StorePath & afterPath, std::string_view indent);
/**
* Create symlinks prefixed by `outLink` to the store paths in
* `buildables`.
*/
void createOutLinks(
const std::filesystem::path & outLink,
const BuiltPaths & buildables,
LocalFSStore & store,
PathSet & symlinks);
}

View File

@@ -29,13 +29,13 @@ EvalSettings evalSettings {
{
{
"flake",
[](EvalState & state, std::string_view rest) {
[](ref<Store> store, std::string_view rest) {
experimentalFeatureSettings.require(Xp::Flakes);
// FIXME `parseFlakeRef` should take a `std::string_view`.
auto flakeRef = parseFlakeRef(fetchSettings, std::string { rest }, {}, true, false);
debug("fetching flake search path element '%s''", rest);
auto storePath = flakeRef.resolve(state.store).fetchTree(state.store).first;
return state.rootPath(state.store->toRealPath(storePath));
auto storePath = flakeRef.resolve(store).fetchTree(store).first;
return store->toRealPath(storePath);
},
},
},

View File

@@ -32,6 +32,16 @@ InstallableDerivedPath InstallableDerivedPath::parse(
// store path.
[&](const ExtendedOutputsSpec::Default &) -> DerivedPath {
auto storePath = store->followLinksToStorePath(prefix);
// Remove this prior to stabilizing the new CLI.
if (storePath.isDerivation()) {
auto oldDerivedPath = DerivedPath::Built {
.drvPath = makeConstantStorePathRef(storePath),
.outputs = OutputsSpec::All { },
};
warn(
"The interpretation of store paths arguments ending in `.drv` recently changed. If this command is now failing try again with '%s'",
oldDerivedPath.to_string(*store));
};
return DerivedPath::Opaque {
.path = std::move(storePath),
};

View File

@@ -75,7 +75,7 @@ InstallableFlake::InstallableFlake(
DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
{
Activity act(*logger, lvlTalkative, actEvaluate, fmt("evaluating derivation '%s'", what()));
Activity act(*logger, lvlTalkative, actUnknown, fmt("evaluating derivation '%s'", what()));
auto attr = getCursor(*state);

View File

@@ -26,7 +26,7 @@ struct ExtraPathInfoFlake : ExtraPathInfoValue
Flake flake;
ExtraPathInfoFlake(Value && v, Flake && f)
: ExtraPathInfoValue(std::move(v)), flake(std::move(f))
: ExtraPathInfoValue(std::move(v)), flake(f)
{ }
};

View File

@@ -59,7 +59,7 @@ struct ExtraPathInfoValue : ExtraPathInfo
Value value;
ExtraPathInfoValue(Value && v)
: value(std::move(v))
: value(v)
{ }
virtual ~ExtraPathInfoValue() = default;

View File

@@ -857,8 +857,7 @@ std::vector<FlakeRef> RawInstallablesCommand::getFlakeRefsForCompletion()
{
applyDefaultInstallables(rawInstallables);
std::vector<FlakeRef> res;
res.reserve(rawInstallables.size());
for (const auto & i : rawInstallables)
for (auto i : rawInstallables)
res.push_back(parseFlakeRefWithFragment(
fetchSettings,
expandTilde(i),
@@ -918,12 +917,4 @@ void BuiltPathsCommand::applyDefaultInstallables(std::vector<std::string> & rawI
rawInstallables.push_back(".");
}
BuiltPaths toBuiltPaths(const std::vector<BuiltPathWithResult> & builtPathsWithResult)
{
BuiltPaths res;
for (auto & i : builtPathsWithResult)
res.push_back(i.path);
return res;
}
}

View File

@@ -86,8 +86,6 @@ struct BuiltPathWithResult
std::optional<BuildResult> result;
};
BuiltPaths toBuiltPaths(const std::vector<BuiltPathWithResult> & builtPathsWithResult);
/**
* Shorthand, for less typing and helping us keep the choice of
* collection in sync.

View File

@@ -14,7 +14,7 @@ project('nix-cmd', 'cpp',
cxx = meson.get_compiler('cpp')
subdir('nix-meson-build-support/deps-lists')
subdir('build-utils-meson/deps-lists')
configdata = configuration_data()
@@ -28,7 +28,9 @@ deps_public_maybe_subproject = [
dependency('nix-flake'),
dependency('nix-main'),
]
subdir('nix-meson-build-support/subprojects')
subdir('build-utils-meson/subprojects')
subdir('build-utils-meson/threads')
nlohmann_json = dependency('nlohmann_json', version : '>= 3.9')
deps_public += nlohmann_json
@@ -70,7 +72,7 @@ add_project_arguments(
language : 'cpp',
)
subdir('nix-meson-build-support/common')
subdir('build-utils-meson/diagnostics')
sources = files(
'built-path.cc',
@@ -125,4 +127,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
libraries_private = []
subdir('nix-meson-build-support/export')
subdir('build-utils-meson/export')

View File

@@ -1 +0,0 @@
../../nix-meson-build-support

View File

@@ -39,8 +39,8 @@ mkMesonLibrary (finalAttrs: {
workDir = ./.;
fileset = fileset.unions [
../../nix-meson-build-support
./nix-meson-build-support
../../build-utils-meson
./build-utils-meson
../../.version
./.version
./meson.build

View File

@@ -0,0 +1 @@
../../build-utils-meson

View File

@@ -14,7 +14,7 @@ project('nix-expr-c', 'cpp',
cxx = meson.get_compiler('cpp')
subdir('nix-meson-build-support/deps-lists')
subdir('build-utils-meson/deps-lists')
configdata = configuration_data()
@@ -27,7 +27,9 @@ deps_public_maybe_subproject = [
dependency('nix-util-c'),
dependency('nix-store-c'),
]
subdir('nix-meson-build-support/subprojects')
subdir('build-utils-meson/subprojects')
subdir('build-utils-meson/threads')
# TODO rename, because it will conflict with downstream projects
configdata.set_quoted('PACKAGE_VERSION', meson.project_version())
@@ -53,7 +55,7 @@ add_project_arguments(
language : 'cpp',
)
subdir('nix-meson-build-support/common')
subdir('build-utils-meson/diagnostics')
sources = files(
'nix_api_expr.cc',
@@ -72,8 +74,8 @@ headers = [config_h] + files(
# TODO move this header to libexpr, maybe don't use it in tests?
headers += files('nix_api_expr_internal.h')
subdir('nix-meson-build-support/export-all-symbols')
subdir('nix-meson-build-support/windows-version')
subdir('build-utils-meson/export-all-symbols')
subdir('build-utils-meson/windows-version')
this_library = library(
'nixexprc',
@@ -89,4 +91,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
libraries_private = []
subdir('nix-meson-build-support/export')
subdir('build-utils-meson/export')

View File

@@ -1 +0,0 @@
../../nix-meson-build-support

View File

@@ -6,7 +6,6 @@
#include "eval-gc.hh"
#include "globals.hh"
#include "eval-settings.hh"
#include "ref.hh"
#include "nix_api_expr.h"
#include "nix_api_expr_internal.h"
@@ -19,29 +18,6 @@
# include <mutex>
#endif
/**
* @brief Allocate and initialize using self-reference
*
* This allows a brace initializer to reference the object being constructed.
*
* @warning Use with care, as the pointer points to an object that is not fully constructed yet.
*
* @tparam T Type to allocate
* @tparam F A function type for `init`, taking a T* and returning the initializer for T
* @param init Function that takes a T* and returns the initializer for T
* @return Pointer to allocated and initialized object
*/
template <typename T, typename F>
static T * unsafe_new_with_self(F && init)
{
// Allocate
void * p = ::operator new(
sizeof(T),
static_cast<std::align_val_t>(alignof(T)));
// Initialize with placement new
return new (p) T(init(static_cast<T *>(p)));
}
nix_err nix_libexpr_init(nix_c_context * context)
{
if (context)
@@ -91,7 +67,7 @@ nix_err nix_value_call_multi(nix_c_context * context, EvalState * state, nix_val
if (context)
context->last_err_code = NIX_OK;
try {
state->state.callFunction(fn->value, {(nix::Value * *) args, nargs}, value->value, nix::noPos);
state->state.callFunction(fn->value, nargs, (nix::Value * *)args, value->value, nix::noPos);
state->state.forceValue(value->value, nix::noPos);
}
NIXC_CATCH_ERRS
@@ -117,42 +93,7 @@ nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, nix_val
NIXC_CATCH_ERRS
}
nix_eval_state_builder * nix_eval_state_builder_new(nix_c_context * context, Store * store)
{
if (context)
context->last_err_code = NIX_OK;
try {
return unsafe_new_with_self<nix_eval_state_builder>([&](auto * self) {
return nix_eval_state_builder{
.store = nix::ref<nix::Store>(store->ptr),
.settings = nix::EvalSettings{/* &bool */ self->readOnlyMode},
.fetchSettings = nix::fetchers::Settings{},
.readOnlyMode = true,
};
});
}
NIXC_CATCH_ERRS_NULL
}
void nix_eval_state_builder_free(nix_eval_state_builder * builder)
{
delete builder;
}
nix_err nix_eval_state_builder_load(nix_c_context * context, nix_eval_state_builder * builder)
{
if (context)
context->last_err_code = NIX_OK;
try {
// TODO: load in one go?
builder->settings.readOnlyMode = nix::settings.readOnlyMode;
loadConfFile(builder->settings);
loadConfFile(builder->fetchSettings);
}
NIXC_CATCH_ERRS
}
nix_err nix_eval_state_builder_set_lookup_path(nix_c_context * context, nix_eval_state_builder * builder, const char ** lookupPath_c)
EvalState * nix_state_create(nix_c_context * context, const char ** lookupPath_c, Store * store)
{
if (context)
context->last_err_code = NIX_OK;
@@ -161,47 +102,28 @@ nix_err nix_eval_state_builder_set_lookup_path(nix_c_context * context, nix_eval
if (lookupPath_c != nullptr)
for (size_t i = 0; lookupPath_c[i] != nullptr; i++)
lookupPath.push_back(lookupPath_c[i]);
builder->lookupPath = nix::LookupPath::parse(lookupPath);
}
NIXC_CATCH_ERRS
}
EvalState * nix_eval_state_build(nix_c_context * context, nix_eval_state_builder * builder)
{
if (context)
context->last_err_code = NIX_OK;
try {
return unsafe_new_with_self<EvalState>([&](auto * self) {
return EvalState{
.fetchSettings = std::move(builder->fetchSettings),
.settings = std::move(builder->settings),
.state = nix::EvalState(
builder->lookupPath,
builder->store,
self->fetchSettings,
self->settings),
};
});
void * p = ::operator new(
sizeof(EvalState),
static_cast<std::align_val_t>(alignof(EvalState)));
auto * p2 = static_cast<EvalState *>(p);
new (p) EvalState {
.fetchSettings = nix::fetchers::Settings{},
.settings = nix::EvalSettings{
nix::settings.readOnlyMode,
},
.state = nix::EvalState(
nix::LookupPath::parse(lookupPath),
store->ptr,
p2->fetchSettings,
p2->settings),
};
loadConfFile(p2->settings);
return p2;
}
NIXC_CATCH_ERRS_NULL
}
EvalState * nix_state_create(nix_c_context * context, const char ** lookupPath_c, Store * store)
{
auto builder = nix_eval_state_builder_new(context, store);
if (builder == nullptr)
return nullptr;
if (nix_eval_state_builder_load(context, builder) != NIX_OK)
return nullptr;
if (nix_eval_state_builder_set_lookup_path(context, builder, lookupPath_c)
!= NIX_OK)
return nullptr;
return nix_eval_state_build(context, builder);
}
void nix_state_free(EvalState * state)
{
delete state;

View File

@@ -30,11 +30,6 @@ extern "C" {
// cffi start
// Type definitions
/**
* @brief Builder for EvalState
*/
typedef struct nix_eval_state_builder nix_eval_state_builder;
/**
* @brief Represents a state of the Nix language evaluator.
*
@@ -134,7 +129,7 @@ nix_err nix_value_call_multi(
* @param[in] state The state of the evaluation.
* @param[out] value The result of the function call.
* @param[in] fn The Nix function to call.
* @param[in] ... The arguments to pass to the function.
* @param[in] args The arguments to pass to the function.
*
* @see nix_value_call_multi
*/
@@ -179,70 +174,12 @@ nix_err nix_value_force(nix_c_context * context, EvalState * state, nix_value *
nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, nix_value * value);
/**
* @brief Create a new nix_eval_state_builder
*
* The settings are initialized to their default value.
* Values can be sourced elsewhere with nix_eval_state_builder_load.
*
* @param[out] context Optional, stores error information
* @param[in] store The Nix store to use.
* @return A new nix_eval_state_builder or NULL on failure.
*/
nix_eval_state_builder * nix_eval_state_builder_new(nix_c_context * context, Store * store);
/**
* @brief Read settings from the ambient environment
*
* Settings are sourced from environment variables and configuration files,
* as documented in the Nix manual.
*
* @param[out] context Optional, stores error information
* @param[out] builder The builder to modify.
* @return NIX_OK if successful, an error code otherwise.
*/
nix_err nix_eval_state_builder_load(nix_c_context * context, nix_eval_state_builder * builder);
/**
* @brief Set the lookup path for `<...>` expressions
*
* @param[in] context Optional, stores error information
* @param[in] builder The builder to modify.
* @param[in] lookupPath Null-terminated array of strings corresponding to entries in NIX_PATH.
*/
nix_err nix_eval_state_builder_set_lookup_path(
nix_c_context * context, nix_eval_state_builder * builder, const char ** lookupPath);
/**
* @brief Create a new Nix language evaluator state
*
* Remember to nix_eval_state_builder_free after building the state.
*
* @param[out] context Optional, stores error information
* @param[in] builder The builder to use and free
* @return A new Nix state or NULL on failure.
* @see nix_eval_state_builder_new, nix_eval_state_builder_free
*/
EvalState * nix_eval_state_build(nix_c_context * context, nix_eval_state_builder * builder);
/**
* @brief Free a nix_eval_state_builder
*
* Does not fail.
*
* @param[in] builder The builder to free.
*/
void nix_eval_state_builder_free(nix_eval_state_builder * builder);
/**
* @brief Create a new Nix language evaluator state
*
* For more control, use nix_eval_state_builder
* @brief Create a new Nix language evaluator state.
*
* @param[out] context Optional, stores error information
* @param[in] lookupPath Null-terminated array of strings corresponding to entries in NIX_PATH.
* @param[in] store The Nix store to use.
* @return A new Nix state or NULL on failure.
* @see nix_state_builder_new
*/
EvalState * nix_state_create(nix_c_context * context, const char ** lookupPath, Store * store);

View File

@@ -6,17 +6,6 @@
#include "eval-settings.hh"
#include "attr-set.hh"
#include "nix_api_value.h"
#include "search-path.hh"
struct nix_eval_state_builder
{
nix::ref<nix::Store> store;
nix::EvalSettings settings;
nix::fetchers::Settings fetchSettings;
nix::LookupPath lookupPath;
// TODO: make an EvalSettings setting own this instead?
bool readOnlyMode;
};
struct EvalState
{

View File

@@ -77,7 +77,8 @@ typedef struct ExternalValue ExternalValue;
*/
typedef struct nix_realised_string nix_realised_string;
/** @defgroup primops Adding primops
/** @defgroup primops
* @brief Create your own primops
* @{
*/
/** @brief Function pointer for primops
@@ -213,7 +214,7 @@ nix_get_string(nix_c_context * context, const nix_value * value, nix_get_string_
/** @brief Get path as string
* @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect
* @return string, if the type is NIX_TYPE_PATH
* @return string
* @return NULL in case of error.
*/
const char * nix_get_path_string(nix_c_context * context, const nix_value * value);
@@ -251,7 +252,7 @@ int64_t nix_get_int(nix_c_context * context, const nix_value * value);
* @param[in] value Nix value to inspect
* @return reference to external, NULL in case of error
*/
ExternalValue * nix_get_external(nix_c_context * context, nix_value * value);
ExternalValue * nix_get_external(nix_c_context * context, nix_value *);
/** @brief Get the ix'th element of a list
*
@@ -422,7 +423,7 @@ nix_list_builder_insert(nix_c_context * context, ListBuilder * list_builder, uns
/** @brief Free a list builder
*
* Does not fail.
* @param[in] list_builder The builder to free.
* @param[in] builder the builder to free
*/
void nix_list_builder_free(ListBuilder * list_builder);

View File

@@ -20,8 +20,8 @@ mkMesonLibrary (finalAttrs: {
workDir = ./.;
fileset = fileset.unions [
../../nix-meson-build-support
./nix-meson-build-support
../../build-utils-meson
./build-utils-meson
../../.version
./.version
./meson.build

View File

@@ -0,0 +1 @@
../../build-utils-meson

View File

@@ -14,7 +14,7 @@ project('nix-expr-test-support', 'cpp',
cxx = meson.get_compiler('cpp')
subdir('nix-meson-build-support/deps-lists')
subdir('build-utils-meson/deps-lists')
deps_private_maybe_subproject = [
]
@@ -24,9 +24,10 @@ deps_public_maybe_subproject = [
dependency('nix-store'),
dependency('nix-store-test-support'),
dependency('nix-expr'),
dependency('nix-expr-c'),
]
subdir('nix-meson-build-support/subprojects')
subdir('build-utils-meson/subprojects')
subdir('build-utils-meson/threads')
rapidcheck = dependency('rapidcheck')
deps_public += rapidcheck
@@ -40,7 +41,7 @@ add_project_arguments(
language : 'cpp',
)
subdir('nix-meson-build-support/common')
subdir('build-utils-meson/diagnostics')
sources = files(
'tests/value/context.cc',
@@ -54,8 +55,8 @@ headers = files(
'tests/value/context.hh',
)
subdir('nix-meson-build-support/export-all-symbols')
subdir('nix-meson-build-support/windows-version')
subdir('build-utils-meson/export-all-symbols')
subdir('build-utils-meson/windows-version')
this_library = library(
'nix-expr-test-support',
@@ -73,4 +74,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
libraries_private = []
subdir('nix-meson-build-support/export')
subdir('build-utils-meson/export')

View File

@@ -1 +0,0 @@
../../nix-meson-build-support

View File

@@ -4,7 +4,6 @@
, nix-store-test-support
, nix-expr
, nix-expr-c
, rapidcheck
@@ -23,8 +22,8 @@ mkMesonLibrary (finalAttrs: {
workDir = ./.;
fileset = fileset.unions [
../../nix-meson-build-support
./nix-meson-build-support
../../build-utils-meson
./build-utils-meson
../../.version
./.version
./meson.build
@@ -36,7 +35,6 @@ mkMesonLibrary (finalAttrs: {
propagatedBuildInputs = [
nix-store-test-support
nix-expr
nix-expr-c
rapidcheck
];

View File

@@ -40,12 +40,6 @@ namespace nix {
return v;
}
Value * maybeThunk(std::string input, bool forceValue = true) {
Expr * e = state.parseExprFromString(input, state.rootPath(CanonPath::root));
assert(e);
return e->maybeThunk(state, state.baseEnv);
}
Symbol createSymbol(const char * value) {
return state.symbols.create(value);
}

View File

@@ -0,0 +1 @@
../../build-utils-meson

View File

@@ -138,27 +138,4 @@ TEST(nix_isAllowedURI, non_scheme_colon) {
ASSERT_FALSE(isAllowedURI("https://foo/bar:baz", allowed));
}
class EvalStateTest : public LibExprTest {};
TEST_F(EvalStateTest, getBuiltins_ok) {
auto evaled = maybeThunk("builtins");
auto & builtins = state.getBuiltins();
ASSERT_TRUE(builtins.type() == nAttrs);
ASSERT_EQ(evaled, &builtins);
}
TEST_F(EvalStateTest, getBuiltin_ok) {
auto & builtin = state.getBuiltin("toString");
ASSERT_TRUE(builtin.type() == nFunction);
// FIXME
// auto evaled = maybeThunk("builtins.toString");
// ASSERT_EQ(evaled, &builtin);
auto & builtin2 = state.getBuiltin("true");
ASSERT_EQ(state.forceBool(builtin2, noPos, "in unit test"), true);
}
TEST_F(EvalStateTest, getBuiltin_fail) {
ASSERT_THROW(state.getBuiltin("nonexistent"), EvalError);
}
} // namespace nix
} // namespace nix

View File

@@ -14,7 +14,7 @@ project('nix-expr-tests', 'cpp',
cxx = meson.get_compiler('cpp')
subdir('nix-meson-build-support/deps-lists')
subdir('build-utils-meson/deps-lists')
deps_private_maybe_subproject = [
dependency('nix-expr'),
@@ -23,10 +23,12 @@ deps_private_maybe_subproject = [
]
deps_public_maybe_subproject = [
]
subdir('nix-meson-build-support/subprojects')
subdir('build-utils-meson/subprojects')
subdir('nix-meson-build-support/export-all-symbols')
subdir('nix-meson-build-support/windows-version')
subdir('build-utils-meson/threads')
subdir('build-utils-meson/export-all-symbols')
subdir('build-utils-meson/windows-version')
rapidcheck = dependency('rapidcheck')
deps_private += rapidcheck
@@ -49,7 +51,7 @@ add_project_arguments(
language : 'cpp',
)
subdir('nix-meson-build-support/common')
subdir('build-utils-meson/diagnostics')
sources = files(
'derived-path.cc',

View File

@@ -1 +0,0 @@
../../nix-meson-build-support

View File

@@ -7,49 +7,12 @@
#include "tests/nix_api_expr.hh"
#include "tests/string_callback.hh"
#include "file-system.hh"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
namespace nixC {
TEST_F(nix_api_store_test, nix_eval_state_lookup_path)
{
auto tmpDir = nix::createTempDir();
auto delTmpDir = std::make_unique<nix::AutoDelete>(tmpDir, true);
auto nixpkgs = tmpDir + "/pkgs";
auto nixos = tmpDir + "/cfg";
std::filesystem::create_directories(nixpkgs);
std::filesystem::create_directories(nixos);
std::string nixpkgsEntry = "nixpkgs=" + nixpkgs;
std::string nixosEntry = "nixos-config=" + nixos;
const char * lookupPath[] = {nixpkgsEntry.c_str(), nixosEntry.c_str(), nullptr};
auto builder = nix_eval_state_builder_new(ctx, store);
assert_ctx_ok();
ASSERT_EQ(NIX_OK, nix_eval_state_builder_set_lookup_path(ctx, builder, lookupPath));
assert_ctx_ok();
auto state = nix_eval_state_build(ctx, builder);
assert_ctx_ok();
nix_eval_state_builder_free(builder);
Value * value = nix_alloc_value(ctx, state);
nix_expr_eval_from_string(ctx, state, "builtins.seq <nixos-config> <nixpkgs>", ".", value);
assert_ctx_ok();
ASSERT_EQ(nix_get_type(ctx, value), NIX_TYPE_PATH);
assert_ctx_ok();
auto pathStr = nix_get_path_string(ctx, value);
assert_ctx_ok();
ASSERT_EQ(0, strcmp(pathStr, nixpkgs.c_str()));
}
TEST_F(nix_api_expr_test, nix_expr_eval_from_string)
{
nix_expr_eval_from_string(nullptr, state, "builtins.nixVersion", ".", value);

View File

@@ -27,8 +27,8 @@ mkMesonExecutable (finalAttrs: {
workDir = ./.;
fileset = fileset.unions [
../../nix-meson-build-support
./nix-meson-build-support
../../build-utils-meson
./build-utils-meson
../../.version
./.version
./meson.build

View File

@@ -177,57 +177,6 @@ namespace nix {
)
);
// The following macros ultimately define 48 tests (16 variations on three
// templates). Each template tests an expression that can be written in 2^4
// different ways, by making four choices about whether to write a particular
// attribute path segment as `x.y = ...;` (collapsed) or `x = { y = ...; };`
// (expanded).
//
// The nestedAttrsetMergeXXXX tests check that the expression
// `{ a.b.c = 1; a.b.d = 2; }` has the same value regardless of how it is
// expanded. (That exact expression is exercised in test
// nestedAttrsetMerge0000, because it is fully collapsed. The test
// nestedAttrsetMerge1001 would instead examine
// `{ a = { b.c = 1; }; a.b = { d = 2; }; }`.)
//
// The nestedAttrsetMergeDupXXXX tests check that the expression
// `{ a.b.c = 1; a.b.c = 2; }` throws a duplicate attribute error, again
// regardless of how it is expanded.
//
// The nestedAttrsetMergeLetXXXX tests check that the expression
// `let a.b.c = 1; a.b.d = 2; in a` has the same value regardless of how it is
// expanded.
#define X_EXPAND_IF0(k, v) k "." v
#define X_EXPAND_IF1(k, v) k " = { " v " };"
#define X4(w, x, y, z) \
TEST_F(TrivialExpressionTest, nestedAttrsetMerge##w##x##y##z) { \
auto v = eval("{ a.b = { c = 1; d = 2; }; } == { " \
X_EXPAND_IF##w("a", X_EXPAND_IF##x("b", "c = 1;")) " " \
X_EXPAND_IF##y("a", X_EXPAND_IF##z("b", "d = 2;")) " }"); \
ASSERT_THAT(v, IsTrue()); \
}; \
TEST_F(TrivialExpressionTest, nestedAttrsetMergeDup##w##x##y##z) { \
ASSERT_THROW(eval("{ " \
X_EXPAND_IF##w("a", X_EXPAND_IF##x("b", "c = 1;")) " " \
X_EXPAND_IF##y("a", X_EXPAND_IF##z("b", "c = 2;")) " }"), Error); \
}; \
TEST_F(TrivialExpressionTest, nestedAttrsetMergeLet##w##x##y##z) { \
auto v = eval("{ b = { c = 1; d = 2; }; } == (let " \
X_EXPAND_IF##w("a", X_EXPAND_IF##x("b", "c = 1;")) " " \
X_EXPAND_IF##y("a", X_EXPAND_IF##z("b", "d = 2;")) " in a)"); \
ASSERT_THAT(v, IsTrue()); \
};
#define X3(...) X4(__VA_ARGS__, 0) X4(__VA_ARGS__, 1)
#define X2(...) X3(__VA_ARGS__, 0) X3(__VA_ARGS__, 1)
#define X1(...) X2(__VA_ARGS__, 0) X2(__VA_ARGS__, 1)
X1(0) X1(1)
#undef X_EXPAND_IF0
#undef X_EXPAND_IF1
#undef X1
#undef X2
#undef X3
#undef X4
TEST_F(TrivialExpressionTest, functor) {
auto v = eval("{ __functor = self: arg: self.v + arg; v = 10; } 5");
ASSERT_THAT(v, IsIntEq(15));

View File

@@ -129,6 +129,7 @@ std::pair<SourcePath, uint32_t> findPackageFilename(EvalState & state, Value & v
try {
auto colon = fn.rfind(':');
if (colon == std::string::npos) fail();
std::string filename(fn, 0, colon);
auto lineno = std::stoi(std::string(fn, colon + 1, std::string::npos));
return {SourcePath{path.accessor, CanonPath(fn.substr(0, colon))}, lineno};
} catch (std::invalid_argument & e) {

View File

@@ -0,0 +1 @@
../../build-utils-meson

View File

@@ -10,9 +10,6 @@ lockFileStr:
# unlocked trees.
overrides:
# This is `prim_fetchFinalTree`.
fetchTreeFinal:
let
lockFile = builtins.fromJSON lockFileStr;
@@ -47,8 +44,7 @@ let
overrides.${key}.sourceInfo
else
# FIXME: remove obsolete node.info.
# Note: lock file entries are always final.
fetchTreeFinal (node.info or {} // removeAttrs node.locked ["dir"]);
fetchTree (node.info or {} // removeAttrs node.locked ["dir"]);
subdir = overrides.${key}.dir or node.locked.dir or "";

View File

@@ -87,15 +87,11 @@ void EvalState::forceValue(Value & v, const PosIdx pos)
{
if (v.isThunk()) {
Env * env = v.payload.thunk.env;
assert(env || v.isBlackhole());
Expr * expr = v.payload.thunk.expr;
try {
v.mkBlackhole();
//checkInterrupt();
if (env) [[likely]]
expr->eval(*this, *env, v);
else
ExprBlackHole::throwInfiniteRecursionError(*this, v);
expr->eval(*this, *env, v);
} catch (...) {
v.mkThunk(env, expr);
tryFixupBlackHolePos(v, pos);

View File

@@ -3,11 +3,10 @@
#include "config.hh"
#include "ref.hh"
#include "source-path.hh"
namespace nix {
class EvalState;
class Store;
struct EvalSettings : Config
{
@@ -19,8 +18,11 @@ struct EvalSettings : Config
*
* The return value is (a) whether the entry was valid, and, if so,
* what does it map to.
*
* @todo Return (`std::optional` of) `SourceAccssor` or something
* more structured instead of mere `std::string`?
*/
using LookupPathHook = std::optional<SourcePath>(EvalState & state, std::string_view);
using LookupPathHook = std::optional<std::string>(ref<Store> store, std::string_view);
/**
* Map from "scheme" to a `LookupPathHook`.

View File

@@ -448,7 +448,7 @@ void EvalState::addConstant(const std::string & name, Value * v, Constant info)
/* Install value the base environment. */
staticBaseEnv->vars.emplace_back(symbols.create(name), baseEnvDispl);
baseEnv.values[baseEnvDispl++] = v;
getBuiltins().payload.attrs->push_back(Attr(symbols.create(name2), v));
baseEnv.values[0]->payload.attrs->push_back(Attr(symbols.create(name2), v));
}
}
@@ -510,32 +510,16 @@ Value * EvalState::addPrimOp(PrimOp && primOp)
Value * v = allocValue();
v->mkPrimOp(new PrimOp(primOp));
if (primOp.internal)
internalPrimOps.emplace(primOp.name, v);
else {
staticBaseEnv->vars.emplace_back(envName, baseEnvDispl);
baseEnv.values[baseEnvDispl++] = v;
getBuiltins().payload.attrs->push_back(Attr(symbols.create(primOp.name), v));
}
staticBaseEnv->vars.emplace_back(envName, baseEnvDispl);
baseEnv.values[baseEnvDispl++] = v;
baseEnv.values[0]->payload.attrs->push_back(Attr(symbols.create(primOp.name), v));
return v;
}
Value & EvalState::getBuiltins()
{
return *baseEnv.values[0];
}
Value & EvalState::getBuiltin(const std::string & name)
{
auto it = getBuiltins().attrs()->get(symbols.create(name));
if (it)
return *it->value;
else
error<EvalError>("builtin '%1%' not found", name).debugThrow();
return *baseEnv.values[0]->attrs()->find(symbols.create(name))->value;
}
@@ -598,14 +582,14 @@ std::optional<EvalState::Doc> EvalState::getDoc(Value & v)
if (isFunctor(v)) {
try {
Value & functor = *v.attrs()->find(sFunctor)->value;
Value * vp[] = {&v};
Value * vp = &v;
Value partiallyApplied;
// The first paramater is not user-provided, and may be
// handled by code that is opaque to the user, like lib.const = x: y: y;
// So preferably we show docs that are relevant to the
// "partially applied" function returned by e.g. `const`.
// We apply the first argument:
callFunction(functor, vp, partiallyApplied, noPos);
callFunction(functor, 1, &vp, partiallyApplied, noPos);
auto _level = addCallDepth(noPos);
return getDoc(partiallyApplied);
}
@@ -1470,7 +1454,7 @@ void ExprLambda::eval(EvalState & state, Env & env, Value & v)
v.mkLambda(&env, this);
}
void EvalState::callFunction(Value & fun, std::span<Value *> args, Value & vRes, const PosIdx pos)
void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & vRes, const PosIdx pos)
{
auto _level = addCallDepth(pos);
@@ -1485,16 +1469,16 @@ void EvalState::callFunction(Value & fun, std::span<Value *> args, Value & vRes,
auto makeAppChain = [&]()
{
vRes = vCur;
for (auto arg : args) {
for (size_t i = 0; i < nrArgs; ++i) {
auto fun2 = allocValue();
*fun2 = vRes;
vRes.mkPrimOpApp(fun2, arg);
vRes.mkPrimOpApp(fun2, args[i]);
}
};
const Attr * functor;
while (args.size() > 0) {
while (nrArgs > 0) {
if (vCur.isLambda()) {
@@ -1597,14 +1581,15 @@ void EvalState::callFunction(Value & fun, std::span<Value *> args, Value & vRes,
throw;
}
args = args.subspan(1);
nrArgs--;
args += 1;
}
else if (vCur.isPrimOp()) {
size_t argsLeft = vCur.primOp()->arity;
if (args.size() < argsLeft) {
if (nrArgs < argsLeft) {
/* We don't have enough arguments, so create a tPrimOpApp chain. */
makeAppChain();
return;
@@ -1616,14 +1601,15 @@ void EvalState::callFunction(Value & fun, std::span<Value *> args, Value & vRes,
if (countCalls) primOpCalls[fn->name]++;
try {
fn->fun(*this, vCur.determinePos(noPos), args.data(), vCur);
fn->fun(*this, vCur.determinePos(noPos), args, vCur);
} catch (Error & e) {
if (fn->addTrace)
addErrorTrace(e, pos, "while calling the '%1%' builtin", fn->name);
throw;
}
args = args.subspan(argsLeft);
nrArgs -= argsLeft;
args += argsLeft;
}
}
@@ -1639,7 +1625,7 @@ void EvalState::callFunction(Value & fun, std::span<Value *> args, Value & vRes,
auto arity = primOp->primOp()->arity;
auto argsLeft = arity - argsDone;
if (args.size() < argsLeft) {
if (nrArgs < argsLeft) {
/* We still don't have enough arguments, so extend the tPrimOpApp chain. */
makeAppChain();
return;
@@ -1671,7 +1657,8 @@ void EvalState::callFunction(Value & fun, std::span<Value *> args, Value & vRes,
throw;
}
args = args.subspan(argsLeft);
nrArgs -= argsLeft;
args += argsLeft;
}
}
@@ -1682,12 +1669,13 @@ void EvalState::callFunction(Value & fun, std::span<Value *> args, Value & vRes,
Value * args2[] = {allocValue(), args[0]};
*args2[0] = vCur;
try {
callFunction(*functor->value, args2, vCur, functor->pos);
callFunction(*functor->value, 2, args2, vCur, functor->pos);
} catch (Error & e) {
e.addTrace(positions[pos], "while calling a functor (an attribute set with a '__functor' attribute)");
throw;
}
args = args.subspan(1);
nrArgs--;
args++;
}
else
@@ -1730,7 +1718,7 @@ void ExprCall::eval(EvalState & state, Env & env, Value & v)
for (size_t i = 0; i < args.size(); ++i)
vArgs[i] = args[i]->maybeThunk(state, env);
state.callFunction(vFun, vArgs, v, pos);
state.callFunction(vFun, args.size(), vArgs.data(), v, pos);
}
@@ -1742,7 +1730,7 @@ void EvalState::incrFunctionCall(ExprLambda * fun)
}
void EvalState::autoCallFunction(const Bindings & args, Value & fun, Value & res)
void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
{
auto pos = fun.determinePos(noPos);
@@ -2052,12 +2040,9 @@ void ExprPos::eval(EvalState & state, Env & env, Value & v)
state.mkPos(v, pos);
}
void ExprBlackHole::eval(EvalState & state, [[maybe_unused]] Env & env, Value & v)
{
throwInfiniteRecursionError(state, v);
}
[[gnu::noinline]] [[noreturn]] void ExprBlackHole::throwInfiniteRecursionError(EvalState & state, Value &v) {
void ExprBlackHole::eval(EvalState & state, Env & env, Value & v)
{
state.error<InfiniteRecursionError>("infinite recursion encountered")
.atPos(v.determinePos(noPos))
.debugThrow();
@@ -3038,8 +3023,8 @@ SourcePath EvalState::findFile(const LookupPath & lookupPath, const std::string_
if (!rOpt) continue;
auto r = *rOpt;
auto res = (r / CanonPath(suffix)).resolveSymlinks();
if (res.pathExists()) return res;
Path res = suffix == "" ? r : concatStrings(r, "/", suffix);
if (pathExists(res)) return rootPath(CanonPath(canonPath(res)));
}
if (hasPrefix(path, "nix/"))
@@ -3054,13 +3039,13 @@ SourcePath EvalState::findFile(const LookupPath & lookupPath, const std::string_
}
std::optional<SourcePath> EvalState::resolveLookupPathPath(const LookupPath::Path & value0, bool initAccessControl)
std::optional<std::string> EvalState::resolveLookupPathPath(const LookupPath::Path & value0, bool initAccessControl)
{
auto & value = value0.s;
auto i = lookupPathResolved.find(value);
if (i != lookupPathResolved.end()) return i->second;
auto finish = [&](SourcePath res) {
auto finish = [&](std::string res) {
debug("resolved search path element '%s' to '%s'", value, res);
lookupPathResolved.emplace(value, res);
return res;
@@ -3073,7 +3058,7 @@ std::optional<SourcePath> EvalState::resolveLookupPathPath(const LookupPath::Pat
fetchSettings,
EvalSettings::resolvePseudoUrl(value));
auto storePath = fetchToStore(*store, SourcePath(accessor), FetchMode::Copy);
return finish(rootPath(store->toRealPath(storePath)));
return finish(store->toRealPath(storePath));
} catch (Error & e) {
logWarning({
.msg = HintFmt("Nix search path entry '%1%' cannot be downloaded, ignoring", value)
@@ -3085,29 +3070,29 @@ std::optional<SourcePath> EvalState::resolveLookupPathPath(const LookupPath::Pat
auto scheme = value.substr(0, colPos);
auto rest = value.substr(colPos + 1);
if (auto * hook = get(settings.lookupPathHooks, scheme)) {
auto res = (*hook)(*this, rest);
auto res = (*hook)(store, rest);
if (res)
return finish(std::move(*res));
}
}
{
auto path = rootPath(value);
auto path = absPath(value);
/* Allow access to paths in the search path. */
if (initAccessControl) {
allowPath(path.path.abs());
if (store->isInStore(path.path.abs())) {
allowPath(path);
if (store->isInStore(path)) {
try {
StorePathSet closure;
store->computeFSClosure(store->toStorePath(path.path.abs()).first, closure);
store->computeFSClosure(store->toStorePath(path).first, closure);
for (auto & p : closure)
allowPath(p);
} catch (InvalidPath &) { }
}
}
if (path.pathExists())
if (pathExists(path))
return finish(std::move(path));
else {
logWarning({
@@ -3118,6 +3103,7 @@ std::optional<SourcePath> EvalState::resolveLookupPathPath(const LookupPath::Pat
debug("failed to resolve search path element '%s'", value);
return std::nullopt;
}
@@ -3178,14 +3164,5 @@ std::ostream & operator << (std::ostream & str, const ExternalValueBase & v) {
return v.print(str);
}
void forceNoNullByte(std::string_view s)
{
if (s.find('\0') != s.npos) {
using namespace std::string_view_literals;
auto str = replaceStrings(std::string(s), "\0"sv, ""sv);
throw Error("input string '%s' cannot be represented as Nix string because it contains null bytes", str);
}
}
}

View File

@@ -91,7 +91,7 @@ struct PrimOp
const char * doc = nullptr;
/**
* Add a trace item, while calling the `<name>` builtin.
* Add a trace item, `while calling the '<name>' builtin`
*
* This is used to remove the redundant item for `builtins.addErrorContext`.
*/
@@ -107,11 +107,6 @@ struct PrimOp
*/
std::optional<ExperimentalFeature> experimentalFeature;
/**
* If true, this primop is not exposed to the user.
*/
bool internal = false;
/**
* Validity check to be performed by functions that introduce primops,
* such as RegisterPrimOp() and Value::mkPrimOp().
@@ -347,7 +342,7 @@ private:
LookupPath lookupPath;
std::map<std::string, std::optional<SourcePath>> lookupPathResolved;
std::map<std::string, std::optional<std::string>> lookupPathResolved;
/**
* Cache used by prim_match().
@@ -452,9 +447,9 @@ public:
*
* If the specified search path element is a URI, download it.
*
* If it is not found, return `std::nullopt`.
* If it is not found, return `std::nullopt`
*/
std::optional<SourcePath> resolveLookupPathPath(
std::optional<std::string> resolveLookupPathPath(
const LookupPath::Path & elem,
bool initAccessControl = false);
@@ -596,11 +591,6 @@ public:
*/
std::shared_ptr<StaticEnv> staticBaseEnv; // !!! should be private
/**
* Internal primops not exposed to the user.
*/
std::unordered_map<std::string, Value *, std::hash<std::string>, std::equal_to<std::string>, traceable_allocator<std::pair<const std::string, Value *>>> internalPrimOps;
/**
* Name and documentation about every constant.
*
@@ -623,19 +613,8 @@ private:
public:
/**
* Retrieve a specific builtin, equivalent to evaluating `builtins.${name}`.
* @param name The attribute name of the builtin to retrieve.
* @throws EvalError if the builtin does not exist.
*/
Value & getBuiltin(const std::string & name);
/**
* Retrieve the `builtins` attrset, equivalent to evaluating the reference `builtins`.
* Always returns an attribute set value.
*/
Value & getBuiltins();
struct Doc
{
Pos pos;
@@ -701,19 +680,20 @@ public:
bool isFunctor(Value & fun);
void callFunction(Value & fun, std::span<Value *> args, Value & vRes, const PosIdx pos);
// FIXME: use std::span
void callFunction(Value & fun, size_t nrArgs, Value * * args, Value & vRes, const PosIdx pos);
void callFunction(Value & fun, Value & arg, Value & vRes, const PosIdx pos)
{
Value * args[] = {&arg};
callFunction(fun, args, vRes, pos);
callFunction(fun, 1, args, vRes, pos);
}
/**
* Automatically call a function for which each argument has a
* default value or has a binding in the `args` map.
*/
void autoCallFunction(const Bindings & args, Value & fun, Value & res);
void autoCallFunction(Bindings & args, Value & fun, Value & res);
/**
* Allocation primitives.
@@ -819,6 +799,7 @@ public:
bool callPathFilter(
Value * filterFun,
const SourcePath & path,
std::string_view pathArg,
PosIdx pos);
DocComment getDocCommentForPos(PosIdx pos);

View File

@@ -50,7 +50,6 @@ class JSONSax : nlohmann::json_sax<json> {
public:
void key(string_t & name, EvalState & state)
{
forceNoNullByte(name);
attrs.insert_or_assign(state.symbols.create(name), &value(state));
}
};
@@ -123,7 +122,6 @@ public:
bool string(string_t & val) override
{
forceNoNullByte(val);
rs->value(state).mkString(val);
rs->add();
return true;

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