Compare commits
180 Commits
directory-
...
2.25-maint
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38de6fbe38 | ||
|
|
0f181346e4 | ||
|
|
d41420c184 | ||
|
|
89028b3388 | ||
|
|
257b660483 | ||
|
|
23cd3720c0 | ||
|
|
4c2259b5fe | ||
|
|
0fb8157642 | ||
|
|
2710d238da | ||
|
|
dcca4fd4bb | ||
|
|
1d162593be | ||
|
|
0823a0c6e1 | ||
|
|
b7c8d5246e | ||
|
|
7eaf8ec028 | ||
|
|
fd86343b89 | ||
|
|
7e9be2b924 | ||
|
|
76098180d2 | ||
|
|
e1c559b27a | ||
|
|
ef12785644 | ||
|
|
cf7d72c733 | ||
|
|
336d07397d | ||
|
|
7be9829896 | ||
|
|
a00b385d2a | ||
|
|
9883341ea8 | ||
|
|
1130be437b | ||
|
|
7fab0741d8 | ||
|
|
43286afc8c | ||
|
|
d87e46cfeb | ||
|
|
40f33b5e17 | ||
|
|
807d186289 | ||
|
|
d99bcd62eb | ||
|
|
a5fa357fdf | ||
|
|
9e7663fe38 | ||
|
|
e2558b8c26 | ||
|
|
9442b9bd7b | ||
|
|
c03bde0133 | ||
|
|
d652513e45 | ||
|
|
4aba8ad022 | ||
|
|
d856328ab5 | ||
|
|
9e83b1aa19 | ||
|
|
a0fb43e229 | ||
|
|
7bfd71e10d | ||
|
|
37393f0c69 | ||
|
|
7d3021f59f | ||
|
|
95253b1f7c | ||
|
|
3fd1316438 | ||
|
|
79a2993e23 | ||
|
|
c69579114b | ||
|
|
24c78e06cf | ||
|
|
566b33b0bd | ||
|
|
6224d87564 | ||
|
|
636c9cfdf0 | ||
|
|
e64fcf62f9 | ||
|
|
08d4e67e84 | ||
|
|
5d2f26e3f6 | ||
|
|
132c992ce0 | ||
|
|
0284eef493 | ||
|
|
df5246dd8e | ||
|
|
8b205302f3 | ||
|
|
8e87c19125 | ||
|
|
c38234bffb | ||
|
|
4d0e2b5ade | ||
|
|
aabf6e6c65 | ||
|
|
7dd6b980aa | ||
|
|
daf101d487 | ||
|
|
938f0f4fd9 | ||
|
|
40bb5ec675 | ||
|
|
98506a5ef1 | ||
|
|
639f526405 | ||
|
|
0b57e7daf5 | ||
|
|
dcfd80610b | ||
|
|
4fea745fe0 | ||
|
|
335e0d9508 | ||
|
|
6963fd4027 | ||
|
|
b8264c4c54 | ||
|
|
30ef0a1f4c | ||
|
|
50a7056b02 | ||
|
|
4c35e6ec6e | ||
|
|
3f96cfd99c | ||
|
|
5b32a021a9 | ||
|
|
cadd9fbe88 | ||
|
|
0ccd1fa0a4 | ||
|
|
8615df48a1 | ||
|
|
6b03f1219e | ||
|
|
08cd0acf65 | ||
|
|
40e35dc567 | ||
|
|
1521a82077 | ||
|
|
009de1f7ac | ||
|
|
7a7a3d20d1 | ||
|
|
70ab8bbb28 | ||
|
|
c902a299a8 | ||
|
|
dee91873bc | ||
|
|
31d6afb476 | ||
|
|
ef1e704707 | ||
|
|
21fe544ed9 | ||
|
|
e1178b8a39 | ||
|
|
31fa189123 | ||
|
|
faecb6e306 | ||
|
|
200e3be41a | ||
|
|
8856b5f2ca | ||
|
|
aa5246bfe3 | ||
|
|
8b4a89f4bb | ||
|
|
ab4159ff99 | ||
|
|
b9f89c846d | ||
|
|
5575a2f1c3 | ||
|
|
2cb2fbbca7 | ||
|
|
6e9281be6d | ||
|
|
4e990b0bcb | ||
|
|
8f5ea8b8ca | ||
|
|
f8999cd4ee | ||
|
|
6aaf623058 | ||
|
|
24a9c6fad9 | ||
|
|
d54c283821 | ||
|
|
bead70acc2 | ||
|
|
4bf020de50 | ||
|
|
6b5b538d98 | ||
|
|
85a4f62400 | ||
|
|
f9fc7fea5c | ||
|
|
e67cf5f306 | ||
|
|
336fdaa119 | ||
|
|
b0784dd69b | ||
|
|
7c4e2fdfd7 | ||
|
|
3fbcd8d7ba | ||
|
|
fdd61cf529 | ||
|
|
6d7ef8f29d | ||
|
|
255379daf1 | ||
|
|
0213f22650 | ||
|
|
8abff3cf05 | ||
|
|
d910cab254 | ||
|
|
a3522b4696 | ||
|
|
29a8ad18ff | ||
|
|
2d63629ed0 | ||
|
|
92b14e072f | ||
|
|
9a2cf3468c | ||
|
|
c396e24c3a | ||
|
|
f1a4544886 | ||
|
|
bb08cc7cc2 | ||
|
|
51166bb388 | ||
|
|
e467269a44 | ||
|
|
fd087ceec6 | ||
|
|
75b657cf7c | ||
|
|
cdd3e3015d | ||
|
|
79a52afe82 | ||
|
|
fe3c94d5c2 | ||
|
|
9f2df5899c | ||
|
|
2eb816226e | ||
|
|
a867747c05 | ||
|
|
c709ca6e36 | ||
|
|
b1058ee0d2 | ||
|
|
7c98167eab | ||
|
|
c797848b88 | ||
|
|
8a81c2428a | ||
|
|
a5ee9a3e99 | ||
|
|
0a2545b23a | ||
|
|
97f0c68389 | ||
|
|
26741bcfda | ||
|
|
218cd6c16c | ||
|
|
61950c3375 | ||
|
|
282bfbdacb | ||
|
|
14432ea4a2 | ||
|
|
8d51c90872 | ||
|
|
118d50992c | ||
|
|
9f9b2ed48c | ||
|
|
eb50683e81 | ||
|
|
c381199e97 | ||
|
|
072ebeee79 | ||
|
|
3501c737d3 | ||
|
|
12eff94815 | ||
|
|
89f4ac3d2c | ||
|
|
1dbe60e073 | ||
|
|
4e2824ce93 | ||
|
|
3bc3e55736 | ||
|
|
d97ebe519a | ||
|
|
f87f87120a | ||
|
|
5ae53d4730 | ||
|
|
7bc52df684 | ||
|
|
3e883b9eaf | ||
|
|
6b96c66302 | ||
|
|
9213bf55ce | ||
|
|
5c5a737885 |
187
.github/workflows/ci.yml
vendored
187
.github/workflows/ci.yml
vendored
@@ -7,14 +7,28 @@ on:
|
||||
permissions: read-all
|
||||
|
||||
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:
|
||||
needs: [check_secrets]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
include:
|
||||
- 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
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -23,103 +37,54 @@ jobs:
|
||||
- uses: cachix/install-nix-action@v30
|
||||
with:
|
||||
# The sandbox would otherwise be disabled by default on Darwin
|
||||
extra_nix_config: "sandbox = true"
|
||||
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
||||
- uses: cachix/cachix-action@v15
|
||||
if: needs.check_secrets.outputs.cachix == 'true'
|
||||
extra_nix_config: |
|
||||
sandbox = true
|
||||
max-jobs = 1
|
||||
- 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:
|
||||
name: '${{ env.CACHIX_NAME }}'
|
||||
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
||||
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
|
||||
name: installer-${{matrix.os}}
|
||||
path: out/*
|
||||
|
||||
installer_test:
|
||||
needs: [installer, check_secrets]
|
||||
if: github.event_name == 'push' && needs.check_secrets.outputs.cachix == 'true'
|
||||
needs: [tests]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
include:
|
||||
- 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:
|
||||
- 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
|
||||
with:
|
||||
install_url: '${{needs.installer.outputs.installerURL}}'
|
||||
install_options: "--tarball-url-prefix https://${{ env.CACHIX_NAME }}.cachix.org/serve"
|
||||
install_url: 'http://localhost:8126/install'
|
||||
install_options: "--tarball-url-prefix http://localhost:8126/"
|
||||
- run: sudo apt install fish zsh
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
if: matrix.os == 'linux'
|
||||
- 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 sh -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 --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:
|
||||
needs: [check_secrets, tests]
|
||||
needs: [tests, vm_tests, check_secrets]
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
if: >-
|
||||
needs.check_secrets.outputs.docker == 'true' &&
|
||||
github.event_name == 'push' &&
|
||||
github.ref_name == 'master' &&
|
||||
needs.check_secrets.outputs.cachix == 'true' &&
|
||||
needs.check_secrets.outputs.docker == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
github.ref_name == 'master'
|
||||
runs-on: ubuntu-24.04
|
||||
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
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: cachix/install-nix-action@v30
|
||||
with:
|
||||
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
|
||||
- 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: docker load -i ./result/image.tar.gz
|
||||
- run: docker tag nix:$NIX_VERSION ${{ secrets.DOCKERHUB_USERNAME }}/nix:$NIX_VERSION
|
||||
@@ -189,7 +172,7 @@ jobs:
|
||||
docker push $IMAGE_ID:master
|
||||
|
||||
vm_tests:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
@@ -198,7 +181,7 @@ jobs:
|
||||
|
||||
flake_regressions:
|
||||
needs: vm_tests
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout nix
|
||||
uses: actions/checkout@v4
|
||||
|
||||
2
.github/workflows/labels.yml
vendored
2
.github/workflows/labels.yml
vendored
@@ -15,7 +15,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
labels:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
if: github.repository_owner == 'NixOS'
|
||||
steps:
|
||||
- uses: actions/labeler@v5
|
||||
|
||||
@@ -5,8 +5,10 @@ queue_rules:
|
||||
- check-success=installer
|
||||
- check-success=installer_test (macos-latest)
|
||||
- check-success=installer_test (ubuntu-latest)
|
||||
- check-success=tests (macos-latest)
|
||||
- check-success=tests (ubuntu-latest)
|
||||
- check-success=tests on macos
|
||||
- check-success=tests on ubuntu
|
||||
- check-success=installer test on macos
|
||||
- check-success=installer test on ubuntu
|
||||
- check-success=vm_tests
|
||||
merge_method: rebase
|
||||
batch_size: 5
|
||||
|
||||
19
default.nix
19
default.nix
@@ -1,10 +1,9 @@
|
||||
(import
|
||||
(
|
||||
let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in
|
||||
fetchTarball {
|
||||
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
|
||||
sha256 = lock.nodes.flake-compat.locked.narHash;
|
||||
}
|
||||
)
|
||||
{ src = ./.; }
|
||||
).defaultNix
|
||||
(import (
|
||||
let
|
||||
lock = builtins.fromJSON (builtins.readFile ./flake.lock);
|
||||
in
|
||||
fetchTarball {
|
||||
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
|
||||
sha256 = lock.nodes.flake-compat.locked.narHash;
|
||||
}
|
||||
) { src = ./.; }).defaultNix
|
||||
|
||||
@@ -5,7 +5,15 @@ in
|
||||
|
||||
builtinsInfo:
|
||||
let
|
||||
showBuiltin = name: { doc, type ? null, args ? [ ], experimental-feature ? null, impure-only ? false }:
|
||||
showBuiltin =
|
||||
name:
|
||||
{
|
||||
doc,
|
||||
type ? null,
|
||||
args ? [ ],
|
||||
experimental-feature ? null,
|
||||
impure-only ? false,
|
||||
}:
|
||||
let
|
||||
type' = optionalString (type != null) " (${type})";
|
||||
|
||||
|
||||
@@ -32,7 +32,13 @@ let
|
||||
|
||||
commandInfo = fromJSON commandDump;
|
||||
|
||||
showCommand = { command, details, filename, toplevel }:
|
||||
showCommand =
|
||||
{
|
||||
command,
|
||||
details,
|
||||
filename,
|
||||
toplevel,
|
||||
}:
|
||||
let
|
||||
|
||||
result = ''
|
||||
@@ -56,26 +62,27 @@ let
|
||||
${maybeOptions}
|
||||
'';
|
||||
|
||||
showSynopsis = command: args:
|
||||
showSynopsis =
|
||||
command: args:
|
||||
let
|
||||
showArgument = arg: "*${arg.label}*" + optionalString (! arg ? arity) "...";
|
||||
showArgument = arg: "*${arg.label}*" + optionalString (!arg ? arity) "...";
|
||||
arguments = concatStringsSep " " (map showArgument args);
|
||||
in ''
|
||||
in
|
||||
''
|
||||
`${command}` [*option*...] ${arguments}
|
||||
'';
|
||||
|
||||
maybeSubcommands = optionalString (details ? commands && details.commands != {})
|
||||
''
|
||||
where *subcommand* is one of the following:
|
||||
maybeSubcommands = optionalString (details ? commands && details.commands != { }) ''
|
||||
where *subcommand* is one of the following:
|
||||
|
||||
${subcommands}
|
||||
'';
|
||||
${subcommands}
|
||||
'';
|
||||
|
||||
subcommands = if length categories > 1
|
||||
then listCategories
|
||||
else listSubcommands details.commands;
|
||||
subcommands = if length categories > 1 then listCategories else listSubcommands details.commands;
|
||||
|
||||
categories = sort (x: y: x.id < y.id) (unique (map (cmd: cmd.category) (attrValues details.commands)));
|
||||
categories = sort (x: y: x.id < y.id) (
|
||||
unique (map (cmd: cmd.category) (attrValues details.commands))
|
||||
);
|
||||
|
||||
listCategories = concatStrings (map showCategory categories);
|
||||
|
||||
@@ -99,38 +106,39 @@ let
|
||||
|
||||
${allStores}
|
||||
'';
|
||||
index = replaceStrings
|
||||
[ "@store-types@" "./local-store.md" "./local-daemon-store.md" ]
|
||||
[ storesOverview "#local-store" "#local-daemon-store" ]
|
||||
details.doc;
|
||||
index =
|
||||
replaceStrings
|
||||
[ "@store-types@" "./local-store.md" "./local-daemon-store.md" ]
|
||||
[ storesOverview "#local-store" "#local-daemon-store" ]
|
||||
details.doc;
|
||||
storesOverview =
|
||||
let
|
||||
showEntry = store:
|
||||
"- [${store.name}](#${store.slug})";
|
||||
showEntry = store: "- [${store.name}](#${store.slug})";
|
||||
in
|
||||
concatStringsSep "\n" (map showEntry storesList) + "\n";
|
||||
allStores = concatStringsSep "\n" (attrValues storePages);
|
||||
storePages = listToAttrs
|
||||
(map (s: { name = s.filename; value = s.page; }) storesList);
|
||||
storePages = listToAttrs (
|
||||
map (s: {
|
||||
name = s.filename;
|
||||
value = s.page;
|
||||
}) storesList
|
||||
);
|
||||
storesList = showStoreDocs {
|
||||
storeInfo = commandInfo.stores;
|
||||
inherit inlineHTML;
|
||||
};
|
||||
hasInfix = infix: content:
|
||||
hasInfix =
|
||||
infix: content:
|
||||
builtins.stringLength content != builtins.stringLength (replaceStrings [ infix ] [ "" ] content);
|
||||
in
|
||||
optionalString (details ? doc) (
|
||||
# An alternate implementation with builtins.match stack overflowed on some systems.
|
||||
if hasInfix "@store-types@" details.doc
|
||||
then help-stores
|
||||
else details.doc
|
||||
if hasInfix "@store-types@" details.doc then help-stores else details.doc
|
||||
);
|
||||
|
||||
maybeOptions =
|
||||
let
|
||||
allVisibleOptions = filterAttrs
|
||||
(_: o: ! o.hiddenCategory)
|
||||
(details.flags // toplevel.flags);
|
||||
allVisibleOptions = filterAttrs (_: o: !o.hiddenCategory) (details.flags // toplevel.flags);
|
||||
in
|
||||
optionalString (allVisibleOptions != { }) ''
|
||||
# Options
|
||||
@@ -142,55 +150,73 @@ let
|
||||
> See [`man nix.conf`](@docroot@/command-ref/conf-file.md#command-line-flags) for overriding configuration settings with command line flags.
|
||||
'';
|
||||
|
||||
showOptions = inlineHTML: allOptions:
|
||||
showOptions =
|
||||
inlineHTML: allOptions:
|
||||
let
|
||||
showCategory = cat: opts: ''
|
||||
${optionalString (cat != "") "## ${cat}"}
|
||||
|
||||
${concatStringsSep "\n" (attrValues (mapAttrs showOption opts))}
|
||||
'';
|
||||
showOption = name: option:
|
||||
showOption =
|
||||
name: option:
|
||||
let
|
||||
result = trim ''
|
||||
- ${item}
|
||||
|
||||
${option.description}
|
||||
'';
|
||||
item = if inlineHTML
|
||||
then ''<span id="opt-${name}">[`--${name}`](#opt-${name})</span> ${shortName} ${labels}''
|
||||
else "`--${name}` ${shortName} ${labels}";
|
||||
shortName = optionalString
|
||||
(option ? shortName)
|
||||
("/ `-${option.shortName}`");
|
||||
labels = optionalString
|
||||
(option ? labels)
|
||||
(concatStringsSep " " (map (s: "*${s}*") option.labels));
|
||||
in result;
|
||||
categories = mapAttrs
|
||||
# Convert each group from a list of key-value pairs back to an attrset
|
||||
(_: listToAttrs)
|
||||
(groupBy
|
||||
(cmd: cmd.value.category)
|
||||
(attrsToList allOptions));
|
||||
in concatStrings (attrValues (mapAttrs showCategory categories));
|
||||
in squash result;
|
||||
item =
|
||||
if inlineHTML then
|
||||
''<span id="opt-${name}">[`--${name}`](#opt-${name})</span> ${shortName} ${labels}''
|
||||
else
|
||||
"`--${name}` ${shortName} ${labels}";
|
||||
shortName = optionalString (option ? shortName) ("/ `-${option.shortName}`");
|
||||
labels = optionalString (option ? labels) (concatStringsSep " " (map (s: "*${s}*") option.labels));
|
||||
in
|
||||
result;
|
||||
categories =
|
||||
mapAttrs
|
||||
# Convert each group from a list of key-value pairs back to an attrset
|
||||
(_: listToAttrs)
|
||||
(groupBy (cmd: cmd.value.category) (attrsToList allOptions));
|
||||
in
|
||||
concatStrings (attrValues (mapAttrs showCategory categories));
|
||||
in
|
||||
squash result;
|
||||
|
||||
appendName = filename: name: (if filename == "nix" then "nix3" else filename) + "-" + name;
|
||||
|
||||
processCommand = { command, details, filename, toplevel }:
|
||||
processCommand =
|
||||
{
|
||||
command,
|
||||
details,
|
||||
filename,
|
||||
toplevel,
|
||||
}:
|
||||
let
|
||||
cmd = {
|
||||
inherit command;
|
||||
name = filename + ".md";
|
||||
value = showCommand { inherit command details filename toplevel; };
|
||||
value = showCommand {
|
||||
inherit
|
||||
command
|
||||
details
|
||||
filename
|
||||
toplevel
|
||||
;
|
||||
};
|
||||
};
|
||||
subcommand = subCmd: processCommand {
|
||||
command = command + " " + subCmd;
|
||||
details = details.commands.${subCmd};
|
||||
filename = appendName filename subCmd;
|
||||
inherit toplevel;
|
||||
};
|
||||
in [ cmd ] ++ concatMap subcommand (attrNames details.commands or {});
|
||||
subcommand =
|
||||
subCmd:
|
||||
processCommand {
|
||||
command = command + " " + subCmd;
|
||||
details = details.commands.${subCmd};
|
||||
filename = appendName filename subCmd;
|
||||
inherit toplevel;
|
||||
};
|
||||
in
|
||||
[ cmd ] ++ concatMap subcommand (attrNames details.commands or { });
|
||||
|
||||
manpages = processCommand {
|
||||
command = "nix";
|
||||
@@ -199,9 +225,11 @@ let
|
||||
toplevel = commandInfo.args;
|
||||
};
|
||||
|
||||
tableOfContents = let
|
||||
showEntry = page:
|
||||
" - [${page.command}](command-ref/new-cli/${page.name})";
|
||||
in concatStringsSep "\n" (map showEntry manpages) + "\n";
|
||||
tableOfContents =
|
||||
let
|
||||
showEntry = page: " - [${page.command}](command-ref/new-cli/${page.name})";
|
||||
in
|
||||
concatStringsSep "\n" (map showEntry manpages) + "\n";
|
||||
|
||||
in (listToAttrs manpages) // { "SUMMARY.md" = tableOfContents; }
|
||||
in
|
||||
(listToAttrs manpages) // { "SUMMARY.md" = tableOfContents; }
|
||||
|
||||
@@ -1,67 +1,99 @@
|
||||
let
|
||||
inherit (builtins) attrValues concatStringsSep isAttrs isBool mapAttrs;
|
||||
inherit (import <nix/utils.nix>) concatStrings indent optionalString squash;
|
||||
inherit (builtins)
|
||||
attrValues
|
||||
concatStringsSep
|
||||
isAttrs
|
||||
isBool
|
||||
mapAttrs
|
||||
;
|
||||
inherit (import <nix/utils.nix>)
|
||||
concatStrings
|
||||
indent
|
||||
optionalString
|
||||
squash
|
||||
;
|
||||
in
|
||||
|
||||
# `inlineHTML` is a hack to accommodate inconsistent output from `lowdown`
|
||||
{ prefix, inlineHTML ? true }: settingsInfo:
|
||||
{
|
||||
prefix,
|
||||
inlineHTML ? true,
|
||||
}:
|
||||
settingsInfo:
|
||||
|
||||
let
|
||||
|
||||
showSetting = prefix: setting: { description, documentDefault, defaultValue, aliases, value, experimentalFeature }:
|
||||
showSetting =
|
||||
prefix: setting:
|
||||
{
|
||||
description,
|
||||
documentDefault,
|
||||
defaultValue,
|
||||
aliases,
|
||||
value,
|
||||
experimentalFeature,
|
||||
}:
|
||||
let
|
||||
result = squash ''
|
||||
- ${item}
|
||||
- ${item}
|
||||
|
||||
${indent " " body}
|
||||
'';
|
||||
item = if inlineHTML
|
||||
then ''<span id="${prefix}-${setting}">[`${setting}`](#${prefix}-${setting})</span>''
|
||||
else "`${setting}`";
|
||||
${indent " " body}
|
||||
'';
|
||||
item =
|
||||
if inlineHTML then
|
||||
''<span id="${prefix}-${setting}">[`${setting}`](#${prefix}-${setting})</span>''
|
||||
else
|
||||
"`${setting}`";
|
||||
# separate body to cleanly handle indentation
|
||||
body = ''
|
||||
${experimentalFeatureNote}
|
||||
${experimentalFeatureNote}
|
||||
|
||||
${description}
|
||||
${description}
|
||||
|
||||
**Default:** ${showDefault documentDefault defaultValue}
|
||||
**Default:** ${showDefault documentDefault defaultValue}
|
||||
|
||||
${showAliases aliases}
|
||||
'';
|
||||
${showAliases aliases}
|
||||
'';
|
||||
|
||||
experimentalFeatureNote = optionalString (experimentalFeature != null) ''
|
||||
> **Warning**
|
||||
>
|
||||
> This setting is part of an
|
||||
> [experimental feature](@docroot@/development/experimental-features.md).
|
||||
>
|
||||
> To change this setting, make sure the
|
||||
> [`${experimentalFeature}` experimental feature](@docroot@/development/experimental-features.md#xp-feature-${experimentalFeature})
|
||||
> is enabled.
|
||||
> For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md):
|
||||
>
|
||||
> ```
|
||||
> extra-experimental-features = ${experimentalFeature}
|
||||
> ${setting} = ...
|
||||
> ```
|
||||
'';
|
||||
> **Warning**
|
||||
>
|
||||
> This setting is part of an
|
||||
> [experimental feature](@docroot@/development/experimental-features.md).
|
||||
>
|
||||
> To change this setting, make sure the
|
||||
> [`${experimentalFeature}` experimental feature](@docroot@/development/experimental-features.md#xp-feature-${experimentalFeature})
|
||||
> is enabled.
|
||||
> For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md):
|
||||
>
|
||||
> ```
|
||||
> extra-experimental-features = ${experimentalFeature}
|
||||
> ${setting} = ...
|
||||
> ```
|
||||
'';
|
||||
|
||||
showDefault = documentDefault: defaultValue:
|
||||
showDefault =
|
||||
documentDefault: defaultValue:
|
||||
if documentDefault then
|
||||
# a StringMap value type is specified as a string, but
|
||||
# this shows the value type. The empty stringmap is `null` in
|
||||
# JSON, but that converts to `{ }` here.
|
||||
if defaultValue == "" || defaultValue == [] || isAttrs defaultValue
|
||||
then "*empty*"
|
||||
else if isBool defaultValue then
|
||||
if defaultValue then "`true`" else "`false`"
|
||||
else "`${toString defaultValue}`"
|
||||
else "*machine-specific*";
|
||||
if defaultValue == "" || defaultValue == [ ] || isAttrs defaultValue then
|
||||
"*empty*"
|
||||
else if isBool defaultValue then
|
||||
if defaultValue then "`true`" else "`false`"
|
||||
else
|
||||
"`${toString defaultValue}`"
|
||||
else
|
||||
"*machine-specific*";
|
||||
|
||||
showAliases = aliases:
|
||||
optionalString (aliases != [])
|
||||
"**Deprecated alias:** ${(concatStringsSep ", " (map (s: "`${s}`") aliases))}";
|
||||
showAliases =
|
||||
aliases:
|
||||
optionalString (aliases != [ ])
|
||||
"**Deprecated alias:** ${(concatStringsSep ", " (map (s: "`${s}`") aliases))}";
|
||||
|
||||
in result;
|
||||
in
|
||||
result;
|
||||
|
||||
in concatStrings (attrValues (mapAttrs (showSetting prefix) settingsInfo))
|
||||
in
|
||||
concatStrings (attrValues (mapAttrs (showSetting prefix) settingsInfo))
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
let
|
||||
inherit (builtins) attrNames listToAttrs concatStringsSep readFile replaceStrings;
|
||||
inherit (import <nix/utils.nix>) optionalString filterAttrs trim squash toLower unique indent;
|
||||
inherit (builtins)
|
||||
attrNames
|
||||
listToAttrs
|
||||
concatStringsSep
|
||||
readFile
|
||||
replaceStrings
|
||||
;
|
||||
inherit (import <nix/utils.nix>)
|
||||
optionalString
|
||||
filterAttrs
|
||||
trim
|
||||
squash
|
||||
toLower
|
||||
unique
|
||||
indent
|
||||
;
|
||||
showSettings = import <nix/generate-settings.nix>;
|
||||
in
|
||||
|
||||
@@ -14,7 +28,13 @@ in
|
||||
|
||||
let
|
||||
|
||||
showStore = { name, slug }: { settings, doc, experimentalFeature }:
|
||||
showStore =
|
||||
{ name, slug }:
|
||||
{
|
||||
settings,
|
||||
doc,
|
||||
experimentalFeature,
|
||||
}:
|
||||
let
|
||||
result = squash ''
|
||||
# ${name}
|
||||
@@ -25,7 +45,10 @@ let
|
||||
|
||||
## Settings
|
||||
|
||||
${showSettings { prefix = "store-${slug}"; inherit inlineHTML; } settings}
|
||||
${showSettings {
|
||||
prefix = "store-${slug}";
|
||||
inherit inlineHTML;
|
||||
} settings}
|
||||
'';
|
||||
|
||||
experimentalFeatureNote = optionalString (experimentalFeature != null) ''
|
||||
@@ -43,15 +66,15 @@ let
|
||||
> extra-experimental-features = ${experimentalFeature}
|
||||
> ```
|
||||
'';
|
||||
in result;
|
||||
in
|
||||
result;
|
||||
|
||||
storesList = map
|
||||
(name: rec {
|
||||
inherit name;
|
||||
slug = replaceStrings [ " " ] [ "-" ] (toLower name);
|
||||
filename = "${slug}.md";
|
||||
page = showStore { inherit name slug; } storeInfo.${name};
|
||||
})
|
||||
(attrNames storeInfo);
|
||||
storesList = map (name: rec {
|
||||
inherit name;
|
||||
slug = replaceStrings [ " " ] [ "-" ] (toLower name);
|
||||
filename = "${slug}.md";
|
||||
page = showStore { inherit name slug; } storeInfo.${name};
|
||||
}) (attrNames storeInfo);
|
||||
|
||||
in storesList
|
||||
in
|
||||
storesList
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
let
|
||||
inherit (builtins) attrNames listToAttrs concatStringsSep readFile replaceStrings;
|
||||
inherit (builtins)
|
||||
attrNames
|
||||
listToAttrs
|
||||
concatStringsSep
|
||||
readFile
|
||||
replaceStrings
|
||||
;
|
||||
showSettings = import <nix/generate-settings.nix>;
|
||||
showStoreDocs = import <nix/generate-store-info.nix>;
|
||||
in
|
||||
@@ -14,26 +20,28 @@ let
|
||||
|
||||
index =
|
||||
let
|
||||
showEntry = store:
|
||||
"- [${store.name}](./${store.filename})";
|
||||
showEntry = store: "- [${store.name}](./${store.filename})";
|
||||
in
|
||||
concatStringsSep "\n" (map showEntry storesList);
|
||||
|
||||
"index.md" = replaceStrings
|
||||
[ "@store-types@" ] [ index ]
|
||||
(readFile ./source/store/types/index.md.in);
|
||||
"index.md" =
|
||||
replaceStrings [ "@store-types@" ] [ index ]
|
||||
(readFile ./source/store/types/index.md.in);
|
||||
|
||||
tableOfContents =
|
||||
let
|
||||
showEntry = store:
|
||||
" - [${store.name}](store/types/${store.filename})";
|
||||
showEntry = store: " - [${store.name}](store/types/${store.filename})";
|
||||
in
|
||||
concatStringsSep "\n" (map showEntry storesList) + "\n";
|
||||
|
||||
"SUMMARY.md" = tableOfContents;
|
||||
|
||||
storePages = listToAttrs
|
||||
(map (s: { name = s.filename; value = s.page; }) storesList);
|
||||
storePages = listToAttrs (
|
||||
map (s: {
|
||||
name = s.filename;
|
||||
value = s.page;
|
||||
}) storesList
|
||||
);
|
||||
|
||||
in
|
||||
storePages // { inherit "index.md" "SUMMARY.md"; }
|
||||
|
||||
@@ -2,8 +2,8 @@ with builtins;
|
||||
with import <nix/utils.nix>;
|
||||
|
||||
let
|
||||
showExperimentalFeature = name: doc:
|
||||
''
|
||||
- [`${name}`](@docroot@/development/experimental-features.md#xp-feature-${name})
|
||||
'';
|
||||
in xps: indent " " (concatStrings (attrValues (mapAttrs showExperimentalFeature xps)))
|
||||
showExperimentalFeature = name: doc: ''
|
||||
- [`${name}`](@docroot@/development/experimental-features.md#xp-feature-${name})
|
||||
'';
|
||||
in
|
||||
xps: indent " " (concatStrings (attrValues (mapAttrs showExperimentalFeature xps)))
|
||||
|
||||
@@ -2,7 +2,8 @@ with builtins;
|
||||
with import <nix/utils.nix>;
|
||||
|
||||
let
|
||||
showExperimentalFeature = name: doc:
|
||||
showExperimentalFeature =
|
||||
name: doc:
|
||||
squash ''
|
||||
## [`${name}`]{#xp-feature-${name}}
|
||||
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
{ lib
|
||||
, mkMesonDerivation
|
||||
{
|
||||
lib,
|
||||
mkMesonDerivation,
|
||||
|
||||
, meson
|
||||
, ninja
|
||||
, lowdown
|
||||
, mdbook
|
||||
, mdbook-linkcheck
|
||||
, jq
|
||||
, python3
|
||||
, rsync
|
||||
, nix-cli
|
||||
meson,
|
||||
ninja,
|
||||
lowdown,
|
||||
mdbook,
|
||||
mdbook-linkcheck,
|
||||
jq,
|
||||
python3,
|
||||
rsync,
|
||||
nix-cli,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
version,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -25,18 +26,22 @@ mkMesonDerivation (finalAttrs: {
|
||||
inherit version;
|
||||
|
||||
workDir = ./.;
|
||||
fileset = fileset.difference
|
||||
(fileset.unions [
|
||||
../../.version
|
||||
# Too many different types of files to filter for now
|
||||
../../doc/manual
|
||||
./.
|
||||
])
|
||||
# Do a blacklist instead
|
||||
../../doc/manual/package.nix;
|
||||
fileset =
|
||||
fileset.difference
|
||||
(fileset.unions [
|
||||
../../.version
|
||||
# Too many different types of files to filter for now
|
||||
../../doc/manual
|
||||
./.
|
||||
])
|
||||
# Do a blacklist instead
|
||||
../../doc/manual/package.nix;
|
||||
|
||||
# TODO the man pages should probably be separate
|
||||
outputs = [ "out" "man" ];
|
||||
outputs = [
|
||||
"out"
|
||||
"man"
|
||||
];
|
||||
|
||||
# Hack for sake of the dev shell
|
||||
passthru.externalNativeBuildInputs = [
|
||||
@@ -54,11 +59,10 @@ mkMesonDerivation (finalAttrs: {
|
||||
nix-cli
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${finalAttrs.version} > ./.version
|
||||
'';
|
||||
preConfigure = ''
|
||||
chmod u+w ./.version
|
||||
echo ${finalAttrs.version} > ./.version
|
||||
'';
|
||||
|
||||
postInstall = ''
|
||||
mkdir -p ''$out/nix-support
|
||||
|
||||
10
doc/manual/rl-next/curl-cloexec.md
Normal file
10
doc/manual/rl-next/curl-cloexec.md
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
synopsis: Set FD_CLOEXEC on sockets created by curl
|
||||
issues: []
|
||||
prs: [12439]
|
||||
---
|
||||
|
||||
|
||||
Curl creates sockets without setting FD_CLOEXEC/SOCK_CLOEXEC, this can cause connections to remain open forever when using commands like `nix shell`
|
||||
|
||||
This change sets the FD_CLOEXEC flag using a CURLOPT_SOCKOPTFUNCTION callback.
|
||||
@@ -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.
|
||||
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 ./env-common.md}}
|
||||
|
||||
@@ -21,6 +21,9 @@ This operation has the following options:
|
||||
Use recursive instead of flat hashing mode, used when adding
|
||||
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}}
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
The operation `--add` adds the specified paths to the Nix store. It
|
||||
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}}
|
||||
|
||||
@@ -297,7 +297,7 @@ Creating a Cachix cache for your installer tests and adding its authorisation to
|
||||
- `armv7l-linux`
|
||||
- `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
|
||||
|
||||
|
||||
@@ -11,10 +11,15 @@ rec {
|
||||
|
||||
concatStrings = concatStringsSep "";
|
||||
|
||||
attrsToList = a:
|
||||
map (name: { inherit name; value = a.${name}; }) (builtins.attrNames a);
|
||||
attrsToList =
|
||||
a:
|
||||
map (name: {
|
||||
inherit name;
|
||||
value = a.${name};
|
||||
}) (builtins.attrNames a);
|
||||
|
||||
replaceStringsRec = from: to: string:
|
||||
replaceStringsRec =
|
||||
from: to: string:
|
||||
# recursively replace occurrences of `from` with `to` within `string`
|
||||
# example:
|
||||
# replaceStringRec "--" "-" "hello-----world"
|
||||
@@ -22,16 +27,18 @@ rec {
|
||||
let
|
||||
replaced = replaceStrings [ from ] [ to ] string;
|
||||
in
|
||||
if replaced == string then string else replaceStringsRec from to replaced;
|
||||
if replaced == string then string else replaceStringsRec from to replaced;
|
||||
|
||||
toLower = replaceStrings upperChars lowerChars;
|
||||
|
||||
squash = replaceStringsRec "\n\n\n" "\n\n";
|
||||
|
||||
trim = string:
|
||||
trim =
|
||||
string:
|
||||
# trim trailing spaces and squash non-leading spaces
|
||||
let
|
||||
trimLine = line:
|
||||
trimLine =
|
||||
line:
|
||||
let
|
||||
# separate leading spaces from the rest
|
||||
parts = split "(^ *)" line;
|
||||
@@ -39,19 +46,30 @@ rec {
|
||||
rest = elemAt parts 2;
|
||||
# drop trailing spaces
|
||||
body = head (split " *$" rest);
|
||||
in spaces + replaceStringsRec " " " " body;
|
||||
in concatStringsSep "\n" (map trimLine (splitLines string));
|
||||
in
|
||||
spaces + replaceStringsRec " " " " body;
|
||||
in
|
||||
concatStringsSep "\n" (map trimLine (splitLines string));
|
||||
|
||||
# FIXME: O(n^2)
|
||||
unique = foldl' (acc: e: if elem e acc then acc else acc ++ [ e ]) [];
|
||||
unique = foldl' (acc: e: if elem e acc then acc else acc ++ [ e ]) [ ];
|
||||
|
||||
nameValuePair = name: value: { inherit name value; };
|
||||
|
||||
filterAttrs = pred: set:
|
||||
listToAttrs (concatMap (name: let v = set.${name}; in if pred name v then [(nameValuePair name v)] else []) (attrNames set));
|
||||
filterAttrs =
|
||||
pred: set:
|
||||
listToAttrs (
|
||||
concatMap (
|
||||
name:
|
||||
let
|
||||
v = set.${name};
|
||||
in
|
||||
if pred name v then [ (nameValuePair name v) ] else [ ]
|
||||
) (attrNames set)
|
||||
);
|
||||
|
||||
optionalString = cond: string: if cond then string else "";
|
||||
|
||||
indent = prefix: s:
|
||||
concatStringsSep "\n" (map (x: if x == "" then x else "${prefix}${x}") (splitLines s));
|
||||
indent =
|
||||
prefix: s: concatStringsSep "\n" (map (x: if x == "" then x else "${prefix}${x}") (splitLines s));
|
||||
}
|
||||
|
||||
381
docker.nix
381
docker.nix
@@ -1,70 +1,72 @@
|
||||
{ pkgs ? import <nixpkgs> { }
|
||||
, lib ? pkgs.lib
|
||||
, name ? "nix"
|
||||
, tag ? "latest"
|
||||
, bundleNixpkgs ? true
|
||||
, channelName ? "nixpkgs"
|
||||
, channelURL ? "https://nixos.org/channels/nixpkgs-unstable"
|
||||
, extraPkgs ? []
|
||||
, maxLayers ? 100
|
||||
, nixConf ? {}
|
||||
, flake-registry ? null
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
lib ? pkgs.lib,
|
||||
name ? "nix",
|
||||
tag ? "latest",
|
||||
bundleNixpkgs ? true,
|
||||
channelName ? "nixpkgs",
|
||||
channelURL ? "https://nixos.org/channels/nixpkgs-unstable",
|
||||
extraPkgs ? [ ],
|
||||
maxLayers ? 100,
|
||||
nixConf ? { },
|
||||
flake-registry ? null,
|
||||
}:
|
||||
let
|
||||
defaultPkgs = with pkgs; [
|
||||
nix
|
||||
bashInteractive
|
||||
coreutils-full
|
||||
gnutar
|
||||
gzip
|
||||
gnugrep
|
||||
which
|
||||
curl
|
||||
less
|
||||
wget
|
||||
man
|
||||
cacert.out
|
||||
findutils
|
||||
iana-etc
|
||||
git
|
||||
openssh
|
||||
] ++ extraPkgs;
|
||||
defaultPkgs =
|
||||
with pkgs;
|
||||
[
|
||||
nix
|
||||
bashInteractive
|
||||
coreutils-full
|
||||
gnutar
|
||||
gzip
|
||||
gnugrep
|
||||
which
|
||||
curl
|
||||
less
|
||||
wget
|
||||
man
|
||||
cacert.out
|
||||
findutils
|
||||
iana-etc
|
||||
git
|
||||
openssh
|
||||
]
|
||||
++ extraPkgs;
|
||||
|
||||
users = {
|
||||
users =
|
||||
{
|
||||
|
||||
root = {
|
||||
uid = 0;
|
||||
shell = "${pkgs.bashInteractive}/bin/bash";
|
||||
home = "/root";
|
||||
gid = 0;
|
||||
groups = [ "root" ];
|
||||
description = "System administrator";
|
||||
};
|
||||
root = {
|
||||
uid = 0;
|
||||
shell = "${pkgs.bashInteractive}/bin/bash";
|
||||
home = "/root";
|
||||
gid = 0;
|
||||
groups = [ "root" ];
|
||||
description = "System administrator";
|
||||
};
|
||||
|
||||
nobody = {
|
||||
uid = 65534;
|
||||
shell = "${pkgs.shadow}/bin/nologin";
|
||||
home = "/var/empty";
|
||||
gid = 65534;
|
||||
groups = [ "nobody" ];
|
||||
description = "Unprivileged account (don't use!)";
|
||||
};
|
||||
nobody = {
|
||||
uid = 65534;
|
||||
shell = "${pkgs.shadow}/bin/nologin";
|
||||
home = "/var/empty";
|
||||
gid = 65534;
|
||||
groups = [ "nobody" ];
|
||||
description = "Unprivileged account (don't use!)";
|
||||
};
|
||||
|
||||
} // lib.listToAttrs (
|
||||
map
|
||||
(
|
||||
n: {
|
||||
name = "nixbld${toString n}";
|
||||
value = {
|
||||
uid = 30000 + n;
|
||||
gid = 30000;
|
||||
groups = [ "nixbld" ];
|
||||
description = "Nix build user ${toString n}";
|
||||
};
|
||||
}
|
||||
)
|
||||
(lib.lists.range 1 32)
|
||||
);
|
||||
}
|
||||
// lib.listToAttrs (
|
||||
map (n: {
|
||||
name = "nixbld${toString n}";
|
||||
value = {
|
||||
uid = 30000 + n;
|
||||
gid = 30000;
|
||||
groups = [ "nixbld" ];
|
||||
description = "Nix build user ${toString n}";
|
||||
};
|
||||
}) (lib.lists.range 1 32)
|
||||
);
|
||||
|
||||
groups = {
|
||||
root.gid = 0;
|
||||
@@ -74,24 +76,20 @@ let
|
||||
|
||||
userToPasswd = (
|
||||
k:
|
||||
{ uid
|
||||
, gid ? 65534
|
||||
, home ? "/var/empty"
|
||||
, description ? ""
|
||||
, shell ? "/bin/false"
|
||||
, groups ? [ ]
|
||||
}: "${k}:x:${toString uid}:${toString gid}:${description}:${home}:${shell}"
|
||||
);
|
||||
passwdContents = (
|
||||
lib.concatStringsSep "\n"
|
||||
(lib.attrValues (lib.mapAttrs userToPasswd users))
|
||||
{
|
||||
uid,
|
||||
gid ? 65534,
|
||||
home ? "/var/empty",
|
||||
description ? "",
|
||||
shell ? "/bin/false",
|
||||
groups ? [ ],
|
||||
}:
|
||||
"${k}:x:${toString uid}:${toString gid}:${description}:${home}:${shell}"
|
||||
);
|
||||
passwdContents = (lib.concatStringsSep "\n" (lib.attrValues (lib.mapAttrs userToPasswd users)));
|
||||
|
||||
userToShadow = k: { ... }: "${k}:!:1::::::";
|
||||
shadowContents = (
|
||||
lib.concatStringsSep "\n"
|
||||
(lib.attrValues (lib.mapAttrs userToShadow users))
|
||||
);
|
||||
shadowContents = (lib.concatStringsSep "\n" (lib.attrValues (lib.mapAttrs userToShadow users)));
|
||||
|
||||
# Map groups to members
|
||||
# {
|
||||
@@ -101,42 +99,35 @@ let
|
||||
let
|
||||
# Create a flat list of user/group mappings
|
||||
mappings = (
|
||||
builtins.foldl'
|
||||
(
|
||||
acc: user:
|
||||
let
|
||||
groups = users.${user}.groups or [ ];
|
||||
in
|
||||
acc ++ map
|
||||
(group: {
|
||||
inherit user group;
|
||||
})
|
||||
groups
|
||||
)
|
||||
[ ]
|
||||
(lib.attrNames users)
|
||||
builtins.foldl' (
|
||||
acc: user:
|
||||
let
|
||||
groups = users.${user}.groups or [ ];
|
||||
in
|
||||
acc
|
||||
++ map (group: {
|
||||
inherit user group;
|
||||
}) groups
|
||||
) [ ] (lib.attrNames users)
|
||||
);
|
||||
in
|
||||
(
|
||||
builtins.foldl'
|
||||
(
|
||||
acc: v: acc // {
|
||||
${v.group} = acc.${v.group} or [ ] ++ [ v.user ];
|
||||
}
|
||||
)
|
||||
{ }
|
||||
mappings)
|
||||
(builtins.foldl' (
|
||||
acc: v:
|
||||
acc
|
||||
// {
|
||||
${v.group} = acc.${v.group} or [ ] ++ [ v.user ];
|
||||
}
|
||||
) { } mappings)
|
||||
);
|
||||
|
||||
groupToGroup = k: { gid }:
|
||||
groupToGroup =
|
||||
k:
|
||||
{ gid }:
|
||||
let
|
||||
members = groupMemberMap.${k} or [ ];
|
||||
in
|
||||
"${k}:x:${toString gid}:${lib.concatStringsSep "," members}";
|
||||
groupContents = (
|
||||
lib.concatStringsSep "\n"
|
||||
(lib.attrValues (lib.mapAttrs groupToGroup groups))
|
||||
);
|
||||
groupContents = (lib.concatStringsSep "\n" (lib.attrValues (lib.mapAttrs groupToGroup groups)));
|
||||
|
||||
defaultNixConf = {
|
||||
sandbox = "false";
|
||||
@@ -144,11 +135,17 @@ let
|
||||
trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
|
||||
};
|
||||
|
||||
nixConfContents = (lib.concatStringsSep "\n" (lib.mapAttrsFlatten (n: v:
|
||||
let
|
||||
vStr = if builtins.isList v then lib.concatStringsSep " " v else v;
|
||||
in
|
||||
"${n} = ${vStr}") (defaultNixConf // nixConf))) + "\n";
|
||||
nixConfContents =
|
||||
(lib.concatStringsSep "\n" (
|
||||
lib.mapAttrsFlatten (
|
||||
n: v:
|
||||
let
|
||||
vStr = if builtins.isList v then lib.concatStringsSep " " v else v;
|
||||
in
|
||||
"${n} = ${vStr}"
|
||||
) (defaultNixConf // nixConf)
|
||||
))
|
||||
+ "\n";
|
||||
|
||||
baseSystem =
|
||||
let
|
||||
@@ -167,21 +164,29 @@ let
|
||||
manifest = pkgs.buildPackages.runCommand "manifest.nix" { } ''
|
||||
cat > $out <<EOF
|
||||
[
|
||||
${lib.concatStringsSep "\n" (builtins.map (drv: let
|
||||
outputs = drv.outputsToInstall or [ "out" ];
|
||||
in ''
|
||||
{
|
||||
${lib.concatStringsSep "\n" (builtins.map (output: ''
|
||||
${output} = { outPath = "${lib.getOutput output drv}"; };
|
||||
'') outputs)}
|
||||
outputs = [ ${lib.concatStringsSep " " (builtins.map (x: "\"${x}\"") outputs)} ];
|
||||
name = "${drv.name}";
|
||||
outPath = "${drv}";
|
||||
system = "${drv.system}";
|
||||
type = "derivation";
|
||||
meta = { };
|
||||
}
|
||||
'') defaultPkgs)}
|
||||
${lib.concatStringsSep "\n" (
|
||||
builtins.map (
|
||||
drv:
|
||||
let
|
||||
outputs = drv.outputsToInstall or [ "out" ];
|
||||
in
|
||||
''
|
||||
{
|
||||
${lib.concatStringsSep "\n" (
|
||||
builtins.map (output: ''
|
||||
${output} = { outPath = "${lib.getOutput output drv}"; };
|
||||
'') outputs
|
||||
)}
|
||||
outputs = [ ${lib.concatStringsSep " " (builtins.map (x: "\"${x}\"") outputs)} ];
|
||||
name = "${drv.name}";
|
||||
outPath = "${drv}";
|
||||
system = "${drv.system}";
|
||||
type = "derivation";
|
||||
meta = { };
|
||||
}
|
||||
''
|
||||
) defaultPkgs
|
||||
)}
|
||||
]
|
||||
EOF
|
||||
'';
|
||||
@@ -190,16 +195,22 @@ let
|
||||
cp -a ${rootEnv}/* $out/
|
||||
ln -s ${manifest} $out/manifest.nix
|
||||
'';
|
||||
flake-registry-path = if (flake-registry == null) then
|
||||
null
|
||||
else if (builtins.readFileType (toString flake-registry)) == "directory" then
|
||||
"${flake-registry}/flake-registry.json"
|
||||
else
|
||||
flake-registry;
|
||||
flake-registry-path =
|
||||
if (flake-registry == null) then
|
||||
null
|
||||
else if (builtins.readFileType (toString flake-registry)) == "directory" then
|
||||
"${flake-registry}/flake-registry.json"
|
||||
else
|
||||
flake-registry;
|
||||
in
|
||||
pkgs.runCommand "base-system"
|
||||
{
|
||||
inherit passwdContents groupContents shadowContents nixConfContents;
|
||||
inherit
|
||||
passwdContents
|
||||
groupContents
|
||||
shadowContents
|
||||
nixConfContents
|
||||
;
|
||||
passAsFile = [
|
||||
"passwdContents"
|
||||
"groupContents"
|
||||
@@ -208,62 +219,66 @@ let
|
||||
];
|
||||
allowSubstitutes = false;
|
||||
preferLocalBuild = true;
|
||||
} (''
|
||||
env
|
||||
set -x
|
||||
mkdir -p $out/etc
|
||||
}
|
||||
(
|
||||
''
|
||||
env
|
||||
set -x
|
||||
mkdir -p $out/etc
|
||||
|
||||
mkdir -p $out/etc/ssl/certs
|
||||
ln -s /nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt $out/etc/ssl/certs
|
||||
mkdir -p $out/etc/ssl/certs
|
||||
ln -s /nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt $out/etc/ssl/certs
|
||||
|
||||
cat $passwdContentsPath > $out/etc/passwd
|
||||
echo "" >> $out/etc/passwd
|
||||
cat $passwdContentsPath > $out/etc/passwd
|
||||
echo "" >> $out/etc/passwd
|
||||
|
||||
cat $groupContentsPath > $out/etc/group
|
||||
echo "" >> $out/etc/group
|
||||
cat $groupContentsPath > $out/etc/group
|
||||
echo "" >> $out/etc/group
|
||||
|
||||
cat $shadowContentsPath > $out/etc/shadow
|
||||
echo "" >> $out/etc/shadow
|
||||
cat $shadowContentsPath > $out/etc/shadow
|
||||
echo "" >> $out/etc/shadow
|
||||
|
||||
mkdir -p $out/usr
|
||||
ln -s /nix/var/nix/profiles/share $out/usr/
|
||||
mkdir -p $out/usr
|
||||
ln -s /nix/var/nix/profiles/share $out/usr/
|
||||
|
||||
mkdir -p $out/nix/var/nix/gcroots
|
||||
mkdir -p $out/nix/var/nix/gcroots
|
||||
|
||||
mkdir $out/tmp
|
||||
mkdir $out/tmp
|
||||
|
||||
mkdir -p $out/var/tmp
|
||||
mkdir -p $out/var/tmp
|
||||
|
||||
mkdir -p $out/etc/nix
|
||||
cat $nixConfContentsPath > $out/etc/nix/nix.conf
|
||||
mkdir -p $out/etc/nix
|
||||
cat $nixConfContentsPath > $out/etc/nix/nix.conf
|
||||
|
||||
mkdir -p $out/root
|
||||
mkdir -p $out/nix/var/nix/profiles/per-user/root
|
||||
mkdir -p $out/root
|
||||
mkdir -p $out/nix/var/nix/profiles/per-user/root
|
||||
|
||||
ln -s ${profile} $out/nix/var/nix/profiles/default-1-link
|
||||
ln -s $out/nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default
|
||||
ln -s /nix/var/nix/profiles/default $out/root/.nix-profile
|
||||
ln -s ${profile} $out/nix/var/nix/profiles/default-1-link
|
||||
ln -s /nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default
|
||||
ln -s /nix/var/nix/profiles/default $out/root/.nix-profile
|
||||
|
||||
ln -s ${channel} $out/nix/var/nix/profiles/per-user/root/channels-1-link
|
||||
ln -s $out/nix/var/nix/profiles/per-user/root/channels-1-link $out/nix/var/nix/profiles/per-user/root/channels
|
||||
ln -s ${channel} $out/nix/var/nix/profiles/per-user/root/channels-1-link
|
||||
ln -s /nix/var/nix/profiles/per-user/root/channels-1-link $out/nix/var/nix/profiles/per-user/root/channels
|
||||
|
||||
mkdir -p $out/root/.nix-defexpr
|
||||
ln -s $out/nix/var/nix/profiles/per-user/root/channels $out/root/.nix-defexpr/channels
|
||||
echo "${channelURL} ${channelName}" > $out/root/.nix-channels
|
||||
mkdir -p $out/root/.nix-defexpr
|
||||
ln -s /nix/var/nix/profiles/per-user/root/channels $out/root/.nix-defexpr/channels
|
||||
echo "${channelURL} ${channelName}" > $out/root/.nix-channels
|
||||
|
||||
mkdir -p $out/bin $out/usr/bin
|
||||
ln -s ${pkgs.coreutils}/bin/env $out/usr/bin/env
|
||||
ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/sh
|
||||
mkdir -p $out/bin $out/usr/bin
|
||||
ln -s ${pkgs.coreutils}/bin/env $out/usr/bin/env
|
||||
ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/sh
|
||||
|
||||
'' + (lib.optionalString (flake-registry-path != null) ''
|
||||
nixCacheDir="/root/.cache/nix"
|
||||
mkdir -p $out$nixCacheDir
|
||||
globalFlakeRegistryPath="$nixCacheDir/flake-registry.json"
|
||||
ln -s ${flake-registry-path} $out$globalFlakeRegistryPath
|
||||
mkdir -p $out/nix/var/nix/gcroots/auto
|
||||
rootName=$(${pkgs.nix}/bin/nix --extra-experimental-features nix-command hash file --type sha1 --base32 <(echo -n $globalFlakeRegistryPath))
|
||||
ln -s $globalFlakeRegistryPath $out/nix/var/nix/gcroots/auto/$rootName
|
||||
''));
|
||||
''
|
||||
+ (lib.optionalString (flake-registry-path != null) ''
|
||||
nixCacheDir="/root/.cache/nix"
|
||||
mkdir -p $out$nixCacheDir
|
||||
globalFlakeRegistryPath="$nixCacheDir/flake-registry.json"
|
||||
ln -s ${flake-registry-path} $out$globalFlakeRegistryPath
|
||||
mkdir -p $out/nix/var/nix/gcroots/auto
|
||||
rootName=$(${pkgs.nix}/bin/nix --extra-experimental-features nix-command hash file --type sha1 --base32 <(echo -n $globalFlakeRegistryPath))
|
||||
ln -s $globalFlakeRegistryPath $out/nix/var/nix/gcroots/auto/$rootName
|
||||
'')
|
||||
);
|
||||
|
||||
in
|
||||
pkgs.dockerTools.buildLayeredImageWithNixDb {
|
||||
@@ -285,15 +300,19 @@ pkgs.dockerTools.buildLayeredImageWithNixDb {
|
||||
Cmd = [ "/root/.nix-profile/bin/bash" ];
|
||||
Env = [
|
||||
"USER=root"
|
||||
"PATH=${lib.concatStringsSep ":" [
|
||||
"/root/.nix-profile/bin"
|
||||
"/nix/var/nix/profiles/default/bin"
|
||||
"/nix/var/nix/profiles/default/sbin"
|
||||
]}"
|
||||
"MANPATH=${lib.concatStringsSep ":" [
|
||||
"/root/.nix-profile/share/man"
|
||||
"/nix/var/nix/profiles/default/share/man"
|
||||
]}"
|
||||
"PATH=${
|
||||
lib.concatStringsSep ":" [
|
||||
"/root/.nix-profile/bin"
|
||||
"/nix/var/nix/profiles/default/bin"
|
||||
"/nix/var/nix/profiles/default/sbin"
|
||||
]
|
||||
}"
|
||||
"MANPATH=${
|
||||
lib.concatStringsSep ":" [
|
||||
"/root/.nix-profile/share/man"
|
||||
"/nix/var/nix/profiles/default/share/man"
|
||||
]
|
||||
}"
|
||||
"SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
|
||||
"GIT_SSL_CAINFO=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
|
||||
"NIX_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
|
||||
|
||||
444
flake.nix
444
flake.nix
@@ -4,8 +4,14 @@
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
|
||||
inputs.nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2";
|
||||
inputs.nixpkgs-23-11.url = "github:NixOS/nixpkgs/a62e6edd6d5e1fa0329b8653c801147986f8d446";
|
||||
inputs.flake-compat = { url = "github:edolstra/flake-compat"; flake = false; };
|
||||
inputs.libgit2 = { url = "github:libgit2/libgit2/v1.8.1"; 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
|
||||
inputs.flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
@@ -18,18 +24,30 @@
|
||||
inputs.git-hooks-nix.inputs.flake-compat.follows = "";
|
||||
inputs.git-hooks-nix.inputs.gitignore.follows = "";
|
||||
|
||||
outputs = inputs@{ self, nixpkgs, nixpkgs-regression, libgit2, ... }:
|
||||
|
||||
outputs =
|
||||
inputs@{
|
||||
self,
|
||||
nixpkgs,
|
||||
nixpkgs-regression,
|
||||
libgit2,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (nixpkgs) lib;
|
||||
|
||||
officialRelease = false;
|
||||
officialRelease = true;
|
||||
|
||||
linux32BitSystems = [ "i686-linux" ];
|
||||
linux64BitSystems = [ "x86_64-linux" "aarch64-linux" ];
|
||||
linux64BitSystems = [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
];
|
||||
linuxSystems = linux32BitSystems ++ linux64BitSystems;
|
||||
darwinSystems = [ "x86_64-darwin" "aarch64-darwin" ];
|
||||
darwinSystems = [
|
||||
"x86_64-darwin"
|
||||
"aarch64-darwin"
|
||||
];
|
||||
systems = linuxSystems ++ darwinSystems;
|
||||
|
||||
crossSystems = [
|
||||
@@ -58,62 +76,76 @@
|
||||
(Provided that the names are unique.)
|
||||
|
||||
See https://nixos.org/manual/nixpkgs/stable/index.html#function-library-lib.attrsets.concatMapAttrs
|
||||
*/
|
||||
*/
|
||||
flatMapAttrs = attrs: f: lib.concatMapAttrs f attrs;
|
||||
|
||||
forAllSystems = lib.genAttrs systems;
|
||||
|
||||
forAllCrossSystems = lib.genAttrs crossSystems;
|
||||
|
||||
forAllStdenvs = f:
|
||||
lib.listToAttrs
|
||||
(map
|
||||
(stdenvName: {
|
||||
name = "${stdenvName}Packages";
|
||||
value = f stdenvName;
|
||||
})
|
||||
stdenvs);
|
||||
|
||||
forAllStdenvs =
|
||||
f:
|
||||
lib.listToAttrs (
|
||||
map (stdenvName: {
|
||||
name = "${stdenvName}Packages";
|
||||
value = f stdenvName;
|
||||
}) stdenvs
|
||||
);
|
||||
|
||||
# We don't apply flake-parts to the whole flake so that non-development attributes
|
||||
# load without fetching any development inputs.
|
||||
devFlake = inputs.flake-parts.lib.mkFlake { inherit inputs; } {
|
||||
imports = [ ./maintainers/flake-module.nix ];
|
||||
systems = lib.subtractLists crossSystems systems;
|
||||
perSystem = { system, ... }: {
|
||||
_module.args.pkgs = nixpkgsFor.${system}.native;
|
||||
};
|
||||
perSystem =
|
||||
{ system, ... }:
|
||||
{
|
||||
_module.args.pkgs = nixpkgsFor.${system}.native;
|
||||
};
|
||||
};
|
||||
|
||||
# Memoize nixpkgs for different platforms for efficiency.
|
||||
nixpkgsFor = forAllSystems
|
||||
(system: let
|
||||
make-pkgs = crossSystem: stdenv: import nixpkgs {
|
||||
localSystem = {
|
||||
inherit system;
|
||||
nixpkgsFor = forAllSystems (
|
||||
system:
|
||||
let
|
||||
make-pkgs =
|
||||
crossSystem: stdenv:
|
||||
import nixpkgs {
|
||||
localSystem = {
|
||||
inherit system;
|
||||
};
|
||||
crossSystem =
|
||||
if crossSystem == null then
|
||||
null
|
||||
else
|
||||
{
|
||||
config = crossSystem;
|
||||
}
|
||||
// lib.optionalAttrs (crossSystem == "x86_64-unknown-freebsd13") {
|
||||
useLLVM = true;
|
||||
};
|
||||
overlays = [
|
||||
(overlayFor (p: p.${stdenv}))
|
||||
];
|
||||
};
|
||||
crossSystem = if crossSystem == null then null else {
|
||||
config = crossSystem;
|
||||
} // lib.optionalAttrs (crossSystem == "x86_64-unknown-freebsd13") {
|
||||
useLLVM = true;
|
||||
};
|
||||
overlays = [
|
||||
(overlayFor (p: p.${stdenv}))
|
||||
];
|
||||
};
|
||||
stdenvs = forAllStdenvs (make-pkgs null);
|
||||
native = stdenvs.stdenvPackages;
|
||||
in {
|
||||
in
|
||||
{
|
||||
inherit stdenvs native;
|
||||
static = native.pkgsStatic;
|
||||
cross = forAllCrossSystems (crossSystem: make-pkgs crossSystem "stdenv");
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
binaryTarball = nix: pkgs: pkgs.callPackage ./scripts/binary-tarball.nix {
|
||||
inherit nix;
|
||||
};
|
||||
binaryTarball =
|
||||
nix: pkgs:
|
||||
pkgs.callPackage ./scripts/binary-tarball.nix {
|
||||
inherit nix;
|
||||
};
|
||||
|
||||
overlayFor = getStdenv: final: prev:
|
||||
overlayFor =
|
||||
getStdenv: final: prev:
|
||||
let
|
||||
stdenv = getStdenv final;
|
||||
in
|
||||
@@ -124,31 +156,42 @@
|
||||
# without "polluting" the top level "`pkgs`" attrset.
|
||||
# This also has the benefit of providing us with a distinct set of packages
|
||||
# we can iterate over.
|
||||
nixComponents = lib.makeScope final.nixDependencies.newScope (import ./packaging/components.nix {
|
||||
inherit (final) lib;
|
||||
inherit officialRelease;
|
||||
src = self;
|
||||
});
|
||||
nixComponents = lib.makeScope final.nixDependencies.newScope (
|
||||
import ./packaging/components.nix {
|
||||
inherit (final) lib;
|
||||
inherit officialRelease;
|
||||
src = self;
|
||||
}
|
||||
);
|
||||
|
||||
# The dependencies are in their own scope, so that they don't have to be
|
||||
# in Nixpkgs top level `pkgs` or `nixComponents`.
|
||||
nixDependencies = lib.makeScope final.newScope (import ./packaging/dependencies.nix {
|
||||
inherit inputs stdenv;
|
||||
pkgs = final;
|
||||
});
|
||||
nixDependencies = lib.makeScope final.newScope (
|
||||
import ./packaging/dependencies.nix {
|
||||
inherit inputs stdenv;
|
||||
pkgs = final;
|
||||
}
|
||||
);
|
||||
|
||||
nix = final.nixComponents.nix;
|
||||
|
||||
# See https://github.com/NixOS/nixpkgs/pull/214409
|
||||
# Remove when fixed in this flake's nixpkgs
|
||||
pre-commit =
|
||||
if prev.stdenv.hostPlatform.system == "i686-linux"
|
||||
then (prev.pre-commit.override (o: { dotnet-sdk = ""; })).overridePythonAttrs (o: { doCheck = false; })
|
||||
else prev.pre-commit;
|
||||
if prev.stdenv.hostPlatform.system == "i686-linux" then
|
||||
(prev.pre-commit.override (o: {
|
||||
dotnet-sdk = "";
|
||||
})).overridePythonAttrs
|
||||
(o: {
|
||||
doCheck = false;
|
||||
})
|
||||
else
|
||||
prev.pre-commit;
|
||||
|
||||
};
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
# A Nixpkgs overlay that overrides the 'nix' and
|
||||
# 'nix-perl-bindings' packages.
|
||||
overlays.default = overlayFor (p: p.stdenv);
|
||||
@@ -167,151 +210,204 @@
|
||||
;
|
||||
};
|
||||
|
||||
checks = forAllSystems (system: {
|
||||
binaryTarball = self.hydraJobs.binaryTarball.${system};
|
||||
installTests = self.hydraJobs.installTests.${system};
|
||||
nixpkgsLibTests = self.hydraJobs.tests.nixpkgsLibTests.${system};
|
||||
rl-next =
|
||||
let pkgs = nixpkgsFor.${system}.native;
|
||||
in pkgs.buildPackages.runCommand "test-rl-next-release-notes" { } ''
|
||||
LANG=C.UTF-8 ${pkgs.changelog-d}/bin/changelog-d ${./doc/manual/rl-next} >$out
|
||||
'';
|
||||
repl-completion = nixpkgsFor.${system}.native.callPackage ./tests/repl-completion.nix { };
|
||||
} // (lib.optionalAttrs (builtins.elem system linux64BitSystems)) {
|
||||
dockerImage = self.hydraJobs.dockerImage.${system};
|
||||
} // (lib.optionalAttrs (!(builtins.elem system linux32BitSystems))) {
|
||||
# Some perl dependencies are broken on i686-linux.
|
||||
# Since the support is only best-effort there, disable the perl
|
||||
# bindings
|
||||
checks = forAllSystems (
|
||||
system:
|
||||
{
|
||||
installerScriptForGHA = self.hydraJobs.installerScriptForGHA.${system};
|
||||
installTests = self.hydraJobs.installTests.${system};
|
||||
nixpkgsLibTests = self.hydraJobs.tests.nixpkgsLibTests.${system};
|
||||
rl-next =
|
||||
let
|
||||
pkgs = nixpkgsFor.${system}.native;
|
||||
in
|
||||
pkgs.buildPackages.runCommand "test-rl-next-release-notes" { } ''
|
||||
LANG=C.UTF-8 ${pkgs.changelog-d}/bin/changelog-d ${./doc/manual/rl-next} >$out
|
||||
'';
|
||||
repl-completion = nixpkgsFor.${system}.native.callPackage ./tests/repl-completion.nix { };
|
||||
}
|
||||
// (lib.optionalAttrs (builtins.elem system linux64BitSystems)) {
|
||||
dockerImage = self.hydraJobs.dockerImage.${system};
|
||||
}
|
||||
// (lib.optionalAttrs (!(builtins.elem system linux32BitSystems))) {
|
||||
# Some perl dependencies are broken on i686-linux.
|
||||
# Since the support is only best-effort there, disable the perl
|
||||
# bindings
|
||||
|
||||
# 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
|
||||
// flatMapAttrs ({
|
||||
"" = nixpkgsFor.${system}.native;
|
||||
} // lib.optionalAttrs (! nixpkgsFor.${system}.native.stdenv.hostPlatform.isDarwin) {
|
||||
# TODO: enable static builds for darwin, blocked on:
|
||||
# https://github.com/NixOS/nixpkgs/issues/320448
|
||||
# TODO: disabled to speed up GHA CI.
|
||||
#"static-" = nixpkgsFor.${system}.static;
|
||||
})
|
||||
(nixpkgsPrefix: nixpkgs:
|
||||
flatMapAttrs nixpkgs.nixComponents
|
||||
(pkgName: pkg:
|
||||
flatMapAttrs pkg.tests or {}
|
||||
(testName: test: {
|
||||
"${nixpkgsPrefix}${pkgName}-${testName}" = test;
|
||||
})
|
||||
# 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
|
||||
// flatMapAttrs ({
|
||||
"" = nixpkgsFor.${system}.native;
|
||||
} // lib.optionalAttrs (! nixpkgsFor.${system}.native.stdenv.hostPlatform.isDarwin) {
|
||||
# TODO: enable static builds for darwin, blocked on:
|
||||
# https://github.com/NixOS/nixpkgs/issues/320448
|
||||
# TODO: disabled to speed up GHA CI.
|
||||
#"static-" = nixpkgsFor.${system}.static;
|
||||
})
|
||||
(nixpkgsPrefix: nixpkgs:
|
||||
flatMapAttrs nixpkgs.nixComponents
|
||||
(pkgName: pkg:
|
||||
flatMapAttrs pkg.tests or {}
|
||||
(testName: test: {
|
||||
"${nixpkgsPrefix}${pkgName}-${testName}" = test;
|
||||
})
|
||||
)
|
||||
// lib.optionalAttrs (nixpkgs.stdenv.hostPlatform == nixpkgs.stdenv.buildPlatform) {
|
||||
"${nixpkgsPrefix}nix-functional-tests" = nixpkgs.nixComponents.nix-functional-tests;
|
||||
}
|
||||
)
|
||||
// lib.optionalAttrs (nixpkgs.stdenv.hostPlatform == nixpkgs.stdenv.buildPlatform) {
|
||||
"${nixpkgsPrefix}nix-functional-tests" = nixpkgs.nixComponents.nix-functional-tests;
|
||||
}
|
||||
)
|
||||
*/
|
||||
// devFlake.checks.${system} or {}
|
||||
*/
|
||||
// devFlake.checks.${system} or { }
|
||||
);
|
||||
|
||||
packages = forAllSystems (system:
|
||||
{ # Here we put attributes that map 1:1 into packages.<system>, ie
|
||||
packages = forAllSystems (
|
||||
system:
|
||||
{
|
||||
# Here we put attributes that map 1:1 into packages.<system>, ie
|
||||
# for which we don't apply the full build matrix such as cross or static.
|
||||
inherit (nixpkgsFor.${system}.native)
|
||||
changelog-d;
|
||||
default = self.packages.${system}.nix-ng;
|
||||
changelog-d
|
||||
;
|
||||
default = self.packages.${system}.nix;
|
||||
binaryTarball = self.hydraJobs.binaryTarball.${system};
|
||||
installerScriptForGHA = self.hydraJobs.installerScriptForGHA.${system};
|
||||
nix-manual = nixpkgsFor.${system}.native.nixComponents.nix-manual;
|
||||
nix-internal-api-docs = nixpkgsFor.${system}.native.nixComponents.nix-internal-api-docs;
|
||||
nix-external-api-docs = nixpkgsFor.${system}.native.nixComponents.nix-external-api-docs;
|
||||
}
|
||||
# We need to flatten recursive attribute sets of derivations to pass `flake check`.
|
||||
// flatMapAttrs
|
||||
{ # Components we'll iterate over in the upcoming lambda
|
||||
"nix" = { };
|
||||
"nix-util" = { };
|
||||
"nix-util-c" = { };
|
||||
"nix-util-test-support" = { };
|
||||
"nix-util-tests" = { };
|
||||
//
|
||||
flatMapAttrs
|
||||
{
|
||||
# Components we'll iterate over in the upcoming lambda
|
||||
"nix" = { };
|
||||
"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-store" = { };
|
||||
"nix-store-c" = { };
|
||||
"nix-store-test-support" = { };
|
||||
"nix-store-tests" = { };
|
||||
|
||||
"nix-fetchers" = { };
|
||||
"nix-fetchers-tests" = { };
|
||||
"nix-fetchers" = { };
|
||||
"nix-fetchers-tests" = { };
|
||||
|
||||
"nix-expr" = { };
|
||||
"nix-expr-c" = { };
|
||||
"nix-expr-test-support" = { };
|
||||
"nix-expr-tests" = { };
|
||||
"nix-expr" = { };
|
||||
"nix-expr-c" = { };
|
||||
"nix-expr-test-support" = { };
|
||||
"nix-expr-tests" = { };
|
||||
|
||||
"nix-flake" = { };
|
||||
"nix-flake-tests" = { };
|
||||
"nix-flake" = { };
|
||||
"nix-flake-tests" = { };
|
||||
|
||||
"nix-main" = { };
|
||||
"nix-main-c" = { };
|
||||
"nix-main" = { };
|
||||
"nix-main-c" = { };
|
||||
|
||||
"nix-cmd" = { };
|
||||
"nix-cmd" = { };
|
||||
|
||||
"nix-cli" = { };
|
||||
"nix-cli" = { };
|
||||
|
||||
"nix-functional-tests" = { supportsCross = false; };
|
||||
"nix-functional-tests" = {
|
||||
supportsCross = false;
|
||||
};
|
||||
|
||||
"nix-perl-bindings" = { supportsCross = false; };
|
||||
"nix-ng" = { };
|
||||
}
|
||||
(pkgName: { supportsCross ? true }: {
|
||||
# These attributes go right into `packages.<system>`.
|
||||
"${pkgName}" = nixpkgsFor.${system}.native.nixComponents.${pkgName};
|
||||
"${pkgName}-static" = nixpkgsFor.${system}.static.nixComponents.${pkgName};
|
||||
"nix-perl-bindings" = {
|
||||
supportsCross = false;
|
||||
};
|
||||
"nix-ng" = { };
|
||||
}
|
||||
// lib.optionalAttrs supportsCross (flatMapAttrs (lib.genAttrs crossSystems (_: { })) (crossSystem: {}: {
|
||||
# These attributes go right into `packages.<system>`.
|
||||
"${pkgName}-${crossSystem}" = nixpkgsFor.${system}.cross.${crossSystem}.nixComponents.${pkgName};
|
||||
}))
|
||||
// flatMapAttrs (lib.genAttrs stdenvs (_: { })) (stdenvName: {}: {
|
||||
# These attributes go right into `packages.<system>`.
|
||||
"${pkgName}-${stdenvName}" = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".nixComponents.${pkgName};
|
||||
})
|
||||
)
|
||||
(
|
||||
pkgName:
|
||||
{
|
||||
supportsCross ? true,
|
||||
}:
|
||||
{
|
||||
# These attributes go right into `packages.<system>`.
|
||||
"${pkgName}" = nixpkgsFor.${system}.native.nixComponents.${pkgName};
|
||||
"${pkgName}-static" = nixpkgsFor.${system}.static.nixComponents.${pkgName};
|
||||
}
|
||||
// lib.optionalAttrs supportsCross (
|
||||
flatMapAttrs (lib.genAttrs crossSystems (_: { })) (
|
||||
crossSystem:
|
||||
{ }:
|
||||
{
|
||||
# These attributes go right into `packages.<system>`.
|
||||
"${pkgName}-${crossSystem}" = nixpkgsFor.${system}.cross.${crossSystem}.nixComponents.${pkgName};
|
||||
}
|
||||
)
|
||||
)
|
||||
// flatMapAttrs (lib.genAttrs stdenvs (_: { })) (
|
||||
stdenvName:
|
||||
{ }:
|
||||
{
|
||||
# These attributes go right into `packages.<system>`.
|
||||
"${pkgName}-${stdenvName}" =
|
||||
nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".nixComponents.${pkgName};
|
||||
}
|
||||
)
|
||||
)
|
||||
// lib.optionalAttrs (builtins.elem system linux64BitSystems) {
|
||||
dockerImage =
|
||||
let
|
||||
pkgs = nixpkgsFor.${system}.native;
|
||||
image = import ./docker.nix { inherit pkgs; tag = pkgs.nix.version; };
|
||||
in
|
||||
pkgs.runCommand
|
||||
"docker-image-tarball-${pkgs.nix.version}"
|
||||
{ meta.description = "Docker image with Nix for ${system}"; }
|
||||
''
|
||||
mkdir -p $out/nix-support
|
||||
image=$out/image.tar.gz
|
||||
ln -s ${image} $image
|
||||
echo "file binary-dist $image" >> $out/nix-support/hydra-build-products
|
||||
'';
|
||||
});
|
||||
dockerImage =
|
||||
let
|
||||
pkgs = nixpkgsFor.${system}.native;
|
||||
image = import ./docker.nix {
|
||||
inherit pkgs;
|
||||
tag = pkgs.nix.version;
|
||||
};
|
||||
in
|
||||
pkgs.runCommand "docker-image-tarball-${pkgs.nix.version}"
|
||||
{ meta.description = "Docker image with Nix for ${system}"; }
|
||||
''
|
||||
mkdir -p $out/nix-support
|
||||
image=$out/image.tar.gz
|
||||
ln -s ${image} $image
|
||||
echo "file binary-dist $image" >> $out/nix-support/hydra-build-products
|
||||
'';
|
||||
}
|
||||
);
|
||||
|
||||
devShells = let
|
||||
makeShell = import ./packaging/dev-shell.nix { inherit lib devFlake; };
|
||||
prefixAttrs = prefix: lib.concatMapAttrs (k: v: { "${prefix}-${k}" = v; });
|
||||
in
|
||||
forAllSystems (system:
|
||||
prefixAttrs "native" (forAllStdenvs (stdenvName: makeShell {
|
||||
pkgs = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages";
|
||||
})) //
|
||||
lib.optionalAttrs (!nixpkgsFor.${system}.native.stdenv.isDarwin) (
|
||||
prefixAttrs "static" (forAllStdenvs (stdenvName: makeShell {
|
||||
pkgs = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".pkgsStatic;
|
||||
})) //
|
||||
prefixAttrs "cross" (forAllCrossSystems (crossSystem: makeShell {
|
||||
pkgs = nixpkgsFor.${system}.cross.${crossSystem};
|
||||
}))
|
||||
) //
|
||||
{
|
||||
devShells =
|
||||
let
|
||||
makeShell = import ./packaging/dev-shell.nix { inherit lib devFlake; };
|
||||
prefixAttrs = prefix: lib.concatMapAttrs (k: v: { "${prefix}-${k}" = v; });
|
||||
in
|
||||
forAllSystems (
|
||||
system:
|
||||
prefixAttrs "native" (
|
||||
forAllStdenvs (
|
||||
stdenvName:
|
||||
makeShell {
|
||||
pkgs = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages";
|
||||
}
|
||||
)
|
||||
)
|
||||
// lib.optionalAttrs (!nixpkgsFor.${system}.native.stdenv.isDarwin) (
|
||||
prefixAttrs "static" (
|
||||
forAllStdenvs (
|
||||
stdenvName:
|
||||
makeShell {
|
||||
pkgs = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".pkgsStatic;
|
||||
}
|
||||
)
|
||||
)
|
||||
// prefixAttrs "cross" (
|
||||
forAllCrossSystems (
|
||||
crossSystem:
|
||||
makeShell {
|
||||
pkgs = nixpkgsFor.${system}.cross.${crossSystem};
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
// {
|
||||
default = self.devShells.${system}.native-stdenvPackages;
|
||||
}
|
||||
);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
639
package.nix
639
package.nix
@@ -1,116 +1,117 @@
|
||||
{ lib
|
||||
, stdenv
|
||||
, releaseTools
|
||||
, autoconf-archive
|
||||
, autoreconfHook
|
||||
, aws-sdk-cpp
|
||||
, boehmgc
|
||||
, nlohmann_json
|
||||
, bison
|
||||
, boost
|
||||
, brotli
|
||||
, bzip2
|
||||
, curl
|
||||
, editline
|
||||
, readline
|
||||
, flex
|
||||
, git
|
||||
, gtest
|
||||
, jq
|
||||
, libarchive
|
||||
, libcpuid
|
||||
, libgit2
|
||||
, libseccomp
|
||||
, libsodium
|
||||
, man
|
||||
, darwin
|
||||
, lowdown
|
||||
, mdbook
|
||||
, mdbook-linkcheck
|
||||
, mercurial
|
||||
, openssh
|
||||
, openssl
|
||||
, pkg-config
|
||||
, rapidcheck
|
||||
, sqlite
|
||||
, toml11
|
||||
, unixtools
|
||||
, xz
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
releaseTools,
|
||||
autoconf-archive,
|
||||
autoreconfHook,
|
||||
aws-sdk-cpp,
|
||||
boehmgc,
|
||||
nlohmann_json,
|
||||
bison,
|
||||
boost,
|
||||
brotli,
|
||||
bzip2,
|
||||
curl,
|
||||
editline,
|
||||
readline,
|
||||
flex,
|
||||
git,
|
||||
gtest,
|
||||
jq,
|
||||
libarchive,
|
||||
libcpuid,
|
||||
libgit2,
|
||||
libseccomp,
|
||||
libsodium,
|
||||
man,
|
||||
darwin,
|
||||
lowdown,
|
||||
mdbook,
|
||||
mdbook-linkcheck,
|
||||
mercurial,
|
||||
openssh,
|
||||
openssl,
|
||||
pkg-config,
|
||||
rapidcheck,
|
||||
sqlite,
|
||||
toml11,
|
||||
unixtools,
|
||||
xz,
|
||||
|
||||
, busybox-sandbox-shell ? null
|
||||
busybox-sandbox-shell ? null,
|
||||
|
||||
# Configuration Options
|
||||
#:
|
||||
# This probably seems like too many degrees of freedom, but it
|
||||
# faithfully reflects how the underlying configure + make build system
|
||||
# work. The top-level flake.nix will choose useful combinations of these
|
||||
# options to CI.
|
||||
# Configuration Options
|
||||
#:
|
||||
# This probably seems like too many degrees of freedom, but it
|
||||
# faithfully reflects how the underlying configure + make build system
|
||||
# work. The top-level flake.nix will choose useful combinations of these
|
||||
# options to CI.
|
||||
|
||||
, pname ? "nix"
|
||||
pname ? "nix",
|
||||
|
||||
, version
|
||||
, versionSuffix
|
||||
version,
|
||||
versionSuffix,
|
||||
|
||||
# Whether to build Nix. Useful to skip for tasks like testing existing pre-built versions of Nix
|
||||
, doBuild ? true
|
||||
# Whether to build Nix. Useful to skip for tasks like testing existing pre-built versions of Nix
|
||||
doBuild ? true,
|
||||
|
||||
# Run the unit tests as part of the build. See `installUnitTests` for an
|
||||
# alternative to this.
|
||||
, doCheck ? __forDefaults.canRunInstalled
|
||||
# Run the unit tests as part of the build. See `installUnitTests` for an
|
||||
# alternative to this.
|
||||
doCheck ? __forDefaults.canRunInstalled,
|
||||
|
||||
# Run the functional tests as part of the build.
|
||||
, doInstallCheck ? test-client != null || __forDefaults.canRunInstalled
|
||||
# Run the functional tests as part of the build.
|
||||
doInstallCheck ? test-client != null || __forDefaults.canRunInstalled,
|
||||
|
||||
# Check test coverage of Nix. Probably want to use with at least
|
||||
# one of `doCHeck` or `doInstallCheck` enabled.
|
||||
, withCoverageChecks ? false
|
||||
# Check test coverage of Nix. Probably want to use with at least
|
||||
# one of `doCHeck` or `doInstallCheck` enabled.
|
||||
withCoverageChecks ? false,
|
||||
|
||||
# Whether to build the regular manual
|
||||
, enableManual ? __forDefaults.canRunInstalled
|
||||
# Whether to build the regular manual
|
||||
enableManual ? __forDefaults.canRunInstalled,
|
||||
|
||||
# Whether to use garbage collection for the Nix language evaluator.
|
||||
#
|
||||
# If it is disabled, we just leak memory, but this is not as bad as it
|
||||
# sounds so long as evaluation just takes places within short-lived
|
||||
# processes. (When the process exits, the memory is reclaimed; it is
|
||||
# only leaked *within* the process.)
|
||||
#
|
||||
# Temporarily disabled on Windows because the `GC_throw_bad_alloc`
|
||||
# symbol is missing during linking.
|
||||
#
|
||||
# Disabled on OpenBSD because of missing `_data_start` symbol while linking
|
||||
, enableGC ? !stdenv.hostPlatform.isWindows && !stdenv.hostPlatform.isOpenBSD
|
||||
# Whether to use garbage collection for the Nix language evaluator.
|
||||
#
|
||||
# If it is disabled, we just leak memory, but this is not as bad as it
|
||||
# sounds so long as evaluation just takes places within short-lived
|
||||
# processes. (When the process exits, the memory is reclaimed; it is
|
||||
# only leaked *within* the process.)
|
||||
#
|
||||
# Temporarily disabled on Windows because the `GC_throw_bad_alloc`
|
||||
# symbol is missing during linking.
|
||||
#
|
||||
# Disabled on OpenBSD because of missing `_data_start` symbol while linking
|
||||
enableGC ? !stdenv.hostPlatform.isWindows && !stdenv.hostPlatform.isOpenBSD,
|
||||
|
||||
# Whether to enable Markdown rendering in the Nix binary.
|
||||
, enableMarkdown ? !stdenv.hostPlatform.isWindows
|
||||
# Whether to enable Markdown rendering in the Nix binary.
|
||||
enableMarkdown ? !stdenv.hostPlatform.isWindows,
|
||||
|
||||
# Which interactive line editor library to use for Nix's repl.
|
||||
#
|
||||
# Currently supported choices are:
|
||||
#
|
||||
# - editline (default)
|
||||
# - readline
|
||||
, readlineFlavor ? if stdenv.hostPlatform.isWindows then "readline" else "editline"
|
||||
# Which interactive line editor library to use for Nix's repl.
|
||||
#
|
||||
# Currently supported choices are:
|
||||
#
|
||||
# - editline (default)
|
||||
# - readline
|
||||
readlineFlavor ? if stdenv.hostPlatform.isWindows then "readline" else "editline",
|
||||
|
||||
# Whether to install unit tests. This is useful when cross compiling
|
||||
# since we cannot run them natively during the build, but can do so
|
||||
# later.
|
||||
, installUnitTests ? doBuild && !__forDefaults.canExecuteHost
|
||||
# Whether to install unit tests. This is useful when cross compiling
|
||||
# since we cannot run them natively during the build, but can do so
|
||||
# later.
|
||||
installUnitTests ? doBuild && !__forDefaults.canExecuteHost,
|
||||
|
||||
# For running the functional tests against a pre-built Nix. Probably
|
||||
# want to use in conjunction with `doBuild = false;`.
|
||||
, test-daemon ? null
|
||||
, test-client ? null
|
||||
# For running the functional tests against a pre-built Nix. Probably
|
||||
# want to use in conjunction with `doBuild = false;`.
|
||||
test-daemon ? null,
|
||||
test-client ? null,
|
||||
|
||||
# Avoid setting things that would interfere with a functioning devShell
|
||||
, forDevShell ? false
|
||||
# Avoid setting things that would interfere with a functioning devShell
|
||||
forDevShell ? false,
|
||||
|
||||
# Not a real argument, just the only way to approximate let-binding some
|
||||
# stuff for argument defaults.
|
||||
, __forDefaults ? {
|
||||
# Not a real argument, just the only way to approximate let-binding some
|
||||
# stuff for argument defaults.
|
||||
__forDefaults ? {
|
||||
canExecuteHost = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
|
||||
canRunInstalled = doBuild && __forDefaults.canExecuteHost;
|
||||
}
|
||||
},
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -124,243 +125,295 @@ let
|
||||
};
|
||||
|
||||
mkDerivation =
|
||||
if withCoverageChecks
|
||||
then
|
||||
if withCoverageChecks then
|
||||
# TODO support `finalAttrs` args function in
|
||||
# `releaseTools.coverageAnalysis`.
|
||||
argsFun:
|
||||
releaseTools.coverageAnalysis (let args = argsFun args; in args)
|
||||
else stdenv.mkDerivation;
|
||||
releaseTools.coverageAnalysis (
|
||||
let
|
||||
args = argsFun args;
|
||||
in
|
||||
args
|
||||
)
|
||||
else
|
||||
stdenv.mkDerivation;
|
||||
in
|
||||
|
||||
mkDerivation (finalAttrs: let
|
||||
mkDerivation (
|
||||
finalAttrs:
|
||||
let
|
||||
|
||||
inherit (finalAttrs)
|
||||
doCheck
|
||||
doInstallCheck
|
||||
;
|
||||
inherit (finalAttrs)
|
||||
doCheck
|
||||
doInstallCheck
|
||||
;
|
||||
|
||||
doBuild = !finalAttrs.dontBuild;
|
||||
doBuild = !finalAttrs.dontBuild;
|
||||
|
||||
# Either running the unit tests during the build, or installing them
|
||||
# to be run later, requiresthe unit tests to be built.
|
||||
buildUnitTests = doCheck || installUnitTests;
|
||||
# Either running the unit tests during the build, or installing them
|
||||
# to be run later, requiresthe unit tests to be built.
|
||||
buildUnitTests = doCheck || installUnitTests;
|
||||
|
||||
in {
|
||||
inherit pname version;
|
||||
in
|
||||
{
|
||||
inherit pname version;
|
||||
|
||||
src =
|
||||
let
|
||||
baseFiles = fileset.fileFilter (f: f.name != ".gitignore") ./.;
|
||||
in
|
||||
src =
|
||||
let
|
||||
baseFiles = fileset.fileFilter (f: f.name != ".gitignore") ./.;
|
||||
in
|
||||
fileset.toSource {
|
||||
root = ./.;
|
||||
fileset = fileset.intersection baseFiles (fileset.unions ([
|
||||
# For configure
|
||||
./.version
|
||||
./configure.ac
|
||||
./m4
|
||||
# TODO: do we really need README.md? It doesn't seem used in the build.
|
||||
./README.md
|
||||
# This could be put behind a conditional
|
||||
./maintainers/local.mk
|
||||
# For make, regardless of what we are building
|
||||
./local.mk
|
||||
./Makefile
|
||||
./Makefile.config.in
|
||||
./mk
|
||||
(fileset.fileFilter (f: lib.strings.hasPrefix "nix-profile" f.name) ./scripts)
|
||||
] ++ lib.optionals doBuild [
|
||||
./doc
|
||||
./misc
|
||||
./precompiled-headers.h
|
||||
(fileset.difference ./src ./src/perl)
|
||||
./COPYING
|
||||
./scripts/local.mk
|
||||
] ++ lib.optionals enableManual [
|
||||
./doc/manual
|
||||
] ++ lib.optionals doInstallCheck [
|
||||
./tests/functional
|
||||
]));
|
||||
fileset = fileset.intersection baseFiles (
|
||||
fileset.unions (
|
||||
[
|
||||
# For configure
|
||||
./.version
|
||||
./configure.ac
|
||||
./m4
|
||||
# TODO: do we really need README.md? It doesn't seem used in the build.
|
||||
./README.md
|
||||
# This could be put behind a conditional
|
||||
./maintainers/local.mk
|
||||
# For make, regardless of what we are building
|
||||
./local.mk
|
||||
./Makefile
|
||||
./Makefile.config.in
|
||||
./mk
|
||||
(fileset.fileFilter (f: lib.strings.hasPrefix "nix-profile" f.name) ./scripts)
|
||||
]
|
||||
++ lib.optionals doBuild [
|
||||
./doc
|
||||
./misc
|
||||
./precompiled-headers.h
|
||||
(fileset.difference ./src ./src/perl)
|
||||
./COPYING
|
||||
./scripts/local.mk
|
||||
]
|
||||
++ lib.optionals enableManual [
|
||||
./doc/manual
|
||||
]
|
||||
++ lib.optionals doInstallCheck [
|
||||
./tests/functional
|
||||
]
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
VERSION_SUFFIX = versionSuffix;
|
||||
VERSION_SUFFIX = versionSuffix;
|
||||
|
||||
outputs = [ "out" ]
|
||||
++ lib.optional doBuild "dev"
|
||||
# If we are doing just build or just docs, the one thing will use
|
||||
# "out". We only need additional outputs if we are doing both.
|
||||
++ lib.optional (doBuild && enableManual) "doc"
|
||||
++ lib.optional installUnitTests "check"
|
||||
++ lib.optional doCheck "testresults"
|
||||
;
|
||||
outputs =
|
||||
[ "out" ]
|
||||
++ lib.optional doBuild "dev"
|
||||
# If we are doing just build or just docs, the one thing will use
|
||||
# "out". We only need additional outputs if we are doing both.
|
||||
++ lib.optional (doBuild && enableManual) "doc"
|
||||
++ lib.optional installUnitTests "check"
|
||||
++ lib.optional doCheck "testresults";
|
||||
|
||||
nativeBuildInputs = [
|
||||
autoconf-archive
|
||||
autoreconfHook
|
||||
pkg-config
|
||||
] ++ lib.optionals doBuild [
|
||||
bison
|
||||
flex
|
||||
] ++ lib.optionals enableManual [
|
||||
(lib.getBin lowdown)
|
||||
mdbook
|
||||
mdbook-linkcheck
|
||||
] ++ lib.optionals doInstallCheck [
|
||||
git
|
||||
mercurial
|
||||
openssh
|
||||
] ++ lib.optionals (doInstallCheck || enableManual) [
|
||||
jq # Also for custom mdBook preprocessor.
|
||||
] ++ lib.optionals enableManual [
|
||||
man
|
||||
] ++ lib.optional stdenv.hostPlatform.isStatic unixtools.hexdump
|
||||
;
|
||||
nativeBuildInputs =
|
||||
[
|
||||
autoconf-archive
|
||||
autoreconfHook
|
||||
pkg-config
|
||||
]
|
||||
++ lib.optionals doBuild [
|
||||
bison
|
||||
flex
|
||||
]
|
||||
++ lib.optionals enableManual [
|
||||
(lib.getBin lowdown)
|
||||
mdbook
|
||||
mdbook-linkcheck
|
||||
]
|
||||
++ lib.optionals doInstallCheck [
|
||||
git
|
||||
mercurial
|
||||
openssh
|
||||
]
|
||||
++ lib.optionals (doInstallCheck || enableManual) [
|
||||
jq # Also for custom mdBook preprocessor.
|
||||
]
|
||||
++ lib.optionals enableManual [
|
||||
man
|
||||
]
|
||||
++ lib.optional stdenv.hostPlatform.isStatic unixtools.hexdump;
|
||||
|
||||
buildInputs = lib.optionals doBuild (
|
||||
[
|
||||
brotli
|
||||
bzip2
|
||||
curl
|
||||
libarchive
|
||||
libgit2
|
||||
libsodium
|
||||
openssl
|
||||
sqlite
|
||||
toml11
|
||||
xz
|
||||
({ inherit readline editline; }.${readlineFlavor})
|
||||
] ++ lib.optionals enableMarkdown [
|
||||
lowdown
|
||||
] ++ lib.optionals buildUnitTests [
|
||||
gtest
|
||||
rapidcheck
|
||||
] ++ lib.optional stdenv.isLinux libseccomp
|
||||
++ lib.optional stdenv.hostPlatform.isDarwin darwin.apple_sdk.libs.sandbox
|
||||
++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid
|
||||
# There have been issues building these dependencies
|
||||
++ lib.optional (stdenv.hostPlatform == stdenv.buildPlatform && (stdenv.isLinux || stdenv.isDarwin))
|
||||
aws-sdk-cpp
|
||||
);
|
||||
buildInputs = lib.optionals doBuild (
|
||||
[
|
||||
brotli
|
||||
bzip2
|
||||
curl
|
||||
libarchive
|
||||
libgit2
|
||||
libsodium
|
||||
openssl
|
||||
sqlite
|
||||
toml11
|
||||
xz
|
||||
({ inherit readline editline; }.${readlineFlavor})
|
||||
]
|
||||
++ lib.optionals enableMarkdown [
|
||||
lowdown
|
||||
]
|
||||
++ lib.optionals buildUnitTests [
|
||||
gtest
|
||||
rapidcheck
|
||||
]
|
||||
++ lib.optional stdenv.isLinux libseccomp
|
||||
++ lib.optional stdenv.hostPlatform.isDarwin darwin.apple_sdk.libs.sandbox
|
||||
++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid
|
||||
# There have been issues building these dependencies
|
||||
++ lib.optional (
|
||||
stdenv.hostPlatform == stdenv.buildPlatform && (stdenv.isLinux || stdenv.isDarwin)
|
||||
) aws-sdk-cpp
|
||||
);
|
||||
|
||||
propagatedBuildInputs = lib.optionals doBuild ([
|
||||
boost
|
||||
nlohmann_json
|
||||
] ++ lib.optional enableGC boehmgc
|
||||
);
|
||||
propagatedBuildInputs = lib.optionals doBuild (
|
||||
[
|
||||
boost
|
||||
nlohmann_json
|
||||
]
|
||||
++ lib.optional enableGC boehmgc
|
||||
);
|
||||
|
||||
dontBuild = !attrs.doBuild;
|
||||
doCheck = attrs.doCheck;
|
||||
dontBuild = !attrs.doBuild;
|
||||
doCheck = attrs.doCheck;
|
||||
|
||||
configureFlags = [
|
||||
(lib.enableFeature doBuild "build")
|
||||
(lib.enableFeature buildUnitTests "unit-tests")
|
||||
(lib.enableFeature doInstallCheck "functional-tests")
|
||||
(lib.enableFeature enableManual "doc-gen")
|
||||
(lib.enableFeature enableGC "gc")
|
||||
(lib.enableFeature enableMarkdown "markdown")
|
||||
(lib.enableFeature installUnitTests "install-unit-tests")
|
||||
(lib.withFeatureAs true "readline-flavor" readlineFlavor)
|
||||
] ++ lib.optionals (!forDevShell) [
|
||||
"--sysconfdir=/etc"
|
||||
] ++ lib.optionals installUnitTests [
|
||||
"--with-check-bin-dir=${builtins.placeholder "check"}/bin"
|
||||
"--with-check-lib-dir=${builtins.placeholder "check"}/lib"
|
||||
] ++ lib.optionals (doBuild) [
|
||||
"--with-boost=${boost}/lib"
|
||||
] ++ lib.optionals (doBuild && stdenv.isLinux) [
|
||||
"--with-sandbox-shell=${busybox-sandbox-shell}/bin/busybox"
|
||||
] ++ lib.optional (doBuild && stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
"LDFLAGS=-fuse-ld=gold"
|
||||
++ lib.optional (doBuild && stdenv.hostPlatform.isStatic) "--enable-embedded-sandbox-shell"
|
||||
;
|
||||
configureFlags =
|
||||
[
|
||||
(lib.enableFeature doBuild "build")
|
||||
(lib.enableFeature buildUnitTests "unit-tests")
|
||||
(lib.enableFeature doInstallCheck "functional-tests")
|
||||
(lib.enableFeature enableManual "doc-gen")
|
||||
(lib.enableFeature enableGC "gc")
|
||||
(lib.enableFeature enableMarkdown "markdown")
|
||||
(lib.enableFeature installUnitTests "install-unit-tests")
|
||||
(lib.withFeatureAs true "readline-flavor" readlineFlavor)
|
||||
]
|
||||
++ lib.optionals (!forDevShell) [
|
||||
"--sysconfdir=/etc"
|
||||
]
|
||||
++ lib.optionals installUnitTests [
|
||||
"--with-check-bin-dir=${builtins.placeholder "check"}/bin"
|
||||
"--with-check-lib-dir=${builtins.placeholder "check"}/lib"
|
||||
]
|
||||
++ lib.optionals (doBuild) [
|
||||
"--with-boost=${boost}/lib"
|
||||
]
|
||||
++ lib.optionals (doBuild && stdenv.isLinux) [
|
||||
"--with-sandbox-shell=${busybox-sandbox-shell}/bin/busybox"
|
||||
]
|
||||
++ lib.optional (
|
||||
doBuild && stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")
|
||||
) "LDFLAGS=-fuse-ld=gold"
|
||||
++ lib.optional (doBuild && stdenv.hostPlatform.isStatic) "--enable-embedded-sandbox-shell";
|
||||
|
||||
enableParallelBuilding = true;
|
||||
enableParallelBuilding = true;
|
||||
|
||||
makeFlags = "profiledir=$(out)/etc/profile.d PRECOMPILE_HEADERS=1";
|
||||
makeFlags = "profiledir=$(out)/etc/profile.d PRECOMPILE_HEADERS=1";
|
||||
|
||||
preCheck = ''
|
||||
mkdir $testresults
|
||||
'';
|
||||
preCheck = ''
|
||||
mkdir $testresults
|
||||
'';
|
||||
|
||||
installTargets = lib.optional doBuild "install";
|
||||
installTargets = lib.optional doBuild "install";
|
||||
|
||||
installFlags = "sysconfdir=$(out)/etc";
|
||||
installFlags = "sysconfdir=$(out)/etc";
|
||||
|
||||
# In this case we are probably just running tests, and so there isn't
|
||||
# anything to install, we just make an empty directory to signify tests
|
||||
# succeeded.
|
||||
installPhase = if finalAttrs.installTargets != [] then null else ''
|
||||
mkdir -p $out
|
||||
'';
|
||||
# In this case we are probably just running tests, and so there isn't
|
||||
# anything to install, we just make an empty directory to signify tests
|
||||
# succeeded.
|
||||
installPhase =
|
||||
if finalAttrs.installTargets != [ ] then
|
||||
null
|
||||
else
|
||||
''
|
||||
mkdir -p $out
|
||||
'';
|
||||
|
||||
postInstall = lib.optionalString doBuild (
|
||||
lib.optionalString stdenv.hostPlatform.isStatic ''
|
||||
mkdir -p $out/nix-support
|
||||
echo "file binary-dist $out/bin/nix" >> $out/nix-support/hydra-build-products
|
||||
''
|
||||
) + lib.optionalString enableManual ''
|
||||
mkdir -p ''${!outputDoc}/nix-support
|
||||
echo "doc manual ''${!outputDoc}/share/doc/nix/manual" >> ''${!outputDoc}/nix-support/hydra-build-products
|
||||
'';
|
||||
postInstall =
|
||||
lib.optionalString doBuild (
|
||||
lib.optionalString stdenv.hostPlatform.isStatic ''
|
||||
mkdir -p $out/nix-support
|
||||
echo "file binary-dist $out/bin/nix" >> $out/nix-support/hydra-build-products
|
||||
''
|
||||
)
|
||||
+ lib.optionalString enableManual ''
|
||||
mkdir -p ''${!outputDoc}/nix-support
|
||||
echo "doc manual ''${!outputDoc}/share/doc/nix/manual" >> ''${!outputDoc}/nix-support/hydra-build-products
|
||||
'';
|
||||
|
||||
# So the check output gets links for DLLs in the out output.
|
||||
preFixup = lib.optionalString (stdenv.hostPlatform.isWindows && builtins.elem "check" finalAttrs.outputs) ''
|
||||
ln -s "$check/lib/"*.dll "$check/bin"
|
||||
ln -s "$out/bin/"*.dll "$check/bin"
|
||||
'';
|
||||
# So the check output gets links for DLLs in the out output.
|
||||
preFixup =
|
||||
lib.optionalString (stdenv.hostPlatform.isWindows && builtins.elem "check" finalAttrs.outputs)
|
||||
''
|
||||
ln -s "$check/lib/"*.dll "$check/bin"
|
||||
ln -s "$out/bin/"*.dll "$check/bin"
|
||||
'';
|
||||
|
||||
doInstallCheck = attrs.doInstallCheck;
|
||||
doInstallCheck = attrs.doInstallCheck;
|
||||
|
||||
installCheckFlags = "sysconfdir=$(out)/etc";
|
||||
# Work around buggy detection in stdenv.
|
||||
installCheckTarget = "installcheck";
|
||||
installCheckFlags = "sysconfdir=$(out)/etc";
|
||||
# Work around buggy detection in stdenv.
|
||||
installCheckTarget = "installcheck";
|
||||
|
||||
# Work around weird bug where it doesn't think there is a Makefile.
|
||||
installCheckPhase = if (!doBuild && doInstallCheck) then ''
|
||||
runHook preInstallCheck
|
||||
mkdir -p src/nix-channel
|
||||
make installcheck -j$NIX_BUILD_CORES -l$NIX_BUILD_CORES
|
||||
'' else null;
|
||||
# Work around weird bug where it doesn't think there is a Makefile.
|
||||
installCheckPhase =
|
||||
if (!doBuild && doInstallCheck) then
|
||||
''
|
||||
runHook preInstallCheck
|
||||
mkdir -p src/nix-channel
|
||||
make installcheck -j$NIX_BUILD_CORES -l$NIX_BUILD_CORES
|
||||
''
|
||||
else
|
||||
null;
|
||||
|
||||
# Needed for tests if we are not doing a build, but testing existing
|
||||
# built Nix.
|
||||
preInstallCheck =
|
||||
lib.optionalString (! doBuild) ''
|
||||
# Needed for tests if we are not doing a build, but testing existing
|
||||
# built Nix.
|
||||
preInstallCheck = lib.optionalString (!doBuild) ''
|
||||
mkdir -p src/nix-channel
|
||||
'';
|
||||
|
||||
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||
|
||||
# TODO Always true after https://github.com/NixOS/nixpkgs/issues/318564
|
||||
strictDeps = !withCoverageChecks;
|
||||
# TODO Always true after https://github.com/NixOS/nixpkgs/issues/318564
|
||||
strictDeps = !withCoverageChecks;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
mainProgram = "nix";
|
||||
broken = !(lib.all (a: a) [
|
||||
# We cannot run or install unit tests if we don't build them or
|
||||
# Nix proper (which they depend on).
|
||||
(installUnitTests -> doBuild)
|
||||
(doCheck -> doBuild)
|
||||
# The build process for the manual currently requires extracting
|
||||
# data from the Nix executable we are trying to document.
|
||||
(enableManual -> doBuild)
|
||||
]);
|
||||
};
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
mainProgram = "nix";
|
||||
broken =
|
||||
!(lib.all (a: a) [
|
||||
# We cannot run or install unit tests if we don't build them or
|
||||
# Nix proper (which they depend on).
|
||||
(installUnitTests -> doBuild)
|
||||
(doCheck -> doBuild)
|
||||
# The build process for the manual currently requires extracting
|
||||
# data from the Nix executable we are trying to document.
|
||||
(enableManual -> doBuild)
|
||||
]);
|
||||
};
|
||||
|
||||
} // lib.optionalAttrs withCoverageChecks {
|
||||
lcovFilter = [ "*/boost/*" "*-tab.*" ];
|
||||
}
|
||||
// lib.optionalAttrs withCoverageChecks {
|
||||
lcovFilter = [
|
||||
"*/boost/*"
|
||||
"*-tab.*"
|
||||
];
|
||||
|
||||
hardeningDisable = ["fortify"];
|
||||
hardeningDisable = [ "fortify" ];
|
||||
|
||||
NIX_CFLAGS_COMPILE = "-DCOVERAGE=1";
|
||||
NIX_CFLAGS_COMPILE = "-DCOVERAGE=1";
|
||||
|
||||
dontInstall = false;
|
||||
} // lib.optionalAttrs (test-daemon != null) {
|
||||
NIX_DAEMON_PACKAGE = test-daemon;
|
||||
} // lib.optionalAttrs (test-client != null) {
|
||||
NIX_CLIENT_PACKAGE = test-client;
|
||||
})
|
||||
dontInstall = false;
|
||||
}
|
||||
// lib.optionalAttrs (test-daemon != null) {
|
||||
NIX_DAEMON_PACKAGE = test-daemon;
|
||||
}
|
||||
// lib.optionalAttrs (test-client != null) {
|
||||
NIX_CLIENT_PACKAGE = test-client;
|
||||
}
|
||||
)
|
||||
|
||||
@@ -13,9 +13,11 @@ let
|
||||
|
||||
versionSuffix = lib.optionalString (!officialRelease) "pre";
|
||||
|
||||
fineVersionSuffix = lib.optionalString
|
||||
(!officialRelease)
|
||||
"pre${builtins.substring 0 8 (src.lastModifiedDate or src.lastModified or "19700101")}_${src.shortRev or "dirty"}";
|
||||
fineVersionSuffix =
|
||||
lib.optionalString (!officialRelease)
|
||||
"pre${
|
||||
builtins.substring 0 8 (src.lastModifiedDate or src.lastModified or "19700101")
|
||||
}_${src.shortRev or "dirty"}";
|
||||
|
||||
fineVersion = baseVersion + fineVersionSuffix;
|
||||
in
|
||||
@@ -58,7 +60,9 @@ in
|
||||
|
||||
nix-cli = callPackage ../src/nix/package.nix { version = fineVersion; };
|
||||
|
||||
nix-functional-tests = callPackage ../src/nix-functional-tests/package.nix { version = fineVersion; };
|
||||
nix-functional-tests = callPackage ../tests/functional/package.nix {
|
||||
version = fineVersion;
|
||||
};
|
||||
|
||||
nix-manual = callPackage ../doc/manual/package.nix { version = fineVersion; };
|
||||
nix-internal-api-docs = callPackage ../src/internal-api-docs/package.nix { version = fineVersion; };
|
||||
|
||||
@@ -19,9 +19,7 @@ let
|
||||
|
||||
root = ../.;
|
||||
|
||||
stdenv = if prevStdenv.isDarwin && prevStdenv.isx86_64
|
||||
then darwinStdenv
|
||||
else prevStdenv;
|
||||
stdenv = if prevStdenv.isDarwin && prevStdenv.isx86_64 then darwinStdenv else prevStdenv;
|
||||
|
||||
# Fix the following error with the default x86_64-darwin SDK:
|
||||
#
|
||||
@@ -38,11 +36,14 @@ let
|
||||
# Indirection for Nixpkgs to override when package.nix files are vendored
|
||||
filesetToSource = lib.fileset.toSource;
|
||||
|
||||
/** Given a set of layers, create a mkDerivation-like function */
|
||||
mkPackageBuilder = exts: userFn:
|
||||
stdenv.mkDerivation (lib.extends (lib.composeManyExtensions exts) userFn);
|
||||
/**
|
||||
Given a set of layers, create a mkDerivation-like function
|
||||
*/
|
||||
mkPackageBuilder =
|
||||
exts: userFn: stdenv.mkDerivation (lib.extends (lib.composeManyExtensions exts) userFn);
|
||||
|
||||
localSourceLayer = finalAttrs: prevAttrs:
|
||||
localSourceLayer =
|
||||
finalAttrs: prevAttrs:
|
||||
let
|
||||
workDirPath =
|
||||
# Ideally we'd pick finalAttrs.workDir, but for now `mkDerivation` has
|
||||
@@ -51,8 +52,13 @@ let
|
||||
prevAttrs.workDir;
|
||||
|
||||
workDirSubpath = lib.path.removePrefix root workDirPath;
|
||||
sources = assert prevAttrs.fileset._type == "fileset"; prevAttrs.fileset;
|
||||
src = lib.fileset.toSource { fileset = sources; inherit root; };
|
||||
sources =
|
||||
assert prevAttrs.fileset._type == "fileset";
|
||||
prevAttrs.fileset;
|
||||
src = lib.fileset.toSource {
|
||||
fileset = sources;
|
||||
inherit root;
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
@@ -64,52 +70,54 @@ let
|
||||
workDir = null;
|
||||
};
|
||||
|
||||
mesonLayer = finalAttrs: prevAttrs:
|
||||
{
|
||||
nativeBuildInputs = [
|
||||
pkgs.buildPackages.meson
|
||||
pkgs.buildPackages.ninja
|
||||
] ++ prevAttrs.nativeBuildInputs or [];
|
||||
};
|
||||
mesonLayer = finalAttrs: prevAttrs: {
|
||||
nativeBuildInputs = [
|
||||
pkgs.buildPackages.meson
|
||||
pkgs.buildPackages.ninja
|
||||
] ++ prevAttrs.nativeBuildInputs or [ ];
|
||||
};
|
||||
|
||||
mesonBuildLayer = finalAttrs: prevAttrs:
|
||||
{
|
||||
nativeBuildInputs = prevAttrs.nativeBuildInputs or [] ++ [
|
||||
pkgs.buildPackages.pkg-config
|
||||
];
|
||||
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
};
|
||||
mesonBuildLayer = finalAttrs: prevAttrs: {
|
||||
nativeBuildInputs = prevAttrs.nativeBuildInputs or [ ] ++ [
|
||||
pkgs.buildPackages.pkg-config
|
||||
];
|
||||
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
};
|
||||
|
||||
mesonLibraryLayer = finalAttrs: prevAttrs:
|
||||
{
|
||||
outputs = prevAttrs.outputs or [ "out" ] ++ [ "dev" ];
|
||||
};
|
||||
mesonLibraryLayer = finalAttrs: prevAttrs: {
|
||||
outputs = prevAttrs.outputs or [ "out" ] ++ [ "dev" ];
|
||||
};
|
||||
|
||||
# Work around weird `--as-needed` linker behavior with BSD, see
|
||||
# https://github.com/mesonbuild/meson/issues/3593
|
||||
bsdNoLinkAsNeeded = finalAttrs: prevAttrs:
|
||||
bsdNoLinkAsNeeded =
|
||||
finalAttrs: prevAttrs:
|
||||
lib.optionalAttrs stdenv.hostPlatform.isBSD {
|
||||
mesonFlags = [ (lib.mesonBool "b_asneeded" false) ] ++ prevAttrs.mesonFlags or [];
|
||||
mesonFlags = [ (lib.mesonBool "b_asneeded" false) ] ++ prevAttrs.mesonFlags or [ ];
|
||||
};
|
||||
|
||||
miscGoodPractice = finalAttrs: prevAttrs:
|
||||
{
|
||||
strictDeps = prevAttrs.strictDeps or true;
|
||||
enableParallelBuilding = true;
|
||||
};
|
||||
miscGoodPractice = finalAttrs: prevAttrs: {
|
||||
strictDeps = prevAttrs.strictDeps or true;
|
||||
enableParallelBuilding = true;
|
||||
};
|
||||
in
|
||||
scope: {
|
||||
inherit stdenv;
|
||||
|
||||
aws-sdk-cpp = (pkgs.aws-sdk-cpp.override {
|
||||
apis = [ "s3" "transfer" ];
|
||||
customMemoryManagement = false;
|
||||
}).overrideAttrs {
|
||||
# only a stripped down version is built, which takes a lot less resources
|
||||
# to build, so we don't need a "big-parallel" machine.
|
||||
requiredSystemFeatures = [ ];
|
||||
};
|
||||
aws-sdk-cpp =
|
||||
(pkgs.aws-sdk-cpp.override {
|
||||
apis = [
|
||||
"s3"
|
||||
"transfer"
|
||||
];
|
||||
customMemoryManagement = false;
|
||||
}).overrideAttrs
|
||||
{
|
||||
# only a stripped down version is built, which takes a lot less resources
|
||||
# to build, so we don't need a "big-parallel" machine.
|
||||
requiredSystemFeatures = [ ];
|
||||
};
|
||||
|
||||
libseccomp = pkgs.libseccomp.overrideAttrs (_: rec {
|
||||
version = "2.5.5";
|
||||
@@ -124,71 +132,44 @@ scope: {
|
||||
};
|
||||
|
||||
# TODO Hack until https://github.com/NixOS/nixpkgs/issues/45462 is fixed.
|
||||
boost = (pkgs.boost.override {
|
||||
extraB2Args = [
|
||||
"--with-container"
|
||||
"--with-context"
|
||||
"--with-coroutine"
|
||||
];
|
||||
}).overrideAttrs (old: {
|
||||
# Need to remove `--with-*` to use `--with-libraries=...`
|
||||
buildPhase = lib.replaceStrings [ "--without-python" ] [ "" ] old.buildPhase;
|
||||
installPhase = lib.replaceStrings [ "--without-python" ] [ "" ] old.installPhase;
|
||||
});
|
||||
|
||||
libgit2 = pkgs.libgit2.overrideAttrs (attrs: {
|
||||
src = inputs.libgit2;
|
||||
version = inputs.libgit2.lastModifiedDate;
|
||||
cmakeFlags = attrs.cmakeFlags or []
|
||||
++ [ "-DUSE_SSH=exec" ];
|
||||
nativeBuildInputs = attrs.nativeBuildInputs or []
|
||||
# gitMinimal does not build on Windows. See packbuilder patch.
|
||||
++ lib.optionals (!stdenv.hostPlatform.isWindows) [
|
||||
# Needed for `git apply`; see `prePatch`
|
||||
pkgs.buildPackages.gitMinimal
|
||||
boost =
|
||||
(pkgs.boost.override {
|
||||
extraB2Args = [
|
||||
"--with-container"
|
||||
"--with-context"
|
||||
"--with-coroutine"
|
||||
];
|
||||
# Only `git apply` can handle git binary patches
|
||||
prePatch = attrs.prePatch or ""
|
||||
+ lib.optionalString (!stdenv.hostPlatform.isWindows) ''
|
||||
patch() {
|
||||
git apply
|
||||
}
|
||||
}).overrideAttrs
|
||||
(old: {
|
||||
# Need to remove `--with-*` to use `--with-libraries=...`
|
||||
buildPhase = lib.replaceStrings [ "--without-python" ] [ "" ] old.buildPhase;
|
||||
installPhase = lib.replaceStrings [ "--without-python" ] [ "" ] old.installPhase;
|
||||
});
|
||||
|
||||
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
|
||||
'';
|
||||
patches = attrs.patches or []
|
||||
++ [
|
||||
./patches/libgit2-mempack-thin-packfile.patch
|
||||
]
|
||||
# gitMinimal does not build on Windows, but fortunately this patch only
|
||||
# impacts interruptibility
|
||||
++ lib.optionals (!stdenv.hostPlatform.isWindows) [
|
||||
# binary patch; see `prePatch`
|
||||
./patches/libgit2-packbuilder-callback-interruptible.patch
|
||||
];
|
||||
});
|
||||
|
||||
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.
|
||||
@@ -198,27 +179,62 @@ scope: {
|
||||
|
||||
inherit resolvePath filesetToSource;
|
||||
|
||||
mkMesonDerivation =
|
||||
mkPackageBuilder [
|
||||
miscGoodPractice
|
||||
localSourceLayer
|
||||
mesonLayer
|
||||
];
|
||||
mkMesonExecutable =
|
||||
mkPackageBuilder [
|
||||
miscGoodPractice
|
||||
bsdNoLinkAsNeeded
|
||||
localSourceLayer
|
||||
mesonLayer
|
||||
mesonBuildLayer
|
||||
];
|
||||
mkMesonLibrary =
|
||||
mkPackageBuilder [
|
||||
miscGoodPractice
|
||||
bsdNoLinkAsNeeded
|
||||
localSourceLayer
|
||||
mesonLayer
|
||||
mesonBuildLayer
|
||||
mesonLibraryLayer
|
||||
];
|
||||
mkMesonDerivation = mkPackageBuilder [
|
||||
miscGoodPractice
|
||||
localSourceLayer
|
||||
mesonLayer
|
||||
];
|
||||
mkMesonExecutable = mkPackageBuilder [
|
||||
miscGoodPractice
|
||||
bsdNoLinkAsNeeded
|
||||
localSourceLayer
|
||||
mesonLayer
|
||||
mesonBuildLayer
|
||||
];
|
||||
mkMesonLibrary = mkPackageBuilder [
|
||||
miscGoodPractice
|
||||
bsdNoLinkAsNeeded
|
||||
localSourceLayer
|
||||
mesonLayer
|
||||
mesonBuildLayer
|
||||
mesonLibraryLayer
|
||||
];
|
||||
|
||||
libgit2 = pkgs.libgit2.overrideAttrs (
|
||||
attrs:
|
||||
{
|
||||
cmakeFlags = attrs.cmakeFlags or [ ] ++ [ "-DUSE_SSH=exec" ];
|
||||
}
|
||||
# libgit2: Nixpkgs 24.11 has < 1.9.0, which needs our patches
|
||||
// lib.optionalAttrs (!lib.versionAtLeast pkgs.libgit2.version "1.9.0") {
|
||||
src = inputs.libgit2;
|
||||
version = inputs.libgit2.lastModifiedDate;
|
||||
nativeBuildInputs =
|
||||
attrs.nativeBuildInputs or [ ]
|
||||
# gitMinimal does not build on Windows. See packbuilder patch.
|
||||
++ lib.optionals (!stdenv.hostPlatform.isWindows) [
|
||||
# Needed for `git apply`; see `prePatch`
|
||||
pkgs.buildPackages.gitMinimal
|
||||
];
|
||||
# Only `git apply` can handle git binary patches
|
||||
prePatch =
|
||||
attrs.prePatch or ""
|
||||
+ lib.optionalString (!stdenv.hostPlatform.isWindows) ''
|
||||
patch() {
|
||||
git apply
|
||||
}
|
||||
'';
|
||||
patches =
|
||||
attrs.patches or [ ]
|
||||
++ [
|
||||
./patches/libgit2-mempack-thin-packfile.patch
|
||||
]
|
||||
# gitMinimal does not build on Windows, but fortunately this patch only
|
||||
# impacts interruptibility
|
||||
++ lib.optionals (!stdenv.hostPlatform.isWindows) [
|
||||
# binary patch; see `prePatch`
|
||||
./patches/libgit2-packbuilder-callback-interruptible.patch
|
||||
];
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,95 +2,103 @@
|
||||
|
||||
{ pkgs }:
|
||||
|
||||
(pkgs.nix.override { forDevShell = true; }).overrideAttrs (attrs:
|
||||
(pkgs.nix.override { forDevShell = true; }).overrideAttrs (
|
||||
attrs:
|
||||
|
||||
let
|
||||
stdenv = pkgs.nixDependencies.stdenv;
|
||||
buildCanExecuteHost = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
|
||||
modular = devFlake.getSystem stdenv.buildPlatform.system;
|
||||
transformFlag = prefix: flag:
|
||||
assert builtins.isString flag;
|
||||
let
|
||||
rest = builtins.substring 2 (builtins.stringLength flag) flag;
|
||||
in
|
||||
let
|
||||
stdenv = pkgs.nixDependencies.stdenv;
|
||||
buildCanExecuteHost = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
|
||||
modular = devFlake.getSystem stdenv.buildPlatform.system;
|
||||
transformFlag =
|
||||
prefix: flag:
|
||||
assert builtins.isString flag;
|
||||
let
|
||||
rest = builtins.substring 2 (builtins.stringLength flag) flag;
|
||||
in
|
||||
"-D${prefix}:${rest}";
|
||||
havePerl = stdenv.buildPlatform == stdenv.hostPlatform && stdenv.hostPlatform.isUnix;
|
||||
ignoreCrossFile = flags: builtins.filter (flag: !(lib.strings.hasInfix "cross-file" flag)) flags;
|
||||
in {
|
||||
pname = "shell-for-" + attrs.pname;
|
||||
havePerl = stdenv.buildPlatform == stdenv.hostPlatform && stdenv.hostPlatform.isUnix;
|
||||
ignoreCrossFile = flags: builtins.filter (flag: !(lib.strings.hasInfix "cross-file" flag)) flags;
|
||||
in
|
||||
{
|
||||
pname = "shell-for-" + attrs.pname;
|
||||
|
||||
# Remove the version suffix to avoid unnecessary attempts to substitute in nix develop
|
||||
version = lib.fileContents ../.version;
|
||||
name = attrs.pname;
|
||||
# Remove the version suffix to avoid unnecessary attempts to substitute in nix develop
|
||||
version = lib.fileContents ../.version;
|
||||
name = attrs.pname;
|
||||
|
||||
installFlags = "sysconfdir=$(out)/etc";
|
||||
shellHook = ''
|
||||
PATH=$prefix/bin:$PATH
|
||||
unset PYTHONPATH
|
||||
export MANPATH=$out/share/man:$MANPATH
|
||||
installFlags = "sysconfdir=$(out)/etc";
|
||||
shellHook = ''
|
||||
PATH=$prefix/bin:$PATH
|
||||
unset PYTHONPATH
|
||||
export MANPATH=$out/share/man:$MANPATH
|
||||
|
||||
# Make bash completion work.
|
||||
XDG_DATA_DIRS+=:$out/share
|
||||
'';
|
||||
# Make bash completion work.
|
||||
XDG_DATA_DIRS+=:$out/share
|
||||
'';
|
||||
|
||||
# We use this shell with the local checkout, not unpackPhase.
|
||||
src = null;
|
||||
# We use this shell with the local checkout, not unpackPhase.
|
||||
src = null;
|
||||
|
||||
env = {
|
||||
# Needed for Meson to find Boost.
|
||||
# https://github.com/NixOS/nixpkgs/issues/86131.
|
||||
BOOST_INCLUDEDIR = "${lib.getDev pkgs.nixDependencies.boost}/include";
|
||||
BOOST_LIBRARYDIR = "${lib.getLib pkgs.nixDependencies.boost}/lib";
|
||||
# For `make format`, to work without installing pre-commit
|
||||
_NIX_PRE_COMMIT_HOOKS_CONFIG =
|
||||
"${(pkgs.formats.yaml { }).generate "pre-commit-config.yaml" modular.pre-commit.settings.rawConfig}";
|
||||
};
|
||||
env = {
|
||||
# Needed for Meson to find Boost.
|
||||
# https://github.com/NixOS/nixpkgs/issues/86131.
|
||||
BOOST_INCLUDEDIR = "${lib.getDev pkgs.nixDependencies.boost}/include";
|
||||
BOOST_LIBRARYDIR = "${lib.getLib pkgs.nixDependencies.boost}/lib";
|
||||
# For `make format`, to work without installing pre-commit
|
||||
_NIX_PRE_COMMIT_HOOKS_CONFIG = "${(pkgs.formats.yaml { }).generate "pre-commit-config.yaml"
|
||||
modular.pre-commit.settings.rawConfig
|
||||
}";
|
||||
};
|
||||
|
||||
mesonFlags =
|
||||
map (transformFlag "libutil") (ignoreCrossFile pkgs.nixComponents.nix-util.mesonFlags)
|
||||
++ map (transformFlag "libstore") (ignoreCrossFile pkgs.nixComponents.nix-store.mesonFlags)
|
||||
++ map (transformFlag "libfetchers") (ignoreCrossFile pkgs.nixComponents.nix-fetchers.mesonFlags)
|
||||
++ lib.optionals havePerl (map (transformFlag "perl") (ignoreCrossFile pkgs.nixComponents.nix-perl-bindings.mesonFlags))
|
||||
++ map (transformFlag "libexpr") (ignoreCrossFile pkgs.nixComponents.nix-expr.mesonFlags)
|
||||
++ map (transformFlag "libcmd") (ignoreCrossFile pkgs.nixComponents.nix-cmd.mesonFlags)
|
||||
;
|
||||
mesonFlags =
|
||||
map (transformFlag "libutil") (ignoreCrossFile pkgs.nixComponents.nix-util.mesonFlags)
|
||||
++ map (transformFlag "libstore") (ignoreCrossFile pkgs.nixComponents.nix-store.mesonFlags)
|
||||
++ map (transformFlag "libfetchers") (ignoreCrossFile pkgs.nixComponents.nix-fetchers.mesonFlags)
|
||||
++ lib.optionals havePerl (
|
||||
map (transformFlag "perl") (ignoreCrossFile pkgs.nixComponents.nix-perl-bindings.mesonFlags)
|
||||
)
|
||||
++ map (transformFlag "libexpr") (ignoreCrossFile pkgs.nixComponents.nix-expr.mesonFlags)
|
||||
++ map (transformFlag "libcmd") (ignoreCrossFile pkgs.nixComponents.nix-cmd.mesonFlags);
|
||||
|
||||
nativeBuildInputs = attrs.nativeBuildInputs or []
|
||||
++ pkgs.nixComponents.nix-util.nativeBuildInputs
|
||||
++ pkgs.nixComponents.nix-store.nativeBuildInputs
|
||||
++ pkgs.nixComponents.nix-fetchers.nativeBuildInputs
|
||||
++ pkgs.nixComponents.nix-expr.nativeBuildInputs
|
||||
++ lib.optionals havePerl pkgs.nixComponents.nix-perl-bindings.nativeBuildInputs
|
||||
++ lib.optionals buildCanExecuteHost pkgs.nixComponents.nix-manual.externalNativeBuildInputs
|
||||
++ pkgs.nixComponents.nix-internal-api-docs.nativeBuildInputs
|
||||
++ pkgs.nixComponents.nix-external-api-docs.nativeBuildInputs
|
||||
++ pkgs.nixComponents.nix-functional-tests.externalNativeBuildInputs
|
||||
++ lib.optional
|
||||
(!buildCanExecuteHost
|
||||
# Hack around https://github.com/nixos/nixpkgs/commit/bf7ad8cfbfa102a90463433e2c5027573b462479
|
||||
&& !(stdenv.hostPlatform.isWindows && stdenv.buildPlatform.isDarwin)
|
||||
&& stdenv.hostPlatform.emulatorAvailable pkgs.buildPackages
|
||||
&& lib.meta.availableOn stdenv.buildPlatform (stdenv.hostPlatform.emulator pkgs.buildPackages))
|
||||
pkgs.buildPackages.mesonEmulatorHook
|
||||
++ [
|
||||
pkgs.buildPackages.cmake
|
||||
pkgs.buildPackages.shellcheck
|
||||
pkgs.buildPackages.changelog-d
|
||||
modular.pre-commit.settings.package
|
||||
(pkgs.writeScriptBin "pre-commit-hooks-install"
|
||||
modular.pre-commit.settings.installationScript)
|
||||
]
|
||||
# TODO: Remove the darwin check once
|
||||
# https://github.com/NixOS/nixpkgs/pull/291814 is available
|
||||
++ lib.optional (stdenv.cc.isClang && !stdenv.buildPlatform.isDarwin) pkgs.buildPackages.bear
|
||||
++ lib.optional (stdenv.cc.isClang && stdenv.hostPlatform == stdenv.buildPlatform) (lib.hiPrio pkgs.buildPackages.clang-tools);
|
||||
nativeBuildInputs =
|
||||
attrs.nativeBuildInputs or [ ]
|
||||
++ pkgs.nixComponents.nix-util.nativeBuildInputs
|
||||
++ pkgs.nixComponents.nix-store.nativeBuildInputs
|
||||
++ pkgs.nixComponents.nix-fetchers.nativeBuildInputs
|
||||
++ pkgs.nixComponents.nix-expr.nativeBuildInputs
|
||||
++ lib.optionals havePerl pkgs.nixComponents.nix-perl-bindings.nativeBuildInputs
|
||||
++ lib.optionals buildCanExecuteHost pkgs.nixComponents.nix-manual.externalNativeBuildInputs
|
||||
++ pkgs.nixComponents.nix-internal-api-docs.nativeBuildInputs
|
||||
++ pkgs.nixComponents.nix-external-api-docs.nativeBuildInputs
|
||||
++ pkgs.nixComponents.nix-functional-tests.externalNativeBuildInputs
|
||||
++ lib.optional (
|
||||
!buildCanExecuteHost
|
||||
# Hack around https://github.com/nixos/nixpkgs/commit/bf7ad8cfbfa102a90463433e2c5027573b462479
|
||||
&& !(stdenv.hostPlatform.isWindows && stdenv.buildPlatform.isDarwin)
|
||||
&& stdenv.hostPlatform.emulatorAvailable pkgs.buildPackages
|
||||
&& lib.meta.availableOn stdenv.buildPlatform (stdenv.hostPlatform.emulator pkgs.buildPackages)
|
||||
) pkgs.buildPackages.mesonEmulatorHook
|
||||
++ [
|
||||
pkgs.buildPackages.cmake
|
||||
pkgs.buildPackages.shellcheck
|
||||
pkgs.buildPackages.changelog-d
|
||||
modular.pre-commit.settings.package
|
||||
(pkgs.writeScriptBin "pre-commit-hooks-install" modular.pre-commit.settings.installationScript)
|
||||
]
|
||||
# TODO: Remove the darwin check once
|
||||
# https://github.com/NixOS/nixpkgs/pull/291814 is available
|
||||
++ lib.optional (stdenv.cc.isClang && !stdenv.buildPlatform.isDarwin) pkgs.buildPackages.bear
|
||||
++ lib.optional (stdenv.cc.isClang && stdenv.hostPlatform == stdenv.buildPlatform) (
|
||||
lib.hiPrio pkgs.buildPackages.clang-tools
|
||||
);
|
||||
|
||||
buildInputs = attrs.buildInputs or []
|
||||
++ pkgs.nixComponents.nix-util.buildInputs
|
||||
++ pkgs.nixComponents.nix-store.buildInputs
|
||||
++ pkgs.nixComponents.nix-fetchers.buildInputs
|
||||
++ pkgs.nixComponents.nix-expr.buildInputs
|
||||
++ pkgs.nixComponents.nix-store-tests.externalBuildInputs
|
||||
++ lib.optional havePerl pkgs.perl
|
||||
;
|
||||
})
|
||||
buildInputs =
|
||||
attrs.buildInputs or [ ]
|
||||
++ pkgs.nixComponents.nix-util.buildInputs
|
||||
++ pkgs.nixComponents.nix-store.buildInputs
|
||||
++ pkgs.nixComponents.nix-fetchers.buildInputs
|
||||
++ pkgs.nixComponents.nix-expr.buildInputs
|
||||
++ pkgs.nixComponents.nix-store-tests.externalBuildInputs
|
||||
++ lib.optional havePerl pkgs.perl;
|
||||
}
|
||||
)
|
||||
|
||||
@@ -42,89 +42,96 @@
|
||||
|
||||
(buildEnv {
|
||||
name = "nix-${nix-cli.version}";
|
||||
paths = [
|
||||
nix-util
|
||||
nix-util-c
|
||||
nix-util-test-support
|
||||
nix-util-tests
|
||||
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-store
|
||||
nix-store-c
|
||||
nix-store-test-support
|
||||
nix-store-tests
|
||||
|
||||
nix-fetchers
|
||||
nix-fetchers-tests
|
||||
nix-fetchers
|
||||
nix-fetchers-tests
|
||||
|
||||
nix-expr
|
||||
nix-expr-c
|
||||
nix-expr-test-support
|
||||
nix-expr-tests
|
||||
nix-expr
|
||||
nix-expr-c
|
||||
nix-expr-test-support
|
||||
nix-expr-tests
|
||||
|
||||
nix-flake
|
||||
nix-flake-tests
|
||||
nix-flake
|
||||
nix-flake-tests
|
||||
|
||||
nix-main
|
||||
nix-main-c
|
||||
nix-main
|
||||
nix-main-c
|
||||
|
||||
nix-cmd
|
||||
nix-cmd
|
||||
|
||||
nix-cli
|
||||
nix-cli
|
||||
|
||||
nix-manual
|
||||
nix-internal-api-docs
|
||||
nix-external-api-docs
|
||||
nix-manual
|
||||
nix-internal-api-docs
|
||||
nix-external-api-docs
|
||||
|
||||
] ++ lib.optionals (stdenv.buildPlatform.canExecute stdenv.hostPlatform) [
|
||||
nix-perl-bindings
|
||||
];
|
||||
]
|
||||
++ lib.optionals (stdenv.buildPlatform.canExecute stdenv.hostPlatform) [
|
||||
nix-perl-bindings
|
||||
];
|
||||
|
||||
meta.mainProgram = "nix";
|
||||
}).overrideAttrs (finalAttrs: prevAttrs: {
|
||||
doCheck = true;
|
||||
doInstallCheck = true;
|
||||
}).overrideAttrs
|
||||
(
|
||||
finalAttrs: prevAttrs: {
|
||||
doCheck = true;
|
||||
doInstallCheck = true;
|
||||
|
||||
checkInputs = [
|
||||
# Actually run the unit tests too
|
||||
nix-util-tests.tests.run
|
||||
nix-store-tests.tests.run
|
||||
nix-expr-tests.tests.run
|
||||
nix-flake-tests.tests.run
|
||||
];
|
||||
installCheckInputs = [
|
||||
nix-functional-tests
|
||||
];
|
||||
passthru = prevAttrs.passthru // {
|
||||
/**
|
||||
These are the libraries that are part of the Nix project. They are used
|
||||
by the Nix CLI and other tools.
|
||||
checkInputs = [
|
||||
# Actually run the unit tests too
|
||||
nix-util-tests.tests.run
|
||||
nix-store-tests.tests.run
|
||||
nix-expr-tests.tests.run
|
||||
nix-flake-tests.tests.run
|
||||
];
|
||||
installCheckInputs = [
|
||||
nix-functional-tests
|
||||
];
|
||||
passthru = prevAttrs.passthru // {
|
||||
inherit (nix-cli) version;
|
||||
|
||||
If you need to use these libraries in your project, we recommend to use
|
||||
the `-c` C API libraries exclusively, if possible.
|
||||
/**
|
||||
These are the libraries that are part of the Nix project. They are used
|
||||
by the Nix CLI and other tools.
|
||||
|
||||
We also recommend that you build the complete package to ensure that the unit tests pass.
|
||||
You could do this in CI, or by passing it in an unused environment variable. e.g in a `mkDerivation` call:
|
||||
If you need to use these libraries in your project, we recommend to use
|
||||
the `-c` C API libraries exclusively, if possible.
|
||||
|
||||
```nix
|
||||
buildInputs = [ nix.libs.nix-util-c nix.libs.nix-store-c ];
|
||||
# Make sure the nix libs we use are ok
|
||||
unusedInputsForTests = [ nix ];
|
||||
disallowedReferences = nix.all;
|
||||
```
|
||||
*/
|
||||
libs = {
|
||||
inherit
|
||||
nix-util
|
||||
nix-util-c
|
||||
nix-store
|
||||
nix-store-c
|
||||
nix-fetchers
|
||||
nix-expr
|
||||
nix-expr-c
|
||||
nix-flake
|
||||
nix-main
|
||||
nix-main-c
|
||||
;
|
||||
};
|
||||
};
|
||||
})
|
||||
We also recommend that you build the complete package to ensure that the unit tests pass.
|
||||
You could do this in CI, or by passing it in an unused environment variable. e.g in a `mkDerivation` call:
|
||||
|
||||
```nix
|
||||
buildInputs = [ nix.libs.nix-util-c nix.libs.nix-store-c ];
|
||||
# Make sure the nix libs we use are ok
|
||||
unusedInputsForTests = [ nix ];
|
||||
disallowedReferences = nix.all;
|
||||
```
|
||||
*/
|
||||
libs = {
|
||||
inherit
|
||||
nix-util
|
||||
nix-util-c
|
||||
nix-store
|
||||
nix-store-c
|
||||
nix-fetchers
|
||||
nix-expr
|
||||
nix-expr-c
|
||||
nix-flake
|
||||
nix-main
|
||||
nix-main-c
|
||||
;
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,29 +1,32 @@
|
||||
{ inputs
|
||||
, binaryTarball
|
||||
, forAllCrossSystems
|
||||
, forAllSystems
|
||||
, lib
|
||||
, linux64BitSystems
|
||||
, nixpkgsFor
|
||||
, self
|
||||
, officialRelease
|
||||
{
|
||||
inputs,
|
||||
binaryTarball,
|
||||
forAllCrossSystems,
|
||||
forAllSystems,
|
||||
lib,
|
||||
linux64BitSystems,
|
||||
nixpkgsFor,
|
||||
self,
|
||||
officialRelease,
|
||||
}:
|
||||
let
|
||||
inherit (inputs) nixpkgs nixpkgs-regression;
|
||||
|
||||
installScriptFor = tarballs:
|
||||
installScriptFor =
|
||||
tarballs:
|
||||
nixpkgsFor.x86_64-linux.native.callPackage ../scripts/installer.nix {
|
||||
inherit tarballs;
|
||||
};
|
||||
|
||||
testNixVersions = pkgs: daemon:
|
||||
testNixVersions =
|
||||
pkgs: daemon:
|
||||
pkgs.nixComponents.nix-functional-tests.override {
|
||||
pname =
|
||||
"nix-tests"
|
||||
+ lib.optionalString
|
||||
(lib.versionAtLeast daemon.version "2.4pre20211005" &&
|
||||
lib.versionAtLeast pkgs.nix.version "2.4pre20211005")
|
||||
"-${pkgs.nix.version}-against-${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;
|
||||
};
|
||||
@@ -59,44 +62,70 @@ let
|
||||
in
|
||||
{
|
||||
# Binary package for various platforms.
|
||||
build = forAllPackages (pkgName:
|
||||
forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.${pkgName}));
|
||||
build = forAllPackages (
|
||||
pkgName: forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.${pkgName})
|
||||
);
|
||||
|
||||
shellInputs = removeAttrs
|
||||
(forAllSystems (system: self.devShells.${system}.default.inputDerivation))
|
||||
[ "i686-linux" ];
|
||||
shellInputs = removeAttrs (forAllSystems (
|
||||
system: self.devShells.${system}.default.inputDerivation
|
||||
)) [ "i686-linux" ];
|
||||
|
||||
buildStatic = forAllPackages (pkgName:
|
||||
lib.genAttrs linux64BitSystems (system: nixpkgsFor.${system}.static.nixComponents.${pkgName}));
|
||||
buildStatic = forAllPackages (
|
||||
pkgName:
|
||||
lib.genAttrs linux64BitSystems (system: nixpkgsFor.${system}.static.nixComponents.${pkgName})
|
||||
);
|
||||
|
||||
buildCross = forAllPackages (pkgName:
|
||||
buildCross = forAllPackages (
|
||||
pkgName:
|
||||
# Hack to avoid non-evaling package
|
||||
(if pkgName == "nix-functional-tests" then lib.flip builtins.removeAttrs ["x86_64-w64-mingw32"] else lib.id)
|
||||
(forAllCrossSystems (crossSystem:
|
||||
lib.genAttrs [ "x86_64-linux" ] (system: nixpkgsFor.${system}.cross.${crossSystem}.nixComponents.${pkgName}))));
|
||||
(
|
||||
if pkgName == "nix-functional-tests" then
|
||||
lib.flip builtins.removeAttrs [ "x86_64-w64-mingw32" ]
|
||||
else
|
||||
lib.id
|
||||
)
|
||||
(
|
||||
forAllCrossSystems (
|
||||
crossSystem:
|
||||
lib.genAttrs [ "x86_64-linux" ] (
|
||||
system: nixpkgsFor.${system}.cross.${crossSystem}.nixComponents.${pkgName}
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
buildNoGc = let
|
||||
components = forAllSystems (system:
|
||||
nixpkgsFor.${system}.native.nixComponents.overrideScope (self: super: {
|
||||
nix-expr = super.nix-expr.override { enableGC = false; };
|
||||
})
|
||||
);
|
||||
in forAllPackages (pkgName: forAllSystems (system: components.${system}.${pkgName}));
|
||||
buildNoGc =
|
||||
let
|
||||
components = forAllSystems (
|
||||
system:
|
||||
nixpkgsFor.${system}.native.nixComponents.overrideScope (
|
||||
self: super: {
|
||||
nix-expr = super.nix-expr.override { enableGC = false; };
|
||||
}
|
||||
)
|
||||
);
|
||||
in
|
||||
forAllPackages (pkgName: forAllSystems (system: components.${system}.${pkgName}));
|
||||
|
||||
buildNoTests = forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.nix-cli);
|
||||
|
||||
# Toggles some settings for better coverage. Windows needs these
|
||||
# library combinations, and Debian build Nix with GNU readline too.
|
||||
buildReadlineNoMarkdown = let
|
||||
components = forAllSystems (system:
|
||||
nixpkgsFor.${system}.native.nixComponents.overrideScope (self: super: {
|
||||
nix-cmd = super.nix-cmd.override {
|
||||
enableMarkdown = false;
|
||||
readlineFlavor = "readline";
|
||||
};
|
||||
})
|
||||
);
|
||||
in forAllPackages (pkgName: forAllSystems (system: components.${system}.${pkgName}));
|
||||
buildReadlineNoMarkdown =
|
||||
let
|
||||
components = forAllSystems (
|
||||
system:
|
||||
nixpkgsFor.${system}.native.nixComponents.overrideScope (
|
||||
self: super: {
|
||||
nix-cmd = super.nix-cmd.override {
|
||||
enableMarkdown = false;
|
||||
readlineFlavor = "readline";
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
in
|
||||
forAllPackages (pkgName: forAllSystems (system: components.${system}.${pkgName}));
|
||||
|
||||
# Perl bindings for various platforms.
|
||||
perlBindings = forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.nix-perl-bindings);
|
||||
@@ -104,13 +133,18 @@ in
|
||||
# Binary tarball for various platforms, containing a Nix store
|
||||
# with the closure of 'nix' package, and the second half of
|
||||
# the installation script.
|
||||
binaryTarball = forAllSystems (system: binaryTarball nixpkgsFor.${system}.native.nix nixpkgsFor.${system}.native);
|
||||
binaryTarball = forAllSystems (
|
||||
system: binaryTarball nixpkgsFor.${system}.native.nix nixpkgsFor.${system}.native
|
||||
);
|
||||
|
||||
binaryTarballCross = lib.genAttrs [ "x86_64-linux" ] (system:
|
||||
forAllCrossSystems (crossSystem:
|
||||
binaryTarball
|
||||
nixpkgsFor.${system}.cross.${crossSystem}.nix
|
||||
nixpkgsFor.${system}.cross.${crossSystem}));
|
||||
binaryTarballCross = lib.genAttrs [ "x86_64-linux" ] (
|
||||
system:
|
||||
forAllCrossSystems (
|
||||
crossSystem:
|
||||
binaryTarball nixpkgsFor.${system}.cross.${crossSystem}.nix
|
||||
nixpkgsFor.${system}.cross.${crossSystem}
|
||||
)
|
||||
);
|
||||
|
||||
# The first half of the installation script. This is uploaded
|
||||
# to https://nixos.org/nix/install. It downloads the binary
|
||||
@@ -128,15 +162,13 @@ in
|
||||
self.hydraJobs.binaryTarballCross."x86_64-linux"."armv7l-unknown-linux-gnueabihf"
|
||||
self.hydraJobs.binaryTarballCross."x86_64-linux"."riscv64-unknown-linux-gnu"
|
||||
];
|
||||
installerScriptForGHA = installScriptFor [
|
||||
# Native
|
||||
self.hydraJobs.binaryTarball."x86_64-linux"
|
||||
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"
|
||||
];
|
||||
|
||||
installerScriptForGHA = forAllSystems (
|
||||
system:
|
||||
nixpkgsFor.${system}.native.callPackage ../scripts/installer.nix {
|
||||
tarballs = [ self.hydraJobs.binaryTarball.${system} ];
|
||||
}
|
||||
);
|
||||
|
||||
# docker image with Nix inside
|
||||
dockerImage = lib.genAttrs linux64BitSystems (system: self.packages.${system}.dockerImage);
|
||||
@@ -157,16 +189,24 @@ in
|
||||
external-api-docs = nixpkgsFor.x86_64-linux.native.nixComponents.nix-external-api-docs;
|
||||
|
||||
# System tests.
|
||||
tests = import ../tests/nixos { inherit lib nixpkgs nixpkgsFor self; } // {
|
||||
tests =
|
||||
import ../tests/nixos {
|
||||
inherit
|
||||
lib
|
||||
nixpkgs
|
||||
nixpkgsFor
|
||||
self
|
||||
;
|
||||
}
|
||||
// {
|
||||
|
||||
# Make sure that nix-env still produces the exact same result
|
||||
# on a particular version of Nixpkgs.
|
||||
evalNixpkgs =
|
||||
let
|
||||
inherit (nixpkgsFor.x86_64-linux.native) runCommand nix;
|
||||
in
|
||||
runCommand "eval-nixos" { buildInputs = [ nix ]; }
|
||||
''
|
||||
# Make sure that nix-env still produces the exact same result
|
||||
# on a particular version of Nixpkgs.
|
||||
evalNixpkgs =
|
||||
let
|
||||
inherit (nixpkgsFor.x86_64-linux.native) runCommand nix;
|
||||
in
|
||||
runCommand "eval-nixos" { buildInputs = [ nix ]; } ''
|
||||
type -p nix-env
|
||||
# Note: we're filtering out nixos-install-tools because https://github.com/NixOS/nixpkgs/pull/153594#issuecomment-1020530593.
|
||||
(
|
||||
@@ -177,36 +217,36 @@ in
|
||||
mkdir $out
|
||||
'';
|
||||
|
||||
nixpkgsLibTests =
|
||||
forAllSystems (system:
|
||||
import (nixpkgs + "/lib/tests/test-with-nix.nix")
|
||||
{
|
||||
lib = nixpkgsFor.${system}.native.lib;
|
||||
nix = self.packages.${system}.nix;
|
||||
pkgs = nixpkgsFor.${system}.native;
|
||||
}
|
||||
nixpkgsLibTests = forAllSystems (
|
||||
system:
|
||||
import (nixpkgs + "/lib/tests/test-with-nix.nix") {
|
||||
lib = nixpkgsFor.${system}.native.lib;
|
||||
nix = self.packages.${system}.nix;
|
||||
pkgs = nixpkgsFor.${system}.native;
|
||||
}
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
metrics.nixpkgs = import "${nixpkgs-regression}/pkgs/top-level/metrics.nix" {
|
||||
pkgs = nixpkgsFor.x86_64-linux.native;
|
||||
nixpkgs = nixpkgs-regression;
|
||||
};
|
||||
|
||||
installTests = forAllSystems (system:
|
||||
let pkgs = nixpkgsFor.${system}.native; in
|
||||
pkgs.runCommand "install-tests"
|
||||
{
|
||||
againstSelf = testNixVersions pkgs pkgs.nix;
|
||||
againstCurrentLatest =
|
||||
# FIXME: temporarily disable this on macOS because of #3605.
|
||||
if system == "x86_64-linux"
|
||||
then testNixVersions pkgs pkgs.nixVersions.latest
|
||||
else null;
|
||||
# Disabled because the latest stable version doesn't handle
|
||||
# `NIX_DAEMON_SOCKET_PATH` which is required for the tests to work
|
||||
# againstLatestStable = testNixVersions pkgs pkgs.nixStable;
|
||||
} "touch $out");
|
||||
installTests = forAllSystems (
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgsFor.${system}.native;
|
||||
in
|
||||
pkgs.runCommand "install-tests" {
|
||||
againstSelf = testNixVersions pkgs pkgs.nix;
|
||||
againstCurrentLatest =
|
||||
# FIXME: temporarily disable this on macOS because of #3605.
|
||||
if system == "x86_64-linux" then testNixVersions pkgs pkgs.nixVersions.latest else null;
|
||||
# Disabled because the latest stable version doesn't handle
|
||||
# `NIX_DAEMON_SOCKET_PATH` which is required for the tests to work
|
||||
# againstLatestStable = testNixVersions pkgs pkgs.nixStable;
|
||||
} "touch $out"
|
||||
);
|
||||
|
||||
installerTests = import ../tests/installer {
|
||||
binaryTarballs = self.hydraJobs.binaryTarball;
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
{ runCommand
|
||||
, system
|
||||
, buildPackages
|
||||
, cacert
|
||||
, nix
|
||||
{
|
||||
runCommand,
|
||||
system,
|
||||
buildPackages,
|
||||
cacert,
|
||||
nix,
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
installerClosureInfo = buildPackages.closureInfo {
|
||||
rootPaths = [ nix cacert ];
|
||||
rootPaths = [
|
||||
nix
|
||||
cacert
|
||||
];
|
||||
};
|
||||
|
||||
inherit (nix) version;
|
||||
@@ -65,7 +69,7 @@ runCommand "nix-binary-tarball-${version}" env ''
|
||||
fn=$out/$dir.tar.xz
|
||||
mkdir -p $out/nix-support
|
||||
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 \
|
||||
--mtime='1970-01-01' \
|
||||
--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
|
||||
:a
|
||||
UUID=$uuid $escaped_mountpoint apfs rw,noauto,nobrowse,suid,owners
|
||||
UUID=$uuid $escaped_mountpoint apfs rw,noauto,nobrowse,nosuid,noatime,owners
|
||||
.
|
||||
:x
|
||||
EOF
|
||||
|
||||
@@ -557,7 +557,7 @@ create_build_user_for_core() {
|
||||
if [ "$actual_uid" != "$uid" ]; then
|
||||
failure <<EOF
|
||||
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.
|
||||
|
||||
If you already created the users and you know they start from
|
||||
|
||||
@@ -1,36 +1,42 @@
|
||||
{ lib
|
||||
, runCommand
|
||||
, nix
|
||||
, tarballs
|
||||
{
|
||||
lib,
|
||||
runCommand,
|
||||
nix,
|
||||
tarballs,
|
||||
}:
|
||||
|
||||
runCommand "installer-script" {
|
||||
buildInputs = [ nix ];
|
||||
} ''
|
||||
mkdir -p $out/nix-support
|
||||
|
||||
# Converts /nix/store/50p3qk8k...-nix-2.4pre20201102_550e11f/bin/nix to 50p3qk8k.../bin/nix.
|
||||
tarballPath() {
|
||||
# Remove the store prefix
|
||||
local path=''${1#${builtins.storeDir}/}
|
||||
# Get the path relative to the derivation root
|
||||
local rest=''${path#*/}
|
||||
# Get the derivation hash
|
||||
local drvHash=''${path%%-*}
|
||||
echo "$drvHash/$rest"
|
||||
runCommand "installer-script"
|
||||
{
|
||||
buildInputs = [ nix ];
|
||||
}
|
||||
''
|
||||
mkdir -p $out/nix-support
|
||||
|
||||
substitute ${./install.in} $out/install \
|
||||
${lib.concatMapStrings
|
||||
(tarball: let
|
||||
inherit (tarball.stdenv.hostPlatform) system;
|
||||
in '' \
|
||||
--replace '@tarballHash_${system}@' $(nix --experimental-features nix-command hash-file --base16 --type sha256 ${tarball}/*.tar.xz) \
|
||||
--replace '@tarballPath_${system}@' $(tarballPath ${tarball}/*.tar.xz) \
|
||||
''
|
||||
)
|
||||
tarballs
|
||||
} --replace '@nixVersion@' ${nix.version}
|
||||
# Converts /nix/store/50p3qk8k...-nix-2.4pre20201102_550e11f/bin/nix to 50p3qk8k.../bin/nix.
|
||||
tarballPath() {
|
||||
# Remove the store prefix
|
||||
local path=''${1#${builtins.storeDir}/}
|
||||
# Get the path relative to the derivation root
|
||||
local rest=''${path#*/}
|
||||
# Get the derivation hash
|
||||
local drvHash=''${path%%-*}
|
||||
echo "$drvHash/$rest"
|
||||
}
|
||||
|
||||
echo "file installer $out/install" >> $out/nix-support/hydra-build-products
|
||||
''
|
||||
substitute ${./install.in} $out/install \
|
||||
${
|
||||
lib.concatMapStrings (
|
||||
tarball:
|
||||
let
|
||||
inherit (tarball.stdenv.hostPlatform) system;
|
||||
in
|
||||
''
|
||||
\
|
||||
--replace '@tarballHash_${system}@' $(nix --experimental-features nix-command hash-file --base16 --type sha256 ${tarball}/*.tar.xz) \
|
||||
--replace '@tarballPath_${system}@' $(tarballPath ${tarball}/*.tar.xz) \
|
||||
''
|
||||
) tarballs
|
||||
} --replace '@nixVersion@' ${nix.version}
|
||||
|
||||
echo "file installer $out/install" >> $out/nix-support/hydra-build-products
|
||||
''
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Only execute this file once per shell.
|
||||
# This file is tested by tests/installer/default.nix.
|
||||
if [ -n "${__ETC_PROFILE_NIX_SOURCED:-}" ]; then return; fi
|
||||
__ETC_PROFILE_NIX_SOURCED=1
|
||||
export __ETC_PROFILE_NIX_SOURCED=1
|
||||
|
||||
NIX_LINK=$HOME/.nix-profile
|
||||
if [ -n "${XDG_STATE_HOME-}" ]; then
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -euo pipefail
|
||||
|
||||
script=$(nix-build -A outputs.hydraJobs.installerScriptForGHA --no-out-link)
|
||||
installerHash=$(echo "$script" | cut -b12-43 -)
|
||||
nix build -L ".#installerScriptForGHA" ".#binaryTarball"
|
||||
|
||||
installerURL=https://$CACHIX_NAME.cachix.org/serve/$installerHash/install
|
||||
|
||||
echo "::set-output name=installerURL::$installerURL"
|
||||
mkdir -p out
|
||||
cp ./result/install "out/install"
|
||||
name="$(basename "$(realpath ./result-1)")"
|
||||
# everything before the first dash
|
||||
cp -r ./result-1 "out/${name%%-*}"
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
# stock path to avoid unexpected command versions
|
||||
PATH="$(/usr/bin/getconf PATH)"
|
||||
|
||||
((NEW_NIX_FIRST_BUILD_UID=351))
|
||||
((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"
|
||||
@@ -1,11 +1,12 @@
|
||||
{ lib
|
||||
, mkMesonDerivation
|
||||
{
|
||||
lib,
|
||||
mkMesonDerivation,
|
||||
|
||||
, doxygen
|
||||
doxygen,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
version,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -38,11 +39,10 @@ mkMesonDerivation (finalAttrs: {
|
||||
doxygen
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${finalAttrs.version} > ./.version
|
||||
'';
|
||||
preConfigure = ''
|
||||
chmod u+w ./.version
|
||||
echo ${finalAttrs.version} > ./.version
|
||||
'';
|
||||
|
||||
postInstall = ''
|
||||
mkdir -p ''${!outputDoc}/nix-support
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
{ lib
|
||||
, mkMesonDerivation
|
||||
{
|
||||
lib,
|
||||
mkMesonDerivation,
|
||||
|
||||
, doxygen
|
||||
doxygen,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
version,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -17,27 +18,28 @@ mkMesonDerivation (finalAttrs: {
|
||||
inherit version;
|
||||
|
||||
workDir = ./.;
|
||||
fileset = let
|
||||
cpp = fileset.fileFilter (file: file.hasExt "cc" || file.hasExt "hh");
|
||||
in fileset.unions [
|
||||
./.version
|
||||
../../.version
|
||||
./meson.build
|
||||
./doxygen.cfg.in
|
||||
# Source is not compiled, but still must be available for Doxygen
|
||||
# to gather comments.
|
||||
(cpp ../.)
|
||||
];
|
||||
fileset =
|
||||
let
|
||||
cpp = fileset.fileFilter (file: file.hasExt "cc" || file.hasExt "hh");
|
||||
in
|
||||
fileset.unions [
|
||||
./.version
|
||||
../../.version
|
||||
./meson.build
|
||||
./doxygen.cfg.in
|
||||
# Source is not compiled, but still must be available for Doxygen
|
||||
# to gather comments.
|
||||
(cpp ../.)
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
doxygen
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${finalAttrs.version} > ./.version
|
||||
'';
|
||||
preConfigure = ''
|
||||
chmod u+w ./.version
|
||||
echo ${finalAttrs.version} > ./.version
|
||||
'';
|
||||
|
||||
postInstall = ''
|
||||
mkdir -p ''${!outputDoc}/nix-support
|
||||
|
||||
@@ -32,16 +32,6 @@ InstallableDerivedPath InstallableDerivedPath::parse(
|
||||
// store path.
|
||||
[&](const ExtendedOutputsSpec::Default &) -> DerivedPath {
|
||||
auto storePath = store->followLinksToStorePath(prefix);
|
||||
// Remove this prior to stabilizing the new CLI.
|
||||
if (storePath.isDerivation()) {
|
||||
auto oldDerivedPath = DerivedPath::Built {
|
||||
.drvPath = makeConstantStorePathRef(storePath),
|
||||
.outputs = OutputsSpec::All { },
|
||||
};
|
||||
warn(
|
||||
"The interpretation of store paths arguments ending in `.drv` recently changed. If this command is now failing try again with '%s'",
|
||||
oldDerivedPath.to_string(*store));
|
||||
};
|
||||
return DerivedPath::Opaque {
|
||||
.path = std::move(storePath),
|
||||
};
|
||||
|
||||
@@ -16,13 +16,25 @@ static std::string doRenderMarkdownToTerminal(std::string_view markdown)
|
||||
{
|
||||
int windowWidth = getWindowSize().second;
|
||||
|
||||
struct lowdown_opts opts
|
||||
{
|
||||
.type = LOWDOWN_TERM,
|
||||
.maxdepth = 20,
|
||||
#if HAVE_LOWDOWN_1_4
|
||||
struct lowdown_opts_term opts_term {
|
||||
.cols = (size_t) std::max(windowWidth - 5, 60),
|
||||
.hmargin = 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,
|
||||
.oflags = LOWDOWN_TERM_NOLINK,
|
||||
};
|
||||
|
||||
@@ -38,6 +38,8 @@ deps_public += nlohmann_json
|
||||
lowdown = dependency('lowdown', version : '>= 0.9.0', required : get_option('markdown'))
|
||||
deps_private += lowdown
|
||||
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')
|
||||
if readline_flavor == 'editline'
|
||||
|
||||
@@ -1,32 +1,33 @@
|
||||
{ lib
|
||||
, stdenv
|
||||
, mkMesonLibrary
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
mkMesonLibrary,
|
||||
|
||||
, nix-util
|
||||
, nix-store
|
||||
, nix-fetchers
|
||||
, nix-expr
|
||||
, nix-flake
|
||||
, nix-main
|
||||
, editline
|
||||
, readline
|
||||
, lowdown
|
||||
, nlohmann_json
|
||||
nix-util,
|
||||
nix-store,
|
||||
nix-fetchers,
|
||||
nix-expr,
|
||||
nix-flake,
|
||||
nix-main,
|
||||
editline,
|
||||
readline,
|
||||
lowdown,
|
||||
nlohmann_json,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
version,
|
||||
|
||||
# Whether to enable Markdown rendering in the Nix binary.
|
||||
, enableMarkdown ? !stdenv.hostPlatform.isWindows
|
||||
# Whether to enable Markdown rendering in the Nix binary.
|
||||
enableMarkdown ? !stdenv.hostPlatform.isWindows,
|
||||
|
||||
# Which interactive line editor library to use for Nix's repl.
|
||||
#
|
||||
# Currently supported choices are:
|
||||
#
|
||||
# - editline (default)
|
||||
# - readline
|
||||
, readlineFlavor ? if stdenv.hostPlatform.isWindows then "readline" else "editline"
|
||||
# Which interactive line editor library to use for Nix's repl.
|
||||
#
|
||||
# Currently supported choices are:
|
||||
#
|
||||
# - editline (default)
|
||||
# - readline
|
||||
readlineFlavor ? if stdenv.hostPlatform.isWindows then "readline" else "editline",
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -76,9 +77,12 @@ mkMesonLibrary (finalAttrs: {
|
||||
(lib.mesonOption "readline-flavor" readlineFlavor)
|
||||
];
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
|
||||
@@ -138,16 +138,13 @@ static std::ostream & showDebugTrace(std::ostream & out, const PosTable & positi
|
||||
out << ANSI_RED "error: " << ANSI_NORMAL;
|
||||
out << dt.hint.str() << "\n";
|
||||
|
||||
// prefer direct pos, but if noPos then try the expr.
|
||||
auto pos = dt.pos
|
||||
? dt.pos
|
||||
: positions[dt.expr.getPos() ? dt.expr.getPos() : noPos];
|
||||
auto pos = dt.getPos(positions);
|
||||
|
||||
if (pos) {
|
||||
out << *pos;
|
||||
if (auto loc = pos->getCodeLines()) {
|
||||
out << pos;
|
||||
if (auto loc = pos.getCodeLines()) {
|
||||
out << "\n";
|
||||
printCodeLines(out, "", *pos, *loc);
|
||||
printCodeLines(out, "", pos, *loc);
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -613,12 +613,8 @@ nix_realised_string * nix_string_realise(nix_c_context * context, EvalState * st
|
||||
context->last_err_code = NIX_OK;
|
||||
try {
|
||||
auto & v = check_value_in(value);
|
||||
nix::NixStringContext stringContext;
|
||||
auto rawStr = state->state.coerceToString(nix::noPos, v, stringContext, "while realising a string").toOwned();
|
||||
nix::StorePathSet storePaths;
|
||||
auto rewrites = state->state.realiseContext(stringContext, &storePaths);
|
||||
|
||||
auto s = nix::rewriteStrings(rawStr, rewrites);
|
||||
auto s = state->state.realiseString(v, &storePaths, isIFD);
|
||||
|
||||
// Convert to the C API StorePath type and convert to vector for index-based access
|
||||
std::vector<StorePath> vec;
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
{ lib
|
||||
, stdenv
|
||||
, mkMesonLibrary
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
mkMesonLibrary,
|
||||
|
||||
, nix-store-c
|
||||
, nix-expr
|
||||
nix-store-c,
|
||||
nix-expr,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
version,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -47,9 +48,12 @@ mkMesonLibrary (finalAttrs: {
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
{ lib
|
||||
, stdenv
|
||||
, mkMesonLibrary
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
mkMesonLibrary,
|
||||
|
||||
, nix-store-test-support
|
||||
, nix-expr
|
||||
nix-store-test-support,
|
||||
nix-expr,
|
||||
|
||||
, rapidcheck
|
||||
rapidcheck,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
version,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -49,9 +50,12 @@ mkMesonLibrary (finalAttrs: {
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
{ lib
|
||||
, buildPackages
|
||||
, stdenv
|
||||
, mkMesonExecutable
|
||||
{
|
||||
lib,
|
||||
buildPackages,
|
||||
stdenv,
|
||||
mkMesonExecutable,
|
||||
|
||||
, nix-expr
|
||||
, nix-expr-c
|
||||
, nix-expr-test-support
|
||||
nix-expr,
|
||||
nix-expr-c,
|
||||
nix-expr-test-support,
|
||||
|
||||
, rapidcheck
|
||||
, gtest
|
||||
, runCommand
|
||||
rapidcheck,
|
||||
gtest,
|
||||
runCommand,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
, resolvePath
|
||||
version,
|
||||
resolvePath,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -56,22 +57,31 @@ mkMesonExecutable (finalAttrs: {
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
passthru = {
|
||||
tests = {
|
||||
run = runCommand "${finalAttrs.pname}-run" {
|
||||
meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages;
|
||||
} (lib.optionalString stdenv.hostPlatform.isWindows ''
|
||||
export HOME="$PWD/home-dir"
|
||||
mkdir -p "$HOME"
|
||||
'' + ''
|
||||
export _NIX_TEST_UNIT_DATA=${resolvePath ./data}
|
||||
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
|
||||
touch $out
|
||||
'');
|
||||
run =
|
||||
runCommand "${finalAttrs.pname}-run"
|
||||
{
|
||||
meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages;
|
||||
}
|
||||
(
|
||||
lib.optionalString stdenv.hostPlatform.isWindows ''
|
||||
export HOME="$PWD/home-dir"
|
||||
mkdir -p "$HOME"
|
||||
''
|
||||
+ ''
|
||||
export _NIX_TEST_UNIT_DATA=${resolvePath ./data}
|
||||
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
|
||||
touch $out
|
||||
''
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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) {
|
||||
auto v = eval("{ __functor = self: arg: self.v + arg; v = 10; } 5");
|
||||
ASSERT_THAT(v, IsIntEq(15));
|
||||
|
||||
@@ -20,70 +20,70 @@ let
|
||||
# Resolve a input spec into a node name. An input spec is
|
||||
# either a node name, or a 'follows' path from the root
|
||||
# node.
|
||||
resolveInput = inputSpec:
|
||||
if builtins.isList inputSpec
|
||||
then getInputByPath lockFile.root inputSpec
|
||||
else inputSpec;
|
||||
resolveInput =
|
||||
inputSpec: if builtins.isList inputSpec then getInputByPath lockFile.root inputSpec else inputSpec;
|
||||
|
||||
# Follow an input path (e.g. ["dwarffs" "nixpkgs"]) from the
|
||||
# root node, returning the final node.
|
||||
getInputByPath = nodeName: path:
|
||||
if path == []
|
||||
then nodeName
|
||||
getInputByPath =
|
||||
nodeName: path:
|
||||
if path == [ ] then
|
||||
nodeName
|
||||
else
|
||||
getInputByPath
|
||||
# Since this could be a 'follows' input, call resolveInput.
|
||||
(resolveInput lockFile.nodes.${nodeName}.inputs.${builtins.head path})
|
||||
(builtins.tail path);
|
||||
|
||||
allNodes =
|
||||
builtins.mapAttrs
|
||||
(key: node:
|
||||
let
|
||||
allNodes = builtins.mapAttrs (
|
||||
key: node:
|
||||
let
|
||||
|
||||
sourceInfo =
|
||||
if overrides ? ${key}
|
||||
then
|
||||
overrides.${key}.sourceInfo
|
||||
else
|
||||
# FIXME: remove obsolete node.info.
|
||||
# Note: lock file entries are always final.
|
||||
fetchTreeFinal (node.info or {} // removeAttrs node.locked ["dir"]);
|
||||
sourceInfo =
|
||||
if overrides ? ${key} then
|
||||
overrides.${key}.sourceInfo
|
||||
else
|
||||
# FIXME: remove obsolete node.info.
|
||||
# Note: lock file entries are always final.
|
||||
fetchTreeFinal (node.info or { } // removeAttrs node.locked [ "dir" ]);
|
||||
|
||||
subdir = overrides.${key}.dir or node.locked.dir or "";
|
||||
subdir = overrides.${key}.dir or node.locked.dir or "";
|
||||
|
||||
outPath = sourceInfo + ((if subdir == "" then "" else "/") + subdir);
|
||||
outPath = sourceInfo + ((if subdir == "" then "" else "/") + subdir);
|
||||
|
||||
flake = import (outPath + "/flake.nix");
|
||||
flake = import (outPath + "/flake.nix");
|
||||
|
||||
inputs = builtins.mapAttrs
|
||||
(inputName: inputSpec: allNodes.${resolveInput inputSpec})
|
||||
(node.inputs or {});
|
||||
inputs = builtins.mapAttrs (inputName: inputSpec: allNodes.${resolveInput inputSpec}) (
|
||||
node.inputs or { }
|
||||
);
|
||||
|
||||
outputs = flake.outputs (inputs // { self = result; });
|
||||
outputs = flake.outputs (inputs // { self = result; });
|
||||
|
||||
result =
|
||||
outputs
|
||||
# We add the sourceInfo attribute for its metadata, as they are
|
||||
# relevant metadata for the flake. However, the outPath of the
|
||||
# sourceInfo does not necessarily match the outPath of the flake,
|
||||
# as the flake may be in a subdirectory of a source.
|
||||
# This is shadowed in the next //
|
||||
// sourceInfo
|
||||
// {
|
||||
# This shadows the sourceInfo.outPath
|
||||
inherit outPath;
|
||||
result =
|
||||
outputs
|
||||
# We add the sourceInfo attribute for its metadata, as they are
|
||||
# relevant metadata for the flake. However, the outPath of the
|
||||
# sourceInfo does not necessarily match the outPath of the flake,
|
||||
# as the flake may be in a subdirectory of a source.
|
||||
# This is shadowed in the next //
|
||||
// sourceInfo
|
||||
// {
|
||||
# This shadows the sourceInfo.outPath
|
||||
inherit outPath;
|
||||
|
||||
inherit inputs; inherit outputs; inherit sourceInfo; _type = "flake";
|
||||
};
|
||||
inherit inputs;
|
||||
inherit outputs;
|
||||
inherit sourceInfo;
|
||||
_type = "flake";
|
||||
};
|
||||
|
||||
in
|
||||
if node.flake or true then
|
||||
assert builtins.isFunction flake.outputs;
|
||||
result
|
||||
else
|
||||
sourceInfo
|
||||
)
|
||||
lockFile.nodes;
|
||||
in
|
||||
if node.flake or true then
|
||||
assert builtins.isFunction flake.outputs;
|
||||
result
|
||||
else
|
||||
sourceInfo
|
||||
) lockFile.nodes;
|
||||
|
||||
in allNodes.${lockFile.root}
|
||||
in
|
||||
allNodes.${lockFile.root}
|
||||
|
||||
@@ -45,7 +45,7 @@ EvalErrorBuilder<T> & EvalErrorBuilder<T>::withFrame(const Env & env, const Expr
|
||||
// TODO: check compatibility with nested debugger calls.
|
||||
// TODO: What side-effects??
|
||||
error.state.debugTraces.push_front(DebugTrace{
|
||||
.pos = error.state.positions[expr.getPos()],
|
||||
.pos = expr.getPos(),
|
||||
.expr = expr,
|
||||
.env = env,
|
||||
.hint = HintFmt("Fake frame for debugging purposes"),
|
||||
|
||||
@@ -396,7 +396,7 @@ void EvalState::checkURI(const std::string & uri)
|
||||
|
||||
/* If the URI is a path, then check it against allowedPaths as
|
||||
well. */
|
||||
if (hasPrefix(uri, "/")) {
|
||||
if (isAbsolute(uri)) {
|
||||
if (auto rootFS2 = rootFS.dynamic_pointer_cast<AllowListSourceAccessor>())
|
||||
rootFS2->checkAccess(CanonPath(uri));
|
||||
return;
|
||||
@@ -734,18 +734,26 @@ void EvalState::runDebugRepl(const Error * error, const Env & env, const Expr &
|
||||
if (!debugRepl || inDebugger)
|
||||
return;
|
||||
|
||||
auto dts =
|
||||
error && expr.getPos()
|
||||
? std::make_unique<DebugTraceStacker>(
|
||||
*this,
|
||||
DebugTrace {
|
||||
.pos = error->info().pos ? error->info().pos : positions[expr.getPos()],
|
||||
auto dts = [&]() -> std::unique_ptr<DebugTraceStacker> {
|
||||
if (error && expr.getPos()) {
|
||||
auto trace = DebugTrace{
|
||||
.pos = [&]() -> std::variant<Pos, PosIdx> {
|
||||
if (error->info().pos) {
|
||||
if (auto * pos = error->info().pos.get())
|
||||
return *pos;
|
||||
return noPos;
|
||||
}
|
||||
return expr.getPos();
|
||||
}(),
|
||||
.expr = expr,
|
||||
.env = env,
|
||||
.hint = error->info().msg,
|
||||
.isError = true
|
||||
})
|
||||
: nullptr;
|
||||
.isError = true};
|
||||
|
||||
return std::make_unique<DebugTraceStacker>(*this, std::move(trace));
|
||||
}
|
||||
return nullptr;
|
||||
}();
|
||||
|
||||
if (error)
|
||||
{
|
||||
@@ -790,7 +798,7 @@ static std::unique_ptr<DebugTraceStacker> makeDebugTraceStacker(
|
||||
EvalState & state,
|
||||
Expr & expr,
|
||||
Env & env,
|
||||
std::shared_ptr<Pos> && pos,
|
||||
std::variant<Pos, PosIdx> pos,
|
||||
const Args & ... formatArgs)
|
||||
{
|
||||
return std::make_unique<DebugTraceStacker>(state,
|
||||
@@ -1067,7 +1075,7 @@ void EvalState::evalFile(const SourcePath & path, Value & v, bool mustBeTrivial)
|
||||
*this,
|
||||
*e,
|
||||
this->baseEnv,
|
||||
e->getPos() ? std::make_shared<Pos>(positions[e->getPos()]) : nullptr,
|
||||
e->getPos(),
|
||||
"while evaluating the file '%1%':", resolvedPath.to_string())
|
||||
: nullptr;
|
||||
|
||||
@@ -1293,9 +1301,7 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
|
||||
state,
|
||||
*this,
|
||||
env2,
|
||||
getPos()
|
||||
? std::make_shared<Pos>(state.positions[getPos()])
|
||||
: nullptr,
|
||||
getPos(),
|
||||
"while evaluating a '%1%' expression",
|
||||
"let"
|
||||
)
|
||||
@@ -1364,7 +1370,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
||||
state,
|
||||
*this,
|
||||
env,
|
||||
state.positions[getPos()],
|
||||
getPos(),
|
||||
"while evaluating the attribute '%1%'",
|
||||
showAttrPath(state, env, attrPath))
|
||||
: nullptr;
|
||||
@@ -1565,7 +1571,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||
try {
|
||||
auto dts = debugRepl
|
||||
? makeDebugTraceStacker(
|
||||
*this, *lambda.body, env2, positions[lambda.pos],
|
||||
*this, *lambda.body, env2, lambda.pos,
|
||||
"while calling %s",
|
||||
lambda.name
|
||||
? concatStrings("'", symbols[lambda.name], "'")
|
||||
@@ -1704,9 +1710,7 @@ void ExprCall::eval(EvalState & state, Env & env, Value & v)
|
||||
state,
|
||||
*this,
|
||||
env,
|
||||
getPos()
|
||||
? std::make_shared<Pos>(state.positions[getPos()])
|
||||
: nullptr,
|
||||
getPos(),
|
||||
"while calling a function"
|
||||
)
|
||||
: nullptr;
|
||||
@@ -2087,7 +2091,7 @@ void EvalState::forceValueDeep(Value & v)
|
||||
try {
|
||||
// If the value is a thunk, we're evaling. Otherwise no trace necessary.
|
||||
auto dts = debugRepl && i.value->isThunk()
|
||||
? makeDebugTraceStacker(*this, *i.value->payload.thunk.expr, *i.value->payload.thunk.env, positions[i.pos],
|
||||
? makeDebugTraceStacker(*this, *i.value->payload.thunk.expr, *i.value->payload.thunk.env, i.pos,
|
||||
"while evaluating the attribute '%1%'", symbols[i.name])
|
||||
: nullptr;
|
||||
|
||||
@@ -2365,7 +2369,7 @@ StorePath EvalState::copyPathToStore(NixStringContext & context, const SourcePat
|
||||
: [&]() {
|
||||
auto dstPath = fetchToStore(
|
||||
*store,
|
||||
path.resolveSymlinks(),
|
||||
path.resolveSymlinks(SymlinkResolution::Ancestors),
|
||||
settings.readOnlyMode ? FetchMode::DryRun : FetchMode::Copy,
|
||||
path.baseName(),
|
||||
ContentAddressMethod::Raw::NixArchive,
|
||||
|
||||
@@ -171,11 +171,28 @@ struct RegexCache;
|
||||
std::shared_ptr<RegexCache> makeRegexCache();
|
||||
|
||||
struct DebugTrace {
|
||||
std::shared_ptr<Pos> pos;
|
||||
/* WARNING: Converting PosIdx -> Pos should be done with extra care. This is
|
||||
due to the fact that operator[] of PosTable is incredibly expensive. */
|
||||
std::variant<Pos, PosIdx> pos;
|
||||
const Expr & expr;
|
||||
const Env & env;
|
||||
HintFmt hint;
|
||||
bool isError;
|
||||
|
||||
Pos getPos(const PosTable & table) const
|
||||
{
|
||||
return std::visit(
|
||||
overloaded{
|
||||
[&](PosIdx idx) {
|
||||
// Prefer direct pos, but if noPos then try the expr.
|
||||
if (!idx)
|
||||
idx = expr.getPos();
|
||||
return table[idx];
|
||||
},
|
||||
[&](Pos pos) { return pos; },
|
||||
},
|
||||
pos);
|
||||
}
|
||||
};
|
||||
|
||||
class EvalState : public std::enable_shared_from_this<EvalState>
|
||||
@@ -805,6 +822,15 @@ public:
|
||||
*/
|
||||
[[nodiscard]] StringMap realiseContext(const NixStringContext & context, StorePathSet * maybePaths = nullptr, bool isIFD = true);
|
||||
|
||||
/**
|
||||
* Realise the given string with context, and return the string with outputs instead of downstream output placeholders.
|
||||
* @param[in] str the string to realise
|
||||
* @param[out] paths all referenced store paths will be added to this set
|
||||
* @return the realised string
|
||||
* @throw EvalError if the value is not a string, path or derivation (see `coerceToString`)
|
||||
*/
|
||||
std::string realiseString(Value & str, StorePathSet * storePathsOutMaybe, bool isIFD = true, const PosIdx pos = noPos);
|
||||
|
||||
/* Call the binary path filter predicate used builtins.path etc. */
|
||||
bool callPathFilter(
|
||||
Value * filterFun,
|
||||
|
||||
@@ -1,40 +1,72 @@
|
||||
{ system ? "" # obsolete
|
||||
, url
|
||||
, hash ? "" # an SRI hash
|
||||
{
|
||||
system ? "", # obsolete
|
||||
url,
|
||||
hash ? "", # an SRI hash
|
||||
|
||||
# Legacy hash specification
|
||||
, md5 ? "", sha1 ? "", sha256 ? "", sha512 ? ""
|
||||
, outputHash ?
|
||||
if hash != "" then hash else if sha512 != "" then sha512 else if sha1 != "" then sha1 else if md5 != "" then md5 else sha256
|
||||
, outputHashAlgo ?
|
||||
if hash != "" then "" else if sha512 != "" then "sha512" else if sha1 != "" then "sha1" else if md5 != "" then "md5" else "sha256"
|
||||
# Legacy hash specification
|
||||
md5 ? "",
|
||||
sha1 ? "",
|
||||
sha256 ? "",
|
||||
sha512 ? "",
|
||||
outputHash ?
|
||||
if hash != "" then
|
||||
hash
|
||||
else if sha512 != "" then
|
||||
sha512
|
||||
else if sha1 != "" then
|
||||
sha1
|
||||
else if md5 != "" then
|
||||
md5
|
||||
else
|
||||
sha256,
|
||||
outputHashAlgo ?
|
||||
if hash != "" then
|
||||
""
|
||||
else if sha512 != "" then
|
||||
"sha512"
|
||||
else if sha1 != "" then
|
||||
"sha1"
|
||||
else if md5 != "" then
|
||||
"md5"
|
||||
else
|
||||
"sha256",
|
||||
|
||||
, executable ? false
|
||||
, unpack ? false
|
||||
, name ? baseNameOf (toString url)
|
||||
, impure ? false
|
||||
executable ? false,
|
||||
unpack ? false,
|
||||
name ? baseNameOf (toString url),
|
||||
impure ? false,
|
||||
}:
|
||||
|
||||
derivation ({
|
||||
builder = "builtin:fetchurl";
|
||||
derivation (
|
||||
{
|
||||
builder = "builtin:fetchurl";
|
||||
|
||||
# New-style output content requirements.
|
||||
outputHashMode = if unpack || executable then "recursive" else "flat";
|
||||
# New-style output content requirements.
|
||||
outputHashMode = if unpack || executable then "recursive" else "flat";
|
||||
|
||||
inherit name url executable unpack;
|
||||
inherit
|
||||
name
|
||||
url
|
||||
executable
|
||||
unpack
|
||||
;
|
||||
|
||||
system = "builtin";
|
||||
system = "builtin";
|
||||
|
||||
# No need to double the amount of network traffic
|
||||
preferLocalBuild = true;
|
||||
# No need to double the amount of network traffic
|
||||
preferLocalBuild = true;
|
||||
|
||||
# This attribute does nothing; it's here to avoid changing evaluation results.
|
||||
impureEnvVars = [
|
||||
"http_proxy" "https_proxy" "ftp_proxy" "all_proxy" "no_proxy"
|
||||
];
|
||||
# This attribute does nothing; it's here to avoid changing evaluation results.
|
||||
impureEnvVars = [
|
||||
"http_proxy"
|
||||
"https_proxy"
|
||||
"ftp_proxy"
|
||||
"all_proxy"
|
||||
"no_proxy"
|
||||
];
|
||||
|
||||
# To make "nix-prefetch-url" work.
|
||||
urls = [ url ];
|
||||
} // (if impure
|
||||
then { __impure = true; }
|
||||
else { inherit outputHashAlgo outputHash; }))
|
||||
# To make "nix-prefetch-url" work.
|
||||
urls = [ url ];
|
||||
}
|
||||
// (if impure then { __impure = true; } else { inherit outputHashAlgo outputHash; })
|
||||
)
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
attrs @ { drvPath, outputs, name, ... }:
|
||||
attrs@{
|
||||
drvPath,
|
||||
outputs,
|
||||
name,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
commonAttrs = (builtins.listToAttrs outputsList) //
|
||||
{ all = map (x: x.value) outputsList;
|
||||
inherit drvPath name;
|
||||
type = "derivation";
|
||||
};
|
||||
commonAttrs = (builtins.listToAttrs outputsList) // {
|
||||
all = map (x: x.value) outputsList;
|
||||
inherit drvPath name;
|
||||
type = "derivation";
|
||||
};
|
||||
|
||||
outputToAttrListElement = outputName:
|
||||
{ name = outputName;
|
||||
value = commonAttrs // {
|
||||
outPath = builtins.getAttr outputName attrs;
|
||||
inherit outputName;
|
||||
};
|
||||
outputToAttrListElement = outputName: {
|
||||
name = outputName;
|
||||
value = commonAttrs // {
|
||||
outPath = builtins.getAttr outputName attrs;
|
||||
inherit outputName;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
outputsList = map outputToAttrListElement outputs;
|
||||
|
||||
in (builtins.head outputsList).value
|
||||
|
||||
in
|
||||
(builtins.head outputsList).value
|
||||
|
||||
@@ -175,8 +175,6 @@ headers = [config_h] + files(
|
||||
# internal: 'lexer-helpers.hh',
|
||||
'nixexpr.hh',
|
||||
'parser-state.hh',
|
||||
'pos-idx.hh',
|
||||
'pos-table.hh',
|
||||
'primops.hh',
|
||||
'print-ambiguous.hh',
|
||||
'print-options.hh',
|
||||
|
||||
@@ -601,41 +601,6 @@ void ExprLambda::setDocComment(DocComment docComment) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Position table. */
|
||||
|
||||
Pos PosTable::operator[](PosIdx p) const
|
||||
{
|
||||
auto origin = resolve(p);
|
||||
if (!origin)
|
||||
return {};
|
||||
|
||||
const auto offset = origin->offsetOf(p);
|
||||
|
||||
Pos result{0, 0, origin->origin};
|
||||
auto lines = this->lines.lock();
|
||||
auto linesForInput = (*lines)[origin->offset];
|
||||
|
||||
if (linesForInput.empty()) {
|
||||
auto source = result.getSource().value_or("");
|
||||
const char * begin = source.data();
|
||||
for (Pos::LinesIterator it(source), end; it != end; it++)
|
||||
linesForInput.push_back(it->data() - begin);
|
||||
if (linesForInput.empty())
|
||||
linesForInput.push_back(0);
|
||||
}
|
||||
// as above: the first line starts at byte 0 and is always present
|
||||
auto lineStartOffset = std::prev(
|
||||
std::upper_bound(linesForInput.begin(), linesForInput.end(), offset));
|
||||
|
||||
result.line = 1 + (lineStartOffset - linesForInput.begin());
|
||||
result.column = 1 + (offset - *lineStartOffset);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Symbol table. */
|
||||
|
||||
size_t SymbolTable::totalSize() const
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
{ lib
|
||||
, stdenv
|
||||
, mkMesonLibrary
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
mkMesonLibrary,
|
||||
|
||||
, bison
|
||||
, flex
|
||||
, cmake # for resolving toml11 dep
|
||||
bison,
|
||||
flex,
|
||||
cmake, # for resolving toml11 dep
|
||||
|
||||
, nix-util
|
||||
, nix-store
|
||||
, nix-fetchers
|
||||
, boost
|
||||
, boehmgc
|
||||
, nlohmann_json
|
||||
, toml11
|
||||
nix-util,
|
||||
nix-store,
|
||||
nix-fetchers,
|
||||
boost,
|
||||
boehmgc,
|
||||
nlohmann_json,
|
||||
toml11,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
version,
|
||||
|
||||
# Whether to use garbage collection for the Nix language evaluator.
|
||||
#
|
||||
# If it is disabled, we just leak memory, but this is not as bad as it
|
||||
# sounds so long as evaluation just takes places within short-lived
|
||||
# processes. (When the process exits, the memory is reclaimed; it is
|
||||
# only leaked *within* the process.)
|
||||
#
|
||||
# Temporarily disabled on Windows because the `GC_throw_bad_alloc`
|
||||
# symbol is missing during linking.
|
||||
, enableGC ? !stdenv.hostPlatform.isWindows
|
||||
# Whether to use garbage collection for the Nix language evaluator.
|
||||
#
|
||||
# If it is disabled, we just leak memory, but this is not as bad as it
|
||||
# sounds so long as evaluation just takes places within short-lived
|
||||
# processes. (When the process exits, the memory is reclaimed; it is
|
||||
# only leaked *within* the process.)
|
||||
#
|
||||
# Temporarily disabled on Windows because the `GC_throw_bad_alloc`
|
||||
# symbol is missing during linking.
|
||||
enableGC ? !stdenv.hostPlatform.isWindows,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -51,10 +52,7 @@ mkMesonLibrary (finalAttrs: {
|
||||
(fileset.fileFilter (file: file.hasExt "hh") ./.)
|
||||
./lexer.l
|
||||
./parser.y
|
||||
(fileset.difference
|
||||
(fileset.fileFilter (file: file.hasExt "nix") ./.)
|
||||
./package.nix
|
||||
)
|
||||
(fileset.difference (fileset.fileFilter (file: file.hasExt "nix") ./.) ./package.nix)
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
@@ -87,14 +85,18 @@ mkMesonLibrary (finalAttrs: {
|
||||
(lib.mesonEnable "gc" enableGC)
|
||||
];
|
||||
|
||||
env = {
|
||||
# Needed for Meson to find Boost.
|
||||
# https://github.com/NixOS/nixpkgs/issues/86131.
|
||||
BOOST_INCLUDEDIR = "${lib.getDev boost}/include";
|
||||
BOOST_LIBRARYDIR = "${lib.getLib boost}/lib";
|
||||
} // lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
{
|
||||
# Needed for Meson to find Boost.
|
||||
# https://github.com/NixOS/nixpkgs/issues/86131.
|
||||
BOOST_INCLUDEDIR = "${lib.getDev boost}/include";
|
||||
BOOST_LIBRARYDIR = "${lib.getLib boost}/lib";
|
||||
}
|
||||
// lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
|
||||
@@ -88,6 +88,7 @@ struct ParserState
|
||||
void dupAttr(const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos);
|
||||
void dupAttr(Symbol attr, const PosIdx pos, const PosIdx prevPos);
|
||||
void addAttr(ExprAttrs * attrs, AttrPath && attrPath, const ParserLocation & loc, Expr * e, const ParserLocation & exprLoc);
|
||||
void addAttr(ExprAttrs * attrs, AttrPath & attrPath, const Symbol & symbol, ExprAttrs::AttrDef && def);
|
||||
Formals * validateFormals(Formals * formals, PosIdx pos = noPos, Symbol arg = {});
|
||||
Expr * stripIndentation(const PosIdx pos,
|
||||
std::vector<std::pair<PosIdx, std::variant<Expr *, StringToken>>> && es);
|
||||
@@ -120,64 +121,29 @@ inline void ParserState::addAttr(ExprAttrs * attrs, AttrPath && attrPath, const
|
||||
// Checking attrPath validity.
|
||||
// ===========================
|
||||
for (i = attrPath.begin(); i + 1 < attrPath.end(); i++) {
|
||||
ExprAttrs * nested;
|
||||
if (i->symbol) {
|
||||
ExprAttrs::AttrDefs::iterator j = attrs->attrs.find(i->symbol);
|
||||
if (j != attrs->attrs.end()) {
|
||||
if (j->second.kind != ExprAttrs::AttrDef::Kind::Inherited) {
|
||||
ExprAttrs * attrs2 = dynamic_cast<ExprAttrs *>(j->second.e);
|
||||
if (!attrs2) dupAttr(attrPath, pos, j->second.pos);
|
||||
attrs = attrs2;
|
||||
} else
|
||||
nested = dynamic_cast<ExprAttrs *>(j->second.e);
|
||||
if (!nested) {
|
||||
attrPath.erase(i + 1, attrPath.end());
|
||||
dupAttr(attrPath, pos, j->second.pos);
|
||||
}
|
||||
} else {
|
||||
ExprAttrs * nested = new ExprAttrs;
|
||||
nested = new ExprAttrs;
|
||||
attrs->attrs[i->symbol] = ExprAttrs::AttrDef(nested, pos);
|
||||
attrs = nested;
|
||||
}
|
||||
} else {
|
||||
ExprAttrs *nested = new ExprAttrs;
|
||||
nested = new ExprAttrs;
|
||||
attrs->dynamicAttrs.push_back(ExprAttrs::DynamicAttrDef(i->expr, nested, pos));
|
||||
attrs = nested;
|
||||
}
|
||||
attrs = nested;
|
||||
}
|
||||
// Expr insertion.
|
||||
// ==========================
|
||||
if (i->symbol) {
|
||||
ExprAttrs::AttrDefs::iterator j = attrs->attrs.find(i->symbol);
|
||||
if (j != attrs->attrs.end()) {
|
||||
// This attr path is already defined. However, if both
|
||||
// e and the expr pointed by the attr path are two attribute sets,
|
||||
// we want to merge them.
|
||||
// Otherwise, throw an error.
|
||||
auto ae = dynamic_cast<ExprAttrs *>(e);
|
||||
auto jAttrs = dynamic_cast<ExprAttrs *>(j->second.e);
|
||||
if (jAttrs && ae) {
|
||||
if (ae->inheritFromExprs && !jAttrs->inheritFromExprs)
|
||||
jAttrs->inheritFromExprs = std::make_unique<std::vector<Expr *>>();
|
||||
for (auto & ad : ae->attrs) {
|
||||
auto j2 = jAttrs->attrs.find(ad.first);
|
||||
if (j2 != jAttrs->attrs.end()) // Attr already defined in iAttrs, error.
|
||||
dupAttr(ad.first, j2->second.pos, ad.second.pos);
|
||||
jAttrs->attrs.emplace(ad.first, ad.second);
|
||||
if (ad.second.kind == ExprAttrs::AttrDef::Kind::InheritedFrom) {
|
||||
auto & sel = dynamic_cast<ExprSelect &>(*ad.second.e);
|
||||
auto & from = dynamic_cast<ExprInheritFrom &>(*sel.e);
|
||||
from.displ += jAttrs->inheritFromExprs->size();
|
||||
}
|
||||
}
|
||||
jAttrs->dynamicAttrs.insert(jAttrs->dynamicAttrs.end(), ae->dynamicAttrs.begin(), ae->dynamicAttrs.end());
|
||||
if (ae->inheritFromExprs) {
|
||||
jAttrs->inheritFromExprs->insert(jAttrs->inheritFromExprs->end(),
|
||||
ae->inheritFromExprs->begin(), ae->inheritFromExprs->end());
|
||||
}
|
||||
} else {
|
||||
dupAttr(attrPath, pos, j->second.pos);
|
||||
}
|
||||
} else {
|
||||
// This attr path is not defined. Let's create it.
|
||||
attrs->attrs.emplace(i->symbol, ExprAttrs::AttrDef(e, pos));
|
||||
e->setName(i->symbol);
|
||||
}
|
||||
addAttr(attrs, attrPath, i->symbol, ExprAttrs::AttrDef(e, pos));
|
||||
} else {
|
||||
attrs->dynamicAttrs.push_back(ExprAttrs::DynamicAttrDef(i->expr, e, pos));
|
||||
}
|
||||
@@ -189,6 +155,60 @@ inline void ParserState::addAttr(ExprAttrs * attrs, AttrPath && attrPath, const
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Precondition: attrPath is used for error messages and should already contain
|
||||
* symbol as its last element.
|
||||
*/
|
||||
inline void ParserState::addAttr(ExprAttrs * attrs, AttrPath & attrPath, const Symbol & symbol, ExprAttrs::AttrDef && def)
|
||||
{
|
||||
ExprAttrs::AttrDefs::iterator j = attrs->attrs.find(symbol);
|
||||
if (j != attrs->attrs.end()) {
|
||||
// This attr path is already defined. However, if both
|
||||
// e and the expr pointed by the attr path are two attribute sets,
|
||||
// we want to merge them.
|
||||
// Otherwise, throw an error.
|
||||
auto ae = dynamic_cast<ExprAttrs *>(def.e);
|
||||
auto jAttrs = dynamic_cast<ExprAttrs *>(j->second.e);
|
||||
|
||||
// N.B. In a world in which we are less bound by our past mistakes, we
|
||||
// would also test that jAttrs and ae are not recursive. The effect of
|
||||
// not doing so is that any `rec` marker on ae is discarded, and any
|
||||
// `rec` marker on jAttrs will apply to the attributes in ae.
|
||||
// See https://github.com/NixOS/nix/issues/9020.
|
||||
if (jAttrs && ae) {
|
||||
if (ae->inheritFromExprs && !jAttrs->inheritFromExprs)
|
||||
jAttrs->inheritFromExprs = std::make_unique<std::vector<Expr *>>();
|
||||
for (auto & ad : ae->attrs) {
|
||||
if (ad.second.kind == ExprAttrs::AttrDef::Kind::InheritedFrom) {
|
||||
auto & sel = dynamic_cast<ExprSelect &>(*ad.second.e);
|
||||
auto & from = dynamic_cast<ExprInheritFrom &>(*sel.e);
|
||||
from.displ += jAttrs->inheritFromExprs->size();
|
||||
}
|
||||
attrPath.emplace_back(AttrName(ad.first));
|
||||
addAttr(jAttrs, attrPath, ad.first, std::move(ad.second));
|
||||
attrPath.pop_back();
|
||||
}
|
||||
ae->attrs.clear();
|
||||
jAttrs->dynamicAttrs.insert(jAttrs->dynamicAttrs.end(),
|
||||
std::make_move_iterator(ae->dynamicAttrs.begin()),
|
||||
std::make_move_iterator(ae->dynamicAttrs.end()));
|
||||
ae->dynamicAttrs.clear();
|
||||
if (ae->inheritFromExprs) {
|
||||
jAttrs->inheritFromExprs->insert(jAttrs->inheritFromExprs->end(),
|
||||
std::make_move_iterator(ae->inheritFromExprs->begin()),
|
||||
std::make_move_iterator(ae->inheritFromExprs->end()));
|
||||
ae->inheritFromExprs = nullptr;
|
||||
}
|
||||
} else {
|
||||
dupAttr(attrPath, def.pos, j->second.pos);
|
||||
}
|
||||
} else {
|
||||
// This attr path is not defined. Let's create it.
|
||||
attrs->attrs.emplace(symbol, def);
|
||||
def.e->setName(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
inline Formals * ParserState::validateFormals(Formals * formals, PosIdx pos, Symbol arg)
|
||||
{
|
||||
std::sort(formals->formals.begin(), formals->formals.end(),
|
||||
|
||||
@@ -47,6 +47,15 @@ static inline Value * mkString(EvalState & state, const std::csub_match & match)
|
||||
return v;
|
||||
}
|
||||
|
||||
std::string EvalState::realiseString(Value & s, StorePathSet * storePathsOutMaybe, bool isIFD, const PosIdx pos)
|
||||
{
|
||||
nix::NixStringContext stringContext;
|
||||
auto rawStr = coerceToString(pos, s, stringContext, "while realising a string").toOwned();
|
||||
auto rewrites = realiseContext(stringContext, storePathsOutMaybe, isIFD);
|
||||
|
||||
return nix::rewriteStrings(rawStr, rewrites);
|
||||
}
|
||||
|
||||
StringMap EvalState::realiseContext(const NixStringContext & context, StorePathSet * maybePathsOut, bool isIFD)
|
||||
{
|
||||
std::vector<DerivedPath::Built> drvs;
|
||||
@@ -4061,7 +4070,7 @@ static RegisterPrimOp primop_toString({
|
||||
});
|
||||
|
||||
/* `substring start len str' returns the substring of `str' starting
|
||||
at character position `min(start, stringLength str)' inclusive and
|
||||
at byte position `min(start, stringLength str)' inclusive and
|
||||
ending at `min(start + len, stringLength str)'. `start' must be
|
||||
non-negative. */
|
||||
static void prim_substring(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
@@ -4100,7 +4109,7 @@ static RegisterPrimOp primop_substring({
|
||||
.name = "__substring",
|
||||
.args = {"start", "len", "s"},
|
||||
.doc = R"(
|
||||
Return the substring of *s* from character position *start*
|
||||
Return the substring of *s* from byte position *start*
|
||||
(zero-based) up to but not including *start + len*. If *start* is
|
||||
greater than the length of the string, an empty string is returned.
|
||||
If *start + len* lies beyond the end of the string or *len* is `-1`,
|
||||
|
||||
@@ -26,27 +26,34 @@
|
||||
Note that `derivation` is very bare-bones, and provides almost no commands during the build.
|
||||
Most likely, you'll want to use functions like `stdenv.mkDerivation` in Nixpkgs to set up a basic environment.
|
||||
*/
|
||||
drvAttrs @ { outputs ? [ "out" ], ... }:
|
||||
drvAttrs@{
|
||||
outputs ? [ "out" ],
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
strict = derivationStrict drvAttrs;
|
||||
|
||||
commonAttrs = drvAttrs // (builtins.listToAttrs outputsList) //
|
||||
{ all = map (x: x.value) outputsList;
|
||||
commonAttrs =
|
||||
drvAttrs
|
||||
// (builtins.listToAttrs outputsList)
|
||||
// {
|
||||
all = map (x: x.value) outputsList;
|
||||
inherit drvAttrs;
|
||||
};
|
||||
|
||||
outputToAttrListElement = outputName:
|
||||
{ name = outputName;
|
||||
value = commonAttrs // {
|
||||
outPath = builtins.getAttr outputName strict;
|
||||
drvPath = strict.drvPath;
|
||||
type = "derivation";
|
||||
inherit outputName;
|
||||
};
|
||||
outputToAttrListElement = outputName: {
|
||||
name = outputName;
|
||||
value = commonAttrs // {
|
||||
outPath = builtins.getAttr outputName strict;
|
||||
drvPath = strict.drvPath;
|
||||
type = "derivation";
|
||||
inherit outputName;
|
||||
};
|
||||
};
|
||||
|
||||
outputsList = map outputToAttrListElement outputs;
|
||||
|
||||
in (builtins.head outputsList).value
|
||||
in
|
||||
(builtins.head outputsList).value
|
||||
|
||||
@@ -108,7 +108,11 @@ json printValueAsJSON(EvalState & state, bool strict,
|
||||
void printValueAsJSON(EvalState & state, bool strict,
|
||||
Value & v, const PosIdx pos, std::ostream & str, NixStringContext & context, bool copyToStore)
|
||||
{
|
||||
str << printValueAsJSON(state, strict, v, pos, context, copyToStore);
|
||||
try {
|
||||
str << printValueAsJSON(state, strict, v, pos, context, copyToStore);
|
||||
} catch (nlohmann::json::exception & e) {
|
||||
throw JSONSerializationError("JSON serialization error: %s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
json ExternalValueBase::printValueAsJSON(EvalState & state, bool strict,
|
||||
|
||||
@@ -16,4 +16,7 @@ nlohmann::json printValueAsJSON(EvalState & state, bool strict,
|
||||
void printValueAsJSON(EvalState & state, bool strict,
|
||||
Value & v, const PosIdx pos, std::ostream & str, NixStringContext & context, bool copyToStore = true);
|
||||
|
||||
|
||||
MakeError(JSONSerializationError, Error);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
{ lib
|
||||
, buildPackages
|
||||
, stdenv
|
||||
, mkMesonExecutable
|
||||
{
|
||||
lib,
|
||||
buildPackages,
|
||||
stdenv,
|
||||
mkMesonExecutable,
|
||||
|
||||
, nix-fetchers
|
||||
, nix-store-test-support
|
||||
nix-fetchers,
|
||||
nix-store-test-support,
|
||||
|
||||
, rapidcheck
|
||||
, gtest
|
||||
, runCommand
|
||||
rapidcheck,
|
||||
gtest,
|
||||
runCommand,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
, resolvePath
|
||||
version,
|
||||
resolvePath,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -54,22 +55,31 @@ mkMesonExecutable (finalAttrs: {
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
passthru = {
|
||||
tests = {
|
||||
run = runCommand "${finalAttrs.pname}-run" {
|
||||
meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages;
|
||||
} (lib.optionalString stdenv.hostPlatform.isWindows ''
|
||||
export HOME="$PWD/home-dir"
|
||||
mkdir -p "$HOME"
|
||||
'' + ''
|
||||
export _NIX_TEST_UNIT_DATA=${resolvePath ./data}
|
||||
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
|
||||
touch $out
|
||||
'');
|
||||
run =
|
||||
runCommand "${finalAttrs.pname}-run"
|
||||
{
|
||||
meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages;
|
||||
}
|
||||
(
|
||||
lib.optionalString stdenv.hostPlatform.isWindows ''
|
||||
export HOME="$PWD/home-dir"
|
||||
mkdir -p "$HOME"
|
||||
''
|
||||
+ ''
|
||||
export _NIX_TEST_UNIT_DATA=${resolvePath ./data}
|
||||
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
|
||||
touch $out
|
||||
''
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ struct CacheImpl : Cache
|
||||
{
|
||||
auto state(_state.lock());
|
||||
|
||||
auto dbPath = getCacheDir() + "/fetcher-cache-v2.sqlite";
|
||||
auto dbPath = getCacheDir() + "/fetcher-cache-v3.sqlite";
|
||||
createDirs(dirOf(dbPath));
|
||||
|
||||
state->db = SQLite(dbPath);
|
||||
|
||||
@@ -66,7 +66,7 @@ Input Input::fromURL(
|
||||
}
|
||||
}
|
||||
|
||||
throw Error("input '%s' is unsupported", url.url);
|
||||
throw Error("input '%s' is unsupported", url);
|
||||
}
|
||||
|
||||
Input Input::fromAttrs(const Settings & settings, Attrs && attrs)
|
||||
|
||||
@@ -205,7 +205,8 @@ static git_packbuilder_progress PACKBUILDER_PROGRESS_CHECK_INTERRUPT = &packBuil
|
||||
|
||||
} // extern "C"
|
||||
|
||||
static void initRepoAtomically(std::filesystem::path &path, bool bare) {
|
||||
static void initRepoAtomically(std::filesystem::path &path, bool bare)
|
||||
{
|
||||
if (pathExists(path.string())) return;
|
||||
|
||||
Path tmpDir = createTempDir(os_string_to_string(PathViewNG { std::filesystem::path(path).parent_path() }));
|
||||
@@ -538,13 +539,10 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
||||
// then use code that was removed in this commit (see blame)
|
||||
|
||||
auto dir = this->path;
|
||||
Strings gitArgs;
|
||||
if (shallow) {
|
||||
gitArgs = { "-C", dir.string(), "fetch", "--quiet", "--force", "--depth", "1", "--", url, refspec };
|
||||
}
|
||||
else {
|
||||
gitArgs = { "-C", dir.string(), "fetch", "--quiet", "--force", "--", url, refspec };
|
||||
}
|
||||
Strings gitArgs{"-C", dir.string(), "--git-dir", ".", "fetch", "--quiet", "--force"};
|
||||
if (shallow)
|
||||
append(gitArgs, {"--depth", "1"});
|
||||
append(gitArgs, {std::string("--"), url, refspec});
|
||||
|
||||
runProgram(RunOptions {
|
||||
.program = "git",
|
||||
|
||||
@@ -425,7 +425,16 @@ struct GitInputScheme : InputScheme
|
||||
auto url = parseURL(getStrAttr(input.attrs, "url"));
|
||||
bool isBareRepository = url.scheme == "file" && !pathExists(url.path + "/.git");
|
||||
repoInfo.isLocal = url.scheme == "file" && !forceHttp && !isBareRepository;
|
||||
repoInfo.url = repoInfo.isLocal ? url.path : url.base;
|
||||
//
|
||||
// FIXME: here we turn a possibly relative path into an absolute path.
|
||||
// This allows relative git flake inputs to be resolved against the
|
||||
// **current working directory** (as in POSIX), which tends to work out
|
||||
// ok in the context of flakes, but is the wrong behavior,
|
||||
// as it should resolve against the flake.nix base directory instead.
|
||||
//
|
||||
// See: https://discourse.nixos.org/t/57783 and #9708
|
||||
//
|
||||
repoInfo.url = repoInfo.isLocal ? std::filesystem::absolute(url.path).string() : url.to_string();
|
||||
|
||||
// If this is a local directory and no ref or revision is
|
||||
// given, then allow the use of an unclean working tree.
|
||||
|
||||
@@ -50,7 +50,7 @@ struct GitArchiveInputScheme : InputScheme
|
||||
else if (std::regex_match(path[2], refRegex))
|
||||
ref = path[2];
|
||||
else
|
||||
throw BadURL("in URL '%s', '%s' is not a commit hash or branch/tag name", url.url, path[2]);
|
||||
throw BadURL("in URL '%s', '%s' is not a commit hash or branch/tag name", url, path[2]);
|
||||
} else if (size > 3) {
|
||||
std::string rs;
|
||||
for (auto i = std::next(path.begin(), 2); i != path.end(); i++) {
|
||||
@@ -63,34 +63,34 @@ struct GitArchiveInputScheme : InputScheme
|
||||
if (std::regex_match(rs, refRegex)) {
|
||||
ref = rs;
|
||||
} else {
|
||||
throw BadURL("in URL '%s', '%s' is not a branch/tag name", url.url, rs);
|
||||
throw BadURL("in URL '%s', '%s' is not a branch/tag name", url, rs);
|
||||
}
|
||||
} else if (size < 2)
|
||||
throw BadURL("URL '%s' is invalid", url.url);
|
||||
throw BadURL("URL '%s' is invalid", url);
|
||||
|
||||
for (auto &[name, value] : url.query) {
|
||||
if (name == "rev") {
|
||||
if (rev)
|
||||
throw BadURL("URL '%s' contains multiple commit hashes", url.url);
|
||||
throw BadURL("URL '%s' contains multiple commit hashes", url);
|
||||
rev = Hash::parseAny(value, HashAlgorithm::SHA1);
|
||||
}
|
||||
else if (name == "ref") {
|
||||
if (!std::regex_match(value, refRegex))
|
||||
throw BadURL("URL '%s' contains an invalid branch/tag name", url.url);
|
||||
throw BadURL("URL '%s' contains an invalid branch/tag name", url);
|
||||
if (ref)
|
||||
throw BadURL("URL '%s' contains multiple branch/tag names", url.url);
|
||||
throw BadURL("URL '%s' contains multiple branch/tag names", url);
|
||||
ref = value;
|
||||
}
|
||||
else if (name == "host") {
|
||||
if (!std::regex_match(value, hostRegex))
|
||||
throw BadURL("URL '%s' contains an invalid instance host", url.url);
|
||||
throw BadURL("URL '%s' contains an invalid instance host", url);
|
||||
host_url = value;
|
||||
}
|
||||
// FIXME: barf on unsupported attributes
|
||||
}
|
||||
|
||||
if (ref && rev)
|
||||
throw BadURL("URL '%s' contains both a commit hash and a branch/tag name %s %s", url.url, *ref, rev->gitRev());
|
||||
throw BadURL("URL '%s' contains both a commit hash and a branch/tag name %s %s", url, *ref, rev->gitRev());
|
||||
|
||||
Input input{settings};
|
||||
input.attrs.insert_or_assign("type", std::string { schemeName() });
|
||||
|
||||
@@ -26,16 +26,16 @@ struct IndirectInputScheme : InputScheme
|
||||
else if (std::regex_match(path[1], refRegex))
|
||||
ref = path[1];
|
||||
else
|
||||
throw BadURL("in flake URL '%s', '%s' is not a commit hash or branch/tag name", url.url, path[1]);
|
||||
throw BadURL("in flake URL '%s', '%s' is not a commit hash or branch/tag name", url, path[1]);
|
||||
} else if (path.size() == 3) {
|
||||
if (!std::regex_match(path[1], refRegex))
|
||||
throw BadURL("in flake URL '%s', '%s' is not a branch/tag name", url.url, path[1]);
|
||||
throw BadURL("in flake URL '%s', '%s' is not a branch/tag name", url, path[1]);
|
||||
ref = path[1];
|
||||
if (!std::regex_match(path[2], revRegex))
|
||||
throw BadURL("in flake URL '%s', '%s' is not a commit hash", url.url, path[2]);
|
||||
throw BadURL("in flake URL '%s', '%s' is not a commit hash", url, path[2]);
|
||||
rev = Hash::parseAny(path[2], HashAlgorithm::SHA1);
|
||||
} else
|
||||
throw BadURL("GitHub URL '%s' is invalid", url.url);
|
||||
throw BadURL("GitHub URL '%s' is invalid", url);
|
||||
|
||||
std::string id = path[0];
|
||||
if (!std::regex_match(id, flakeRegex))
|
||||
|
||||
@@ -161,7 +161,7 @@ struct MercurialInputScheme : InputScheme
|
||||
{
|
||||
auto url = parseURL(getStrAttr(input.attrs, "url"));
|
||||
bool isLocal = url.scheme == "file";
|
||||
return {isLocal, isLocal ? url.path : url.base};
|
||||
return {isLocal, isLocal ? url.path : url.to_string()};
|
||||
}
|
||||
|
||||
StorePath fetchToStore(ref<Store> store, Input & input) const
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
{ lib
|
||||
, stdenv
|
||||
, mkMesonLibrary
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
mkMesonLibrary,
|
||||
|
||||
, nix-util
|
||||
, nix-store
|
||||
, nlohmann_json
|
||||
, libgit2
|
||||
nix-util,
|
||||
nix-store,
|
||||
nlohmann_json,
|
||||
libgit2,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
version,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -49,9 +50,12 @@ mkMesonLibrary (finalAttrs: {
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
|
||||
@@ -14,7 +14,7 @@ struct PathInputScheme : InputScheme
|
||||
if (url.scheme != "path") return {};
|
||||
|
||||
if (url.authority && *url.authority != "")
|
||||
throw Error("path URL '%s' should not have an authority ('%s')", url.url, *url.authority);
|
||||
throw Error("path URL '%s' should not have an authority ('%s')", url, *url.authority);
|
||||
|
||||
Input input{settings};
|
||||
input.attrs.insert_or_assign("type", "path");
|
||||
@@ -27,10 +27,10 @@ struct PathInputScheme : InputScheme
|
||||
if (auto n = string2Int<uint64_t>(value))
|
||||
input.attrs.insert_or_assign(name, *n);
|
||||
else
|
||||
throw Error("path URL '%s' has invalid parameter '%s'", url.to_string(), name);
|
||||
throw Error("path URL '%s' has invalid parameter '%s'", url, name);
|
||||
}
|
||||
else
|
||||
throw Error("path URL '%s' has unsupported parameter '%s'", url.to_string(), name);
|
||||
throw Error("path URL '%s' has unsupported parameter '%s'", url, name);
|
||||
|
||||
return input;
|
||||
}
|
||||
@@ -97,7 +97,7 @@ struct PathInputScheme : InputScheme
|
||||
std::optional<std::string> isRelative(const Input & input) const
|
||||
{
|
||||
auto path = getStrAttr(input.attrs, "path");
|
||||
if (hasPrefix(path, "/"))
|
||||
if (isAbsolute(path))
|
||||
return std::nullopt;
|
||||
else
|
||||
return path;
|
||||
|
||||
@@ -156,7 +156,7 @@ static std::shared_ptr<Registry> getGlobalRegistry(const Settings & settings, re
|
||||
return std::make_shared<Registry>(settings, Registry::Global); // empty registry
|
||||
}
|
||||
|
||||
if (!hasPrefix(path, "/")) {
|
||||
if (!isAbsolute(path)) {
|
||||
auto storePath = downloadFile(store, path, "flake-registry.json").storePath;
|
||||
if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>())
|
||||
store2->addPermRoot(storePath, getCacheDir() + "/flake-registry.json");
|
||||
|
||||
@@ -7,18 +7,60 @@ namespace nix {
|
||||
|
||||
/* ----------- tests for flake/flakeref.hh --------------------------------------------------*/
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* to_string
|
||||
* --------------------------------------------------------------------------*/
|
||||
TEST(parseFlakeRef, path) {
|
||||
experimentalFeatureSettings.experimentalFeatures.get().insert(Xp::Flakes);
|
||||
|
||||
fetchers::Settings fetchSettings;
|
||||
|
||||
{
|
||||
auto s = "/foo/bar";
|
||||
auto flakeref = parseFlakeRef(fetchSettings, s);
|
||||
ASSERT_EQ(flakeref.to_string(), "path:/foo/bar");
|
||||
}
|
||||
|
||||
{
|
||||
auto s = "/foo/bar?revCount=123&rev=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
auto flakeref = parseFlakeRef(fetchSettings, s);
|
||||
ASSERT_EQ(flakeref.to_string(), "path:/foo/bar?rev=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&revCount=123");
|
||||
}
|
||||
|
||||
{
|
||||
auto s = "/foo/bar?xyzzy=123";
|
||||
EXPECT_THROW(
|
||||
parseFlakeRef(fetchSettings, s),
|
||||
Error);
|
||||
}
|
||||
|
||||
{
|
||||
auto s = "/foo/bar#bla";
|
||||
EXPECT_THROW(
|
||||
parseFlakeRef(fetchSettings, s),
|
||||
Error);
|
||||
}
|
||||
|
||||
{
|
||||
auto s = "/foo/bar#bla";
|
||||
auto [flakeref, fragment] = parseFlakeRefWithFragment(fetchSettings, s);
|
||||
ASSERT_EQ(flakeref.to_string(), "path:/foo/bar");
|
||||
ASSERT_EQ(fragment, "bla");
|
||||
}
|
||||
|
||||
{
|
||||
auto s = "/foo/bar?revCount=123#bla";
|
||||
auto [flakeref, fragment] = parseFlakeRefWithFragment(fetchSettings, s);
|
||||
ASSERT_EQ(flakeref.to_string(), "path:/foo/bar?revCount=123");
|
||||
ASSERT_EQ(fragment, "bla");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(to_string, doesntReencodeUrl) {
|
||||
fetchers::Settings fetchSettings;
|
||||
auto s = "http://localhost:8181/test/+3d.tar.gz";
|
||||
auto flakeref = parseFlakeRef(fetchSettings, s);
|
||||
auto parsed = flakeref.to_string();
|
||||
auto unparsed = flakeref.to_string();
|
||||
auto expected = "http://localhost:8181/test/%2B3d.tar.gz";
|
||||
|
||||
ASSERT_EQ(parsed, expected);
|
||||
ASSERT_EQ(unparsed, expected);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
{ lib
|
||||
, buildPackages
|
||||
, stdenv
|
||||
, mkMesonExecutable
|
||||
{
|
||||
lib,
|
||||
buildPackages,
|
||||
stdenv,
|
||||
mkMesonExecutable,
|
||||
|
||||
, nix-flake
|
||||
, nix-expr-test-support
|
||||
nix-flake,
|
||||
nix-expr-test-support,
|
||||
|
||||
, rapidcheck
|
||||
, gtest
|
||||
, runCommand
|
||||
rapidcheck,
|
||||
gtest,
|
||||
runCommand,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
, resolvePath
|
||||
version,
|
||||
resolvePath,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -54,22 +55,31 @@ mkMesonExecutable (finalAttrs: {
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
passthru = {
|
||||
tests = {
|
||||
run = runCommand "${finalAttrs.pname}-run" {
|
||||
meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages;
|
||||
} (lib.optionalString stdenv.hostPlatform.isWindows ''
|
||||
export HOME="$PWD/home-dir"
|
||||
mkdir -p "$HOME"
|
||||
'' + ''
|
||||
export _NIX_TEST_UNIT_DATA=${resolvePath ./data}
|
||||
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
|
||||
touch $out
|
||||
'');
|
||||
run =
|
||||
runCommand "${finalAttrs.pname}-run"
|
||||
{
|
||||
meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages;
|
||||
}
|
||||
(
|
||||
lib.optionalString stdenv.hostPlatform.isWindows ''
|
||||
export HOME="$PWD/home-dir"
|
||||
mkdir -p "$HOME"
|
||||
''
|
||||
+ ''
|
||||
export _NIX_TEST_UNIT_DATA=${resolvePath ./data}
|
||||
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
|
||||
touch $out
|
||||
''
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -67,6 +67,20 @@ std::optional<FlakeRef> maybeParseFlakeRef(
|
||||
}
|
||||
}
|
||||
|
||||
static std::pair<FlakeRef, std::string> fromParsedURL(
|
||||
const fetchers::Settings & fetchSettings,
|
||||
ParsedURL && parsedURL,
|
||||
bool isFlake)
|
||||
{
|
||||
auto dir = getOr(parsedURL.query, "dir", "");
|
||||
parsedURL.query.erase("dir");
|
||||
|
||||
std::string fragment;
|
||||
std::swap(fragment, parsedURL.fragment);
|
||||
|
||||
return {FlakeRef(fetchers::Input::fromURL(fetchSettings, parsedURL, isFlake), dir), fragment};
|
||||
}
|
||||
|
||||
std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
|
||||
const fetchers::Settings & fetchSettings,
|
||||
const std::string & url,
|
||||
@@ -74,28 +88,21 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
|
||||
bool allowMissing,
|
||||
bool isFlake)
|
||||
{
|
||||
std::string path = url;
|
||||
std::string fragment = "";
|
||||
std::map<std::string, std::string> query;
|
||||
auto pathEnd = url.find_first_of("#?");
|
||||
auto fragmentStart = pathEnd;
|
||||
if (pathEnd != std::string::npos && url[pathEnd] == '?') {
|
||||
fragmentStart = url.find("#");
|
||||
}
|
||||
if (pathEnd != std::string::npos) {
|
||||
path = url.substr(0, pathEnd);
|
||||
}
|
||||
if (fragmentStart != std::string::npos) {
|
||||
fragment = percentDecode(url.substr(fragmentStart+1));
|
||||
}
|
||||
if (pathEnd != std::string::npos && fragmentStart != std::string::npos && url[pathEnd] == '?') {
|
||||
query = decodeQuery(url.substr(pathEnd+1, fragmentStart-pathEnd-1));
|
||||
}
|
||||
static std::regex pathFlakeRegex(
|
||||
R"(([^?#]*)(\?([^#]*))?(#(.*))?)",
|
||||
std::regex::ECMAScript);
|
||||
|
||||
std::smatch match;
|
||||
auto succeeds = std::regex_match(url, match, pathFlakeRegex);
|
||||
assert(succeeds);
|
||||
auto path = match[1].str();
|
||||
auto query = decodeQuery(match[3]);
|
||||
auto fragment = percentDecode(match[5].str());
|
||||
|
||||
if (baseDir) {
|
||||
/* Check if 'url' is a path (either absolute or relative
|
||||
to 'baseDir'). If so, search upward to the root of the
|
||||
repo (i.e. the directory containing .git). */
|
||||
to 'baseDir'). If so, search upward to the root of the
|
||||
repo (i.e. the directory containing .git). */
|
||||
|
||||
path = absPath(path, baseDir);
|
||||
|
||||
@@ -144,15 +151,12 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
|
||||
|
||||
while (flakeRoot != "/") {
|
||||
if (pathExists(flakeRoot + "/.git")) {
|
||||
auto base = std::string("git+file://") + flakeRoot;
|
||||
|
||||
auto parsedURL = ParsedURL{
|
||||
.url = base, // FIXME
|
||||
.base = base,
|
||||
.scheme = "git+file",
|
||||
.authority = "",
|
||||
.path = flakeRoot,
|
||||
.query = query,
|
||||
.fragment = fragment,
|
||||
};
|
||||
|
||||
if (subdir != "") {
|
||||
@@ -164,9 +168,7 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
|
||||
if (pathExists(flakeRoot + "/.git/shallow"))
|
||||
parsedURL.query.insert_or_assign("shallow", "1");
|
||||
|
||||
return std::make_pair(
|
||||
FlakeRef(fetchers::Input::fromURL(fetchSettings, parsedURL), getOr(parsedURL.query, "dir", "")),
|
||||
fragment);
|
||||
return fromParsedURL(fetchSettings, std::move(parsedURL), isFlake);
|
||||
}
|
||||
|
||||
subdir = std::string(baseNameOf(flakeRoot)) + (subdir.empty() ? "" : "/" + subdir);
|
||||
@@ -175,21 +177,24 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!hasPrefix(path, "/"))
|
||||
if (!isAbsolute(path))
|
||||
throw BadURL("flake reference '%s' is not an absolute path", url);
|
||||
path = canonPath(path + "/" + getOr(query, "dir", ""));
|
||||
}
|
||||
|
||||
fetchers::Attrs attrs;
|
||||
attrs.insert_or_assign("type", "path");
|
||||
attrs.insert_or_assign("path", path);
|
||||
return fromParsedURL(fetchSettings, {
|
||||
.scheme = "path",
|
||||
.authority = "",
|
||||
.path = path,
|
||||
.query = query,
|
||||
.fragment = fragment
|
||||
}, isFlake);
|
||||
}
|
||||
|
||||
return std::make_pair(FlakeRef(fetchers::Input::fromAttrs(fetchSettings, std::move(attrs)), ""), fragment);
|
||||
};
|
||||
|
||||
|
||||
/* Check if 'url' is a flake ID. This is an abbreviated syntax for
|
||||
'flake:<flake-id>?ref=<ref>&rev=<rev>'. */
|
||||
/**
|
||||
* Check if `url` is a flake ID. This is an abbreviated syntax for
|
||||
* `flake:<flake-id>?ref=<ref>&rev=<rev>`.
|
||||
*/
|
||||
static std::optional<std::pair<FlakeRef, std::string>> parseFlakeIdRef(
|
||||
const fetchers::Settings & fetchSettings,
|
||||
const std::string & url,
|
||||
@@ -205,8 +210,6 @@ static std::optional<std::pair<FlakeRef, std::string>> parseFlakeIdRef(
|
||||
|
||||
if (std::regex_match(url, match, flakeRegex)) {
|
||||
auto parsedURL = ParsedURL{
|
||||
.url = url,
|
||||
.base = "flake:" + match.str(1),
|
||||
.scheme = "flake",
|
||||
.authority = "",
|
||||
.path = match[1],
|
||||
@@ -227,22 +230,16 @@ std::optional<std::pair<FlakeRef, std::string>> parseURLFlakeRef(
|
||||
bool isFlake
|
||||
)
|
||||
{
|
||||
ParsedURL parsedURL;
|
||||
try {
|
||||
parsedURL = parseURL(url);
|
||||
auto parsed = parseURL(url);
|
||||
if (baseDir
|
||||
&& parsed.scheme == "path"
|
||||
&& !isAbsolute(parsed.path))
|
||||
parsed.path = absPath(parsed.path, *baseDir);
|
||||
return fromParsedURL(fetchSettings, std::move(parsed), isFlake);
|
||||
} catch (BadURL &) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::string fragment;
|
||||
std::swap(fragment, parsedURL.fragment);
|
||||
|
||||
auto input = fetchers::Input::fromURL(fetchSettings, parsedURL, isFlake);
|
||||
input.parent = baseDir;
|
||||
|
||||
return std::make_pair(
|
||||
FlakeRef(std::move(input), getOr(parsedURL.query, "dir", "")),
|
||||
fragment);
|
||||
}
|
||||
|
||||
std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
{ lib
|
||||
, stdenv
|
||||
, mkMesonLibrary
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
mkMesonLibrary,
|
||||
|
||||
, nix-util
|
||||
, nix-store
|
||||
, nix-fetchers
|
||||
, nix-expr
|
||||
, nlohmann_json
|
||||
nix-util,
|
||||
nix-store,
|
||||
nix-fetchers,
|
||||
nix-expr,
|
||||
nlohmann_json,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
version,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -48,9 +49,12 @@ mkMesonLibrary (finalAttrs: {
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
{ lib
|
||||
, stdenv
|
||||
, mkMesonLibrary
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
mkMesonLibrary,
|
||||
|
||||
, nix-util-c
|
||||
, nix-store
|
||||
, nix-store-c
|
||||
, nix-main
|
||||
nix-util-c,
|
||||
nix-store,
|
||||
nix-store-c,
|
||||
nix-main,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
version,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -51,9 +52,12 @@ mkMesonLibrary (finalAttrs: {
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
|
||||
@@ -17,7 +17,9 @@ MixCommonArgs::MixCommonArgs(const std::string & programName)
|
||||
.shortName = 'v',
|
||||
.description = "Increase the logging verbosity level.",
|
||||
.category = loggingCategory,
|
||||
.handler = {[]() { verbosity = (Verbosity) (verbosity + 1); }},
|
||||
.handler = {[]() {
|
||||
verbosity = (Verbosity) std::min<std::underlying_type_t<Verbosity>>(verbosity + 1, lvlVomit);
|
||||
}},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
{ lib
|
||||
, stdenv
|
||||
, mkMesonLibrary
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
mkMesonLibrary,
|
||||
|
||||
, openssl
|
||||
openssl,
|
||||
|
||||
, nix-util
|
||||
, nix-store
|
||||
nix-util,
|
||||
nix-store,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
version,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -45,9 +46,12 @@ mkMesonLibrary (finalAttrs: {
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
{ lib
|
||||
, stdenv
|
||||
, mkMesonLibrary
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
mkMesonLibrary,
|
||||
|
||||
, nix-util-c
|
||||
, nix-store
|
||||
nix-util-c,
|
||||
nix-store,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
version,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -47,9 +48,12 @@ mkMesonLibrary (finalAttrs: {
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
{ lib
|
||||
, stdenv
|
||||
, mkMesonLibrary
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
mkMesonLibrary,
|
||||
|
||||
, nix-util-test-support
|
||||
, nix-store
|
||||
nix-util-test-support,
|
||||
nix-store,
|
||||
|
||||
, rapidcheck
|
||||
rapidcheck,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
version,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -49,9 +50,12 @@ mkMesonLibrary (finalAttrs: {
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
{ lib
|
||||
, buildPackages
|
||||
, stdenv
|
||||
, mkMesonExecutable
|
||||
{
|
||||
lib,
|
||||
buildPackages,
|
||||
stdenv,
|
||||
mkMesonExecutable,
|
||||
|
||||
, nix-store
|
||||
, nix-store-c
|
||||
, nix-store-test-support
|
||||
, sqlite
|
||||
nix-store,
|
||||
nix-store-c,
|
||||
nix-store-test-support,
|
||||
sqlite,
|
||||
|
||||
, rapidcheck
|
||||
, gtest
|
||||
, runCommand
|
||||
rapidcheck,
|
||||
gtest,
|
||||
runCommand,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
, filesetToSource
|
||||
version,
|
||||
filesetToSource,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -62,32 +63,42 @@ mkMesonExecutable (finalAttrs: {
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
passthru = {
|
||||
tests = {
|
||||
run = let
|
||||
# Some data is shared with the functional tests: they create it,
|
||||
# we consume it.
|
||||
data = filesetToSource {
|
||||
root = ../..;
|
||||
fileset = lib.fileset.unions [
|
||||
./data
|
||||
../../tests/functional/derivation
|
||||
];
|
||||
};
|
||||
in runCommand "${finalAttrs.pname}-run" {
|
||||
meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages;
|
||||
} (lib.optionalString stdenv.hostPlatform.isWindows ''
|
||||
export HOME="$PWD/home-dir"
|
||||
mkdir -p "$HOME"
|
||||
'' + ''
|
||||
export _NIX_TEST_UNIT_DATA=${data + "/src/libstore-tests/data"}
|
||||
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
|
||||
touch $out
|
||||
'');
|
||||
run =
|
||||
let
|
||||
# Some data is shared with the functional tests: they create it,
|
||||
# we consume it.
|
||||
data = filesetToSource {
|
||||
root = ../..;
|
||||
fileset = lib.fileset.unions [
|
||||
./data
|
||||
../../tests/functional/derivation
|
||||
];
|
||||
};
|
||||
in
|
||||
runCommand "${finalAttrs.pname}-run"
|
||||
{
|
||||
meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages;
|
||||
}
|
||||
(
|
||||
lib.optionalString stdenv.hostPlatform.isWindows ''
|
||||
export HOME="$PWD/home-dir"
|
||||
mkdir -p "$HOME"
|
||||
''
|
||||
+ ''
|
||||
export _NIX_TEST_UNIT_DATA=${data + "/src/libstore-tests/data"}
|
||||
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
|
||||
touch $out
|
||||
''
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -1158,7 +1158,7 @@ HookReply DerivationGoal::tryBuildHook()
|
||||
throw;
|
||||
}
|
||||
}();
|
||||
if (handleJSONLogMessage(s, worker.act, worker.hook->activities, true))
|
||||
if (handleJSONLogMessage(s, worker.act, worker.hook->activities, "the build hook", true))
|
||||
;
|
||||
else if (s.substr(0, 2) == "# ") {
|
||||
reply = s.substr(2);
|
||||
@@ -1343,9 +1343,9 @@ void DerivationGoal::handleChildOutput(Descriptor fd, std::string_view data)
|
||||
if (hook && fd == hook->fromHook.readSide.get()) {
|
||||
for (auto c : data)
|
||||
if (c == '\n') {
|
||||
auto json = parseJSONMessage(currentHookLine);
|
||||
auto json = parseJSONMessage(currentHookLine, "the derivation builder");
|
||||
if (json) {
|
||||
auto s = handleJSONLogMessage(*json, worker.act, hook->activities, true);
|
||||
auto s = handleJSONLogMessage(*json, worker.act, hook->activities, "the derivation builder", true);
|
||||
// ensure that logs from a builder using `ssh-ng://` as protocol
|
||||
// are also available to `nix log`.
|
||||
if (s && !isWrittenToLog && logSink) {
|
||||
@@ -1387,7 +1387,7 @@ void DerivationGoal::handleEOF(Descriptor fd)
|
||||
|
||||
void DerivationGoal::flushLine()
|
||||
{
|
||||
if (handleJSONLogMessage(currentLogLine, *act, builderActivities, false))
|
||||
if (handleJSONLogMessage(currentLogLine, *act, builderActivities, "the derivation builder", false))
|
||||
;
|
||||
|
||||
else {
|
||||
|
||||
@@ -300,6 +300,14 @@ struct curlFileTransfer : public FileTransfer
|
||||
return ((TransferItem *) userp)->readCallback(buffer, size, nitems);
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) && LIBCURL_VERSION_NUM >= 0x071000
|
||||
static int cloexec_callback(void *, curl_socket_t curlfd, curlsocktype purpose) {
|
||||
unix::closeOnExec(curlfd);
|
||||
vomit("cloexec set for fd %i", curlfd);
|
||||
return CURL_SOCKOPT_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
void init()
|
||||
{
|
||||
if (!req) req = curl_easy_init();
|
||||
@@ -359,6 +367,10 @@ struct curlFileTransfer : public FileTransfer
|
||||
curl_easy_setopt(req, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) && LIBCURL_VERSION_NUM >= 0x071000
|
||||
curl_easy_setopt(req, CURLOPT_SOCKOPTFUNCTION, cloexec_callback);
|
||||
#endif
|
||||
|
||||
curl_easy_setopt(req, CURLOPT_CONNECTTIMEOUT, fileTransferSettings.connectTimeout.get());
|
||||
|
||||
curl_easy_setopt(req, CURLOPT_LOW_SPEED_LIMIT, 1L);
|
||||
@@ -767,7 +779,7 @@ struct curlFileTransfer : public FileTransfer
|
||||
auto s3Res = s3Helper.getObject(bucketName, key);
|
||||
FileTransferResult res;
|
||||
if (!s3Res.data)
|
||||
throw FileTransferError(NotFound, "S3 object '%s' does not exist", request.uri);
|
||||
throw FileTransferError(NotFound, {}, "S3 object '%s' does not exist", request.uri);
|
||||
res.data = std::move(*s3Res.data);
|
||||
res.urls.push_back(request.uri);
|
||||
callback(std::move(res));
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "finally.hh"
|
||||
#include "unix-domain-socket.hh"
|
||||
#include "signals.hh"
|
||||
#include "posix-fs-canonicalise.hh"
|
||||
|
||||
#if !defined(__linux__)
|
||||
// For shelling out to lsof
|
||||
@@ -763,13 +764,18 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto & path : topoSortPaths(visited)) {
|
||||
if (!dead.insert(path).second) continue;
|
||||
if (shouldDelete) {
|
||||
invalidatePathChecked(path);
|
||||
deleteFromStore(path.to_string());
|
||||
referrersCache.erase(path);
|
||||
try {
|
||||
invalidatePathChecked(path);
|
||||
deleteFromStore(path.to_string());
|
||||
referrersCache.erase(path);
|
||||
} catch (PathInUse &e) {
|
||||
// If we end up here, it's likely a new occurence
|
||||
// of https://github.com/NixOS/nix/issues/11923
|
||||
printError("BUG: %s", e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -181,7 +181,12 @@ LocalStore::LocalStore(
|
||||
for (auto & perUserDir : {profilesDir + "/per-user", gcRootsDir + "/per-user"}) {
|
||||
createDirs(perUserDir);
|
||||
if (!readOnly) {
|
||||
if (chmod(perUserDir.c_str(), 0755) == -1)
|
||||
auto st = lstat(perUserDir);
|
||||
|
||||
// Skip chmod call if the directory already has the correct permissions (0755).
|
||||
// This is to avoid failing when the executing user lacks permissions to change the directory's permissions
|
||||
// even if it would be no-op.
|
||||
if ((st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) != 0755 && chmod(perUserDir.c_str(), 0755) == -1)
|
||||
throw SysError("could not set permissions on '%s' to 755", perUserDir);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
{ lib
|
||||
, stdenv
|
||||
, mkMesonLibrary
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
mkMesonLibrary,
|
||||
|
||||
, unixtools
|
||||
, darwin
|
||||
unixtools,
|
||||
darwin,
|
||||
|
||||
, nix-util
|
||||
, boost
|
||||
, curl
|
||||
, aws-sdk-cpp
|
||||
, libseccomp
|
||||
, nlohmann_json
|
||||
, sqlite
|
||||
nix-util,
|
||||
boost,
|
||||
curl,
|
||||
aws-sdk-cpp,
|
||||
libseccomp,
|
||||
nlohmann_json,
|
||||
sqlite,
|
||||
|
||||
, busybox-sandbox-shell ? null
|
||||
busybox-sandbox-shell ? null,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
version,
|
||||
|
||||
, embeddedSandboxShell ? stdenv.hostPlatform.isStatic
|
||||
embeddedSandboxShell ? stdenv.hostPlatform.isStatic,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -48,19 +49,20 @@ mkMesonLibrary (finalAttrs: {
|
||||
(fileset.fileFilter (file: file.hasExt "sql") ./.)
|
||||
];
|
||||
|
||||
nativeBuildInputs =
|
||||
lib.optional embeddedSandboxShell unixtools.hexdump;
|
||||
nativeBuildInputs = lib.optional embeddedSandboxShell unixtools.hexdump;
|
||||
|
||||
buildInputs = [
|
||||
boost
|
||||
curl
|
||||
sqlite
|
||||
] ++ lib.optional stdenv.hostPlatform.isLinux libseccomp
|
||||
buildInputs =
|
||||
[
|
||||
boost
|
||||
curl
|
||||
sqlite
|
||||
]
|
||||
++ lib.optional stdenv.hostPlatform.isLinux libseccomp
|
||||
# There have been issues building these dependencies
|
||||
++ lib.optional stdenv.hostPlatform.isDarwin darwin.apple_sdk.libs.sandbox
|
||||
++ lib.optional (stdenv.hostPlatform == stdenv.buildPlatform && (stdenv.isLinux || stdenv.isDarwin))
|
||||
aws-sdk-cpp
|
||||
;
|
||||
++ lib.optional (
|
||||
stdenv.hostPlatform == stdenv.buildPlatform && (stdenv.isLinux || stdenv.isDarwin)
|
||||
) aws-sdk-cpp;
|
||||
|
||||
propagatedBuildInputs = [
|
||||
nix-util
|
||||
@@ -75,21 +77,27 @@ mkMesonLibrary (finalAttrs: {
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
(lib.mesonEnable "seccomp-sandboxing" stdenv.hostPlatform.isLinux)
|
||||
(lib.mesonBool "embedded-sandbox-shell" embeddedSandboxShell)
|
||||
] ++ lib.optionals stdenv.hostPlatform.isLinux [
|
||||
(lib.mesonOption "sandbox-shell" "${busybox-sandbox-shell}/bin/busybox")
|
||||
];
|
||||
mesonFlags =
|
||||
[
|
||||
(lib.mesonEnable "seccomp-sandboxing" stdenv.hostPlatform.isLinux)
|
||||
(lib.mesonBool "embedded-sandbox-shell" embeddedSandboxShell)
|
||||
]
|
||||
++ lib.optionals stdenv.hostPlatform.isLinux [
|
||||
(lib.mesonOption "sandbox-shell" "${busybox-sandbox-shell}/bin/busybox")
|
||||
];
|
||||
|
||||
env = {
|
||||
# Needed for Meson to find Boost.
|
||||
# https://github.com/NixOS/nixpkgs/issues/86131.
|
||||
BOOST_INCLUDEDIR = "${lib.getDev boost}/include";
|
||||
BOOST_LIBRARYDIR = "${lib.getLib boost}/lib";
|
||||
} // lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
{
|
||||
# Needed for Meson to find Boost.
|
||||
# https://github.com/NixOS/nixpkgs/issues/86131.
|
||||
BOOST_INCLUDEDIR = "${lib.getDev boost}/include";
|
||||
BOOST_LIBRARYDIR = "${lib.getLib boost}/lib";
|
||||
}
|
||||
// lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
|
||||
@@ -534,14 +534,27 @@ void RemoteStore::addToStore(const ValidPathInfo & info, Source & source,
|
||||
|
||||
|
||||
void RemoteStore::addMultipleToStore(
|
||||
PathsSource & pathsToCopy,
|
||||
PathsSource && pathsToCopy,
|
||||
Activity & act,
|
||||
RepairFlag repair,
|
||||
CheckSigsFlag checkSigs)
|
||||
{
|
||||
// `addMultipleToStore` is single threaded
|
||||
size_t bytesExpected = 0;
|
||||
for (auto & [pathInfo, _] : pathsToCopy) {
|
||||
bytesExpected += pathInfo.narSize;
|
||||
}
|
||||
act.setExpected(actCopyPath, bytesExpected);
|
||||
|
||||
auto source = sinkToSource([&](Sink & sink) {
|
||||
sink << pathsToCopy.size();
|
||||
for (auto & [pathInfo, pathSource] : pathsToCopy) {
|
||||
size_t nrTotal = pathsToCopy.size();
|
||||
sink << nrTotal;
|
||||
// Reverse, so we can release memory at the original start
|
||||
std::reverse(pathsToCopy.begin(), pathsToCopy.end());
|
||||
while (!pathsToCopy.empty()) {
|
||||
act.progress(nrTotal - pathsToCopy.size(), nrTotal, size_t(1), size_t(0));
|
||||
|
||||
auto & [pathInfo, pathSource] = pathsToCopy.back();
|
||||
WorkerProto::Serialise<ValidPathInfo>::write(*this,
|
||||
WorkerProto::WriteConn {
|
||||
.to = sink,
|
||||
@@ -549,6 +562,7 @@ void RemoteStore::addMultipleToStore(
|
||||
},
|
||||
pathInfo);
|
||||
pathSource->drainInto(sink);
|
||||
pathsToCopy.pop_back();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ public:
|
||||
CheckSigsFlag checkSigs) override;
|
||||
|
||||
void addMultipleToStore(
|
||||
PathsSource & pathsToCopy,
|
||||
PathsSource && pathsToCopy,
|
||||
Activity & act,
|
||||
RepairFlag repair,
|
||||
CheckSigsFlag checkSigs) override;
|
||||
|
||||
@@ -223,7 +223,7 @@ StorePath Store::addToStore(
|
||||
}
|
||||
|
||||
void Store::addMultipleToStore(
|
||||
PathsSource & pathsToCopy,
|
||||
PathsSource && pathsToCopy,
|
||||
Activity & act,
|
||||
RepairFlag repair,
|
||||
CheckSigsFlag checkSigs)
|
||||
@@ -242,13 +242,11 @@ void Store::addMultipleToStore(
|
||||
storePathsToAdd.insert(thingToAdd.first.path);
|
||||
}
|
||||
|
||||
auto showProgress = [&]() {
|
||||
act.progress(nrDone, pathsToCopy.size(), nrRunning, nrFailed);
|
||||
auto showProgress = [&, nrTotal = pathsToCopy.size()]() {
|
||||
act.progress(nrDone, nrTotal, nrRunning, nrFailed);
|
||||
};
|
||||
|
||||
ThreadPool pool;
|
||||
|
||||
processGraph<StorePath>(pool,
|
||||
processGraph<StorePath>(
|
||||
storePathsToAdd,
|
||||
|
||||
[&](const StorePath & path) {
|
||||
@@ -1028,12 +1026,10 @@ std::map<StorePath, StorePath> copyPaths(
|
||||
}
|
||||
auto pathsMap = copyPaths(srcStore, dstStore, storePaths, repair, checkSigs, substitute);
|
||||
|
||||
ThreadPool pool;
|
||||
|
||||
try {
|
||||
// Copy the realisation closure
|
||||
processGraph<Realisation>(
|
||||
pool, Realisation::closure(srcStore, toplevelRealisations),
|
||||
Realisation::closure(srcStore, toplevelRealisations),
|
||||
[&](const Realisation & current) -> std::set<Realisation> {
|
||||
std::set<Realisation> children;
|
||||
for (const auto & [drvOutput, _] : current.dependentRealisations) {
|
||||
@@ -1108,9 +1104,6 @@ std::map<StorePath, StorePath> copyPaths(
|
||||
return storePathForDst;
|
||||
};
|
||||
|
||||
// total is accessed by each copy, which are each handled in separate threads
|
||||
std::atomic<uint64_t> total = 0;
|
||||
|
||||
for (auto & missingPath : sortedMissing) {
|
||||
auto info = srcStore.queryPathInfo(missingPath);
|
||||
|
||||
@@ -1120,9 +1113,10 @@ std::map<StorePath, StorePath> copyPaths(
|
||||
ValidPathInfo infoForDst = *info;
|
||||
infoForDst.path = storePathForDst;
|
||||
|
||||
auto source = sinkToSource([&](Sink & sink) {
|
||||
auto source = sinkToSource([&, narSize = info->narSize](Sink & sink) {
|
||||
// We can reasonably assume that the copy will happen whenever we
|
||||
// read the path, so log something about that at that point
|
||||
uint64_t total = 0;
|
||||
auto srcUri = srcStore.getUri();
|
||||
auto dstUri = dstStore.getUri();
|
||||
auto storePathS = srcStore.printStorePath(missingPath);
|
||||
@@ -1133,16 +1127,16 @@ std::map<StorePath, StorePath> copyPaths(
|
||||
|
||||
LambdaSink progressSink([&](std::string_view data) {
|
||||
total += data.size();
|
||||
act.progress(total, info->narSize);
|
||||
act.progress(total, narSize);
|
||||
});
|
||||
TeeSink tee { sink, progressSink };
|
||||
|
||||
srcStore.narFromPath(missingPath, tee);
|
||||
});
|
||||
pathsToCopy.push_back(std::pair{infoForDst, std::move(source)});
|
||||
pathsToCopy.emplace_back(std::move(infoForDst), std::move(source));
|
||||
}
|
||||
|
||||
dstStore.addMultipleToStore(pathsToCopy, act, repair, checkSigs);
|
||||
dstStore.addMultipleToStore(std::move(pathsToCopy), act, repair, checkSigs);
|
||||
|
||||
return pathsMap;
|
||||
}
|
||||
|
||||
@@ -425,7 +425,7 @@ public:
|
||||
CheckSigsFlag checkSigs = CheckSigs);
|
||||
|
||||
virtual void addMultipleToStore(
|
||||
PathsSource & pathsToCopy,
|
||||
PathsSource && pathsToCopy,
|
||||
Activity & act,
|
||||
RepairFlag repair = NoRepair,
|
||||
CheckSigsFlag checkSigs = CheckSigs);
|
||||
|
||||
@@ -2149,7 +2149,18 @@ void LocalDerivationGoal::runChild()
|
||||
without file-write* allowed, access() incorrectly returns EPERM
|
||||
*/
|
||||
sandboxProfile += "(allow file-read* file-write* process-exec\n";
|
||||
|
||||
// We create multiple allow lists, to avoid exceeding a limit in the darwin sandbox interpreter.
|
||||
// See https://github.com/NixOS/nix/issues/4119
|
||||
// We split our allow groups approximately at half the actual limit, 1 << 16
|
||||
const int breakpoint = sandboxProfile.length() + (1 << 14);
|
||||
for (auto & i : pathsInChroot) {
|
||||
|
||||
if (sandboxProfile.length() >= breakpoint) {
|
||||
debug("Sandbox break: %d %d", sandboxProfile.length(), breakpoint);
|
||||
sandboxProfile += ")\n(allow file-read* file-write* process-exec\n";
|
||||
}
|
||||
|
||||
if (i.first != i.second.source)
|
||||
throw Error(
|
||||
"can't map '%1%' to '%2%': mismatched impure paths not supported on Darwin",
|
||||
@@ -2657,10 +2668,14 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs()
|
||||
wanted.to_string(HashFormat::SRI, true),
|
||||
got.to_string(HashFormat::SRI, true)));
|
||||
}
|
||||
if (!newInfo0.references.empty())
|
||||
if (!newInfo0.references.empty()) {
|
||||
auto numViolations = newInfo.references.size();
|
||||
delayedException = std::make_exception_ptr(
|
||||
BuildError("illegal path references in fixed-output derivation '%s'",
|
||||
worker.store.printStorePath(drvPath)));
|
||||
BuildError("fixed-output derivations must not reference store paths: '%s' references %d distinct paths, e.g. '%s'",
|
||||
worker.store.printStorePath(drvPath),
|
||||
numViolations,
|
||||
worker.store.printStorePath(*newInfo.references.begin())));
|
||||
}
|
||||
|
||||
return newInfo0;
|
||||
},
|
||||
@@ -2927,8 +2942,12 @@ void LocalDerivationGoal::checkOutputs(const std::map<std::string, ValidPathInfo
|
||||
spec.insert(worker.store.parseStorePath(i));
|
||||
else if (auto output = get(outputs, i))
|
||||
spec.insert(output->path);
|
||||
else
|
||||
throw BuildError("derivation contains an illegal reference specifier '%s'", i);
|
||||
else {
|
||||
std::string outputsListing = concatMapStringsSep(", ", outputs, [](auto & o) { return o.first; });
|
||||
throw BuildError("derivation '%s' output check for '%s' contains an illegal reference specifier '%s',"
|
||||
" expected store path or output name (one of [%s])",
|
||||
worker.store.printStorePath(drvPath), outputName, i, outputsListing);
|
||||
}
|
||||
}
|
||||
|
||||
auto used = recursive
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
{ lib
|
||||
, stdenv
|
||||
, mkMesonLibrary
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
mkMesonLibrary,
|
||||
|
||||
, nix-util
|
||||
nix-util,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
version,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -45,9 +46,12 @@ mkMesonLibrary (finalAttrs: {
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
{ lib
|
||||
, stdenv
|
||||
, mkMesonLibrary
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
mkMesonLibrary,
|
||||
|
||||
, nix-util
|
||||
nix-util,
|
||||
|
||||
, rapidcheck
|
||||
rapidcheck,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
version,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -47,9 +48,12 @@ mkMesonLibrary (finalAttrs: {
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
|
||||
@@ -261,4 +261,18 @@ TEST(pathExists, bogusPathDoesNotExist)
|
||||
{
|
||||
ASSERT_FALSE(pathExists("/schnitzel/darmstadt/pommes"));
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* makeParentCanonical
|
||||
* --------------------------------------------------------------------------*/
|
||||
|
||||
TEST(makeParentCanonical, noParent)
|
||||
{
|
||||
ASSERT_EQ(makeParentCanonical("file"), absPath(std::filesystem::path("file")));
|
||||
}
|
||||
|
||||
TEST(makeParentCanonical, root)
|
||||
{
|
||||
ASSERT_EQ(makeParentCanonical("/"), "/");
|
||||
}
|
||||
}
|
||||
|
||||
18
src/libutil-tests/monitorfdhup.cc
Normal file
18
src/libutil-tests/monitorfdhup.cc
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "util.hh"
|
||||
#include "monitor-fd.hh"
|
||||
|
||||
#include <sys/file.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace nix {
|
||||
TEST(MonitorFdHup, shouldNotBlock)
|
||||
{
|
||||
Pipe p;
|
||||
p.create();
|
||||
{
|
||||
// when monitor gets destroyed it should cancel the
|
||||
// background thread and do not block
|
||||
MonitorFdHup monitor(p.readSide.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,20 @@
|
||||
{ lib
|
||||
, buildPackages
|
||||
, stdenv
|
||||
, mkMesonExecutable
|
||||
{
|
||||
lib,
|
||||
buildPackages,
|
||||
stdenv,
|
||||
mkMesonExecutable,
|
||||
|
||||
, nix-util
|
||||
, nix-util-c
|
||||
, nix-util-test-support
|
||||
nix-util,
|
||||
nix-util-c,
|
||||
nix-util-test-support,
|
||||
|
||||
, rapidcheck
|
||||
, gtest
|
||||
, runCommand
|
||||
rapidcheck,
|
||||
gtest,
|
||||
runCommand,
|
||||
|
||||
# Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
version,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -55,22 +56,31 @@ mkMesonExecutable (finalAttrs: {
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
env =
|
||||
lib.optionalAttrs
|
||||
(stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux"))
|
||||
{
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
passthru = {
|
||||
tests = {
|
||||
run = runCommand "${finalAttrs.pname}-run" {
|
||||
meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages;
|
||||
} (lib.optionalString stdenv.hostPlatform.isWindows ''
|
||||
export HOME="$PWD/home-dir"
|
||||
mkdir -p "$HOME"
|
||||
'' + ''
|
||||
export _NIX_TEST_UNIT_DATA=${./data}
|
||||
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
|
||||
touch $out
|
||||
'');
|
||||
run =
|
||||
runCommand "${finalAttrs.pname}-run"
|
||||
{
|
||||
meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages;
|
||||
}
|
||||
(
|
||||
lib.optionalString stdenv.hostPlatform.isWindows ''
|
||||
export HOME="$PWD/home-dir"
|
||||
mkdir -p "$HOME"
|
||||
''
|
||||
+ ''
|
||||
export _NIX_TEST_UNIT_DATA=${./data}
|
||||
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
|
||||
touch $out
|
||||
''
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -81,6 +81,42 @@ TEST(concatStringsSep, buildSingleString)
|
||||
ASSERT_EQ(concatStringsSep(",", strings), "this");
|
||||
}
|
||||
|
||||
TEST(concatMapStringsSep, empty)
|
||||
{
|
||||
Strings strings;
|
||||
|
||||
ASSERT_EQ(concatMapStringsSep(",", strings, [](const std::string & s) { return s; }), "");
|
||||
}
|
||||
|
||||
TEST(concatMapStringsSep, justOne)
|
||||
{
|
||||
Strings strings;
|
||||
strings.push_back("this");
|
||||
|
||||
ASSERT_EQ(concatMapStringsSep(",", strings, [](const std::string & s) { return s; }), "this");
|
||||
}
|
||||
|
||||
TEST(concatMapStringsSep, two)
|
||||
{
|
||||
Strings strings;
|
||||
strings.push_back("this");
|
||||
strings.push_back("that");
|
||||
|
||||
ASSERT_EQ(concatMapStringsSep(",", strings, [](const std::string & s) { return s; }), "this,that");
|
||||
}
|
||||
|
||||
TEST(concatMapStringsSep, map)
|
||||
{
|
||||
std::map<std::string, std::string> strings;
|
||||
strings["this"] = "that";
|
||||
strings["1"] = "one";
|
||||
|
||||
ASSERT_EQ(
|
||||
concatMapStringsSep(
|
||||
", ", strings, [](const std::pair<std::string, std::string> & s) { return s.first + " -> " + s.second; }),
|
||||
"1 -> one, this -> that");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* dropEmptyInitThenConcatStringsSep
|
||||
* --------------------------------------------------------------------------*/
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user