mirror of
https://github.com/NixOS/nix.git
synced 2025-11-17 07:52:43 +01:00
Merge branch 'master' into document-derivation-and-deriving-path
This commit is contained in:
commit
16bd5a44ef
375 changed files with 6188 additions and 2232 deletions
50
.github/ISSUE_TEMPLATE/bug_report.md
vendored
50
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
|
@ -1,36 +1,54 @@
|
||||||
---
|
---
|
||||||
name: Bug report
|
name: Bug report
|
||||||
about: Create a report to help us improve
|
about: Report unexpected or incorrect behaviour
|
||||||
title: ''
|
title: ''
|
||||||
labels: bug
|
labels: bug
|
||||||
assignees: ''
|
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,
|
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.
|
you probably want to file an issue at https://github.com/NixOS/nixpkgs/issues.
|
||||||
|
-->
|
||||||
|
|
||||||
**Steps To Reproduce**
|
## Steps To Reproduce
|
||||||
|
|
||||||
1. Go to '...'
|
<!--
|
||||||
2. Click on '....'
|
Example:
|
||||||
3. Scroll down to '....'
|
|
||||||
4. See error
|
|
||||||
|
|
||||||
**Expected behavior**
|
1. Clone this repository: ...
|
||||||
|
2. Run `nix-... ...`
|
||||||
|
3. Observe unexpected behaviour
|
||||||
|
-->
|
||||||
|
|
||||||
A clear and concise description of what you expected to happen.
|
## Expected behavior
|
||||||
|
|
||||||
**`nix-env --version` output**
|
<!-- A clear and concise description of what you expected to happen. -->
|
||||||
|
|
||||||
**Additional context**
|
## Metadata
|
||||||
|
|
||||||
Add any other context about the problem here.
|
<!-- Please insert the output of running `nix-env --version` below this line -->
|
||||||
|
|
||||||
**Priorities**
|
## 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
Add :+1: to [issues you find important](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).
|
Add :+1: to [issues you find important](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).
|
||||||
|
|
|
||||||
35
.github/ISSUE_TEMPLATE/feature_request.md
vendored
35
.github/ISSUE_TEMPLATE/feature_request.md
vendored
|
|
@ -1,24 +1,39 @@
|
||||||
---
|
---
|
||||||
name: Feature request
|
name: Feature request
|
||||||
about: Suggest an idea for this project
|
about: Suggest a new feature
|
||||||
title: ''
|
title: ''
|
||||||
labels: feature
|
labels: feature
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Is your feature request related to a problem? Please describe.**
|
## Is your feature request related to a problem?
|
||||||
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 the problem is. Ex. I'm always frustrated when [...] -->
|
||||||
A clear and concise description of what you want to happen.
|
|
||||||
|
|
||||||
**Describe alternatives you've considered**
|
## Proposed solution
|
||||||
A clear and concise description of any alternative solutions or features you've considered.
|
|
||||||
|
|
||||||
**Additional context**
|
<!-- A clear and concise description of what you want to happen. -->
|
||||||
Add any other context or screenshots about the feature request here.
|
|
||||||
|
|
||||||
**Priorities**
|
## 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
Add :+1: to [issues you find important](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).
|
Add :+1: to [issues you find important](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).
|
||||||
|
|
|
||||||
17
.github/ISSUE_TEMPLATE/installer.md
vendored
17
.github/ISSUE_TEMPLATE/installer.md
vendored
|
|
@ -23,14 +23,25 @@ assignees: ''
|
||||||
|
|
||||||
<details><summary>Output</summary>
|
<details><summary>Output</summary>
|
||||||
|
|
||||||
```log
|
<!-- paste console output inside the below code block -->
|
||||||
|
|
||||||
<!-- paste console output here and remove this comment -->
|
```log
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## Priorities
|
## 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
Add :+1: to [issues you find important](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).
|
Add :+1: to [issues you find important](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,6 @@ assignees: ''
|
||||||
[source]: https://github.com/NixOS/nix/tree/master/doc/manual/source
|
[source]: https://github.com/NixOS/nix/tree/master/doc/manual/source
|
||||||
[open documentation issues and pull requests]: https://github.com/NixOS/nix/labels/documentation
|
[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).
|
Add :+1: to [issues you find important](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).
|
||||||
|
|
|
||||||
8
.github/PULL_REQUEST_TEMPLATE.md
vendored
8
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
|
@ -17,10 +17,12 @@ so you understand the process and the expectations.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
# Motivation
|
## Motivation
|
||||||
|
|
||||||
<!-- Briefly explain what the change is about and why it is desirable. -->
|
<!-- Briefly explain what the change is about and why it is desirable. -->
|
||||||
|
|
||||||
# Context
|
## Context
|
||||||
|
|
||||||
<!-- Provide context. Reference open issues if available. -->
|
<!-- Provide context. Reference open issues if available. -->
|
||||||
|
|
||||||
<!-- Non-trivial change: Briefly outline the implementation strategy. -->
|
<!-- Non-trivial change: Briefly outline the implementation strategy. -->
|
||||||
|
|
@ -29,7 +31,7 @@ so you understand the process and the expectations.
|
||||||
|
|
||||||
<!-- Large change: Provide instructions to reviewers how to read the diff. -->
|
<!-- 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).
|
Add :+1: to [pull requests you find important](https://github.com/NixOS/nix/pulls?q=is%3Aopen+sort%3Areactions-%2B1-desc).
|
||||||
|
|
||||||
|
|
|
||||||
197
.github/workflows/ci.yml
vendored
197
.github/workflows/ci.yml
vendored
|
|
@ -7,14 +7,28 @@ on:
|
||||||
permissions: read-all
|
permissions: read-all
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
eval:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: cachix/install-nix-action@v30
|
||||||
|
- run: nix --experimental-features 'nix-command flakes' flake show --all-systems --json
|
||||||
|
|
||||||
tests:
|
tests:
|
||||||
needs: [check_secrets]
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest]
|
include:
|
||||||
runs-on: ${{ matrix.os }}
|
- scenario: on ubuntu
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
os: linux
|
||||||
|
- scenario: on macos
|
||||||
|
runs-on: macos-14
|
||||||
|
os: darwin
|
||||||
|
name: tests ${{ matrix.scenario }}
|
||||||
|
runs-on: ${{ matrix.runs-on }}
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
@ -23,103 +37,54 @@ jobs:
|
||||||
- uses: cachix/install-nix-action@v30
|
- uses: cachix/install-nix-action@v30
|
||||||
with:
|
with:
|
||||||
# The sandbox would otherwise be disabled by default on Darwin
|
# The sandbox would otherwise be disabled by default on Darwin
|
||||||
extra_nix_config: "sandbox = true"
|
extra_nix_config: |
|
||||||
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
sandbox = true
|
||||||
- uses: cachix/cachix-action@v15
|
max-jobs = 1
|
||||||
if: needs.check_secrets.outputs.cachix == 'true'
|
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||||
|
# Since ubuntu 22.30, unprivileged usernamespaces are no longer allowed to map to the root user:
|
||||||
|
# https://ubuntu.com/blog/ubuntu-23-10-restricted-unprivileged-user-namespaces
|
||||||
|
- run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
|
||||||
|
if: matrix.os == 'linux'
|
||||||
|
- run: scripts/build-checks
|
||||||
|
- run: scripts/prepare-installer-for-github-actions
|
||||||
|
- name: Upload installer tarball
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: '${{ env.CACHIX_NAME }}'
|
name: installer-${{matrix.os}}
|
||||||
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
path: out/*
|
||||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
|
||||||
- if: matrix.os == 'ubuntu-latest'
|
|
||||||
run: |
|
|
||||||
free -h
|
|
||||||
swapon --show
|
|
||||||
swap=$(swapon --show --noheadings | head -n 1 | awk '{print $1}')
|
|
||||||
echo "Found swap: $swap"
|
|
||||||
sudo swapoff $swap
|
|
||||||
# resize it (fallocate)
|
|
||||||
sudo fallocate -l 10G $swap
|
|
||||||
sudo mkswap $swap
|
|
||||||
sudo swapon $swap
|
|
||||||
free -h
|
|
||||||
(
|
|
||||||
while sleep 60; do
|
|
||||||
free -h
|
|
||||||
done
|
|
||||||
) &
|
|
||||||
- run: nix --experimental-features 'nix-command flakes' flake check -L
|
|
||||||
- run: nix --experimental-features 'nix-command flakes' flake show --all-systems --json
|
|
||||||
|
|
||||||
# Steps to test CI automation in your own fork.
|
|
||||||
# Cachix:
|
|
||||||
# 1. Sign-up for https://www.cachix.org/
|
|
||||||
# 2. Create a cache for $githubuser-nix-install-tests
|
|
||||||
# 3. Create a cachix auth token and save it in https://github.com/$githubuser/nix/settings/secrets/actions in "Repository secrets" as CACHIX_AUTH_TOKEN
|
|
||||||
# Dockerhub:
|
|
||||||
# 1. Sign-up for https://hub.docker.com/
|
|
||||||
# 2. Store your dockerhub username as DOCKERHUB_USERNAME in "Repository secrets" of your fork repository settings (https://github.com/$githubuser/nix/settings/secrets/actions)
|
|
||||||
# 3. Create an access token in https://hub.docker.com/settings/security and store it as DOCKERHUB_TOKEN in "Repository secrets" of your fork
|
|
||||||
check_secrets:
|
|
||||||
permissions:
|
|
||||||
contents: none
|
|
||||||
name: Check Cachix and Docker secrets present for installer tests
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
cachix: ${{ steps.secret.outputs.cachix }}
|
|
||||||
docker: ${{ steps.secret.outputs.docker }}
|
|
||||||
steps:
|
|
||||||
- name: Check for secrets
|
|
||||||
id: secret
|
|
||||||
env:
|
|
||||||
_CACHIX_SECRETS: ${{ secrets.CACHIX_SIGNING_KEY }}${{ secrets.CACHIX_AUTH_TOKEN }}
|
|
||||||
_DOCKER_SECRETS: ${{ secrets.DOCKERHUB_USERNAME }}${{ secrets.DOCKERHUB_TOKEN }}
|
|
||||||
run: |
|
|
||||||
echo "::set-output name=cachix::${{ env._CACHIX_SECRETS != '' }}"
|
|
||||||
echo "::set-output name=docker::${{ env._DOCKER_SECRETS != '' }}"
|
|
||||||
|
|
||||||
installer:
|
|
||||||
needs: [tests, check_secrets]
|
|
||||||
if: github.event_name == 'push' && needs.check_secrets.outputs.cachix == 'true'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
installerURL: ${{ steps.prepare-installer.outputs.installerURL }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
|
||||||
- uses: cachix/install-nix-action@v30
|
|
||||||
with:
|
|
||||||
install_url: https://releases.nixos.org/nix/nix-2.20.3/install
|
|
||||||
- uses: cachix/cachix-action@v15
|
|
||||||
with:
|
|
||||||
name: '${{ env.CACHIX_NAME }}'
|
|
||||||
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
|
||||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
|
||||||
cachixArgs: '-v'
|
|
||||||
- id: prepare-installer
|
|
||||||
run: scripts/prepare-installer-for-github-actions
|
|
||||||
|
|
||||||
installer_test:
|
installer_test:
|
||||||
needs: [installer, check_secrets]
|
needs: [tests]
|
||||||
if: github.event_name == 'push' && needs.check_secrets.outputs.cachix == 'true'
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest]
|
include:
|
||||||
runs-on: ${{ matrix.os }}
|
- scenario: on ubuntu
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
os: linux
|
||||||
|
- scenario: on macos
|
||||||
|
runs-on: macos-14
|
||||||
|
os: darwin
|
||||||
|
name: installer test ${{ matrix.scenario }}
|
||||||
|
runs-on: ${{ matrix.runs-on }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
- name: Download installer tarball
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: installer-${{matrix.os}}
|
||||||
|
path: out
|
||||||
|
- name: Serving installer
|
||||||
|
id: serving_installer
|
||||||
|
run: ./scripts/serve-installer-for-github-actions
|
||||||
- uses: cachix/install-nix-action@v30
|
- uses: cachix/install-nix-action@v30
|
||||||
with:
|
with:
|
||||||
install_url: '${{needs.installer.outputs.installerURL}}'
|
install_url: 'http://localhost:8126/install'
|
||||||
install_options: "--tarball-url-prefix https://${{ env.CACHIX_NAME }}.cachix.org/serve"
|
install_options: "--tarball-url-prefix http://localhost:8126/"
|
||||||
- run: sudo apt install fish zsh
|
- run: sudo apt install fish zsh
|
||||||
if: matrix.os == 'ubuntu-latest'
|
if: matrix.os == 'linux'
|
||||||
- run: brew install fish
|
- run: brew install fish
|
||||||
if: matrix.os == 'macos-latest'
|
if: matrix.os == 'darwin'
|
||||||
- run: exec bash -c "nix-instantiate -E 'builtins.currentTime' --eval"
|
- run: exec bash -c "nix-instantiate -E 'builtins.currentTime' --eval"
|
||||||
- run: exec sh -c "nix-instantiate -E 'builtins.currentTime' --eval"
|
- run: exec sh -c "nix-instantiate -E 'builtins.currentTime' --eval"
|
||||||
- run: exec zsh -c "nix-instantiate -E 'builtins.currentTime' --eval"
|
- run: exec zsh -c "nix-instantiate -E 'builtins.currentTime' --eval"
|
||||||
|
|
@ -127,32 +92,50 @@ jobs:
|
||||||
- run: exec bash -c "nix-channel --add https://releases.nixos.org/nixos/unstable/nixos-23.05pre466020.60c1d71f2ba nixpkgs"
|
- run: exec bash -c "nix-channel --add https://releases.nixos.org/nixos/unstable/nixos-23.05pre466020.60c1d71f2ba nixpkgs"
|
||||||
- run: exec bash -c "nix-channel --update && nix-env -iA nixpkgs.hello && hello"
|
- run: exec bash -c "nix-channel --update && nix-env -iA nixpkgs.hello && hello"
|
||||||
|
|
||||||
|
# Steps to test CI automation in your own fork.
|
||||||
|
# 1. Sign-up for https://hub.docker.com/
|
||||||
|
# 2. Store your dockerhub username as DOCKERHUB_USERNAME in "Repository secrets" of your fork repository settings (https://github.com/$githubuser/nix/settings/secrets/actions)
|
||||||
|
# 3. Create an access token in https://hub.docker.com/settings/security and store it as DOCKERHUB_TOKEN in "Repository secrets" of your fork
|
||||||
|
check_secrets:
|
||||||
|
permissions:
|
||||||
|
contents: none
|
||||||
|
name: Check Docker secrets present for installer tests
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
outputs:
|
||||||
|
docker: ${{ steps.secret.outputs.docker }}
|
||||||
|
steps:
|
||||||
|
- name: Check for secrets
|
||||||
|
id: secret
|
||||||
|
env:
|
||||||
|
_DOCKER_SECRETS: ${{ secrets.DOCKERHUB_USERNAME }}${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
echo "::set-output name=docker::${{ env._DOCKER_SECRETS != '' }}"
|
||||||
|
|
||||||
docker_push_image:
|
docker_push_image:
|
||||||
needs: [check_secrets, tests]
|
needs: [tests, vm_tests, check_secrets]
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
packages: write
|
packages: write
|
||||||
if: >-
|
if: >-
|
||||||
|
needs.check_secrets.outputs.docker == 'true' &&
|
||||||
github.event_name == 'push' &&
|
github.event_name == 'push' &&
|
||||||
github.ref_name == 'master' &&
|
github.ref_name == 'master'
|
||||||
needs.check_secrets.outputs.cachix == 'true' &&
|
runs-on: ubuntu-24.04
|
||||||
needs.check_secrets.outputs.docker == 'true'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: Check for secrets
|
||||||
|
id: secret
|
||||||
|
env:
|
||||||
|
_DOCKER_SECRETS: ${{ secrets.DOCKERHUB_USERNAME }}${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
echo "::set-output name=docker::${{ env._DOCKER_SECRETS != '' }}"
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: cachix/install-nix-action@v30
|
- uses: cachix/install-nix-action@v30
|
||||||
with:
|
with:
|
||||||
install_url: https://releases.nixos.org/nix/nix-2.20.3/install
|
install_url: https://releases.nixos.org/nix/nix-2.20.3/install
|
||||||
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||||
- run: echo NIX_VERSION="$(nix --experimental-features 'nix-command flakes' eval .\#nix.version | tr -d \")" >> $GITHUB_ENV
|
- run: echo NIX_VERSION="$(nix --experimental-features 'nix-command flakes' eval .\#nix.version | tr -d \")" >> $GITHUB_ENV
|
||||||
- uses: cachix/cachix-action@v15
|
|
||||||
if: needs.check_secrets.outputs.cachix == 'true'
|
|
||||||
with:
|
|
||||||
name: '${{ env.CACHIX_NAME }}'
|
|
||||||
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
|
||||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
|
||||||
- run: nix --experimental-features 'nix-command flakes' build .#dockerImage -L
|
- run: nix --experimental-features 'nix-command flakes' build .#dockerImage -L
|
||||||
- run: docker load -i ./result/image.tar.gz
|
- run: docker load -i ./result/image.tar.gz
|
||||||
- run: docker tag nix:$NIX_VERSION ${{ secrets.DOCKERHUB_USERNAME }}/nix:$NIX_VERSION
|
- run: docker tag nix:$NIX_VERSION ${{ secrets.DOCKERHUB_USERNAME }}/nix:$NIX_VERSION
|
||||||
|
|
@ -189,16 +172,22 @@ jobs:
|
||||||
docker push $IMAGE_ID:master
|
docker push $IMAGE_ID:master
|
||||||
|
|
||||||
vm_tests:
|
vm_tests:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: DeterminateSystems/nix-installer-action@main
|
- uses: DeterminateSystems/nix-installer-action@main
|
||||||
- uses: DeterminateSystems/magic-nix-cache-action@main
|
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||||
- run: nix build -L .#hydraJobs.tests.githubFlakes .#hydraJobs.tests.tarballFlakes .#hydraJobs.tests.functional_user
|
- run: |
|
||||||
|
nix build -L \
|
||||||
|
.#hydraJobs.tests.functional_user \
|
||||||
|
.#hydraJobs.tests.githubFlakes \
|
||||||
|
.#hydraJobs.tests.nix-docker \
|
||||||
|
.#hydraJobs.tests.tarballFlakes \
|
||||||
|
;
|
||||||
|
|
||||||
flake_regressions:
|
flake_regressions:
|
||||||
needs: vm_tests
|
needs: vm_tests
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout nix
|
- name: Checkout nix
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
@ -214,4 +203,4 @@ jobs:
|
||||||
path: flake-regressions/tests
|
path: flake-regressions/tests
|
||||||
- uses: DeterminateSystems/nix-installer-action@main
|
- uses: DeterminateSystems/nix-installer-action@main
|
||||||
- uses: DeterminateSystems/magic-nix-cache-action@main
|
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||||
- run: nix build --out-link ./new-nix && PATH=$(pwd)/new-nix/bin:$PATH MAX_FLAKES=25 flake-regressions/eval-all.sh
|
- run: nix build -L --out-link ./new-nix && PATH=$(pwd)/new-nix/bin:$PATH MAX_FLAKES=25 flake-regressions/eval-all.sh
|
||||||
|
|
|
||||||
2
.github/workflows/labels.yml
vendored
2
.github/workflows/labels.yml
vendored
|
|
@ -15,7 +15,7 @@ permissions:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
labels:
|
labels:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-24.04
|
||||||
if: github.repository_owner == 'NixOS'
|
if: github.repository_owner == 'NixOS'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/labeler@v5
|
- uses: actions/labeler@v5
|
||||||
|
|
|
||||||
122
.gitignore
vendored
122
.gitignore
vendored
|
|
@ -1,110 +1,12 @@
|
||||||
Makefile.config
|
|
||||||
perl/Makefile.config
|
|
||||||
|
|
||||||
# /
|
|
||||||
/aclocal.m4
|
|
||||||
/autom4te.cache
|
|
||||||
/precompiled-headers.h.gch
|
|
||||||
/config.*
|
|
||||||
/configure
|
|
||||||
/stamp-h1
|
|
||||||
/svn-revision
|
|
||||||
/libtool
|
|
||||||
/config/config.*
|
|
||||||
# Default meson build dir
|
# Default meson build dir
|
||||||
/build
|
/build
|
||||||
|
|
||||||
# /doc/manual/
|
|
||||||
/doc/manual/*.1
|
|
||||||
/doc/manual/*.5
|
|
||||||
/doc/manual/*.8
|
|
||||||
/doc/manual/generated/*
|
|
||||||
/doc/manual/nix.json
|
|
||||||
/doc/manual/conf-file.json
|
|
||||||
/doc/manual/language.json
|
|
||||||
/doc/manual/xp-features.json
|
|
||||||
/doc/manual/source/SUMMARY.md
|
|
||||||
/doc/manual/source/SUMMARY-rl-next.md
|
|
||||||
/doc/manual/source/store/types/*
|
|
||||||
!/doc/manual/source/store/types/index.md.in
|
|
||||||
/doc/manual/source/command-ref/new-cli
|
|
||||||
/doc/manual/source/command-ref/conf-file.md
|
|
||||||
/doc/manual/source/command-ref/experimental-features-shortlist.md
|
|
||||||
/doc/manual/source/contributing/experimental-feature-descriptions.md
|
|
||||||
/doc/manual/source/language/builtins.md
|
|
||||||
/doc/manual/source/language/builtin-constants.md
|
|
||||||
/doc/manual/source/release-notes/rl-next.md
|
|
||||||
|
|
||||||
# /scripts/
|
|
||||||
/scripts/nix-profile.sh
|
|
||||||
/scripts/nix-profile-daemon.sh
|
|
||||||
/scripts/nix-profile.fish
|
|
||||||
/scripts/nix-profile-daemon.fish
|
|
||||||
|
|
||||||
# /src/libexpr/
|
|
||||||
/src/libexpr/lexer-tab.cc
|
|
||||||
/src/libexpr/lexer-tab.hh
|
|
||||||
/src/libexpr/parser-tab.cc
|
|
||||||
/src/libexpr/parser-tab.hh
|
|
||||||
/src/libexpr/parser-tab.output
|
|
||||||
/src/libexpr/nix.tbl
|
|
||||||
/src/libexpr/tests
|
|
||||||
/src/libexpr-tests/libnixexpr-tests
|
|
||||||
|
|
||||||
# /src/libfetchers
|
|
||||||
/src/libfetchers-tests/libnixfetchers-tests
|
|
||||||
|
|
||||||
# /src/libflake
|
|
||||||
/src/libflake-tests/libnixflake-tests
|
|
||||||
|
|
||||||
# /src/libstore/
|
|
||||||
*.gen.*
|
|
||||||
/src/libstore/tests
|
|
||||||
/src/libstore-tests/libnixstore-tests
|
|
||||||
|
|
||||||
# /src/libutil/
|
|
||||||
/src/libutil/tests
|
|
||||||
/src/libutil-tests/libnixutil-tests
|
|
||||||
|
|
||||||
/src/nix/nix
|
|
||||||
|
|
||||||
/src/nix/generated-doc
|
|
||||||
|
|
||||||
# /src/nix-env/
|
|
||||||
/src/nix-env/nix-env
|
|
||||||
|
|
||||||
# /src/nix-instantiate/
|
|
||||||
/src/nix-instantiate/nix-instantiate
|
|
||||||
|
|
||||||
# /src/nix-store/
|
|
||||||
/src/nix-store/nix-store
|
|
||||||
|
|
||||||
/src/nix-prefetch-url/nix-prefetch-url
|
|
||||||
|
|
||||||
/src/nix-collect-garbage/nix-collect-garbage
|
|
||||||
|
|
||||||
# /src/nix-channel/
|
|
||||||
/src/nix-channel/nix-channel
|
|
||||||
|
|
||||||
# /src/nix-build/
|
|
||||||
/src/nix-build/nix-build
|
|
||||||
|
|
||||||
/src/nix-copy-closure/nix-copy-closure
|
|
||||||
|
|
||||||
/src/error-demo/error-demo
|
|
||||||
|
|
||||||
/src/build-remote/build-remote
|
|
||||||
|
|
||||||
# /tests/functional/
|
# /tests/functional/
|
||||||
/tests/functional/test-tmp
|
|
||||||
/tests/functional/common/subst-vars.sh
|
/tests/functional/common/subst-vars.sh
|
||||||
/tests/functional/result*
|
|
||||||
/tests/functional/restricted-innocent
|
/tests/functional/restricted-innocent
|
||||||
/tests/functional/shell
|
|
||||||
/tests/functional/shell.drv
|
|
||||||
/tests/functional/repl-result-out
|
|
||||||
/tests/functional/debugger-test-out
|
/tests/functional/debugger-test-out
|
||||||
/tests/functional/test-libstoreconsumer/test-libstoreconsumer
|
/tests/functional/test-libstoreconsumer/test-libstoreconsumer
|
||||||
|
/tests/functional/nix-shell
|
||||||
|
|
||||||
# /tests/functional/lang/
|
# /tests/functional/lang/
|
||||||
/tests/functional/lang/*.out
|
/tests/functional/lang/*.out
|
||||||
|
|
@ -112,27 +14,9 @@ perl/Makefile.config
|
||||||
/tests/functional/lang/*.err
|
/tests/functional/lang/*.err
|
||||||
/tests/functional/lang/*.ast
|
/tests/functional/lang/*.ast
|
||||||
|
|
||||||
/perl/lib/Nix/Config.pm
|
|
||||||
/perl/lib/Nix/Store.cc
|
|
||||||
|
|
||||||
/misc/systemd/nix-daemon.service
|
|
||||||
/misc/systemd/nix-daemon.socket
|
|
||||||
/misc/systemd/nix-daemon.conf
|
|
||||||
/misc/upstart/nix-daemon.conf
|
|
||||||
|
|
||||||
outputs/
|
outputs/
|
||||||
|
|
||||||
*.a
|
|
||||||
*.o
|
|
||||||
*.o.tmp
|
|
||||||
*.so
|
|
||||||
*.dylib
|
|
||||||
*.dll
|
|
||||||
*.exe
|
|
||||||
*.dep
|
|
||||||
*~
|
*~
|
||||||
*.pc
|
|
||||||
*.plist
|
|
||||||
|
|
||||||
# GNU Global
|
# GNU Global
|
||||||
GPATH
|
GPATH
|
||||||
|
|
@ -147,8 +31,6 @@ GTAGS
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
*.compile_commands.json
|
*.compile_commands.json
|
||||||
|
|
||||||
nix-rust/target
|
|
||||||
|
|
||||||
result
|
result
|
||||||
result-*
|
result-*
|
||||||
|
|
||||||
|
|
@ -163,3 +45,5 @@ result-*
|
||||||
|
|
||||||
# Mac OS
|
# Mac OS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
flake-regressions
|
||||||
|
|
|
||||||
20
.mergify.yml
20
.mergify.yml
|
|
@ -2,13 +2,11 @@ queue_rules:
|
||||||
- name: default
|
- name: default
|
||||||
# all required tests need to go here
|
# all required tests need to go here
|
||||||
merge_conditions:
|
merge_conditions:
|
||||||
- check-success=installer
|
- check-success=tests on macos
|
||||||
- check-success=installer_test (macos-latest)
|
- check-success=tests on ubuntu
|
||||||
- check-success=installer_test (ubuntu-latest)
|
- check-success=installer test on macos
|
||||||
- check-success=tests (macos-latest)
|
- check-success=installer test on ubuntu
|
||||||
- check-success=tests (ubuntu-latest)
|
|
||||||
- check-success=vm_tests
|
- check-success=vm_tests
|
||||||
merge_method: rebase
|
|
||||||
batch_size: 5
|
batch_size: 5
|
||||||
|
|
||||||
pull_request_rules:
|
pull_request_rules:
|
||||||
|
|
@ -90,3 +88,13 @@ pull_request_rules:
|
||||||
- "2.24-maintenance"
|
- "2.24-maintenance"
|
||||||
labels:
|
labels:
|
||||||
- merge-queue
|
- merge-queue
|
||||||
|
|
||||||
|
- name: backport patches to 2.25
|
||||||
|
conditions:
|
||||||
|
- label=backport 2.25-maintenance
|
||||||
|
actions:
|
||||||
|
backport:
|
||||||
|
branches:
|
||||||
|
- "2.25-maintenance"
|
||||||
|
labels:
|
||||||
|
- merge-queue
|
||||||
|
|
|
||||||
|
|
@ -1,6 +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
|
|
||||||
|
|
@ -199,6 +199,7 @@ nix3_manpages = [
|
||||||
'nix3-build',
|
'nix3-build',
|
||||||
'nix3-bundle',
|
'nix3-bundle',
|
||||||
'nix3-config',
|
'nix3-config',
|
||||||
|
'nix3-config-check',
|
||||||
'nix3-config-show',
|
'nix3-config-show',
|
||||||
'nix3-copy',
|
'nix3-copy',
|
||||||
'nix3-daemon',
|
'nix3-daemon',
|
||||||
|
|
@ -206,8 +207,8 @@ nix3_manpages = [
|
||||||
'nix3-derivation',
|
'nix3-derivation',
|
||||||
'nix3-derivation-show',
|
'nix3-derivation-show',
|
||||||
'nix3-develop',
|
'nix3-develop',
|
||||||
#'nix3-doctor',
|
|
||||||
'nix3-edit',
|
'nix3-edit',
|
||||||
|
'nix3-env-shell',
|
||||||
'nix3-eval',
|
'nix3-eval',
|
||||||
'nix3-flake-archive',
|
'nix3-flake-archive',
|
||||||
'nix3-flake-check',
|
'nix3-flake-check',
|
||||||
|
|
@ -224,6 +225,7 @@ nix3_manpages = [
|
||||||
'nix3-fmt',
|
'nix3-fmt',
|
||||||
'nix3-hash-file',
|
'nix3-hash-file',
|
||||||
'nix3-hash',
|
'nix3-hash',
|
||||||
|
'nix3-hash-convert',
|
||||||
'nix3-hash-path',
|
'nix3-hash-path',
|
||||||
'nix3-hash-to-base16',
|
'nix3-hash-to-base16',
|
||||||
'nix3-hash-to-base32',
|
'nix3-hash-to-base32',
|
||||||
|
|
@ -238,6 +240,7 @@ nix3_manpages = [
|
||||||
'nix3-nar-cat',
|
'nix3-nar-cat',
|
||||||
'nix3-nar-dump-path',
|
'nix3-nar-dump-path',
|
||||||
'nix3-nar-ls',
|
'nix3-nar-ls',
|
||||||
|
'nix3-nar-pack',
|
||||||
'nix3-nar',
|
'nix3-nar',
|
||||||
'nix3-path-info',
|
'nix3-path-info',
|
||||||
'nix3-print-dev-env',
|
'nix3-print-dev-env',
|
||||||
|
|
@ -260,7 +263,7 @@ nix3_manpages = [
|
||||||
'nix3-repl',
|
'nix3-repl',
|
||||||
'nix3-run',
|
'nix3-run',
|
||||||
'nix3-search',
|
'nix3-search',
|
||||||
#'nix3-shell',
|
'nix3-store-add',
|
||||||
'nix3-store-add-file',
|
'nix3-store-add-file',
|
||||||
'nix3-store-add-path',
|
'nix3-store-add-path',
|
||||||
'nix3-store-cat',
|
'nix3-store-cat',
|
||||||
|
|
@ -270,6 +273,7 @@ nix3_manpages = [
|
||||||
'nix3-store-diff-closures',
|
'nix3-store-diff-closures',
|
||||||
'nix3-store-dump-path',
|
'nix3-store-dump-path',
|
||||||
'nix3-store-gc',
|
'nix3-store-gc',
|
||||||
|
'nix3-store-info',
|
||||||
'nix3-store-ls',
|
'nix3-store-ls',
|
||||||
'nix3-store-make-content-addressed',
|
'nix3-store-make-content-addressed',
|
||||||
'nix3-store',
|
'nix3-store',
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
, meson
|
, meson
|
||||||
, ninja
|
, ninja
|
||||||
, lowdown
|
, lowdown-unsandboxed
|
||||||
, mdbook
|
, mdbook
|
||||||
, mdbook-linkcheck
|
, mdbook-linkcheck
|
||||||
, jq
|
, jq
|
||||||
|
|
@ -42,7 +42,7 @@ mkMesonDerivation (finalAttrs: {
|
||||||
passthru.externalNativeBuildInputs = [
|
passthru.externalNativeBuildInputs = [
|
||||||
meson
|
meson
|
||||||
ninja
|
ninja
|
||||||
(lib.getBin lowdown)
|
(lib.getBin lowdown-unsandboxed)
|
||||||
mdbook
|
mdbook
|
||||||
mdbook-linkcheck
|
mdbook-linkcheck
|
||||||
jq
|
jq
|
||||||
|
|
|
||||||
22
doc/manual/rl-next/ignore-local-registries.md
Normal file
22
doc/manual/rl-next/ignore-local-registries.md
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
---
|
||||||
|
synopsis: "Flake lock file generation now ignores local registries"
|
||||||
|
prs: [12019]
|
||||||
|
---
|
||||||
|
|
||||||
|
When resolving indirect flake references like `nixpkgs` in `flake.nix` files, Nix will no longer use the system and user flake registries. It will only use the global flake registry and overrides given on the command line via `--override-flake`.
|
||||||
|
|
||||||
|
This avoids accidents where users have local registry overrides that map `nixpkgs` to a `path:` flake in the local file system, which then end up in committed lock files pushed to other users.
|
||||||
|
|
||||||
|
In the future, we may remove the use of the registry during lock file generation altogether. It's better to explicitly specify the URL of a flake input. For example, instead of
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
outputs = { self, nixpkgs }: { ... };
|
||||||
|
}
|
||||||
|
```
|
||||||
|
write
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
|
||||||
|
outputs = { self, nixpkgs }: { ... };
|
||||||
|
}
|
||||||
|
```
|
||||||
18
doc/manual/rl-next/nix-copy-flags.md
Normal file
18
doc/manual/rl-next/nix-copy-flags.md
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
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.
|
||||||
8
doc/manual/rl-next/nix-instantiate-raw.md
Normal file
8
doc/manual/rl-next/nix-instantiate-raw.md
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
synopsis: "`nix-instantiate --eval` now supports `--raw`"
|
||||||
|
prs: [12119]
|
||||||
|
---
|
||||||
|
|
||||||
|
The `nix-instantiate --eval` command now supports a `--raw` flag, when used
|
||||||
|
the evaluation result must be a string, which is printed verbatim without
|
||||||
|
quotation marks or escaping.
|
||||||
21
doc/manual/rl-next/nix-sshopts-parsing.md
Normal file
21
doc/manual/rl-next/nix-sshopts-parsing.md
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
synopsis: "Improved `NIX_SSHOPTS` parsing for better SSH option handling"
|
||||||
|
issues: [5181]
|
||||||
|
prs: [12020]
|
||||||
|
---
|
||||||
|
|
||||||
|
The parsing of the `NIX_SSHOPTS` environment variable has been improved to handle spaces and quotes correctly.
|
||||||
|
Previously, incorrectly split SSH options could cause failures in CLIs like `nix-copy-closure`,
|
||||||
|
especially when using complex ssh invocations such as `-o ProxyCommand="ssh -W %h:%p ..."`.
|
||||||
|
|
||||||
|
This change introduces a `shellSplitString` function to ensure
|
||||||
|
that `NIX_SSHOPTS` is parsed in a manner consistent with shell
|
||||||
|
behavior, addressing common parsing errors.
|
||||||
|
|
||||||
|
For example, the following now works as expected:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export NIX_SSHOPTS='-o ProxyCommand="ssh -W %h:%p ..."'
|
||||||
|
```
|
||||||
|
|
||||||
|
This update improves the reliability of SSH-related operations using `NIX_SSHOPTS` across Nix CLIs.
|
||||||
12
doc/manual/rl-next/relative-path-flakes.md
Normal file
12
doc/manual/rl-next/relative-path-flakes.md
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
synopsis: "Support for relative path inputs"
|
||||||
|
prs: [10089]
|
||||||
|
---
|
||||||
|
|
||||||
|
Flakes can now refer to other flakes in the same repository using relative paths, e.g.
|
||||||
|
```nix
|
||||||
|
inputs.foo.url = "path:./foo";
|
||||||
|
```
|
||||||
|
uses the flake in the `foo` subdirectory of the referring flake. For more information, see the documentation on [the `path` flake input type](@docroot@/command-ref/new-cli/nix3-flake.md#path-fetcher).
|
||||||
|
|
||||||
|
This feature required a change to the lock file format. Previous Nix versions will not be able to use lock files that have locks for relative path inputs in them.
|
||||||
|
|
@ -36,7 +36,7 @@ Instead, it looks in a few locations, and acts on all profiles it finds there:
|
||||||
>
|
>
|
||||||
> Not stable; subject to change
|
> Not stable; subject to change
|
||||||
>
|
>
|
||||||
> Do not rely on this functionality; it just exists for migration purposes and is may change in the future.
|
> Do not rely on this functionality; it just exists for migration purposes and may change in the future.
|
||||||
> These deprecated paths remain a private implementation detail of Nix.
|
> These deprecated paths remain a private implementation detail of Nix.
|
||||||
|
|
||||||
`$NIX_STATE_DIR/profiles` and `$NIX_STATE_DIR/profiles/per-user`.
|
`$NIX_STATE_DIR/profiles` and `$NIX_STATE_DIR/profiles/per-user`.
|
||||||
|
|
@ -62,6 +62,15 @@ These options are for deleting old [profiles] prior to deleting unreachable [sto
|
||||||
This is the equivalent of invoking [`nix-env --delete-generations <period>`](@docroot@/command-ref/nix-env/delete-generations.md#generations-time) on each found profile.
|
This is the equivalent of invoking [`nix-env --delete-generations <period>`](@docroot@/command-ref/nix-env/delete-generations.md#generations-time) on each found profile.
|
||||||
See the documentation of that command for additional information about the *period* argument.
|
See the documentation of that command for additional information about the *period* argument.
|
||||||
|
|
||||||
|
- <span id="opt-max-freed">[`--max-freed`](#opt-max-freed)</span> *bytes*
|
||||||
|
|
||||||
|
<!-- duplication from https://github.com/NixOS/nix/blob/442a2623e48357ff72c77bb11cf2cf06d94d2f90/doc/manual/source/command-ref/nix-store/gc.md?plain=1#L39-L44 -->
|
||||||
|
|
||||||
|
Keep deleting paths until at least *bytes* bytes have been deleted,
|
||||||
|
then stop. The argument *bytes* can be followed by the
|
||||||
|
multiplicative suffix `K`, `M`, `G` or `T`, denoting KiB, MiB, GiB
|
||||||
|
or TiB units.
|
||||||
|
|
||||||
{{#include ./opt-common.md}}
|
{{#include ./opt-common.md}}
|
||||||
|
|
||||||
{{#include ./env-common.md}}
|
{{#include ./env-common.md}}
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ When using public key authentication, you can avoid typing the passphrase with `
|
||||||
> Copy GNU Hello from a remote machine using a known store path, and run it:
|
> Copy GNU Hello from a remote machine using a known store path, and run it:
|
||||||
>
|
>
|
||||||
> ```shell-session
|
> ```shell-session
|
||||||
> $ storePath="$(nix-instantiate --eval '<nixpkgs>' -I nixpkgs=channel:nixpkgs-unstable -A hello.outPath | tr -d '"')"
|
> $ storePath="$(nix-instantiate --eval --raw '<nixpkgs>' -I nixpkgs=channel:nixpkgs-unstable -A hello.outPath)"
|
||||||
> $ nix-copy-closure --from alice@itchy.example.org "$storePath"
|
> $ nix-copy-closure --from alice@itchy.example.org "$storePath"
|
||||||
> $ "$storePath"/bin/hello
|
> $ "$storePath"/bin/hello
|
||||||
> Hello, world!
|
> Hello, world!
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
[`--from-profile` *path*]
|
[`--from-profile` *path*]
|
||||||
[`--preserve-installed` | `-P`]
|
[`--preserve-installed` | `-P`]
|
||||||
[`--remove-all` | `-r`]
|
[`--remove-all` | `-r`]
|
||||||
|
[`--priority` *priority*]
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
|
|
@ -61,6 +62,10 @@ The arguments *args* map to store paths in a number of possible ways:
|
||||||
The derivations returned by those function calls are installed.
|
The derivations returned by those function calls are installed.
|
||||||
This allows derivations to be specified in an unambiguous way, which is necessary if there are multiple derivations with the same name.
|
This allows derivations to be specified in an unambiguous way, which is necessary if there are multiple derivations with the same name.
|
||||||
|
|
||||||
|
- If `--priority` *priority* is given, the priority of the derivations being installed is set to *priority*.
|
||||||
|
This can be used to override the priority of the derivations being installed.
|
||||||
|
This is useful if *args* are [store paths], which don't have any priority information.
|
||||||
|
|
||||||
- If *args* are [store paths] to [derivations](@docroot@/glossary.md#gloss-derivation), then those derivations are [realised], and the resulting output paths are installed.
|
- If *args* are [store paths] to [derivations](@docroot@/glossary.md#gloss-derivation), then those derivations are [realised], and the resulting output paths are installed.
|
||||||
|
|
||||||
- If *args* are [store paths] not to derivations, then these are [realised] and installed.
|
- If *args* are [store paths] not to derivations, then these are [realised] and installed.
|
||||||
|
|
@ -235,4 +240,3 @@ channel:
|
||||||
```console
|
```console
|
||||||
$ nix-env --file https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz --install --attr firefox
|
$ nix-env --file https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz --install --attr firefox
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
# Synopsis
|
# Synopsis
|
||||||
|
|
||||||
`nix-instantiate`
|
`nix-instantiate`
|
||||||
[`--parse` | `--eval` [`--strict`] [`--json`] [`--xml`] ]
|
[`--parse` | `--eval` [`--strict`] [`--raw` | `--json` | `--xml`] ]
|
||||||
[`--read-write-mode`]
|
[`--read-write-mode`]
|
||||||
[`--arg` *name* *value*]
|
[`--arg` *name* *value*]
|
||||||
[{`--attr`| `-A`} *attrPath*]
|
[{`--attr`| `-A`} *attrPath*]
|
||||||
|
|
@ -102,6 +102,11 @@ standard input.
|
||||||
> This option can cause non-termination, because lazy data
|
> This option can cause non-termination, because lazy data
|
||||||
> structures can be infinitely large.
|
> structures can be infinitely large.
|
||||||
|
|
||||||
|
- `--raw`
|
||||||
|
|
||||||
|
When used with `--eval`, the evaluation result must be a string,
|
||||||
|
which is printed verbatim, without quoting, escaping or trailing newline.
|
||||||
|
|
||||||
- `--json`
|
- `--json`
|
||||||
|
|
||||||
When used with `--eval`, print the resulting value as an JSON
|
When used with `--eval`, print the resulting value as an JSON
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,9 @@ All options not listed here are passed to `nix-store
|
||||||
cleared before the interactive shell is started, so you get an
|
cleared before the interactive shell is started, so you get an
|
||||||
environment that more closely corresponds to the “real” Nix build. A
|
environment that more closely corresponds to the “real” Nix build. A
|
||||||
few variables, in particular `HOME`, `USER` and `DISPLAY`, are
|
few variables, in particular `HOME`, `USER` and `DISPLAY`, are
|
||||||
retained.
|
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`.
|
||||||
|
|
||||||
- `--packages` / `-p` *packages*…
|
- `--packages` / `-p` *packages*…
|
||||||
|
|
||||||
|
|
@ -112,11 +114,30 @@ All options not listed here are passed to `nix-store
|
||||||
|
|
||||||
# Environment variables
|
# Environment variables
|
||||||
|
|
||||||
- `NIX_BUILD_SHELL`
|
- <span id="env-NIX_BUILD_SHELL">[`NIX_BUILD_SHELL`](#env-NIX_BUILD_SHELL)</span>
|
||||||
|
|
||||||
Shell used to start the interactive environment. Defaults to the
|
Shell used to start the interactive environment.
|
||||||
`bash` found in `<nixpkgs>`, falling back to the `bash` found in
|
Defaults to the `bash` from `bashInteractive` found in `<nixpkgs>`, falling back to the `bash` found in `PATH` if not found.
|
||||||
`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;
|
||||||
|
> }
|
||||||
|
> ```
|
||||||
|
|
||||||
{{#include ./env-common.md}}
|
{{#include ./env-common.md}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,9 @@ This operation has the following options:
|
||||||
Use recursive instead of flat hashing mode, used when adding
|
Use recursive instead of flat hashing mode, used when adding
|
||||||
directories to the store.
|
directories to the store.
|
||||||
|
|
||||||
|
*paths* that refer to symlinks are not dereferenced, but added to the store
|
||||||
|
as symlinks with the same target.
|
||||||
|
|
||||||
{{#include ./opt-common.md}}
|
{{#include ./opt-common.md}}
|
||||||
|
|
||||||
{{#include ../opt-common.md}}
|
{{#include ../opt-common.md}}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,9 @@
|
||||||
The operation `--add` adds the specified paths to the Nix store. It
|
The operation `--add` adds the specified paths to the Nix store. It
|
||||||
prints the resulting paths in the Nix store on standard output.
|
prints the resulting paths in the Nix store on standard output.
|
||||||
|
|
||||||
|
*paths* that refer to symlinks are not dereferenced, but added to the store
|
||||||
|
as symlinks with the same target.
|
||||||
|
|
||||||
{{#include ./opt-common.md}}
|
{{#include ./opt-common.md}}
|
||||||
|
|
||||||
{{#include ../opt-common.md}}
|
{{#include ../opt-common.md}}
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,11 @@ nix-build -E '(import ./.).packages.${builtins.currentSystem}.nix.doc'
|
||||||
or
|
or
|
||||||
|
|
||||||
```console
|
```console
|
||||||
nix build .#nix^doc
|
nix build .#nix-manual
|
||||||
```
|
```
|
||||||
|
|
||||||
and open `./result-doc/share/doc/nix/manual/index.html`.
|
and open `./result/share/doc/nix/manual/index.html`.
|
||||||
|
|
||||||
|
|
||||||
To build the manual incrementally, [enter the development shell](./building.md) and run:
|
To build the manual incrementally, [enter the development shell](./building.md) and run:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -297,7 +297,7 @@ Creating a Cachix cache for your installer tests and adding its authorisation to
|
||||||
- `armv7l-linux`
|
- `armv7l-linux`
|
||||||
- `x86_64-darwin`
|
- `x86_64-darwin`
|
||||||
|
|
||||||
- The `installer_test` job (which runs on `ubuntu-latest` and `macos-latest`) will try to install Nix with the cached installer and run a trivial Nix command.
|
- The `installer_test` job (which runs on `ubuntu-24.04` and `macos-14`) will try to install Nix with the cached installer and run a trivial Nix command.
|
||||||
|
|
||||||
### One-time setup
|
### One-time setup
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,3 +57,21 @@ $ nix build ./\#hydraJobs.dockerImage.x86_64-linux
|
||||||
$ docker load -i ./result/image.tar.gz
|
$ docker load -i ./result/image.tar.gz
|
||||||
$ docker run -ti nix:2.5pre20211105
|
$ 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
|
||||||
|
```
|
||||||
|
|
|
||||||
52
docker.nix
52
docker.nix
|
|
@ -9,6 +9,10 @@
|
||||||
, maxLayers ? 100
|
, maxLayers ? 100
|
||||||
, nixConf ? {}
|
, nixConf ? {}
|
||||||
, flake-registry ? null
|
, flake-registry ? null
|
||||||
|
, uid ? 0
|
||||||
|
, gid ? 0
|
||||||
|
, uname ? "root"
|
||||||
|
, gname ? "root"
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
defaultPkgs = with pkgs; [
|
defaultPkgs = with pkgs; [
|
||||||
|
|
@ -50,6 +54,15 @@ let
|
||||||
description = "Unprivileged account (don't use!)";
|
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 (
|
} // lib.listToAttrs (
|
||||||
map
|
map
|
||||||
(
|
(
|
||||||
|
|
@ -70,6 +83,8 @@ let
|
||||||
root.gid = 0;
|
root.gid = 0;
|
||||||
nixbld.gid = 30000;
|
nixbld.gid = 30000;
|
||||||
nobody.gid = 65534;
|
nobody.gid = 65534;
|
||||||
|
} // lib.optionalAttrs (gid != 0) {
|
||||||
|
"${gname}".gid = gid;
|
||||||
};
|
};
|
||||||
|
|
||||||
userToPasswd = (
|
userToPasswd = (
|
||||||
|
|
@ -150,6 +165,8 @@ let
|
||||||
in
|
in
|
||||||
"${n} = ${vStr}") (defaultNixConf // nixConf))) + "\n";
|
"${n} = ${vStr}") (defaultNixConf // nixConf))) + "\n";
|
||||||
|
|
||||||
|
userHome = if uid == 0 then "/root" else "/home/${uname}";
|
||||||
|
|
||||||
baseSystem =
|
baseSystem =
|
||||||
let
|
let
|
||||||
nixpkgs = pkgs.path;
|
nixpkgs = pkgs.path;
|
||||||
|
|
@ -237,26 +254,26 @@ let
|
||||||
mkdir -p $out/etc/nix
|
mkdir -p $out/etc/nix
|
||||||
cat $nixConfContentsPath > $out/etc/nix/nix.conf
|
cat $nixConfContentsPath > $out/etc/nix/nix.conf
|
||||||
|
|
||||||
mkdir -p $out/root
|
mkdir -p $out${userHome}
|
||||||
mkdir -p $out/nix/var/nix/profiles/per-user/root
|
mkdir -p $out/nix/var/nix/profiles/per-user/${uname}
|
||||||
|
|
||||||
ln -s ${profile} $out/nix/var/nix/profiles/default-1-link
|
ln -s ${profile} $out/nix/var/nix/profiles/default-1-link
|
||||||
ln -s $out/nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default
|
ln -s /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 /nix/var/nix/profiles/default $out${userHome}/.nix-profile
|
||||||
|
|
||||||
ln -s ${channel} $out/nix/var/nix/profiles/per-user/root/channels-1-link
|
ln -s ${channel} $out/nix/var/nix/profiles/per-user/${uname}/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
|
ln -s /nix/var/nix/profiles/per-user/${uname}/channels-1-link $out/nix/var/nix/profiles/per-user/${uname}/channels
|
||||||
|
|
||||||
mkdir -p $out/root/.nix-defexpr
|
mkdir -p $out${userHome}/.nix-defexpr
|
||||||
ln -s $out/nix/var/nix/profiles/per-user/root/channels $out/root/.nix-defexpr/channels
|
ln -s /nix/var/nix/profiles/per-user/${uname}/channels $out${userHome}/.nix-defexpr/channels
|
||||||
echo "${channelURL} ${channelName}" > $out/root/.nix-channels
|
echo "${channelURL} ${channelName}" > $out${userHome}/.nix-channels
|
||||||
|
|
||||||
mkdir -p $out/bin $out/usr/bin
|
mkdir -p $out/bin $out/usr/bin
|
||||||
ln -s ${pkgs.coreutils}/bin/env $out/usr/bin/env
|
ln -s ${pkgs.coreutils}/bin/env $out/usr/bin/env
|
||||||
ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/sh
|
ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/sh
|
||||||
|
|
||||||
'' + (lib.optionalString (flake-registry-path != null) ''
|
'' + (lib.optionalString (flake-registry-path != null) ''
|
||||||
nixCacheDir="/root/.cache/nix"
|
nixCacheDir="${userHome}/.cache/nix"
|
||||||
mkdir -p $out$nixCacheDir
|
mkdir -p $out$nixCacheDir
|
||||||
globalFlakeRegistryPath="$nixCacheDir/flake-registry.json"
|
globalFlakeRegistryPath="$nixCacheDir/flake-registry.json"
|
||||||
ln -s ${flake-registry-path} $out$globalFlakeRegistryPath
|
ln -s ${flake-registry-path} $out$globalFlakeRegistryPath
|
||||||
|
|
@ -268,7 +285,7 @@ let
|
||||||
in
|
in
|
||||||
pkgs.dockerTools.buildLayeredImageWithNixDb {
|
pkgs.dockerTools.buildLayeredImageWithNixDb {
|
||||||
|
|
||||||
inherit name tag maxLayers;
|
inherit name tag maxLayers uid gid uname gname;
|
||||||
|
|
||||||
contents = [ baseSystem ];
|
contents = [ baseSystem ];
|
||||||
|
|
||||||
|
|
@ -279,25 +296,28 @@ pkgs.dockerTools.buildLayeredImageWithNixDb {
|
||||||
fakeRootCommands = ''
|
fakeRootCommands = ''
|
||||||
chmod 1777 tmp
|
chmod 1777 tmp
|
||||||
chmod 1777 var/tmp
|
chmod 1777 var/tmp
|
||||||
|
chown -R ${toString uid}:${toString gid} .${userHome}
|
||||||
|
chown -R ${toString uid}:${toString gid} nix
|
||||||
'';
|
'';
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
Cmd = [ "/root/.nix-profile/bin/bash" ];
|
Cmd = [ "${userHome}/.nix-profile/bin/bash" ];
|
||||||
|
User = "${toString uid}:${toString gid}";
|
||||||
Env = [
|
Env = [
|
||||||
"USER=root"
|
"USER=${uname}"
|
||||||
"PATH=${lib.concatStringsSep ":" [
|
"PATH=${lib.concatStringsSep ":" [
|
||||||
"/root/.nix-profile/bin"
|
"${userHome}/.nix-profile/bin"
|
||||||
"/nix/var/nix/profiles/default/bin"
|
"/nix/var/nix/profiles/default/bin"
|
||||||
"/nix/var/nix/profiles/default/sbin"
|
"/nix/var/nix/profiles/default/sbin"
|
||||||
]}"
|
]}"
|
||||||
"MANPATH=${lib.concatStringsSep ":" [
|
"MANPATH=${lib.concatStringsSep ":" [
|
||||||
"/root/.nix-profile/share/man"
|
"${userHome}/.nix-profile/share/man"
|
||||||
"/nix/var/nix/profiles/default/share/man"
|
"/nix/var/nix/profiles/default/share/man"
|
||||||
]}"
|
]}"
|
||||||
"SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
|
"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"
|
"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_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
|
||||||
"NIX_PATH=/nix/var/nix/profiles/per-user/root/channels:/root/.nix-defexpr/channels"
|
"NIX_PATH=/nix/var/nix/profiles/per-user/${uname}/channels:${userHome}/.nix-defexpr/channels"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
44
flake.lock
generated
44
flake.lock
generated
|
|
@ -3,11 +3,11 @@
|
||||||
"flake-compat": {
|
"flake-compat": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1696426674,
|
"lastModified": 1733328505,
|
||||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
"narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
|
||||||
"owner": "edolstra",
|
"owner": "edolstra",
|
||||||
"repo": "flake-compat",
|
"repo": "flake-compat",
|
||||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
"rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -23,11 +23,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1719994518,
|
"lastModified": 1733312601,
|
||||||
"narHash": "sha256-pQMhCCHyQGRzdfAkdJ4cIWiw+JNuWsTX7f0ZYSyz0VY=",
|
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "9227223f6d922fee3c7b190b2cc238a99527bbb7",
|
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -48,11 +48,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1721042469,
|
"lastModified": 1734279981,
|
||||||
"narHash": "sha256-6FPUl7HVtvRHCCBQne7Ylp4p+dpP3P/OYuzjztZ4s70=",
|
"narHash": "sha256-NdaCraHPp8iYMWzdXAt5Nv6sA3MUzlCiGiR586TCwo0=",
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"repo": "git-hooks.nix",
|
"repo": "git-hooks.nix",
|
||||||
"rev": "f451c19376071a90d8c58ab1a953c6e9840527fd",
|
"rev": "aa9f40c906904ebd83da78e7f328cd8aeaeae785",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -61,35 +61,18 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"libgit2": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1715853528,
|
|
||||||
"narHash": "sha256-J2rCxTecyLbbDdsyBWn9w7r3pbKRMkI9E7RvRgAqBdY=",
|
|
||||||
"owner": "libgit2",
|
|
||||||
"repo": "libgit2",
|
|
||||||
"rev": "36f7e21ad757a3dacc58cf7944329da6bc1d6e96",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "libgit2",
|
|
||||||
"ref": "v1.8.1",
|
|
||||||
"repo": "libgit2",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1723688146,
|
"lastModified": 1734359947,
|
||||||
"narHash": "sha256-sqLwJcHYeWLOeP/XoLwAtYjr01TISlkOfz+NG82pbdg=",
|
"narHash": "sha256-1Noao/H+N8nFB4Beoy8fgwrcOQLVm9o4zKW1ODaqK9E=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "c3d4ac725177c030b1e289015989da2ad9d56af0",
|
"rev": "48d12d5e70ee91fe8481378e540433a7303dbf6a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"ref": "nixos-24.05",
|
"ref": "release-24.11",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
|
@ -131,7 +114,6 @@
|
||||||
"flake-compat": "flake-compat",
|
"flake-compat": "flake-compat",
|
||||||
"flake-parts": "flake-parts",
|
"flake-parts": "flake-parts",
|
||||||
"git-hooks-nix": "git-hooks-nix",
|
"git-hooks-nix": "git-hooks-nix",
|
||||||
"libgit2": "libgit2",
|
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"nixpkgs-23-11": "nixpkgs-23-11",
|
"nixpkgs-23-11": "nixpkgs-23-11",
|
||||||
"nixpkgs-regression": "nixpkgs-regression"
|
"nixpkgs-regression": "nixpkgs-regression"
|
||||||
|
|
|
||||||
61
flake.nix
61
flake.nix
|
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
description = "The purely functional package manager";
|
description = "The purely functional package manager";
|
||||||
|
|
||||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
|
inputs.nixpkgs.url = "github:NixOS/nixpkgs/release-24.11";
|
||||||
|
|
||||||
inputs.nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2";
|
inputs.nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2";
|
||||||
inputs.nixpkgs-23-11.url = "github:NixOS/nixpkgs/a62e6edd6d5e1fa0329b8653c801147986f8d446";
|
inputs.nixpkgs-23-11.url = "github:NixOS/nixpkgs/a62e6edd6d5e1fa0329b8653c801147986f8d446";
|
||||||
inputs.flake-compat = { url = "github:edolstra/flake-compat"; flake = false; };
|
inputs.flake-compat = { url = "github:edolstra/flake-compat"; flake = false; };
|
||||||
inputs.libgit2 = { url = "github:libgit2/libgit2/v1.8.1"; flake = false; };
|
|
||||||
|
|
||||||
# dev tooling
|
# dev tooling
|
||||||
inputs.flake-parts.url = "github:hercules-ci/flake-parts";
|
inputs.flake-parts.url = "github:hercules-ci/flake-parts";
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
inputs.git-hooks-nix.inputs.flake-compat.follows = "";
|
inputs.git-hooks-nix.inputs.flake-compat.follows = "";
|
||||||
inputs.git-hooks-nix.inputs.gitignore.follows = "";
|
inputs.git-hooks-nix.inputs.gitignore.follows = "";
|
||||||
|
|
||||||
outputs = inputs@{ self, nixpkgs, nixpkgs-regression, libgit2, ... }:
|
outputs = inputs@{ self, nixpkgs, nixpkgs-regression, ... }:
|
||||||
|
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
@ -36,7 +36,8 @@
|
||||||
"armv6l-unknown-linux-gnueabihf"
|
"armv6l-unknown-linux-gnueabihf"
|
||||||
"armv7l-unknown-linux-gnueabihf"
|
"armv7l-unknown-linux-gnueabihf"
|
||||||
"riscv64-unknown-linux-gnu"
|
"riscv64-unknown-linux-gnu"
|
||||||
"x86_64-unknown-netbsd"
|
# Disabled because of https://github.com/NixOS/nixpkgs/issues/344423
|
||||||
|
# "x86_64-unknown-netbsd"
|
||||||
"x86_64-unknown-freebsd"
|
"x86_64-unknown-freebsd"
|
||||||
"x86_64-w64-mingw32"
|
"x86_64-w64-mingw32"
|
||||||
];
|
];
|
||||||
|
|
@ -106,6 +107,7 @@
|
||||||
in {
|
in {
|
||||||
inherit stdenvs native;
|
inherit stdenvs native;
|
||||||
static = native.pkgsStatic;
|
static = native.pkgsStatic;
|
||||||
|
llvm = native.pkgsLLVM;
|
||||||
cross = forAllCrossSystems (crossSystem: make-pkgs crossSystem "stdenv");
|
cross = forAllCrossSystems (crossSystem: make-pkgs crossSystem "stdenv");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -124,18 +126,36 @@
|
||||||
# without "polluting" the top level "`pkgs`" attrset.
|
# without "polluting" the top level "`pkgs`" attrset.
|
||||||
# This also has the benefit of providing us with a distinct set of packages
|
# This also has the benefit of providing us with a distinct set of packages
|
||||||
# we can iterate over.
|
# we can iterate over.
|
||||||
nixComponents = lib.makeScope final.nixDependencies.newScope (import ./packaging/components.nix {
|
nixComponents =
|
||||||
inherit (final) lib;
|
lib.makeScopeWithSplicing'
|
||||||
inherit officialRelease;
|
{
|
||||||
src = self;
|
inherit (final) splicePackages;
|
||||||
});
|
inherit (final.nixDependencies) newScope;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
otherSplices = final.generateSplicesForMkScope "nixComponents";
|
||||||
|
f = 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
|
# The dependencies are in their own scope, so that they don't have to be
|
||||||
# in Nixpkgs top level `pkgs` or `nixComponents`.
|
# in Nixpkgs top level `pkgs` or `nixComponents`.
|
||||||
nixDependencies = lib.makeScope final.newScope (import ./packaging/dependencies.nix {
|
nixDependencies =
|
||||||
inherit inputs stdenv;
|
lib.makeScopeWithSplicing'
|
||||||
pkgs = final;
|
{
|
||||||
});
|
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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
nix = final.nixComponents.nix-cli;
|
nix = final.nixComponents.nix-cli;
|
||||||
|
|
||||||
|
|
@ -145,7 +165,6 @@
|
||||||
if prev.stdenv.hostPlatform.system == "i686-linux"
|
if prev.stdenv.hostPlatform.system == "i686-linux"
|
||||||
then (prev.pre-commit.override (o: { dotnet-sdk = ""; })).overridePythonAttrs (o: { doCheck = false; })
|
then (prev.pre-commit.override (o: { dotnet-sdk = ""; })).overridePythonAttrs (o: { doCheck = false; })
|
||||||
else prev.pre-commit;
|
else prev.pre-commit;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
in {
|
in {
|
||||||
|
|
@ -168,7 +187,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
checks = forAllSystems (system: {
|
checks = forAllSystems (system: {
|
||||||
binaryTarball = self.hydraJobs.binaryTarball.${system};
|
installerScriptForGHA = self.hydraJobs.installerScriptForGHA.${system};
|
||||||
installTests = self.hydraJobs.installTests.${system};
|
installTests = self.hydraJobs.installTests.${system};
|
||||||
nixpkgsLibTests = self.hydraJobs.tests.nixpkgsLibTests.${system};
|
nixpkgsLibTests = self.hydraJobs.tests.nixpkgsLibTests.${system};
|
||||||
rl-next =
|
rl-next =
|
||||||
|
|
@ -183,11 +202,7 @@
|
||||||
# Some perl dependencies are broken on i686-linux.
|
# Some perl dependencies are broken on i686-linux.
|
||||||
# Since the support is only best-effort there, disable the perl
|
# Since the support is only best-effort there, disable the perl
|
||||||
# bindings
|
# bindings
|
||||||
|
perlBindings = self.hydraJobs.perlBindings.${system};
|
||||||
# Temporarily disabled because GitHub Actions OOM issues. Once
|
|
||||||
# the old build system is gone and we are back to one build
|
|
||||||
# system, we should reenable this.
|
|
||||||
#perlBindings = self.hydraJobs.perlBindings.${system};
|
|
||||||
}
|
}
|
||||||
# Add "passthru" tests
|
# Add "passthru" tests
|
||||||
// flatMapAttrs ({
|
// flatMapAttrs ({
|
||||||
|
|
@ -219,6 +234,8 @@
|
||||||
inherit (nixpkgsFor.${system}.native)
|
inherit (nixpkgsFor.${system}.native)
|
||||||
changelog-d;
|
changelog-d;
|
||||||
default = self.packages.${system}.nix;
|
default = self.packages.${system}.nix;
|
||||||
|
installerScriptForGHA = self.hydraJobs.installerScriptForGHA.${system};
|
||||||
|
binaryTarball = self.hydraJobs.binaryTarball.${system};
|
||||||
# TODO probably should be `nix-cli`
|
# TODO probably should be `nix-cli`
|
||||||
nix = self.packages.${system}.nix-everything;
|
nix = self.packages.${system}.nix-everything;
|
||||||
nix-manual = nixpkgsFor.${system}.native.nixComponents.nix-manual;
|
nix-manual = nixpkgsFor.${system}.native.nixComponents.nix-manual;
|
||||||
|
|
@ -266,6 +283,7 @@
|
||||||
# These attributes go right into `packages.<system>`.
|
# These attributes go right into `packages.<system>`.
|
||||||
"${pkgName}" = nixpkgsFor.${system}.native.nixComponents.${pkgName};
|
"${pkgName}" = nixpkgsFor.${system}.native.nixComponents.${pkgName};
|
||||||
"${pkgName}-static" = nixpkgsFor.${system}.static.nixComponents.${pkgName};
|
"${pkgName}-static" = nixpkgsFor.${system}.static.nixComponents.${pkgName};
|
||||||
|
"${pkgName}-llvm" = nixpkgsFor.${system}.llvm.nixComponents.${pkgName};
|
||||||
}
|
}
|
||||||
// lib.optionalAttrs supportsCross (flatMapAttrs (lib.genAttrs crossSystems (_: { })) (crossSystem: {}: {
|
// lib.optionalAttrs supportsCross (flatMapAttrs (lib.genAttrs crossSystems (_: { })) (crossSystem: {}: {
|
||||||
# These attributes go right into `packages.<system>`.
|
# These attributes go right into `packages.<system>`.
|
||||||
|
|
@ -305,6 +323,9 @@
|
||||||
prefixAttrs "static" (forAllStdenvs (stdenvName: makeShell {
|
prefixAttrs "static" (forAllStdenvs (stdenvName: makeShell {
|
||||||
pkgs = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".pkgsStatic;
|
pkgs = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".pkgsStatic;
|
||||||
})) //
|
})) //
|
||||||
|
prefixAttrs "llvm" (forAllStdenvs (stdenvName: makeShell {
|
||||||
|
pkgs = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".pkgsLLVM;
|
||||||
|
})) //
|
||||||
prefixAttrs "cross" (forAllCrossSystems (crossSystem: makeShell {
|
prefixAttrs "cross" (forAllCrossSystems (crossSystem: makeShell {
|
||||||
pkgs = nixpkgsFor.${system}.cross.${crossSystem};
|
pkgs = nixpkgsFor.${system}.cross.${crossSystem};
|
||||||
}))
|
}))
|
||||||
|
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
# Ensure that this bug is not present in the C++ toolchain we are using.
|
|
||||||
#
|
|
||||||
# URL for bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80431
|
|
||||||
#
|
|
||||||
# The test program is from that issue, with only a slight modification
|
|
||||||
# to set an exit status instead of printing strings.
|
|
||||||
AC_DEFUN([ENSURE_NO_GCC_BUG_80431],
|
|
||||||
[
|
|
||||||
AC_MSG_CHECKING([that GCC bug 80431 is fixed])
|
|
||||||
AC_LANG_PUSH(C++)
|
|
||||||
AC_RUN_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM(
|
|
||||||
[[
|
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
static bool a = true;
|
|
||||||
static bool b = true;
|
|
||||||
|
|
||||||
struct Options { };
|
|
||||||
|
|
||||||
struct Option
|
|
||||||
{
|
|
||||||
Option(Options * options)
|
|
||||||
{
|
|
||||||
a = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
~Option()
|
|
||||||
{
|
|
||||||
b = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MyOptions : Options { };
|
|
||||||
|
|
||||||
struct MyOptions2 : virtual MyOptions
|
|
||||||
{
|
|
||||||
Option foo{this};
|
|
||||||
};
|
|
||||||
]],
|
|
||||||
[[
|
|
||||||
{
|
|
||||||
MyOptions2 opts;
|
|
||||||
}
|
|
||||||
return (a << 1) | b;
|
|
||||||
]])],
|
|
||||||
[status_80431=0],
|
|
||||||
[status_80431=$?],
|
|
||||||
[status_80431=''])
|
|
||||||
AC_LANG_POP(C++)
|
|
||||||
AS_CASE([$status_80431],
|
|
||||||
[''],[
|
|
||||||
AC_MSG_RESULT(cannot check because cross compiling)
|
|
||||||
AC_MSG_NOTICE(assume we are bug free)
|
|
||||||
],
|
|
||||||
[0],[
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
],
|
|
||||||
[2],[
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
AC_MSG_ERROR(Cannot build Nix with C++ compiler with this bug)
|
|
||||||
],
|
|
||||||
[
|
|
||||||
AC_MSG_RESULT(unexpected result $status_80431: not expected failure with bug, ignoring)
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
@ -10,8 +10,31 @@
|
||||||
# https://flake.parts/options/git-hooks-nix#options
|
# https://flake.parts/options/git-hooks-nix#options
|
||||||
pre-commit.settings = {
|
pre-commit.settings = {
|
||||||
hooks = {
|
hooks = {
|
||||||
|
# Conflicts are usually found by other checks, but not those in docs,
|
||||||
|
# and potentially other places.
|
||||||
|
check-merge-conflicts.enable = true;
|
||||||
|
# built-in check-merge-conflicts seems ineffective against those produced by mergify backports
|
||||||
|
check-merge-conflicts-2 = {
|
||||||
|
enable = true;
|
||||||
|
entry = "${pkgs.writeScript "check-merge-conflicts" ''
|
||||||
|
#!${pkgs.runtimeShell}
|
||||||
|
conflicts=false
|
||||||
|
for file in "$@"; do
|
||||||
|
if grep --with-filename --line-number -E '^>>>>>>> ' -- "$file"; then
|
||||||
|
conflicts=true
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if $conflicts; then
|
||||||
|
echo "ERROR: found merge/patch conflicts in files"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
touch $out
|
||||||
|
''}";
|
||||||
|
};
|
||||||
clang-format = {
|
clang-format = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
# https://github.com/cachix/git-hooks.nix/pull/532
|
||||||
|
package = pkgs.llvmPackages_latest.clang-tools;
|
||||||
excludes = [
|
excludes = [
|
||||||
# We don't want to format test data
|
# We don't want to format test data
|
||||||
# ''tests/(?!nixos/).*\.nix''
|
# ''tests/(?!nixos/).*\.nix''
|
||||||
|
|
@ -354,6 +377,7 @@
|
||||||
''^src/libutil/util\.cc$''
|
''^src/libutil/util\.cc$''
|
||||||
''^src/libutil/util\.hh$''
|
''^src/libutil/util\.hh$''
|
||||||
''^src/libutil/variant-wrapper\.hh$''
|
''^src/libutil/variant-wrapper\.hh$''
|
||||||
|
''^src/libutil/widecharwidth/widechar_width\.h$'' # vendored source
|
||||||
''^src/libutil/windows/file-descriptor\.cc$''
|
''^src/libutil/windows/file-descriptor\.cc$''
|
||||||
''^src/libutil/windows/file-path\.cc$''
|
''^src/libutil/windows/file-path\.cc$''
|
||||||
''^src/libutil/windows/processes\.cc$''
|
''^src/libutil/windows/processes\.cc$''
|
||||||
|
|
@ -496,7 +520,6 @@
|
||||||
''^scripts/create-darwin-volume\.sh$''
|
''^scripts/create-darwin-volume\.sh$''
|
||||||
''^scripts/install-darwin-multi-user\.sh$''
|
''^scripts/install-darwin-multi-user\.sh$''
|
||||||
''^scripts/install-multi-user\.sh$''
|
''^scripts/install-multi-user\.sh$''
|
||||||
''^scripts/install-nix-from-closure\.sh$''
|
|
||||||
''^scripts/install-systemd-multi-user\.sh$''
|
''^scripts/install-systemd-multi-user\.sh$''
|
||||||
''^src/nix/get-env\.sh$''
|
''^src/nix/get-env\.sh$''
|
||||||
''^tests/functional/ca/build-dry\.sh$''
|
''^tests/functional/ca/build-dry\.sh$''
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ endif
|
||||||
subproject('libutil-c')
|
subproject('libutil-c')
|
||||||
subproject('libstore-c')
|
subproject('libstore-c')
|
||||||
subproject('libexpr-c')
|
subproject('libexpr-c')
|
||||||
|
subproject('libflake-c')
|
||||||
subproject('libmain-c')
|
subproject('libmain-c')
|
||||||
|
|
||||||
# Language Bindings
|
# Language Bindings
|
||||||
|
|
|
||||||
13
misc/launchd/meson.build
Normal file
13
misc/launchd/meson.build
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
@ -2,4 +2,10 @@ subdir('bash')
|
||||||
subdir('fish')
|
subdir('fish')
|
||||||
subdir('zsh')
|
subdir('zsh')
|
||||||
|
|
||||||
subdir('systemd')
|
if host_machine.system() == 'linux'
|
||||||
|
subdir('systemd')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if host_machine.system() == 'darwin'
|
||||||
|
subdir('launchd')
|
||||||
|
endif
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
# 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(
|
add_project_arguments(
|
||||||
'-Wdeprecated-copy',
|
'-Wdeprecated-copy',
|
||||||
'-Werror=suggest-override',
|
'-Werror=suggest-override',
|
||||||
|
|
@ -44,6 +44,7 @@ in
|
||||||
nix-expr-tests = callPackage ../src/libexpr-tests/package.nix { };
|
nix-expr-tests = callPackage ../src/libexpr-tests/package.nix { };
|
||||||
|
|
||||||
nix-flake = callPackage ../src/libflake/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-flake-tests = callPackage ../src/libflake-tests/package.nix { };
|
||||||
|
|
||||||
nix-main = callPackage ../src/libmain/package.nix { };
|
nix-main = callPackage ../src/libmain/package.nix { };
|
||||||
|
|
|
||||||
|
|
@ -66,10 +66,28 @@ let
|
||||||
|
|
||||||
mesonLayer = finalAttrs: prevAttrs:
|
mesonLayer = finalAttrs: prevAttrs:
|
||||||
{
|
{
|
||||||
|
# NOTE:
|
||||||
|
# As of https://github.com/NixOS/nixpkgs/blob/8baf8241cea0c7b30e0b8ae73474cb3de83c1a30/pkgs/by-name/me/meson/setup-hook.sh#L26,
|
||||||
|
# `mesonBuildType` defaults to `plain` if not specified. We want our Nix-built binaries to be optimized by default.
|
||||||
|
# More on build types here: https://mesonbuild.com/Builtin-options.html#details-for-buildtype.
|
||||||
|
mesonBuildType = "release";
|
||||||
|
# NOTE:
|
||||||
|
# Users who are debugging Nix builds are expected to set the environment variable `mesonBuildType`, per the
|
||||||
|
# guidance in https://github.com/NixOS/nix/blob/8a3fc27f1b63a08ac983ee46435a56cf49ebaf4a/doc/manual/source/development/debugging.md?plain=1#L10.
|
||||||
|
# For this reason, we don't want to refer to `finalAttrs.mesonBuildType` here, but rather use the environment variable.
|
||||||
|
preConfigure = prevAttrs.preConfigure or "" + ''
|
||||||
|
case "$mesonBuildType" in
|
||||||
|
release|minsize) appendToVar mesonFlags "-Db_lto=true" ;;
|
||||||
|
*) appendToVar mesonFlags "-Db_lto=false" ;;
|
||||||
|
esac
|
||||||
|
'';
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
pkgs.buildPackages.meson
|
pkgs.buildPackages.meson
|
||||||
pkgs.buildPackages.ninja
|
pkgs.buildPackages.ninja
|
||||||
] ++ prevAttrs.nativeBuildInputs or [];
|
] ++ prevAttrs.nativeBuildInputs or [];
|
||||||
|
mesonCheckFlags = prevAttrs.mesonCheckFlags or [] ++ [
|
||||||
|
"--print-errorlogs"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
mesonBuildLayer = finalAttrs: prevAttrs:
|
mesonBuildLayer = finalAttrs: prevAttrs:
|
||||||
|
|
@ -79,6 +97,12 @@ let
|
||||||
];
|
];
|
||||||
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||||
|
env = prevAttrs.env or {}
|
||||||
|
// lib.optionalAttrs
|
||||||
|
(stdenv.isLinux
|
||||||
|
&& !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")
|
||||||
|
&& !(stdenv.hostPlatform.useLLVM or false))
|
||||||
|
{ LDFLAGS = "-fuse-ld=gold"; };
|
||||||
};
|
};
|
||||||
|
|
||||||
mesonLibraryLayer = finalAttrs: prevAttrs:
|
mesonLibraryLayer = finalAttrs: prevAttrs:
|
||||||
|
|
@ -111,14 +135,6 @@ scope: {
|
||||||
requiredSystemFeatures = [ ];
|
requiredSystemFeatures = [ ];
|
||||||
};
|
};
|
||||||
|
|
||||||
libseccomp = pkgs.libseccomp.overrideAttrs (_: rec {
|
|
||||||
version = "2.5.5";
|
|
||||||
src = pkgs.fetchurl {
|
|
||||||
url = "https://github.com/seccomp/libseccomp/releases/download/v${version}/libseccomp-${version}.tar.gz";
|
|
||||||
hash = "sha256-JIosik2bmFiqa69ScSw0r+/PnJ6Ut23OAsHJqiX7M3U=";
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
boehmgc = pkgs.boehmgc.override {
|
boehmgc = pkgs.boehmgc.override {
|
||||||
enableLargeConfig = true;
|
enableLargeConfig = true;
|
||||||
};
|
};
|
||||||
|
|
@ -137,8 +153,6 @@ scope: {
|
||||||
});
|
});
|
||||||
|
|
||||||
libgit2 = pkgs.libgit2.overrideAttrs (attrs: {
|
libgit2 = pkgs.libgit2.overrideAttrs (attrs: {
|
||||||
src = inputs.libgit2;
|
|
||||||
version = inputs.libgit2.lastModifiedDate;
|
|
||||||
cmakeFlags = attrs.cmakeFlags or []
|
cmakeFlags = attrs.cmakeFlags or []
|
||||||
++ [ "-DUSE_SSH=exec" ];
|
++ [ "-DUSE_SSH=exec" ];
|
||||||
nativeBuildInputs = attrs.nativeBuildInputs or []
|
nativeBuildInputs = attrs.nativeBuildInputs or []
|
||||||
|
|
@ -166,36 +180,6 @@ scope: {
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
busybox-sandbox-shell = pkgs.busybox-sandbox-shell or (pkgs.busybox.override {
|
|
||||||
useMusl = true;
|
|
||||||
enableStatic = true;
|
|
||||||
enableMinimal = true;
|
|
||||||
extraConfig = ''
|
|
||||||
CONFIG_FEATURE_FANCY_ECHO y
|
|
||||||
CONFIG_FEATURE_SH_MATH y
|
|
||||||
CONFIG_FEATURE_SH_MATH_64 y
|
|
||||||
|
|
||||||
CONFIG_ASH y
|
|
||||||
CONFIG_ASH_OPTIMIZE_FOR_SIZE y
|
|
||||||
|
|
||||||
CONFIG_ASH_ALIAS y
|
|
||||||
CONFIG_ASH_BASH_COMPAT y
|
|
||||||
CONFIG_ASH_CMDCMD y
|
|
||||||
CONFIG_ASH_ECHO y
|
|
||||||
CONFIG_ASH_GETOPTS y
|
|
||||||
CONFIG_ASH_INTERNAL_GLOB y
|
|
||||||
CONFIG_ASH_JOB_CONTROL y
|
|
||||||
CONFIG_ASH_PRINTF y
|
|
||||||
CONFIG_ASH_TEST y
|
|
||||||
'';
|
|
||||||
});
|
|
||||||
|
|
||||||
# TODO change in Nixpkgs, Windows works fine. First commit of
|
|
||||||
# https://github.com/NixOS/nixpkgs/pull/322977 backported will fix.
|
|
||||||
toml11 = pkgs.toml11.overrideAttrs (old: {
|
|
||||||
meta.platforms = lib.platforms.all;
|
|
||||||
});
|
|
||||||
|
|
||||||
inherit resolvePath filesetToSource;
|
inherit resolvePath filesetToSource;
|
||||||
|
|
||||||
mkMesonDerivation =
|
mkMesonDerivation =
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,10 @@
|
||||||
|
|
||||||
nix-util,
|
nix-util,
|
||||||
nix-util-c,
|
nix-util-c,
|
||||||
nix-util-test-support,
|
|
||||||
nix-util-tests,
|
nix-util-tests,
|
||||||
|
|
||||||
nix-store,
|
nix-store,
|
||||||
nix-store-c,
|
nix-store-c,
|
||||||
nix-store-test-support,
|
|
||||||
nix-store-tests,
|
nix-store-tests,
|
||||||
|
|
||||||
nix-fetchers,
|
nix-fetchers,
|
||||||
|
|
@ -18,10 +16,10 @@
|
||||||
|
|
||||||
nix-expr,
|
nix-expr,
|
||||||
nix-expr-c,
|
nix-expr-c,
|
||||||
nix-expr-test-support,
|
|
||||||
nix-expr-tests,
|
nix-expr-tests,
|
||||||
|
|
||||||
nix-flake,
|
nix-flake,
|
||||||
|
nix-flake-c,
|
||||||
nix-flake-tests,
|
nix-flake-tests,
|
||||||
|
|
||||||
nix-main,
|
nix-main,
|
||||||
|
|
@ -38,45 +36,82 @@
|
||||||
nix-external-api-docs,
|
nix-external-api-docs,
|
||||||
|
|
||||||
nix-perl-bindings,
|
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 {
|
(buildEnv {
|
||||||
name = "nix-${nix-cli.version}";
|
name = "nix-${nix-cli.version}";
|
||||||
paths = [
|
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-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";
|
meta.mainProgram = "nix";
|
||||||
|
|
@ -85,12 +120,25 @@
|
||||||
doInstallCheck = true;
|
doInstallCheck = true;
|
||||||
|
|
||||||
checkInputs = [
|
checkInputs = [
|
||||||
# Actually run the unit tests too
|
# Make sure the unit tests have passed
|
||||||
nix-util-tests.tests.run
|
nix-util-tests.tests.run
|
||||||
nix-store-tests.tests.run
|
nix-store-tests.tests.run
|
||||||
nix-expr-tests.tests.run
|
nix-expr-tests.tests.run
|
||||||
|
nix-fetchers-tests.tests.run
|
||||||
nix-flake-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 = [
|
installCheckInputs = [
|
||||||
nix-functional-tests
|
nix-functional-tests
|
||||||
];
|
];
|
||||||
|
|
@ -124,9 +172,31 @@
|
||||||
nix-expr
|
nix-expr
|
||||||
nix-expr-c
|
nix-expr-c
|
||||||
nix-flake
|
nix-flake
|
||||||
|
nix-flake-c
|
||||||
nix-main
|
nix-main
|
||||||
nix-main-c
|
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;
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,8 @@ let
|
||||||
|
|
||||||
testNixVersions = pkgs: daemon:
|
testNixVersions = pkgs: daemon:
|
||||||
pkgs.nixComponents.nix-functional-tests.override {
|
pkgs.nixComponents.nix-functional-tests.override {
|
||||||
pname =
|
pname = "nix-daemon-compat-tests";
|
||||||
"nix-tests"
|
version = "${pkgs.nix.version}-with-daemon-${daemon.version}";
|
||||||
+ lib.optionalString
|
|
||||||
(lib.versionAtLeast daemon.version "2.4pre20211005" &&
|
|
||||||
lib.versionAtLeast pkgs.nix.version "2.4pre20211005")
|
|
||||||
"-${pkgs.nix.version}-against-${daemon.version}";
|
|
||||||
|
|
||||||
test-daemon = daemon;
|
test-daemon = daemon;
|
||||||
};
|
};
|
||||||
|
|
@ -127,15 +123,10 @@ in
|
||||||
self.hydraJobs.binaryTarballCross."x86_64-linux"."armv7l-unknown-linux-gnueabihf"
|
self.hydraJobs.binaryTarballCross."x86_64-linux"."armv7l-unknown-linux-gnueabihf"
|
||||||
self.hydraJobs.binaryTarballCross."x86_64-linux"."riscv64-unknown-linux-gnu"
|
self.hydraJobs.binaryTarballCross."x86_64-linux"."riscv64-unknown-linux-gnu"
|
||||||
];
|
];
|
||||||
installerScriptForGHA = installScriptFor [
|
|
||||||
# Native
|
installerScriptForGHA = forAllSystems (system: nixpkgsFor.${system}.native.callPackage ../scripts/installer.nix {
|
||||||
self.hydraJobs.binaryTarball."x86_64-linux"
|
tarballs = [ self.hydraJobs.binaryTarball.${system} ];
|
||||||
self.hydraJobs.binaryTarball."aarch64-darwin"
|
});
|
||||||
# Cross
|
|
||||||
self.hydraJobs.binaryTarballCross."x86_64-linux"."armv6l-unknown-linux-gnueabihf"
|
|
||||||
self.hydraJobs.binaryTarballCross."x86_64-linux"."armv7l-unknown-linux-gnueabihf"
|
|
||||||
self.hydraJobs.binaryTarballCross."x86_64-linux"."riscv64-unknown-linux-gnu"
|
|
||||||
];
|
|
||||||
|
|
||||||
# docker image with Nix inside
|
# docker image with Nix inside
|
||||||
dockerImage = lib.genAttrs linux64BitSystems (system: self.packages.${system}.dockerImage);
|
dockerImage = lib.genAttrs linux64BitSystems (system: self.packages.${system}.dockerImage);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ in
|
||||||
runCommand "nix-binary-tarball-${version}" env ''
|
runCommand "nix-binary-tarball-${version}" env ''
|
||||||
cp ${installerClosureInfo}/registration $TMPDIR/reginfo
|
cp ${installerClosureInfo}/registration $TMPDIR/reginfo
|
||||||
cp ${./create-darwin-volume.sh} $TMPDIR/create-darwin-volume.sh
|
cp ${./create-darwin-volume.sh} $TMPDIR/create-darwin-volume.sh
|
||||||
substitute ${./install-nix-from-closure.sh} $TMPDIR/install \
|
substitute ${./install-nix-from-tarball.sh} $TMPDIR/install \
|
||||||
--subst-var-by nix ${nix} \
|
--subst-var-by nix ${nix} \
|
||||||
--subst-var-by cacert ${cacert}
|
--subst-var-by cacert ${cacert}
|
||||||
|
|
||||||
|
|
@ -65,7 +65,7 @@ runCommand "nix-binary-tarball-${version}" env ''
|
||||||
fn=$out/$dir.tar.xz
|
fn=$out/$dir.tar.xz
|
||||||
mkdir -p $out/nix-support
|
mkdir -p $out/nix-support
|
||||||
echo "file binary-dist $fn" >> $out/nix-support/hydra-build-products
|
echo "file binary-dist $fn" >> $out/nix-support/hydra-build-products
|
||||||
tar cvfJ $fn \
|
tar cfJ $fn \
|
||||||
--owner=0 --group=0 --mode=u+rw,uga+r \
|
--owner=0 --group=0 --mode=u+rw,uga+r \
|
||||||
--mtime='1970-01-01' \
|
--mtime='1970-01-01' \
|
||||||
--absolute-names \
|
--absolute-names \
|
||||||
|
|
|
||||||
6
scripts/build-checks
Executable file
6
scripts/build-checks
Executable file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
system=$(nix eval --raw --impure --expr builtins.currentSystem)
|
||||||
|
nix eval --json ".#checks.$system" --apply builtins.attrNames | \
|
||||||
|
jq -r '.[]' | \
|
||||||
|
xargs -P0 -I '{}' sh -c "nix build -L .#checks.$system.{} || { echo 'FAILED: \033[0;31mnix build -L .#checks.$system.{}\\033[0m'; kill 0; }"
|
||||||
|
|
@ -463,7 +463,7 @@ EOF
|
||||||
|
|
||||||
EDITOR="$SCRATCH/ex_cleanroom_wrapper" _sudo "to add nix to fstab" "$@" <<EOF
|
EDITOR="$SCRATCH/ex_cleanroom_wrapper" _sudo "to add nix to fstab" "$@" <<EOF
|
||||||
:a
|
:a
|
||||||
UUID=$uuid $escaped_mountpoint apfs rw,noauto,nobrowse,suid,owners
|
UUID=$uuid $escaped_mountpoint apfs rw,noauto,nobrowse,nosuid,noatime,owners
|
||||||
.
|
.
|
||||||
:x
|
:x
|
||||||
EOF
|
EOF
|
||||||
|
|
|
||||||
|
|
@ -145,13 +145,28 @@ poly_user_id_get() {
|
||||||
dsclattr "/Users/$1" "UniqueID"
|
dsclattr "/Users/$1" "UniqueID"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dscl_create() {
|
||||||
|
# workaround a bug in dscl where it sometimes fails with eNotYetImplemented:
|
||||||
|
# https://github.com/NixOS/nix/issues/12140
|
||||||
|
while ! _sudo "$1" /usr/bin/dscl . -create "$2" "$3" "$4" 2> "$SCRATCH/dscl.err"; do
|
||||||
|
local err=$?
|
||||||
|
if [[ $err -eq 140 ]] && grep -q "-14988 (eNotYetImplemented)" "$SCRATCH/dscl.err"; then
|
||||||
|
echo "dscl failed with eNotYetImplemented, retrying..."
|
||||||
|
sleep 1
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
cat "$SCRATCH/dscl.err"
|
||||||
|
return $err
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
poly_user_hidden_get() {
|
poly_user_hidden_get() {
|
||||||
dsclattr "/Users/$1" "IsHidden"
|
dsclattr "/Users/$1" "IsHidden"
|
||||||
}
|
}
|
||||||
|
|
||||||
poly_user_hidden_set() {
|
poly_user_hidden_set() {
|
||||||
_sudo "in order to make $1 a hidden user" \
|
dscl_create "in order to make $1 a hidden user" \
|
||||||
/usr/bin/dscl . -create "/Users/$1" "IsHidden" "1"
|
"/Users/$1" "IsHidden" "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
poly_user_home_get() {
|
poly_user_home_get() {
|
||||||
|
|
@ -161,8 +176,8 @@ poly_user_home_get() {
|
||||||
poly_user_home_set() {
|
poly_user_home_set() {
|
||||||
# This can trigger a permission prompt now:
|
# This can trigger a permission prompt now:
|
||||||
# "Terminal" would like to administer your computer. Administration can include modifying passwords, networking, and system settings.
|
# "Terminal" would like to administer your computer. Administration can include modifying passwords, networking, and system settings.
|
||||||
_sudo "in order to give $1 a safe home directory" \
|
dscl_create "in order to give $1 a safe home directory" \
|
||||||
/usr/bin/dscl . -create "/Users/$1" "NFSHomeDirectory" "$2"
|
"/Users/$1" "NFSHomeDirectory" "$2"
|
||||||
}
|
}
|
||||||
|
|
||||||
poly_user_note_get() {
|
poly_user_note_get() {
|
||||||
|
|
@ -170,8 +185,8 @@ poly_user_note_get() {
|
||||||
}
|
}
|
||||||
|
|
||||||
poly_user_note_set() {
|
poly_user_note_set() {
|
||||||
_sudo "in order to give $username a useful note" \
|
dscl_create "in order to give $1 a useful note" \
|
||||||
/usr/bin/dscl . -create "/Users/$1" "RealName" "$2"
|
"/Users/$1" "RealName" "$2"
|
||||||
}
|
}
|
||||||
|
|
||||||
poly_user_shell_get() {
|
poly_user_shell_get() {
|
||||||
|
|
@ -179,8 +194,8 @@ poly_user_shell_get() {
|
||||||
}
|
}
|
||||||
|
|
||||||
poly_user_shell_set() {
|
poly_user_shell_set() {
|
||||||
_sudo "in order to give $1 a safe shell" \
|
dscl_create "in order to give $1 a safe shell" \
|
||||||
/usr/bin/dscl . -create "/Users/$1" "UserShell" "$2"
|
"/Users/$1" "UserShell" "$2"
|
||||||
}
|
}
|
||||||
|
|
||||||
poly_user_in_group_check() {
|
poly_user_in_group_check() {
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,9 @@ readonly NIX_INSTALLED_CACERT="@cacert@"
|
||||||
#readonly NIX_INSTALLED_CACERT="/nix/store/7dxhzymvy330i28ii676fl1pqwcahv2f-nss-cacert-3.49.2"
|
#readonly NIX_INSTALLED_CACERT="/nix/store/7dxhzymvy330i28ii676fl1pqwcahv2f-nss-cacert-3.49.2"
|
||||||
readonly EXTRACTED_NIX_PATH="$(dirname "$0")"
|
readonly EXTRACTED_NIX_PATH="$(dirname "$0")"
|
||||||
|
|
||||||
|
# allow to override identity change command
|
||||||
|
readonly NIX_BECOME=${NIX_BECOME:-sudo}
|
||||||
|
|
||||||
readonly ROOT_HOME=~root
|
readonly ROOT_HOME=~root
|
||||||
|
|
||||||
if [ -t 0 ] && [ -z "${NIX_INSTALLER_YES:-}" ]; then
|
if [ -t 0 ] && [ -z "${NIX_INSTALLER_YES:-}" ]; then
|
||||||
|
|
@ -123,7 +126,7 @@ uninstall_directions() {
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
$step. Restore $profile_target$PROFILE_BACKUP_SUFFIX back to $profile_target
|
$step. Restore $profile_target$PROFILE_BACKUP_SUFFIX back to $profile_target
|
||||||
|
|
||||||
sudo mv $profile_target$PROFILE_BACKUP_SUFFIX $profile_target
|
$NIX_BECOME mv $profile_target$PROFILE_BACKUP_SUFFIX $profile_target
|
||||||
|
|
||||||
(after this one, you may need to re-open any terminals that were
|
(after this one, you may need to re-open any terminals that were
|
||||||
opened while it existed.)
|
opened while it existed.)
|
||||||
|
|
@ -136,7 +139,7 @@ EOF
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
$step. Delete the files Nix added to your system:
|
$step. Delete the files Nix added to your system:
|
||||||
|
|
||||||
sudo rm -rf "/etc/nix" "$NIX_ROOT" "$ROOT_HOME/.nix-profile" "$ROOT_HOME/.nix-defexpr" "$ROOT_HOME/.nix-channels" "$ROOT_HOME/.local/state/nix" "$ROOT_HOME/.cache/nix" "$HOME/.nix-profile" "$HOME/.nix-defexpr" "$HOME/.nix-channels" "$HOME/.local/state/nix" "$HOME/.cache/nix"
|
$NIX_BECOME rm -rf "/etc/nix" "$NIX_ROOT" "$ROOT_HOME/.nix-profile" "$ROOT_HOME/.nix-defexpr" "$ROOT_HOME/.nix-channels" "$ROOT_HOME/.local/state/nix" "$ROOT_HOME/.cache/nix" "$HOME/.nix-profile" "$HOME/.nix-defexpr" "$HOME/.nix-channels" "$HOME/.local/state/nix" "$HOME/.cache/nix"
|
||||||
|
|
||||||
and that is it.
|
and that is it.
|
||||||
|
|
||||||
|
|
@ -343,7 +346,7 @@ __sudo() {
|
||||||
|
|
||||||
echo "I am executing:"
|
echo "I am executing:"
|
||||||
echo ""
|
echo ""
|
||||||
printf " $ sudo %s\\n" "$cmd"
|
printf " $ $NIX_BECOME %s\\n" "$cmd"
|
||||||
echo ""
|
echo ""
|
||||||
echo "$expl"
|
echo "$expl"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
@ -361,7 +364,9 @@ _sudo() {
|
||||||
if is_root; then
|
if is_root; then
|
||||||
env "$@"
|
env "$@"
|
||||||
else
|
else
|
||||||
sudo "$@"
|
# env sets environment variables for sudo alternatives
|
||||||
|
# that don't support "VAR=value command" syntax
|
||||||
|
$NIX_BECOME env "$@"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -557,7 +562,7 @@ create_build_user_for_core() {
|
||||||
if [ "$actual_uid" != "$uid" ]; then
|
if [ "$actual_uid" != "$uid" ]; then
|
||||||
failure <<EOF
|
failure <<EOF
|
||||||
It seems the build user $username already exists, but with the UID
|
It seems the build user $username already exists, but with the UID
|
||||||
with the UID '$actual_uid'. This script can't really handle that right
|
'$actual_uid'. This script can't really handle that right
|
||||||
now, so I'm going to give up.
|
now, so I'm going to give up.
|
||||||
|
|
||||||
If you already created the users and you know they start from
|
If you already created the users and you know they start from
|
||||||
|
|
@ -690,7 +695,7 @@ place_channel_configuration() {
|
||||||
if [ -z "${NIX_INSTALLER_NO_CHANNEL_ADD:-}" ]; then
|
if [ -z "${NIX_INSTALLER_NO_CHANNEL_ADD:-}" ]; then
|
||||||
echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > "$SCRATCH/.nix-channels"
|
echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > "$SCRATCH/.nix-channels"
|
||||||
_sudo "to set up the default system channel (part 1)" \
|
_sudo "to set up the default system channel (part 1)" \
|
||||||
install -m 0664 "$SCRATCH/.nix-channels" "$ROOT_HOME/.nix-channels"
|
install -m 0644 "$SCRATCH/.nix-channels" "$ROOT_HOME/.nix-channels"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -964,7 +969,7 @@ $NIX_EXTRA_CONF
|
||||||
build-users-group = $NIX_BUILD_GROUP_NAME
|
build-users-group = $NIX_BUILD_GROUP_NAME
|
||||||
EOF
|
EOF
|
||||||
_sudo "to place the default nix daemon configuration (part 2)" \
|
_sudo "to place the default nix daemon configuration (part 2)" \
|
||||||
install -m 0664 "$SCRATCH/nix.conf" /etc/nix/nix.conf
|
install -m 0644 "$SCRATCH/nix.conf" /etc/nix/nix.conf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ self="$(dirname "$0")"
|
||||||
nix="@nix@"
|
nix="@nix@"
|
||||||
cacert="@cacert@"
|
cacert="@cacert@"
|
||||||
|
|
||||||
|
# allow to override identity change command
|
||||||
|
readonly NIX_BECOME="${NIX_BECOME:-sudo}"
|
||||||
|
|
||||||
if ! [ -e "$self/.reginfo" ]; then
|
if ! [ -e "$self/.reginfo" ]; then
|
||||||
echo "$0: incomplete installer (.reginfo is missing)" >&2
|
echo "$0: incomplete installer (.reginfo is missing)" >&2
|
||||||
|
|
@ -48,15 +50,14 @@ case "$(uname -s)" in
|
||||||
INSTALL_MODE=no-daemon;;
|
INSTALL_MODE=no-daemon;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# space-separated string
|
ACTION=
|
||||||
ACTIONS=
|
|
||||||
|
|
||||||
# handle the command line flags
|
# handle the command line flags
|
||||||
while [ $# -gt 0 ]; do
|
while [ $# -gt 0 ]; do
|
||||||
case $1 in
|
case $1 in
|
||||||
--daemon)
|
--daemon)
|
||||||
INSTALL_MODE=daemon
|
INSTALL_MODE=daemon
|
||||||
ACTIONS="${ACTIONS}install "
|
ACTION=install
|
||||||
;;
|
;;
|
||||||
--no-daemon)
|
--no-daemon)
|
||||||
if [ "$(uname -s)" = "Darwin" ]; then
|
if [ "$(uname -s)" = "Darwin" ]; then
|
||||||
|
|
@ -64,19 +65,14 @@ while [ $# -gt 0 ]; do
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
INSTALL_MODE=no-daemon
|
INSTALL_MODE=no-daemon
|
||||||
# intentional tail space
|
ACTION=install
|
||||||
ACTIONS="${ACTIONS}install "
|
|
||||||
;;
|
;;
|
||||||
# --uninstall)
|
|
||||||
# # intentional tail space
|
|
||||||
# ACTIONS="${ACTIONS}uninstall "
|
|
||||||
# ;;
|
|
||||||
--yes)
|
--yes)
|
||||||
export NIX_INSTALLER_YES=1;;
|
export NIX_INSTALLER_YES=1;;
|
||||||
--no-channel-add)
|
--no-channel-add)
|
||||||
export NIX_INSTALLER_NO_CHANNEL_ADD=1;;
|
export NIX_INSTALLER_NO_CHANNEL_ADD=1;;
|
||||||
--daemon-user-count)
|
--daemon-user-count)
|
||||||
export NIX_USER_COUNT=$2
|
export NIX_USER_COUNT="$2"
|
||||||
shift;;
|
shift;;
|
||||||
--no-modify-profile)
|
--no-modify-profile)
|
||||||
NIX_INSTALLER_NO_MODIFY_PROFILE=1;;
|
NIX_INSTALLER_NO_MODIFY_PROFILE=1;;
|
||||||
|
|
@ -128,7 +124,7 @@ done
|
||||||
|
|
||||||
if [ "$INSTALL_MODE" = "daemon" ]; then
|
if [ "$INSTALL_MODE" = "daemon" ]; then
|
||||||
printf '\e[1;31mSwitching to the Multi-user Installer\e[0m\n'
|
printf '\e[1;31mSwitching to the Multi-user Installer\e[0m\n'
|
||||||
exec "$self/install-multi-user" $ACTIONS # let ACTIONS split
|
exec "$self/install-multi-user" $ACTION
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -140,8 +136,8 @@ echo "performing a single-user installation of Nix..." >&2
|
||||||
|
|
||||||
if ! [ -e "$dest" ]; then
|
if ! [ -e "$dest" ]; then
|
||||||
cmd="mkdir -m 0755 $dest && chown $USER $dest"
|
cmd="mkdir -m 0755 $dest && chown $USER $dest"
|
||||||
echo "directory $dest does not exist; creating it by running '$cmd' using sudo" >&2
|
echo "directory $dest does not exist; creating it by running '$cmd' using $NIX_BECOME" >&2
|
||||||
if ! sudo sh -c "$cmd"; then
|
if ! $NIX_BECOME sh -c "$cmd"; then
|
||||||
echo "$0: please manually run '$cmd' as root to create $dest" >&2
|
echo "$0: please manually run '$cmd' as root to create $dest" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -euo pipefail
|
||||||
|
|
||||||
script=$(nix-build -A outputs.hydraJobs.installerScriptForGHA --no-out-link)
|
nix build -L ".#installerScriptForGHA" ".#binaryTarball"
|
||||||
installerHash=$(echo "$script" | cut -b12-43 -)
|
|
||||||
|
|
||||||
installerURL=https://$CACHIX_NAME.cachix.org/serve/$installerHash/install
|
mkdir -p out
|
||||||
|
cp ./result/install "out/install"
|
||||||
echo "::set-output name=installerURL::$installerURL"
|
name="$(basename "$(realpath ./result-1)")"
|
||||||
|
# everything before the first dash
|
||||||
|
cp -r ./result-1 "out/${name%%-*}"
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
|
||||||
|
# stock path to avoid unexpected command versions
|
||||||
|
PATH="$(/usr/bin/getconf PATH)"
|
||||||
|
|
||||||
((NEW_NIX_FIRST_BUILD_UID=351))
|
((NEW_NIX_FIRST_BUILD_UID=351))
|
||||||
((TEMP_NIX_FIRST_BUILD_UID=31000))
|
((TEMP_NIX_FIRST_BUILD_UID=31000))
|
||||||
|
|
||||||
|
|
|
||||||
22
scripts/serve-installer-for-github-actions
Executable file
22
scripts/serve-installer-for-github-actions
Executable file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
if [[ ! -d out ]]; then
|
||||||
|
echo "run prepare-installer-for-github-actions first"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
cd out
|
||||||
|
PORT=${PORT:-8126}
|
||||||
|
nohup python -m http.server "$PORT" >/dev/null 2>&1 &
|
||||||
|
pid=$!
|
||||||
|
|
||||||
|
while ! curl -s "http://localhost:$PORT"; do
|
||||||
|
sleep 1
|
||||||
|
if ! kill -0 $pid; then
|
||||||
|
echo "Failed to start http server"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo 'To install nix, run the following command:'
|
||||||
|
echo "sh <(curl http://localhost:$PORT/install) --tarball-url-prefix http://localhost:$PORT"
|
||||||
|
|
@ -40,6 +40,7 @@ GENERATE_LATEX = NO
|
||||||
INPUT = \
|
INPUT = \
|
||||||
@src@/src/libutil-c \
|
@src@/src/libutil-c \
|
||||||
@src@/src/libexpr-c \
|
@src@/src/libexpr-c \
|
||||||
|
@src@/src/libflake-c \
|
||||||
@src@/src/libstore-c \
|
@src@/src/libstore-c \
|
||||||
@src@/src/external-api-docs/README.md
|
@src@/src/external-api-docs/README.md
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ mkMesonDerivation (finalAttrs: {
|
||||||
# Source is not compiled, but still must be available for Doxygen
|
# Source is not compiled, but still must be available for Doxygen
|
||||||
# to gather comments.
|
# to gather comments.
|
||||||
(cpp ../libexpr-c)
|
(cpp ../libexpr-c)
|
||||||
|
(cpp ../libflake-c)
|
||||||
(cpp ../libstore-c)
|
(cpp ../libstore-c)
|
||||||
(cpp ../libutil-c)
|
(cpp ../libutil-c)
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
../../build-utils-meson
|
|
||||||
|
|
@ -179,30 +179,34 @@ BuiltPathsCommand::BuiltPathsCommand(bool recursive)
|
||||||
|
|
||||||
void BuiltPathsCommand::run(ref<Store> store, Installables && installables)
|
void BuiltPathsCommand::run(ref<Store> store, Installables && installables)
|
||||||
{
|
{
|
||||||
BuiltPaths paths;
|
BuiltPaths rootPaths, allPaths;
|
||||||
|
|
||||||
if (all) {
|
if (all) {
|
||||||
if (installables.size())
|
if (installables.size())
|
||||||
throw UsageError("'--all' does not expect arguments");
|
throw UsageError("'--all' does not expect arguments");
|
||||||
// XXX: Only uses opaque paths, ignores all the realisations
|
// XXX: Only uses opaque paths, ignores all the realisations
|
||||||
for (auto & p : store->queryAllValidPaths())
|
for (auto & p : store->queryAllValidPaths())
|
||||||
paths.emplace_back(BuiltPath::Opaque{p});
|
rootPaths.emplace_back(BuiltPath::Opaque{p});
|
||||||
|
allPaths = rootPaths;
|
||||||
} else {
|
} else {
|
||||||
paths = Installable::toBuiltPaths(getEvalStore(), store, realiseMode, operateOn, installables);
|
rootPaths = Installable::toBuiltPaths(getEvalStore(), store, realiseMode, operateOn, installables);
|
||||||
|
allPaths = rootPaths;
|
||||||
|
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
// XXX: This only computes the store path closure, ignoring
|
// XXX: This only computes the store path closure, ignoring
|
||||||
// intermediate realisations
|
// intermediate realisations
|
||||||
StorePathSet pathsRoots, pathsClosure;
|
StorePathSet pathsRoots, pathsClosure;
|
||||||
for (auto & root : paths) {
|
for (auto & root : rootPaths) {
|
||||||
auto rootFromThis = root.outPaths();
|
auto rootFromThis = root.outPaths();
|
||||||
pathsRoots.insert(rootFromThis.begin(), rootFromThis.end());
|
pathsRoots.insert(rootFromThis.begin(), rootFromThis.end());
|
||||||
}
|
}
|
||||||
store->computeFSClosure(pathsRoots, pathsClosure);
|
store->computeFSClosure(pathsRoots, pathsClosure);
|
||||||
for (auto & path : pathsClosure)
|
for (auto & path : pathsClosure)
|
||||||
paths.emplace_back(BuiltPath::Opaque{path});
|
allPaths.emplace_back(BuiltPath::Opaque{path});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
run(store, std::move(paths));
|
run(store, std::move(allPaths), std::move(rootPaths));
|
||||||
}
|
}
|
||||||
|
|
||||||
StorePathsCommand::StorePathsCommand(bool recursive)
|
StorePathsCommand::StorePathsCommand(bool recursive)
|
||||||
|
|
@ -210,10 +214,10 @@ StorePathsCommand::StorePathsCommand(bool recursive)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void StorePathsCommand::run(ref<Store> store, BuiltPaths && paths)
|
void StorePathsCommand::run(ref<Store> store, BuiltPaths && allPaths, BuiltPaths && rootPaths)
|
||||||
{
|
{
|
||||||
StorePathSet storePaths;
|
StorePathSet storePaths;
|
||||||
for (auto & builtPath : paths)
|
for (auto & builtPath : allPaths)
|
||||||
for (auto & p : builtPath.outPaths())
|
for (auto & p : builtPath.outPaths())
|
||||||
storePaths.insert(p);
|
storePaths.insert(p);
|
||||||
|
|
||||||
|
|
@ -245,7 +249,7 @@ void MixProfile::updateProfile(const StorePath & storePath)
|
||||||
{
|
{
|
||||||
if (!profile)
|
if (!profile)
|
||||||
return;
|
return;
|
||||||
auto store = getStore().dynamic_pointer_cast<LocalFSStore>();
|
auto store = getDstStore().dynamic_pointer_cast<LocalFSStore>();
|
||||||
if (!store)
|
if (!store)
|
||||||
throw Error("'--profile' is not supported for this Nix store");
|
throw Error("'--profile' is not supported for this Nix store");
|
||||||
auto profile2 = absPath(*profile);
|
auto profile2 = absPath(*profile);
|
||||||
|
|
@ -365,4 +369,31 @@ void MixEnvironment::setEnviron()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void createOutLinks(const std::filesystem::path & outLink, const BuiltPaths & buildables, LocalFSStore & store)
|
||||||
|
{
|
||||||
|
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()));
|
||||||
|
},
|
||||||
|
[&](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()));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
buildable.raw());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ extern char ** savedArgv;
|
||||||
class EvalState;
|
class EvalState;
|
||||||
struct Pos;
|
struct Pos;
|
||||||
class Store;
|
class Store;
|
||||||
|
class LocalFSStore;
|
||||||
|
|
||||||
static constexpr Command::Category catHelp = -1;
|
static constexpr Command::Category catHelp = -1;
|
||||||
static constexpr Command::Category catSecondary = 100;
|
static constexpr Command::Category catSecondary = 100;
|
||||||
|
|
@ -46,7 +47,20 @@ struct StoreCommand : virtual Command
|
||||||
{
|
{
|
||||||
StoreCommand();
|
StoreCommand();
|
||||||
void run() override;
|
void run() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the default Nix store.
|
||||||
|
*/
|
||||||
ref<Store> getStore();
|
ref<Store> getStore();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the destination Nix store.
|
||||||
|
*/
|
||||||
|
virtual ref<Store> getDstStore()
|
||||||
|
{
|
||||||
|
return getStore();
|
||||||
|
}
|
||||||
|
|
||||||
virtual ref<Store> createStore();
|
virtual ref<Store> createStore();
|
||||||
/**
|
/**
|
||||||
* Main entry point, with a `Store` provided
|
* Main entry point, with a `Store` provided
|
||||||
|
|
@ -69,7 +83,7 @@ struct CopyCommand : virtual StoreCommand
|
||||||
|
|
||||||
ref<Store> createStore() override;
|
ref<Store> createStore() override;
|
||||||
|
|
||||||
ref<Store> getDstStore();
|
ref<Store> getDstStore() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -239,7 +253,7 @@ public:
|
||||||
|
|
||||||
BuiltPathsCommand(bool recursive = false);
|
BuiltPathsCommand(bool recursive = false);
|
||||||
|
|
||||||
virtual void run(ref<Store> store, BuiltPaths && paths) = 0;
|
virtual void run(ref<Store> store, BuiltPaths && allPaths, BuiltPaths && rootPaths) = 0;
|
||||||
|
|
||||||
void run(ref<Store> store, Installables && installables) override;
|
void run(ref<Store> store, Installables && installables) override;
|
||||||
|
|
||||||
|
|
@ -252,7 +266,7 @@ struct StorePathsCommand : public BuiltPathsCommand
|
||||||
|
|
||||||
virtual void run(ref<Store> store, StorePaths && storePaths) = 0;
|
virtual void run(ref<Store> store, StorePaths && storePaths) = 0;
|
||||||
|
|
||||||
void run(ref<Store> store, BuiltPaths && paths) override;
|
void run(ref<Store> store, BuiltPaths && allPaths, BuiltPaths && rootPaths) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -354,4 +368,10 @@ std::string showVersions(const std::set<std::string> & versions);
|
||||||
void printClosureDiff(
|
void printClosureDiff(
|
||||||
ref<Store> store, const StorePath & beforePath, const StorePath & afterPath, std::string_view indent);
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,13 @@ EvalSettings evalSettings {
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"flake",
|
"flake",
|
||||||
[](ref<Store> store, std::string_view rest) {
|
[](EvalState & state, std::string_view rest) {
|
||||||
experimentalFeatureSettings.require(Xp::Flakes);
|
experimentalFeatureSettings.require(Xp::Flakes);
|
||||||
// FIXME `parseFlakeRef` should take a `std::string_view`.
|
// FIXME `parseFlakeRef` should take a `std::string_view`.
|
||||||
auto flakeRef = parseFlakeRef(fetchSettings, std::string { rest }, {}, true, false);
|
auto flakeRef = parseFlakeRef(fetchSettings, std::string { rest }, {}, true, false);
|
||||||
debug("fetching flake search path element '%s''", rest);
|
debug("fetching flake search path element '%s''", rest);
|
||||||
auto storePath = flakeRef.resolve(store).fetchTree(store).first;
|
auto storePath = flakeRef.resolve(state.store).fetchTree(state.store).first;
|
||||||
return store->toRealPath(storePath);
|
return state.rootPath(state.store->toRealPath(storePath));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -450,7 +450,7 @@ ref<eval_cache::EvalCache> openEvalCache(
|
||||||
std::shared_ptr<flake::LockedFlake> lockedFlake)
|
std::shared_ptr<flake::LockedFlake> lockedFlake)
|
||||||
{
|
{
|
||||||
auto fingerprint = evalSettings.useEvalCache && evalSettings.pureEval
|
auto fingerprint = evalSettings.useEvalCache && evalSettings.pureEval
|
||||||
? lockedFlake->getFingerprint(state.store)
|
? lockedFlake->getFingerprint(state.store, state.fetchSettings)
|
||||||
: std::nullopt;
|
: std::nullopt;
|
||||||
auto rootLoader = [&state, lockedFlake]()
|
auto rootLoader = [&state, lockedFlake]()
|
||||||
{
|
{
|
||||||
|
|
@ -858,7 +858,7 @@ std::vector<FlakeRef> RawInstallablesCommand::getFlakeRefsForCompletion()
|
||||||
applyDefaultInstallables(rawInstallables);
|
applyDefaultInstallables(rawInstallables);
|
||||||
std::vector<FlakeRef> res;
|
std::vector<FlakeRef> res;
|
||||||
res.reserve(rawInstallables.size());
|
res.reserve(rawInstallables.size());
|
||||||
for (auto i : rawInstallables)
|
for (const auto & i : rawInstallables)
|
||||||
res.push_back(parseFlakeRefWithFragment(
|
res.push_back(parseFlakeRefWithFragment(
|
||||||
fetchSettings,
|
fetchSettings,
|
||||||
expandTilde(i),
|
expandTilde(i),
|
||||||
|
|
@ -918,4 +918,12 @@ void BuiltPathsCommand::applyDefaultInstallables(std::vector<std::string> & rawI
|
||||||
rawInstallables.push_back(".");
|
rawInstallables.push_back(".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BuiltPaths toBuiltPaths(const std::vector<BuiltPathWithResult> & builtPathsWithResult)
|
||||||
|
{
|
||||||
|
BuiltPaths res;
|
||||||
|
for (auto & i : builtPathsWithResult)
|
||||||
|
res.push_back(i.path);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,8 @@ struct BuiltPathWithResult
|
||||||
std::optional<BuildResult> result;
|
std::optional<BuildResult> result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BuiltPaths toBuiltPaths(const std::vector<BuiltPathWithResult> & builtPathsWithResult);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shorthand, for less typing and helping us keep the choice of
|
* Shorthand, for less typing and helping us keep the choice of
|
||||||
* collection in sync.
|
* collection in sync.
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,25 @@ static std::string doRenderMarkdownToTerminal(std::string_view markdown)
|
||||||
{
|
{
|
||||||
int windowWidth = getWindowSize().second;
|
int windowWidth = getWindowSize().second;
|
||||||
|
|
||||||
struct lowdown_opts opts
|
#if HAVE_LOWDOWN_1_4
|
||||||
{
|
struct lowdown_opts_term opts_term {
|
||||||
.type = LOWDOWN_TERM,
|
|
||||||
.maxdepth = 20,
|
|
||||||
.cols = (size_t) std::max(windowWidth - 5, 60),
|
.cols = (size_t) std::max(windowWidth - 5, 60),
|
||||||
.hmargin = 0,
|
.hmargin = 0,
|
||||||
.vmargin = 0,
|
.vmargin = 0,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
struct lowdown_opts opts
|
||||||
|
{
|
||||||
|
.type = LOWDOWN_TERM,
|
||||||
|
#if HAVE_LOWDOWN_1_4
|
||||||
|
.term = opts_term,
|
||||||
|
#endif
|
||||||
|
.maxdepth = 20,
|
||||||
|
#if !HAVE_LOWDOWN_1_4
|
||||||
|
.cols = (size_t) std::max(windowWidth - 5, 60),
|
||||||
|
.hmargin = 0,
|
||||||
|
.vmargin = 0,
|
||||||
|
#endif
|
||||||
.feat = LOWDOWN_COMMONMARK | LOWDOWN_FENCED | LOWDOWN_DEFLIST | LOWDOWN_TABLES,
|
.feat = LOWDOWN_COMMONMARK | LOWDOWN_FENCED | LOWDOWN_DEFLIST | LOWDOWN_TABLES,
|
||||||
.oflags = LOWDOWN_TERM_NOLINK,
|
.oflags = LOWDOWN_TERM_NOLINK,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,6 @@ project('nix-cmd', 'cpp',
|
||||||
'cpp_std=c++2a',
|
'cpp_std=c++2a',
|
||||||
# TODO(Qyriad): increase the warning level
|
# TODO(Qyriad): increase the warning level
|
||||||
'warning_level=1',
|
'warning_level=1',
|
||||||
'debug=true',
|
|
||||||
'optimization=2',
|
|
||||||
'errorlogs=true', # Please print logs for tests that fail
|
'errorlogs=true', # Please print logs for tests that fail
|
||||||
],
|
],
|
||||||
meson_version : '>= 1.1',
|
meson_version : '>= 1.1',
|
||||||
|
|
@ -14,7 +12,7 @@ project('nix-cmd', 'cpp',
|
||||||
|
|
||||||
cxx = meson.get_compiler('cpp')
|
cxx = meson.get_compiler('cpp')
|
||||||
|
|
||||||
subdir('build-utils-meson/deps-lists')
|
subdir('nix-meson-build-support/deps-lists')
|
||||||
|
|
||||||
configdata = configuration_data()
|
configdata = configuration_data()
|
||||||
|
|
||||||
|
|
@ -28,9 +26,7 @@ deps_public_maybe_subproject = [
|
||||||
dependency('nix-flake'),
|
dependency('nix-flake'),
|
||||||
dependency('nix-main'),
|
dependency('nix-main'),
|
||||||
]
|
]
|
||||||
subdir('build-utils-meson/subprojects')
|
subdir('nix-meson-build-support/subprojects')
|
||||||
|
|
||||||
subdir('build-utils-meson/threads')
|
|
||||||
|
|
||||||
nlohmann_json = dependency('nlohmann_json', version : '>= 3.9')
|
nlohmann_json = dependency('nlohmann_json', version : '>= 3.9')
|
||||||
deps_public += nlohmann_json
|
deps_public += nlohmann_json
|
||||||
|
|
@ -38,6 +34,8 @@ deps_public += nlohmann_json
|
||||||
lowdown = dependency('lowdown', version : '>= 0.9.0', required : get_option('markdown'))
|
lowdown = dependency('lowdown', version : '>= 0.9.0', required : get_option('markdown'))
|
||||||
deps_private += lowdown
|
deps_private += lowdown
|
||||||
configdata.set('HAVE_LOWDOWN', lowdown.found().to_int())
|
configdata.set('HAVE_LOWDOWN', lowdown.found().to_int())
|
||||||
|
# The API changed slightly around terminal initialization.
|
||||||
|
configdata.set('HAVE_LOWDOWN_1_4', lowdown.version().version_compare('>= 1.4.0').to_int())
|
||||||
|
|
||||||
readline_flavor = get_option('readline-flavor')
|
readline_flavor = get_option('readline-flavor')
|
||||||
if readline_flavor == 'editline'
|
if readline_flavor == 'editline'
|
||||||
|
|
@ -72,7 +70,7 @@ add_project_arguments(
|
||||||
language : 'cpp',
|
language : 'cpp',
|
||||||
)
|
)
|
||||||
|
|
||||||
subdir('build-utils-meson/diagnostics')
|
subdir('nix-meson-build-support/common')
|
||||||
|
|
||||||
sources = files(
|
sources = files(
|
||||||
'built-path.cc',
|
'built-path.cc',
|
||||||
|
|
@ -127,4 +125,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
|
||||||
|
|
||||||
libraries_private = []
|
libraries_private = []
|
||||||
|
|
||||||
subdir('build-utils-meson/export')
|
subdir('nix-meson-build-support/export')
|
||||||
|
|
|
||||||
1
src/libcmd/nix-meson-build-support
Symbolic link
1
src/libcmd/nix-meson-build-support
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../nix-meson-build-support
|
||||||
|
|
@ -39,8 +39,8 @@ mkMesonLibrary (finalAttrs: {
|
||||||
|
|
||||||
workDir = ./.;
|
workDir = ./.;
|
||||||
fileset = fileset.unions [
|
fileset = fileset.unions [
|
||||||
../../build-utils-meson
|
../../nix-meson-build-support
|
||||||
./build-utils-meson
|
./nix-meson-build-support
|
||||||
../../.version
|
../../.version
|
||||||
./.version
|
./.version
|
||||||
./meson.build
|
./meson.build
|
||||||
|
|
@ -76,10 +76,6 @@ mkMesonLibrary (finalAttrs: {
|
||||||
(lib.mesonOption "readline-flavor" readlineFlavor)
|
(lib.mesonOption "readline-flavor" readlineFlavor)
|
||||||
];
|
];
|
||||||
|
|
||||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
|
||||||
LDFLAGS = "-fuse-ld=gold";
|
|
||||||
};
|
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
../../build-utils-meson
|
|
||||||
|
|
@ -4,8 +4,6 @@ project('nix-expr-c', 'cpp',
|
||||||
'cpp_std=c++2a',
|
'cpp_std=c++2a',
|
||||||
# TODO(Qyriad): increase the warning level
|
# TODO(Qyriad): increase the warning level
|
||||||
'warning_level=1',
|
'warning_level=1',
|
||||||
'debug=true',
|
|
||||||
'optimization=2',
|
|
||||||
'errorlogs=true', # Please print logs for tests that fail
|
'errorlogs=true', # Please print logs for tests that fail
|
||||||
],
|
],
|
||||||
meson_version : '>= 1.1',
|
meson_version : '>= 1.1',
|
||||||
|
|
@ -14,7 +12,7 @@ project('nix-expr-c', 'cpp',
|
||||||
|
|
||||||
cxx = meson.get_compiler('cpp')
|
cxx = meson.get_compiler('cpp')
|
||||||
|
|
||||||
subdir('build-utils-meson/deps-lists')
|
subdir('nix-meson-build-support/deps-lists')
|
||||||
|
|
||||||
configdata = configuration_data()
|
configdata = configuration_data()
|
||||||
|
|
||||||
|
|
@ -27,9 +25,7 @@ deps_public_maybe_subproject = [
|
||||||
dependency('nix-util-c'),
|
dependency('nix-util-c'),
|
||||||
dependency('nix-store-c'),
|
dependency('nix-store-c'),
|
||||||
]
|
]
|
||||||
subdir('build-utils-meson/subprojects')
|
subdir('nix-meson-build-support/subprojects')
|
||||||
|
|
||||||
subdir('build-utils-meson/threads')
|
|
||||||
|
|
||||||
# TODO rename, because it will conflict with downstream projects
|
# TODO rename, because it will conflict with downstream projects
|
||||||
configdata.set_quoted('PACKAGE_VERSION', meson.project_version())
|
configdata.set_quoted('PACKAGE_VERSION', meson.project_version())
|
||||||
|
|
@ -55,7 +51,7 @@ add_project_arguments(
|
||||||
language : 'cpp',
|
language : 'cpp',
|
||||||
)
|
)
|
||||||
|
|
||||||
subdir('build-utils-meson/diagnostics')
|
subdir('nix-meson-build-support/common')
|
||||||
|
|
||||||
sources = files(
|
sources = files(
|
||||||
'nix_api_expr.cc',
|
'nix_api_expr.cc',
|
||||||
|
|
@ -74,8 +70,8 @@ headers = [config_h] + files(
|
||||||
# TODO move this header to libexpr, maybe don't use it in tests?
|
# TODO move this header to libexpr, maybe don't use it in tests?
|
||||||
headers += files('nix_api_expr_internal.h')
|
headers += files('nix_api_expr_internal.h')
|
||||||
|
|
||||||
subdir('build-utils-meson/export-all-symbols')
|
subdir('nix-meson-build-support/export-all-symbols')
|
||||||
subdir('build-utils-meson/windows-version')
|
subdir('nix-meson-build-support/windows-version')
|
||||||
|
|
||||||
this_library = library(
|
this_library = library(
|
||||||
'nixexprc',
|
'nixexprc',
|
||||||
|
|
@ -91,4 +87,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
|
||||||
|
|
||||||
libraries_private = []
|
libraries_private = []
|
||||||
|
|
||||||
subdir('build-utils-meson/export')
|
subdir('nix-meson-build-support/export')
|
||||||
|
|
|
||||||
1
src/libexpr-c/nix-meson-build-support
Symbolic link
1
src/libexpr-c/nix-meson-build-support
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../nix-meson-build-support
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include "eval-gc.hh"
|
#include "eval-gc.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
#include "eval-settings.hh"
|
#include "eval-settings.hh"
|
||||||
|
#include "ref.hh"
|
||||||
|
|
||||||
#include "nix_api_expr.h"
|
#include "nix_api_expr.h"
|
||||||
#include "nix_api_expr_internal.h"
|
#include "nix_api_expr_internal.h"
|
||||||
|
|
@ -18,6 +19,29 @@
|
||||||
# include <mutex>
|
# include <mutex>
|
||||||
#endif
|
#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)
|
nix_err nix_libexpr_init(nix_c_context * context)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
|
|
@ -67,7 +91,7 @@ nix_err nix_value_call_multi(nix_c_context * context, EvalState * state, nix_val
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
try {
|
try {
|
||||||
state->state.callFunction(fn->value, nargs, (nix::Value * *)args, value->value, nix::noPos);
|
state->state.callFunction(fn->value, {(nix::Value * *) args, nargs}, value->value, nix::noPos);
|
||||||
state->state.forceValue(value->value, nix::noPos);
|
state->state.forceValue(value->value, nix::noPos);
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
|
|
@ -93,7 +117,42 @@ nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, nix_val
|
||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
EvalState * nix_state_create(nix_c_context * context, const char ** lookupPath_c, Store * store)
|
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)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
|
|
@ -102,28 +161,47 @@ EvalState * nix_state_create(nix_c_context * context, const char ** lookupPath_c
|
||||||
if (lookupPath_c != nullptr)
|
if (lookupPath_c != nullptr)
|
||||||
for (size_t i = 0; lookupPath_c[i] != nullptr; i++)
|
for (size_t i = 0; lookupPath_c[i] != nullptr; i++)
|
||||||
lookupPath.push_back(lookupPath_c[i]);
|
lookupPath.push_back(lookupPath_c[i]);
|
||||||
|
builder->lookupPath = nix::LookupPath::parse(lookupPath);
|
||||||
|
}
|
||||||
|
NIXC_CATCH_ERRS
|
||||||
|
}
|
||||||
|
|
||||||
void * p = ::operator new(
|
EvalState * nix_eval_state_build(nix_c_context * context, nix_eval_state_builder * builder)
|
||||||
sizeof(EvalState),
|
{
|
||||||
static_cast<std::align_val_t>(alignof(EvalState)));
|
if (context)
|
||||||
auto * p2 = static_cast<EvalState *>(p);
|
context->last_err_code = NIX_OK;
|
||||||
new (p) EvalState {
|
try {
|
||||||
.fetchSettings = nix::fetchers::Settings{},
|
return unsafe_new_with_self<EvalState>([&](auto * self) {
|
||||||
.settings = nix::EvalSettings{
|
return EvalState{
|
||||||
nix::settings.readOnlyMode,
|
.fetchSettings = std::move(builder->fetchSettings),
|
||||||
},
|
.settings = std::move(builder->settings),
|
||||||
.state = nix::EvalState(
|
.state = nix::EvalState(
|
||||||
nix::LookupPath::parse(lookupPath),
|
builder->lookupPath,
|
||||||
store->ptr,
|
builder->store,
|
||||||
p2->fetchSettings,
|
self->fetchSettings,
|
||||||
p2->settings),
|
self->settings),
|
||||||
};
|
};
|
||||||
loadConfFile(p2->settings);
|
});
|
||||||
return p2;
|
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS_NULL
|
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)
|
void nix_state_free(EvalState * state)
|
||||||
{
|
{
|
||||||
delete state;
|
delete state;
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,11 @@ extern "C" {
|
||||||
// cffi start
|
// cffi start
|
||||||
|
|
||||||
// Type definitions
|
// 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.
|
* @brief Represents a state of the Nix language evaluator.
|
||||||
*
|
*
|
||||||
|
|
@ -174,12 +179,70 @@ 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);
|
nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, nix_value * value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a new Nix language evaluator state.
|
* @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
|
||||||
*
|
*
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
* @param[in] lookupPath Null-terminated array of strings corresponding to entries in NIX_PATH.
|
* @param[in] lookupPath Null-terminated array of strings corresponding to entries in NIX_PATH.
|
||||||
* @param[in] store The Nix store to use.
|
* @param[in] store The Nix store to use.
|
||||||
* @return A new Nix state or NULL on failure.
|
* @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);
|
EvalState * nix_state_create(nix_c_context * context, const char ** lookupPath, Store * store);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,17 @@
|
||||||
#include "eval-settings.hh"
|
#include "eval-settings.hh"
|
||||||
#include "attr-set.hh"
|
#include "attr-set.hh"
|
||||||
#include "nix_api_value.h"
|
#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
|
struct EvalState
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,7 @@ nix_get_string(nix_c_context * context, const nix_value * value, nix_get_string_
|
||||||
/** @brief Get path as string
|
/** @brief Get path as string
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
* @param[in] value Nix value to inspect
|
* @param[in] value Nix value to inspect
|
||||||
* @return string
|
* @return string, if the type is NIX_TYPE_PATH
|
||||||
* @return NULL in case of error.
|
* @return NULL in case of error.
|
||||||
*/
|
*/
|
||||||
const char * nix_get_path_string(nix_c_context * context, const nix_value * value);
|
const char * nix_get_path_string(nix_c_context * context, const nix_value * value);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
{ lib
|
{ lib
|
||||||
, stdenv
|
|
||||||
, mkMesonLibrary
|
, mkMesonLibrary
|
||||||
|
|
||||||
, nix-store-c
|
, nix-store-c
|
||||||
|
|
@ -20,8 +19,8 @@ mkMesonLibrary (finalAttrs: {
|
||||||
|
|
||||||
workDir = ./.;
|
workDir = ./.;
|
||||||
fileset = fileset.unions [
|
fileset = fileset.unions [
|
||||||
../../build-utils-meson
|
../../nix-meson-build-support
|
||||||
./build-utils-meson
|
./nix-meson-build-support
|
||||||
../../.version
|
../../.version
|
||||||
./.version
|
./.version
|
||||||
./meson.build
|
./meson.build
|
||||||
|
|
@ -47,10 +46,6 @@ mkMesonLibrary (finalAttrs: {
|
||||||
mesonFlags = [
|
mesonFlags = [
|
||||||
];
|
];
|
||||||
|
|
||||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
|
||||||
LDFLAGS = "-fuse-ld=gold";
|
|
||||||
};
|
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
../../build-utils-meson
|
|
||||||
|
|
@ -4,8 +4,6 @@ project('nix-expr-test-support', 'cpp',
|
||||||
'cpp_std=c++2a',
|
'cpp_std=c++2a',
|
||||||
# TODO(Qyriad): increase the warning level
|
# TODO(Qyriad): increase the warning level
|
||||||
'warning_level=1',
|
'warning_level=1',
|
||||||
'debug=true',
|
|
||||||
'optimization=2',
|
|
||||||
'errorlogs=true', # Please print logs for tests that fail
|
'errorlogs=true', # Please print logs for tests that fail
|
||||||
],
|
],
|
||||||
meson_version : '>= 1.1',
|
meson_version : '>= 1.1',
|
||||||
|
|
@ -14,7 +12,7 @@ project('nix-expr-test-support', 'cpp',
|
||||||
|
|
||||||
cxx = meson.get_compiler('cpp')
|
cxx = meson.get_compiler('cpp')
|
||||||
|
|
||||||
subdir('build-utils-meson/deps-lists')
|
subdir('nix-meson-build-support/deps-lists')
|
||||||
|
|
||||||
deps_private_maybe_subproject = [
|
deps_private_maybe_subproject = [
|
||||||
]
|
]
|
||||||
|
|
@ -24,10 +22,9 @@ deps_public_maybe_subproject = [
|
||||||
dependency('nix-store'),
|
dependency('nix-store'),
|
||||||
dependency('nix-store-test-support'),
|
dependency('nix-store-test-support'),
|
||||||
dependency('nix-expr'),
|
dependency('nix-expr'),
|
||||||
|
dependency('nix-expr-c'),
|
||||||
]
|
]
|
||||||
subdir('build-utils-meson/subprojects')
|
subdir('nix-meson-build-support/subprojects')
|
||||||
|
|
||||||
subdir('build-utils-meson/threads')
|
|
||||||
|
|
||||||
rapidcheck = dependency('rapidcheck')
|
rapidcheck = dependency('rapidcheck')
|
||||||
deps_public += rapidcheck
|
deps_public += rapidcheck
|
||||||
|
|
@ -41,7 +38,7 @@ add_project_arguments(
|
||||||
language : 'cpp',
|
language : 'cpp',
|
||||||
)
|
)
|
||||||
|
|
||||||
subdir('build-utils-meson/diagnostics')
|
subdir('nix-meson-build-support/common')
|
||||||
|
|
||||||
sources = files(
|
sources = files(
|
||||||
'tests/value/context.cc',
|
'tests/value/context.cc',
|
||||||
|
|
@ -55,8 +52,8 @@ headers = files(
|
||||||
'tests/value/context.hh',
|
'tests/value/context.hh',
|
||||||
)
|
)
|
||||||
|
|
||||||
subdir('build-utils-meson/export-all-symbols')
|
subdir('nix-meson-build-support/export-all-symbols')
|
||||||
subdir('build-utils-meson/windows-version')
|
subdir('nix-meson-build-support/windows-version')
|
||||||
|
|
||||||
this_library = library(
|
this_library = library(
|
||||||
'nix-expr-test-support',
|
'nix-expr-test-support',
|
||||||
|
|
@ -74,4 +71,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
|
||||||
|
|
||||||
libraries_private = []
|
libraries_private = []
|
||||||
|
|
||||||
subdir('build-utils-meson/export')
|
subdir('nix-meson-build-support/export')
|
||||||
|
|
|
||||||
1
src/libexpr-test-support/nix-meson-build-support
Symbolic link
1
src/libexpr-test-support/nix-meson-build-support
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../nix-meson-build-support
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
{ lib
|
{ lib
|
||||||
, stdenv
|
|
||||||
, mkMesonLibrary
|
, mkMesonLibrary
|
||||||
|
|
||||||
, nix-store-test-support
|
, nix-store-test-support
|
||||||
, nix-expr
|
, nix-expr
|
||||||
|
, nix-expr-c
|
||||||
|
|
||||||
, rapidcheck
|
, rapidcheck
|
||||||
|
|
||||||
|
|
@ -22,8 +22,8 @@ mkMesonLibrary (finalAttrs: {
|
||||||
|
|
||||||
workDir = ./.;
|
workDir = ./.;
|
||||||
fileset = fileset.unions [
|
fileset = fileset.unions [
|
||||||
../../build-utils-meson
|
../../nix-meson-build-support
|
||||||
./build-utils-meson
|
./nix-meson-build-support
|
||||||
../../.version
|
../../.version
|
||||||
./.version
|
./.version
|
||||||
./meson.build
|
./meson.build
|
||||||
|
|
@ -35,6 +35,7 @@ mkMesonLibrary (finalAttrs: {
|
||||||
propagatedBuildInputs = [
|
propagatedBuildInputs = [
|
||||||
nix-store-test-support
|
nix-store-test-support
|
||||||
nix-expr
|
nix-expr
|
||||||
|
nix-expr-c
|
||||||
rapidcheck
|
rapidcheck
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -49,10 +50,6 @@ mkMesonLibrary (finalAttrs: {
|
||||||
mesonFlags = [
|
mesonFlags = [
|
||||||
];
|
];
|
||||||
|
|
||||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
|
||||||
LDFLAGS = "-fuse-ld=gold";
|
|
||||||
};
|
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,12 @@ namespace nix {
|
||||||
return v;
|
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) {
|
Symbol createSymbol(const char * value) {
|
||||||
return state.symbols.create(value);
|
return state.symbols.create(value);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
../../build-utils-meson
|
|
||||||
|
|
@ -691,15 +691,15 @@ namespace nix {
|
||||||
ASSERT_TRACE2("elemAt \"foo\" (-1)",
|
ASSERT_TRACE2("elemAt \"foo\" (-1)",
|
||||||
TypeError,
|
TypeError,
|
||||||
HintFmt("expected a list but found %s: %s", "a string", Uncolored(ANSI_MAGENTA "\"foo\"" ANSI_NORMAL)),
|
HintFmt("expected a list but found %s: %s", "a string", Uncolored(ANSI_MAGENTA "\"foo\"" ANSI_NORMAL)),
|
||||||
HintFmt("while evaluating the first argument passed to builtins.elemAt"));
|
HintFmt("while evaluating the first argument passed to 'builtins.elemAt'"));
|
||||||
|
|
||||||
ASSERT_TRACE1("elemAt [] (-1)",
|
ASSERT_TRACE1("elemAt [] (-1)",
|
||||||
Error,
|
Error,
|
||||||
HintFmt("list index %d is out of bounds", -1));
|
HintFmt("'builtins.elemAt' called with index %d on a list of size %d", -1, 0));
|
||||||
|
|
||||||
ASSERT_TRACE1("elemAt [\"foo\"] 3",
|
ASSERT_TRACE1("elemAt [\"foo\"] 3",
|
||||||
Error,
|
Error,
|
||||||
HintFmt("list index %d is out of bounds", 3));
|
HintFmt("'builtins.elemAt' called with index %d on a list of size %d", 3, 1));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -708,11 +708,11 @@ namespace nix {
|
||||||
ASSERT_TRACE2("head 1",
|
ASSERT_TRACE2("head 1",
|
||||||
TypeError,
|
TypeError,
|
||||||
HintFmt("expected a list but found %s: %s", "an integer", Uncolored(ANSI_CYAN "1" ANSI_NORMAL)),
|
HintFmt("expected a list but found %s: %s", "an integer", Uncolored(ANSI_CYAN "1" ANSI_NORMAL)),
|
||||||
HintFmt("while evaluating the first argument passed to builtins.elemAt"));
|
HintFmt("while evaluating the first argument passed to 'builtins.head'"));
|
||||||
|
|
||||||
ASSERT_TRACE1("head []",
|
ASSERT_TRACE1("head []",
|
||||||
Error,
|
Error,
|
||||||
HintFmt("list index %d is out of bounds", 0));
|
HintFmt("'builtins.head' called on an empty list"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -721,11 +721,11 @@ namespace nix {
|
||||||
ASSERT_TRACE2("tail 1",
|
ASSERT_TRACE2("tail 1",
|
||||||
TypeError,
|
TypeError,
|
||||||
HintFmt("expected a list but found %s: %s", "an integer", Uncolored(ANSI_CYAN "1" ANSI_NORMAL)),
|
HintFmt("expected a list but found %s: %s", "an integer", Uncolored(ANSI_CYAN "1" ANSI_NORMAL)),
|
||||||
HintFmt("while evaluating the first argument passed to builtins.tail"));
|
HintFmt("while evaluating the first argument passed to 'builtins.tail'"));
|
||||||
|
|
||||||
ASSERT_TRACE1("tail []",
|
ASSERT_TRACE1("tail []",
|
||||||
Error,
|
Error,
|
||||||
HintFmt("'tail' called on an empty list"));
|
HintFmt("'builtins.tail' called on an empty list"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -138,4 +138,27 @@ TEST(nix_isAllowedURI, non_scheme_colon) {
|
||||||
ASSERT_FALSE(isAllowedURI("https://foo/bar:baz", allowed));
|
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
|
||||||
|
|
@ -4,8 +4,6 @@ project('nix-expr-tests', 'cpp',
|
||||||
'cpp_std=c++2a',
|
'cpp_std=c++2a',
|
||||||
# TODO(Qyriad): increase the warning level
|
# TODO(Qyriad): increase the warning level
|
||||||
'warning_level=1',
|
'warning_level=1',
|
||||||
'debug=true',
|
|
||||||
'optimization=2',
|
|
||||||
'errorlogs=true', # Please print logs for tests that fail
|
'errorlogs=true', # Please print logs for tests that fail
|
||||||
],
|
],
|
||||||
meson_version : '>= 1.1',
|
meson_version : '>= 1.1',
|
||||||
|
|
@ -14,7 +12,7 @@ project('nix-expr-tests', 'cpp',
|
||||||
|
|
||||||
cxx = meson.get_compiler('cpp')
|
cxx = meson.get_compiler('cpp')
|
||||||
|
|
||||||
subdir('build-utils-meson/deps-lists')
|
subdir('nix-meson-build-support/deps-lists')
|
||||||
|
|
||||||
deps_private_maybe_subproject = [
|
deps_private_maybe_subproject = [
|
||||||
dependency('nix-expr'),
|
dependency('nix-expr'),
|
||||||
|
|
@ -23,12 +21,10 @@ deps_private_maybe_subproject = [
|
||||||
]
|
]
|
||||||
deps_public_maybe_subproject = [
|
deps_public_maybe_subproject = [
|
||||||
]
|
]
|
||||||
subdir('build-utils-meson/subprojects')
|
subdir('nix-meson-build-support/subprojects')
|
||||||
|
|
||||||
subdir('build-utils-meson/threads')
|
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')
|
|
||||||
|
|
||||||
rapidcheck = dependency('rapidcheck')
|
rapidcheck = dependency('rapidcheck')
|
||||||
deps_private += rapidcheck
|
deps_private += rapidcheck
|
||||||
|
|
@ -51,7 +47,7 @@ add_project_arguments(
|
||||||
language : 'cpp',
|
language : 'cpp',
|
||||||
)
|
)
|
||||||
|
|
||||||
subdir('build-utils-meson/diagnostics')
|
subdir('nix-meson-build-support/common')
|
||||||
|
|
||||||
sources = files(
|
sources = files(
|
||||||
'derived-path.cc',
|
'derived-path.cc',
|
||||||
|
|
|
||||||
1
src/libexpr-tests/nix-meson-build-support
Symbolic link
1
src/libexpr-tests/nix-meson-build-support
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../nix-meson-build-support
|
||||||
|
|
@ -7,12 +7,49 @@
|
||||||
|
|
||||||
#include "tests/nix_api_expr.hh"
|
#include "tests/nix_api_expr.hh"
|
||||||
#include "tests/string_callback.hh"
|
#include "tests/string_callback.hh"
|
||||||
|
#include "file-system.hh"
|
||||||
|
|
||||||
#include <gmock/gmock.h>
|
#include <gmock/gmock.h>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
namespace nixC {
|
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)
|
TEST_F(nix_api_expr_test, nix_expr_eval_from_string)
|
||||||
{
|
{
|
||||||
nix_expr_eval_from_string(nullptr, state, "builtins.nixVersion", ".", value);
|
nix_expr_eval_from_string(nullptr, state, "builtins.nixVersion", ".", value);
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,8 @@ mkMesonExecutable (finalAttrs: {
|
||||||
|
|
||||||
workDir = ./.;
|
workDir = ./.;
|
||||||
fileset = fileset.unions [
|
fileset = fileset.unions [
|
||||||
../../build-utils-meson
|
../../nix-meson-build-support
|
||||||
./build-utils-meson
|
./nix-meson-build-support
|
||||||
../../.version
|
../../.version
|
||||||
./.version
|
./.version
|
||||||
./meson.build
|
./meson.build
|
||||||
|
|
@ -56,10 +56,6 @@ mkMesonExecutable (finalAttrs: {
|
||||||
mesonFlags = [
|
mesonFlags = [
|
||||||
];
|
];
|
||||||
|
|
||||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
|
||||||
LDFLAGS = "-fuse-ld=gold";
|
|
||||||
};
|
|
||||||
|
|
||||||
passthru = {
|
passthru = {
|
||||||
tests = {
|
tests = {
|
||||||
run = runCommand "${finalAttrs.pname}-run" {
|
run = runCommand "${finalAttrs.pname}-run" {
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,57 @@ 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) {
|
TEST_F(TrivialExpressionTest, functor) {
|
||||||
auto v = eval("{ __functor = self: arg: self.v + arg; v = 10; } 5");
|
auto v = eval("{ __functor = self: arg: self.v + arg; v = 10; } 5");
|
||||||
ASSERT_THAT(v, IsIntEq(15));
|
ASSERT_THAT(v, IsIntEq(15));
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,6 @@ std::pair<SourcePath, uint32_t> findPackageFilename(EvalState & state, Value & v
|
||||||
try {
|
try {
|
||||||
auto colon = fn.rfind(':');
|
auto colon = fn.rfind(':');
|
||||||
if (colon == std::string::npos) fail();
|
if (colon == std::string::npos) fail();
|
||||||
std::string filename(fn, 0, colon);
|
|
||||||
auto lineno = std::stoi(std::string(fn, colon + 1, std::string::npos));
|
auto lineno = std::stoi(std::string(fn, colon + 1, std::string::npos));
|
||||||
return {SourcePath{path.accessor, CanonPath(fn.substr(0, colon))}, lineno};
|
return {SourcePath{path.accessor, CanonPath(fn.substr(0, colon))}, lineno};
|
||||||
} catch (std::invalid_argument & e) {
|
} catch (std::invalid_argument & e) {
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
../../build-utils-meson
|
|
||||||
|
|
@ -41,10 +41,17 @@ let
|
||||||
(key: node:
|
(key: node:
|
||||||
let
|
let
|
||||||
|
|
||||||
|
parentNode = allNodes.${getInputByPath lockFile.root node.parent};
|
||||||
|
|
||||||
sourceInfo =
|
sourceInfo =
|
||||||
if overrides ? ${key}
|
if overrides ? ${key}
|
||||||
then
|
then
|
||||||
overrides.${key}.sourceInfo
|
overrides.${key}.sourceInfo
|
||||||
|
else if node.locked.type == "path" && builtins.substring 0 1 node.locked.path != "/"
|
||||||
|
then
|
||||||
|
parentNode.sourceInfo // {
|
||||||
|
outPath = parentNode.outPath + ("/" + node.locked.path);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
# FIXME: remove obsolete node.info.
|
# FIXME: remove obsolete node.info.
|
||||||
# Note: lock file entries are always final.
|
# Note: lock file entries are always final.
|
||||||
|
|
|
||||||
|
|
@ -87,11 +87,15 @@ void EvalState::forceValue(Value & v, const PosIdx pos)
|
||||||
{
|
{
|
||||||
if (v.isThunk()) {
|
if (v.isThunk()) {
|
||||||
Env * env = v.payload.thunk.env;
|
Env * env = v.payload.thunk.env;
|
||||||
|
assert(env || v.isBlackhole());
|
||||||
Expr * expr = v.payload.thunk.expr;
|
Expr * expr = v.payload.thunk.expr;
|
||||||
try {
|
try {
|
||||||
v.mkBlackhole();
|
v.mkBlackhole();
|
||||||
//checkInterrupt();
|
//checkInterrupt();
|
||||||
expr->eval(*this, *env, v);
|
if (env) [[likely]]
|
||||||
|
expr->eval(*this, *env, v);
|
||||||
|
else
|
||||||
|
ExprBlackHole::throwInfiniteRecursionError(*this, v);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
v.mkThunk(env, expr);
|
v.mkThunk(env, expr);
|
||||||
tryFixupBlackHolePos(v, pos);
|
tryFixupBlackHolePos(v, pos);
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,11 @@
|
||||||
|
|
||||||
#include "config.hh"
|
#include "config.hh"
|
||||||
#include "ref.hh"
|
#include "ref.hh"
|
||||||
|
#include "source-path.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
class Store;
|
class EvalState;
|
||||||
|
|
||||||
struct EvalSettings : Config
|
struct EvalSettings : Config
|
||||||
{
|
{
|
||||||
|
|
@ -18,11 +19,8 @@ struct EvalSettings : Config
|
||||||
*
|
*
|
||||||
* The return value is (a) whether the entry was valid, and, if so,
|
* The return value is (a) whether the entry was valid, and, if so,
|
||||||
* what does it map to.
|
* what does it map to.
|
||||||
*
|
|
||||||
* @todo Return (`std::optional` of) `SourceAccssor` or something
|
|
||||||
* more structured instead of mere `std::string`?
|
|
||||||
*/
|
*/
|
||||||
using LookupPathHook = std::optional<std::string>(ref<Store> store, std::string_view);
|
using LookupPathHook = std::optional<SourcePath>(EvalState & state, std::string_view);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map from "scheme" to a `LookupPathHook`.
|
* Map from "scheme" to a `LookupPathHook`.
|
||||||
|
|
|
||||||
|
|
@ -347,6 +347,16 @@ void EvalState::allowPath(const StorePath & storePath)
|
||||||
rootFS2->allowPrefix(CanonPath(store->toRealPath(storePath)));
|
rootFS2->allowPrefix(CanonPath(store->toRealPath(storePath)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EvalState::allowClosure(const StorePath & storePath)
|
||||||
|
{
|
||||||
|
if (!rootFS.dynamic_pointer_cast<AllowListSourceAccessor>()) return;
|
||||||
|
|
||||||
|
StorePathSet closure;
|
||||||
|
store->computeFSClosure(storePath, closure);
|
||||||
|
for (auto & p : closure)
|
||||||
|
allowPath(p);
|
||||||
|
}
|
||||||
|
|
||||||
void EvalState::allowAndSetStorePathString(const StorePath & storePath, Value & v)
|
void EvalState::allowAndSetStorePathString(const StorePath & storePath, Value & v)
|
||||||
{
|
{
|
||||||
allowPath(storePath);
|
allowPath(storePath);
|
||||||
|
|
@ -396,7 +406,7 @@ void EvalState::checkURI(const std::string & uri)
|
||||||
|
|
||||||
/* If the URI is a path, then check it against allowedPaths as
|
/* If the URI is a path, then check it against allowedPaths as
|
||||||
well. */
|
well. */
|
||||||
if (hasPrefix(uri, "/")) {
|
if (isAbsolute(uri)) {
|
||||||
if (auto rootFS2 = rootFS.dynamic_pointer_cast<AllowListSourceAccessor>())
|
if (auto rootFS2 = rootFS.dynamic_pointer_cast<AllowListSourceAccessor>())
|
||||||
rootFS2->checkAccess(CanonPath(uri));
|
rootFS2->checkAccess(CanonPath(uri));
|
||||||
return;
|
return;
|
||||||
|
|
@ -448,7 +458,7 @@ void EvalState::addConstant(const std::string & name, Value * v, Constant info)
|
||||||
/* Install value the base environment. */
|
/* Install value the base environment. */
|
||||||
staticBaseEnv->vars.emplace_back(symbols.create(name), baseEnvDispl);
|
staticBaseEnv->vars.emplace_back(symbols.create(name), baseEnvDispl);
|
||||||
baseEnv.values[baseEnvDispl++] = v;
|
baseEnv.values[baseEnvDispl++] = v;
|
||||||
baseEnv.values[0]->payload.attrs->push_back(Attr(symbols.create(name2), v));
|
getBuiltins().payload.attrs->push_back(Attr(symbols.create(name2), v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -516,16 +526,26 @@ Value * EvalState::addPrimOp(PrimOp && primOp)
|
||||||
else {
|
else {
|
||||||
staticBaseEnv->vars.emplace_back(envName, baseEnvDispl);
|
staticBaseEnv->vars.emplace_back(envName, baseEnvDispl);
|
||||||
baseEnv.values[baseEnvDispl++] = v;
|
baseEnv.values[baseEnvDispl++] = v;
|
||||||
baseEnv.values[0]->payload.attrs->push_back(Attr(symbols.create(primOp.name), v));
|
getBuiltins().payload.attrs->push_back(Attr(symbols.create(primOp.name), v));
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Value & EvalState::getBuiltins()
|
||||||
|
{
|
||||||
|
return *baseEnv.values[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Value & EvalState::getBuiltin(const std::string & name)
|
Value & EvalState::getBuiltin(const std::string & name)
|
||||||
{
|
{
|
||||||
return *baseEnv.values[0]->attrs()->find(symbols.create(name))->value;
|
auto it = getBuiltins().attrs()->get(symbols.create(name));
|
||||||
|
if (it)
|
||||||
|
return *it->value;
|
||||||
|
else
|
||||||
|
error<EvalError>("builtin '%1%' not found", name).debugThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -588,14 +608,14 @@ std::optional<EvalState::Doc> EvalState::getDoc(Value & v)
|
||||||
if (isFunctor(v)) {
|
if (isFunctor(v)) {
|
||||||
try {
|
try {
|
||||||
Value & functor = *v.attrs()->find(sFunctor)->value;
|
Value & functor = *v.attrs()->find(sFunctor)->value;
|
||||||
Value * vp = &v;
|
Value * vp[] = {&v};
|
||||||
Value partiallyApplied;
|
Value partiallyApplied;
|
||||||
// The first paramater is not user-provided, and may be
|
// 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;
|
// 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
|
// So preferably we show docs that are relevant to the
|
||||||
// "partially applied" function returned by e.g. `const`.
|
// "partially applied" function returned by e.g. `const`.
|
||||||
// We apply the first argument:
|
// We apply the first argument:
|
||||||
callFunction(functor, 1, &vp, partiallyApplied, noPos);
|
callFunction(functor, vp, partiallyApplied, noPos);
|
||||||
auto _level = addCallDepth(noPos);
|
auto _level = addCallDepth(noPos);
|
||||||
return getDoc(partiallyApplied);
|
return getDoc(partiallyApplied);
|
||||||
}
|
}
|
||||||
|
|
@ -1460,7 +1480,7 @@ void ExprLambda::eval(EvalState & state, Env & env, Value & v)
|
||||||
v.mkLambda(&env, this);
|
v.mkLambda(&env, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & vRes, const PosIdx pos)
|
void EvalState::callFunction(Value & fun, std::span<Value *> args, Value & vRes, const PosIdx pos)
|
||||||
{
|
{
|
||||||
auto _level = addCallDepth(pos);
|
auto _level = addCallDepth(pos);
|
||||||
|
|
||||||
|
|
@ -1475,16 +1495,16 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
auto makeAppChain = [&]()
|
auto makeAppChain = [&]()
|
||||||
{
|
{
|
||||||
vRes = vCur;
|
vRes = vCur;
|
||||||
for (size_t i = 0; i < nrArgs; ++i) {
|
for (auto arg : args) {
|
||||||
auto fun2 = allocValue();
|
auto fun2 = allocValue();
|
||||||
*fun2 = vRes;
|
*fun2 = vRes;
|
||||||
vRes.mkPrimOpApp(fun2, args[i]);
|
vRes.mkPrimOpApp(fun2, arg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const Attr * functor;
|
const Attr * functor;
|
||||||
|
|
||||||
while (nrArgs > 0) {
|
while (args.size() > 0) {
|
||||||
|
|
||||||
if (vCur.isLambda()) {
|
if (vCur.isLambda()) {
|
||||||
|
|
||||||
|
|
@ -1587,15 +1607,14 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
nrArgs--;
|
args = args.subspan(1);
|
||||||
args += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (vCur.isPrimOp()) {
|
else if (vCur.isPrimOp()) {
|
||||||
|
|
||||||
size_t argsLeft = vCur.primOp()->arity;
|
size_t argsLeft = vCur.primOp()->arity;
|
||||||
|
|
||||||
if (nrArgs < argsLeft) {
|
if (args.size() < argsLeft) {
|
||||||
/* We don't have enough arguments, so create a tPrimOpApp chain. */
|
/* We don't have enough arguments, so create a tPrimOpApp chain. */
|
||||||
makeAppChain();
|
makeAppChain();
|
||||||
return;
|
return;
|
||||||
|
|
@ -1607,15 +1626,14 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
if (countCalls) primOpCalls[fn->name]++;
|
if (countCalls) primOpCalls[fn->name]++;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fn->fun(*this, vCur.determinePos(noPos), args, vCur);
|
fn->fun(*this, vCur.determinePos(noPos), args.data(), vCur);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
if (fn->addTrace)
|
if (fn->addTrace)
|
||||||
addErrorTrace(e, pos, "while calling the '%1%' builtin", fn->name);
|
addErrorTrace(e, pos, "while calling the '%1%' builtin", fn->name);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
nrArgs -= argsLeft;
|
args = args.subspan(argsLeft);
|
||||||
args += argsLeft;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1631,7 +1649,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
auto arity = primOp->primOp()->arity;
|
auto arity = primOp->primOp()->arity;
|
||||||
auto argsLeft = arity - argsDone;
|
auto argsLeft = arity - argsDone;
|
||||||
|
|
||||||
if (nrArgs < argsLeft) {
|
if (args.size() < argsLeft) {
|
||||||
/* We still don't have enough arguments, so extend the tPrimOpApp chain. */
|
/* We still don't have enough arguments, so extend the tPrimOpApp chain. */
|
||||||
makeAppChain();
|
makeAppChain();
|
||||||
return;
|
return;
|
||||||
|
|
@ -1663,8 +1681,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
nrArgs -= argsLeft;
|
args = args.subspan(argsLeft);
|
||||||
args += argsLeft;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1675,13 +1692,12 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
Value * args2[] = {allocValue(), args[0]};
|
Value * args2[] = {allocValue(), args[0]};
|
||||||
*args2[0] = vCur;
|
*args2[0] = vCur;
|
||||||
try {
|
try {
|
||||||
callFunction(*functor->value, 2, args2, vCur, functor->pos);
|
callFunction(*functor->value, args2, vCur, functor->pos);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(positions[pos], "while calling a functor (an attribute set with a '__functor' attribute)");
|
e.addTrace(positions[pos], "while calling a functor (an attribute set with a '__functor' attribute)");
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
nrArgs--;
|
args = args.subspan(1);
|
||||||
args++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
@ -1724,7 +1740,7 @@ void ExprCall::eval(EvalState & state, Env & env, Value & v)
|
||||||
for (size_t i = 0; i < args.size(); ++i)
|
for (size_t i = 0; i < args.size(); ++i)
|
||||||
vArgs[i] = args[i]->maybeThunk(state, env);
|
vArgs[i] = args[i]->maybeThunk(state, env);
|
||||||
|
|
||||||
state.callFunction(vFun, args.size(), vArgs.data(), v, pos);
|
state.callFunction(vFun, vArgs, v, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2046,9 +2062,12 @@ void ExprPos::eval(EvalState & state, Env & env, Value & v)
|
||||||
state.mkPos(v, pos);
|
state.mkPos(v, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExprBlackHole::eval(EvalState & state, [[maybe_unused]] Env & env, Value & v)
|
||||||
void ExprBlackHole::eval(EvalState & state, Env & env, Value & v)
|
|
||||||
{
|
{
|
||||||
|
throwInfiniteRecursionError(state, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[gnu::noinline]] [[noreturn]] void ExprBlackHole::throwInfiniteRecursionError(EvalState & state, Value &v) {
|
||||||
state.error<InfiniteRecursionError>("infinite recursion encountered")
|
state.error<InfiniteRecursionError>("infinite recursion encountered")
|
||||||
.atPos(v.determinePos(noPos))
|
.atPos(v.determinePos(noPos))
|
||||||
.debugThrow();
|
.debugThrow();
|
||||||
|
|
@ -3029,8 +3048,8 @@ SourcePath EvalState::findFile(const LookupPath & lookupPath, const std::string_
|
||||||
if (!rOpt) continue;
|
if (!rOpt) continue;
|
||||||
auto r = *rOpt;
|
auto r = *rOpt;
|
||||||
|
|
||||||
Path res = suffix == "" ? r : concatStrings(r, "/", suffix);
|
auto res = (r / CanonPath(suffix)).resolveSymlinks();
|
||||||
if (pathExists(res)) return rootPath(CanonPath(canonPath(res)));
|
if (res.pathExists()) return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasPrefix(path, "nix/"))
|
if (hasPrefix(path, "nix/"))
|
||||||
|
|
@ -3045,13 +3064,13 @@ SourcePath EvalState::findFile(const LookupPath & lookupPath, const std::string_
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::optional<std::string> EvalState::resolveLookupPathPath(const LookupPath::Path & value0, bool initAccessControl)
|
std::optional<SourcePath> EvalState::resolveLookupPathPath(const LookupPath::Path & value0, bool initAccessControl)
|
||||||
{
|
{
|
||||||
auto & value = value0.s;
|
auto & value = value0.s;
|
||||||
auto i = lookupPathResolved.find(value);
|
auto i = lookupPathResolved.find(value);
|
||||||
if (i != lookupPathResolved.end()) return i->second;
|
if (i != lookupPathResolved.end()) return i->second;
|
||||||
|
|
||||||
auto finish = [&](std::string res) {
|
auto finish = [&](SourcePath res) {
|
||||||
debug("resolved search path element '%s' to '%s'", value, res);
|
debug("resolved search path element '%s' to '%s'", value, res);
|
||||||
lookupPathResolved.emplace(value, res);
|
lookupPathResolved.emplace(value, res);
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -3064,7 +3083,7 @@ std::optional<std::string> EvalState::resolveLookupPathPath(const LookupPath::Pa
|
||||||
fetchSettings,
|
fetchSettings,
|
||||||
EvalSettings::resolvePseudoUrl(value));
|
EvalSettings::resolvePseudoUrl(value));
|
||||||
auto storePath = fetchToStore(*store, SourcePath(accessor), FetchMode::Copy);
|
auto storePath = fetchToStore(*store, SourcePath(accessor), FetchMode::Copy);
|
||||||
return finish(store->toRealPath(storePath));
|
return finish(rootPath(store->toRealPath(storePath)));
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
logWarning({
|
logWarning({
|
||||||
.msg = HintFmt("Nix search path entry '%1%' cannot be downloaded, ignoring", value)
|
.msg = HintFmt("Nix search path entry '%1%' cannot be downloaded, ignoring", value)
|
||||||
|
|
@ -3076,29 +3095,26 @@ std::optional<std::string> EvalState::resolveLookupPathPath(const LookupPath::Pa
|
||||||
auto scheme = value.substr(0, colPos);
|
auto scheme = value.substr(0, colPos);
|
||||||
auto rest = value.substr(colPos + 1);
|
auto rest = value.substr(colPos + 1);
|
||||||
if (auto * hook = get(settings.lookupPathHooks, scheme)) {
|
if (auto * hook = get(settings.lookupPathHooks, scheme)) {
|
||||||
auto res = (*hook)(store, rest);
|
auto res = (*hook)(*this, rest);
|
||||||
if (res)
|
if (res)
|
||||||
return finish(std::move(*res));
|
return finish(std::move(*res));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto path = absPath(value);
|
auto path = rootPath(value);
|
||||||
|
|
||||||
/* Allow access to paths in the search path. */
|
/* Allow access to paths in the search path. */
|
||||||
if (initAccessControl) {
|
if (initAccessControl) {
|
||||||
allowPath(path);
|
allowPath(path.path.abs());
|
||||||
if (store->isInStore(path)) {
|
if (store->isInStore(path.path.abs())) {
|
||||||
try {
|
try {
|
||||||
StorePathSet closure;
|
allowClosure(store->toStorePath(path.path.abs()).first);
|
||||||
store->computeFSClosure(store->toStorePath(path).first, closure);
|
|
||||||
for (auto & p : closure)
|
|
||||||
allowPath(p);
|
|
||||||
} catch (InvalidPath &) { }
|
} catch (InvalidPath &) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pathExists(path))
|
if (path.pathExists())
|
||||||
return finish(std::move(path));
|
return finish(std::move(path));
|
||||||
else {
|
else {
|
||||||
logWarning({
|
logWarning({
|
||||||
|
|
@ -3109,7 +3125,6 @@ std::optional<std::string> EvalState::resolveLookupPathPath(const LookupPath::Pa
|
||||||
|
|
||||||
debug("failed to resolve search path element '%s'", value);
|
debug("failed to resolve search path element '%s'", value);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -3170,5 +3185,18 @@ std::ostream & operator << (std::ostream & str, const ExternalValueBase & v) {
|
||||||
return v.print(str);
|
return v.print(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void forceNoNullByte(std::string_view s, std::function<Pos()> pos)
|
||||||
|
{
|
||||||
|
if (s.find('\0') != s.npos) {
|
||||||
|
using namespace std::string_view_literals;
|
||||||
|
auto str = replaceStrings(std::string(s), "\0"sv, "␀"sv);
|
||||||
|
Error error("input string '%s' cannot be represented as Nix string because it contains null bytes", str);
|
||||||
|
if (pos) {
|
||||||
|
error.atPos(pos());
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -347,7 +347,7 @@ private:
|
||||||
|
|
||||||
LookupPath lookupPath;
|
LookupPath lookupPath;
|
||||||
|
|
||||||
std::map<std::string, std::optional<std::string>> lookupPathResolved;
|
std::map<std::string, std::optional<SourcePath>> lookupPathResolved;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache used by prim_match().
|
* Cache used by prim_match().
|
||||||
|
|
@ -400,6 +400,11 @@ public:
|
||||||
*/
|
*/
|
||||||
void allowPath(const StorePath & storePath);
|
void allowPath(const StorePath & storePath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow access to the closure of a store path.
|
||||||
|
*/
|
||||||
|
void allowClosure(const StorePath & storePath);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow access to a store path and return it as a string.
|
* Allow access to a store path and return it as a string.
|
||||||
*/
|
*/
|
||||||
|
|
@ -452,9 +457,9 @@ public:
|
||||||
*
|
*
|
||||||
* If the specified search path element is a URI, download it.
|
* 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<std::string> resolveLookupPathPath(
|
std::optional<SourcePath> resolveLookupPathPath(
|
||||||
const LookupPath::Path & elem,
|
const LookupPath::Path & elem,
|
||||||
bool initAccessControl = false);
|
bool initAccessControl = false);
|
||||||
|
|
||||||
|
|
@ -623,8 +628,19 @@ private:
|
||||||
|
|
||||||
public:
|
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);
|
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
|
struct Doc
|
||||||
{
|
{
|
||||||
Pos pos;
|
Pos pos;
|
||||||
|
|
@ -690,13 +706,12 @@ public:
|
||||||
|
|
||||||
bool isFunctor(Value & fun);
|
bool isFunctor(Value & fun);
|
||||||
|
|
||||||
// FIXME: use std::span
|
void callFunction(Value & fun, std::span<Value *> args, Value & vRes, const PosIdx pos);
|
||||||
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)
|
void callFunction(Value & fun, Value & arg, Value & vRes, const PosIdx pos)
|
||||||
{
|
{
|
||||||
Value * args[] = {&arg};
|
Value * args[] = {&arg};
|
||||||
callFunction(fun, 1, args, vRes, pos);
|
callFunction(fun, args, vRes, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -809,7 +824,6 @@ public:
|
||||||
bool callPathFilter(
|
bool callPathFilter(
|
||||||
Value * filterFun,
|
Value * filterFun,
|
||||||
const SourcePath & path,
|
const SourcePath & path,
|
||||||
std::string_view pathArg,
|
|
||||||
PosIdx pos);
|
PosIdx pos);
|
||||||
|
|
||||||
DocComment getDocCommentForPos(PosIdx pos);
|
DocComment getDocCommentForPos(PosIdx pos);
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ class JSONSax : nlohmann::json_sax<json> {
|
||||||
public:
|
public:
|
||||||
void key(string_t & name, EvalState & state)
|
void key(string_t & name, EvalState & state)
|
||||||
{
|
{
|
||||||
|
forceNoNullByte(name);
|
||||||
attrs.insert_or_assign(state.symbols.create(name), &value(state));
|
attrs.insert_or_assign(state.symbols.create(name), &value(state));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -122,6 +123,7 @@ public:
|
||||||
|
|
||||||
bool string(string_t & val) override
|
bool string(string_t & val) override
|
||||||
{
|
{
|
||||||
|
forceNoNullByte(val);
|
||||||
rs->value(state).mkString(val);
|
rs->value(state).mkString(val);
|
||||||
rs->add();
|
rs->add();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
// inluding the generated headers twice leads to errors
|
||||||
|
#ifndef BISON_HEADER
|
||||||
|
# include "lexer-tab.hh"
|
||||||
|
# include "parser-tab.hh"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace nix::lexer::internal {
|
namespace nix::lexer::internal {
|
||||||
|
|
||||||
void initLoc(YYLTYPE * loc);
|
void initLoc(YYLTYPE * loc);
|
||||||
|
|
|
||||||
|
|
@ -41,16 +41,18 @@ namespace nix {
|
||||||
|
|
||||||
// we make use of the fact that the parser receives a private copy of the input
|
// we make use of the fact that the parser receives a private copy of the input
|
||||||
// string and can munge around in it.
|
// string and can munge around in it.
|
||||||
static StringToken unescapeStr(SymbolTable & symbols, char * s, size_t length)
|
// getting the position is expensive and thus it is implemented lazily.
|
||||||
|
static StringToken unescapeStr(char * const s, size_t length, std::function<Pos()> && pos)
|
||||||
{
|
{
|
||||||
char * result = s;
|
bool noNullByte = true;
|
||||||
char * t = s;
|
char * t = s;
|
||||||
char c;
|
|
||||||
// the input string is terminated with *two* NULs, so we can safely take
|
// the input string is terminated with *two* NULs, so we can safely take
|
||||||
// *one* character after the one being checked against.
|
// *one* character after the one being checked against.
|
||||||
while ((c = *s++)) {
|
for (size_t i = 0; i < length; t++) {
|
||||||
|
char c = s[i++];
|
||||||
|
noNullByte &= c != '\0';
|
||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
c = *s++;
|
c = s[i++];
|
||||||
if (c == 'n') *t = '\n';
|
if (c == 'n') *t = '\n';
|
||||||
else if (c == 'r') *t = '\r';
|
else if (c == 'r') *t = '\r';
|
||||||
else if (c == 't') *t = '\t';
|
else if (c == 't') *t = '\t';
|
||||||
|
|
@ -59,12 +61,14 @@ static StringToken unescapeStr(SymbolTable & symbols, char * s, size_t length)
|
||||||
else if (c == '\r') {
|
else if (c == '\r') {
|
||||||
/* Normalise CR and CR/LF into LF. */
|
/* Normalise CR and CR/LF into LF. */
|
||||||
*t = '\n';
|
*t = '\n';
|
||||||
if (*s == '\n') s++; /* cr/lf */
|
if (s[i] == '\n') i++; /* cr/lf */
|
||||||
}
|
}
|
||||||
else *t = c;
|
else *t = c;
|
||||||
t++;
|
|
||||||
}
|
}
|
||||||
return {result, size_t(t - result)};
|
if (!noNullByte) {
|
||||||
|
forceNoNullByte({s, size_t(t - s)}, std::move(pos));
|
||||||
|
}
|
||||||
|
return {s, size_t(t - s)};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void requireExperimentalFeature(const ExperimentalFeature & feature, const Pos & pos)
|
static void requireExperimentalFeature(const ExperimentalFeature & feature, const Pos & pos)
|
||||||
|
|
@ -175,7 +179,7 @@ or { return OR_KW; }
|
||||||
/* It is impossible to match strings ending with '$' with one
|
/* It is impossible to match strings ending with '$' with one
|
||||||
regex because trailing contexts are only valid at the end
|
regex because trailing contexts are only valid at the end
|
||||||
of a rule. (A sane but undocumented limitation.) */
|
of a rule. (A sane but undocumented limitation.) */
|
||||||
yylval->str = unescapeStr(state->symbols, yytext, yyleng);
|
yylval->str = unescapeStr(yytext, yyleng, [&]() { return state->positions[CUR_POS]; });
|
||||||
return STR;
|
return STR;
|
||||||
}
|
}
|
||||||
<STRING>\$\{ { PUSH_STATE(DEFAULT); return DOLLAR_CURLY; }
|
<STRING>\$\{ { PUSH_STATE(DEFAULT); return DOLLAR_CURLY; }
|
||||||
|
|
@ -191,6 +195,7 @@ or { return OR_KW; }
|
||||||
\'\'(\ *\n)? { PUSH_STATE(IND_STRING); return IND_STRING_OPEN; }
|
\'\'(\ *\n)? { PUSH_STATE(IND_STRING); return IND_STRING_OPEN; }
|
||||||
<IND_STRING>([^\$\']|\$[^\{\']|\'[^\'\$])+ {
|
<IND_STRING>([^\$\']|\$[^\{\']|\'[^\'\$])+ {
|
||||||
yylval->str = {yytext, (size_t) yyleng, true};
|
yylval->str = {yytext, (size_t) yyleng, true};
|
||||||
|
forceNoNullByte(yylval->str, [&]() { return state->positions[CUR_POS]; });
|
||||||
return IND_STR;
|
return IND_STR;
|
||||||
}
|
}
|
||||||
<IND_STRING>\'\'\$ |
|
<IND_STRING>\'\'\$ |
|
||||||
|
|
@ -203,7 +208,7 @@ or { return OR_KW; }
|
||||||
return IND_STR;
|
return IND_STR;
|
||||||
}
|
}
|
||||||
<IND_STRING>\'\'\\{ANY} {
|
<IND_STRING>\'\'\\{ANY} {
|
||||||
yylval->str = unescapeStr(state->symbols, yytext + 2, yyleng - 2);
|
yylval->str = unescapeStr(yytext + 2, yyleng - 2, [&]() { return state->positions[CUR_POS]; });
|
||||||
return IND_STR;
|
return IND_STR;
|
||||||
}
|
}
|
||||||
<IND_STRING>\$\{ { PUSH_STATE(DEFAULT); return DOLLAR_CURLY; }
|
<IND_STRING>\$\{ { PUSH_STATE(DEFAULT); return DOLLAR_CURLY; }
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,6 @@ project('nix-expr', 'cpp',
|
||||||
'cpp_std=c++2a',
|
'cpp_std=c++2a',
|
||||||
# TODO(Qyriad): increase the warning level
|
# TODO(Qyriad): increase the warning level
|
||||||
'warning_level=1',
|
'warning_level=1',
|
||||||
'debug=true',
|
|
||||||
'optimization=2',
|
|
||||||
'errorlogs=true', # Please print logs for tests that fail
|
'errorlogs=true', # Please print logs for tests that fail
|
||||||
],
|
],
|
||||||
meson_version : '>= 1.1',
|
meson_version : '>= 1.1',
|
||||||
|
|
@ -14,7 +12,7 @@ project('nix-expr', 'cpp',
|
||||||
|
|
||||||
cxx = meson.get_compiler('cpp')
|
cxx = meson.get_compiler('cpp')
|
||||||
|
|
||||||
subdir('build-utils-meson/deps-lists')
|
subdir('nix-meson-build-support/deps-lists')
|
||||||
|
|
||||||
configdata = configuration_data()
|
configdata = configuration_data()
|
||||||
|
|
||||||
|
|
@ -25,9 +23,7 @@ deps_public_maybe_subproject = [
|
||||||
dependency('nix-store'),
|
dependency('nix-store'),
|
||||||
dependency('nix-fetchers'),
|
dependency('nix-fetchers'),
|
||||||
]
|
]
|
||||||
subdir('build-utils-meson/subprojects')
|
subdir('nix-meson-build-support/subprojects')
|
||||||
|
|
||||||
subdir('build-utils-meson/threads')
|
|
||||||
|
|
||||||
boost = dependency(
|
boost = dependency(
|
||||||
'boost',
|
'boost',
|
||||||
|
|
@ -79,7 +75,7 @@ add_project_arguments(
|
||||||
language : 'cpp',
|
language : 'cpp',
|
||||||
)
|
)
|
||||||
|
|
||||||
subdir('build-utils-meson/diagnostics')
|
subdir('nix-meson-build-support/common')
|
||||||
|
|
||||||
parser_tab = custom_target(
|
parser_tab = custom_target(
|
||||||
input : 'parser.y',
|
input : 'parser.y',
|
||||||
|
|
@ -123,7 +119,7 @@ lexer_tab = custom_target(
|
||||||
install_dir : get_option('includedir') / 'nix',
|
install_dir : get_option('includedir') / 'nix',
|
||||||
)
|
)
|
||||||
|
|
||||||
subdir('build-utils-meson/generate-header')
|
subdir('nix-meson-build-support/generate-header')
|
||||||
|
|
||||||
generated_headers = []
|
generated_headers = []
|
||||||
foreach header : [
|
foreach header : [
|
||||||
|
|
@ -207,4 +203,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
|
||||||
|
|
||||||
libraries_private = []
|
libraries_private = []
|
||||||
|
|
||||||
subdir('build-utils-meson/export')
|
subdir('nix-meson-build-support/export')
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue