Compare commits
387 Commits
unix-sourc
...
2.28.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fefd97fba8 | ||
|
|
7762b7d629 | ||
|
|
75e6c8dc90 | ||
|
|
2f63896e01 | ||
|
|
c848e58683 | ||
|
|
8049b297ce | ||
|
|
834bf0d029 | ||
|
|
552ecdaee2 | ||
|
|
0e8f6b1308 | ||
|
|
1b8acb5694 | ||
|
|
05c7da24cc | ||
|
|
73201a6144 | ||
|
|
265e535650 | ||
|
|
25b653559b | ||
|
|
1a4dbd9fa1 | ||
|
|
b728740ea5 | ||
|
|
31005f2236 | ||
|
|
945d9d7264 | ||
|
|
448bbbe0fd | ||
|
|
2c57edd677 | ||
|
|
2939ee0ada | ||
|
|
49062664ed | ||
|
|
9656003292 | ||
|
|
b96f21441d | ||
|
|
a24fddb779 | ||
|
|
2b4e25b49d | ||
|
|
b13a119a79 | ||
|
|
99343a66af | ||
|
|
9956c97ed9 | ||
|
|
7ad7c662bb | ||
|
|
63c66c04be | ||
|
|
2402aa219f | ||
|
|
e73d16377a | ||
|
|
84f27a1329 | ||
|
|
5bd259b311 | ||
|
|
35e563b6bd | ||
|
|
ec920aea61 | ||
|
|
86ffcbcbfe | ||
|
|
8450dee5a2 | ||
|
|
cae5086c60 | ||
|
|
b2a2cf6934 | ||
|
|
e261cc8f0d | ||
|
|
8db221bc50 | ||
|
|
3fe1b42423 | ||
|
|
0d763f7ce2 | ||
|
|
9af1782bdf | ||
|
|
01963be827 | ||
|
|
66a5d4c31b | ||
|
|
e52fe2cab4 | ||
|
|
cac6cfe51e | ||
|
|
4f105e7c7d | ||
|
|
ffe384b21e | ||
|
|
f97ff25aec | ||
|
|
63f18cd0c6 | ||
|
|
556b71d6c0 | ||
|
|
aace3d91ac | ||
|
|
ab3ad122db | ||
|
|
b320aa50fe | ||
|
|
59da02def5 | ||
|
|
8f5e9b38f1 | ||
|
|
e04004ebc2 | ||
|
|
f56f6e9e14 | ||
|
|
354d4c4a32 | ||
|
|
3a3ee4a692 | ||
|
|
7126d57220 | ||
|
|
c0a1e07bca | ||
|
|
4a1e3ad48b | ||
|
|
1e371c4a49 | ||
|
|
0560581a48 | ||
|
|
3eb5a7cf30 | ||
|
|
bab4e58a5e | ||
|
|
08f7ddbee5 | ||
|
|
6c0cc04ce4 | ||
|
|
c78676a1de | ||
|
|
8a1b7377cf | ||
|
|
5ae4ee99d3 | ||
|
|
aa9d588891 | ||
|
|
ec4707df91 | ||
|
|
c56833e941 | ||
|
|
13a8fe7580 | ||
|
|
a0a94b9027 | ||
|
|
5763c356a9 | ||
|
|
23ecb1067c | ||
|
|
70439b4174 | ||
|
|
14a5e2a4a3 | ||
|
|
f5dfd9a4a4 | ||
|
|
6151c36a0b | ||
|
|
13206c132d | ||
|
|
448c5d912c | ||
|
|
a5264aa46e | ||
|
|
7b97377ac3 | ||
|
|
91141aa76d | ||
|
|
bd8cd3c15d | ||
|
|
3fd8523af7 | ||
|
|
65f435708a | ||
|
|
be0e78ae23 | ||
|
|
5ebe8b8536 | ||
|
|
8f8877417c | ||
|
|
faaf5b86c6 | ||
|
|
34f06900aa | ||
|
|
7a98e1b7c4 | ||
|
|
814822ba43 | ||
|
|
d08a448596 | ||
|
|
3206585a74 | ||
|
|
beb845981b | ||
|
|
a2941dc574 | ||
|
|
a98ff409fa | ||
|
|
decc0bfd79 | ||
|
|
6c7215b278 | ||
|
|
983d3922ff | ||
|
|
37fe2584c1 | ||
|
|
24c1aa735a | ||
|
|
c6d7a1bb42 | ||
|
|
d3840a1472 | ||
|
|
aee067f539 | ||
|
|
6f4c2a0a3b | ||
|
|
f3c10d8c6f | ||
|
|
ddec59e694 | ||
|
|
ac328b88d8 | ||
|
|
a7588b47f2 | ||
|
|
d1e397d2a5 | ||
|
|
a3e6953c71 | ||
|
|
4168ee57ec | ||
|
|
c4d6c6a3ca | ||
|
|
58c84bcf8a | ||
|
|
f8984c4182 | ||
|
|
8f5172d026 | ||
|
|
47ba78d251 | ||
|
|
b4bfe15559 | ||
|
|
2e31ed2f19 | ||
|
|
0acb13b7fe | ||
|
|
c0cef69790 | ||
|
|
79eed1d9c4 | ||
|
|
9fd0cd8ed0 | ||
|
|
68fd62b1fb | ||
|
|
f9dd4e5605 | ||
|
|
3d8d19928e | ||
|
|
0f4b17e51f | ||
|
|
8de4c272dc | ||
|
|
6ba4b1d252 | ||
|
|
bf0f35ec69 | ||
|
|
ff6e0f5228 | ||
|
|
60a6baa2d7 | ||
|
|
1e2e52b66a | ||
|
|
6b16f919da | ||
|
|
4d4a91ab8d | ||
|
|
9ba32a2981 | ||
|
|
323e840d17 | ||
|
|
1c9e94789e | ||
|
|
e20b0d7b29 | ||
|
|
709f05989d | ||
|
|
dfbb52e6bd | ||
|
|
5a7cdc4373 | ||
|
|
357a0f639c | ||
|
|
10350537b1 | ||
|
|
b179259d6f | ||
|
|
3019007eb5 | ||
|
|
6390b8b7cf | ||
|
|
8686ba906f | ||
|
|
04fcc879e6 | ||
|
|
4da3fada6e | ||
|
|
5a2ee1b952 | ||
|
|
06cc94432e | ||
|
|
d3c79e2b13 | ||
|
|
70921714cb | ||
|
|
f666ec3837 | ||
|
|
ba22a85a35 | ||
|
|
e555207048 | ||
|
|
8a7b8dce5f | ||
|
|
29ae14114e | ||
|
|
30d900b313 | ||
|
|
5f0ddd7467 | ||
|
|
f19184191e | ||
|
|
37bcd29e5f | ||
|
|
5ecbf6b9dc | ||
|
|
f233a99cc8 | ||
|
|
818fc68db6 | ||
|
|
671364748c | ||
|
|
9a969e29cf | ||
|
|
a603401cdd | ||
|
|
3e895be4e4 | ||
|
|
b1a1f4bd2f | ||
|
|
f18180a045 | ||
|
|
9156550493 | ||
|
|
011f6e06a2 | ||
|
|
61bb405839 | ||
|
|
c53bd8905b | ||
|
|
beab9eb978 | ||
|
|
4d990f1459 | ||
|
|
f9c262c3d5 | ||
|
|
bb8af4ceb7 | ||
|
|
2892b758b3 | ||
|
|
e191b93a0e | ||
|
|
080950b0fe | ||
|
|
6d98cef93f | ||
|
|
a08477975d | ||
|
|
c548e92860 | ||
|
|
a7f078aa84 | ||
|
|
cd7e01526e | ||
|
|
16a2cddfb9 | ||
|
|
1a4332fd3a | ||
|
|
3a4dc47c22 | ||
|
|
f0ed61bb4e | ||
|
|
85902fad58 | ||
|
|
467a1df842 | ||
|
|
aa1c690ebf | ||
|
|
3a758fc348 | ||
|
|
17de9dd275 | ||
|
|
6dde30bacf | ||
|
|
5b21c94fab | ||
|
|
a4962f73b5 | ||
|
|
288fee2d14 | ||
|
|
42ba32f1ff | ||
|
|
e0778c2796 | ||
|
|
e7dbf0fc0a | ||
|
|
e3a8e43600 | ||
|
|
9cdf72beaa | ||
|
|
efb0feb22b | ||
|
|
7e96f31753 | ||
|
|
49b6766332 | ||
|
|
63b9b932f4 | ||
|
|
3bb46b73a8 | ||
|
|
1b119ded3a | ||
|
|
615344fdf0 | ||
|
|
bd2d5b7335 | ||
|
|
5c90b41715 | ||
|
|
d81cd04d23 | ||
|
|
0a66906e55 | ||
|
|
0b4fea7872 | ||
|
|
651df50996 | ||
|
|
6d53506ae3 | ||
|
|
b9fc326a9a | ||
|
|
36ce86dfb6 | ||
|
|
cd31a8ca84 | ||
|
|
994c8b6a7a | ||
|
|
4edd560269 | ||
|
|
ddfb268ff5 | ||
|
|
3a5bbca252 | ||
|
|
f48a72afc5 | ||
|
|
d73ed6f310 | ||
|
|
a47ea7ed04 | ||
|
|
c972cbd2bb | ||
|
|
c066fa671d | ||
|
|
1ca3ee1287 | ||
|
|
918b6cbfea | ||
|
|
b87b3d79f2 | ||
|
|
fea87a94e6 | ||
|
|
6687ce2a6d | ||
|
|
703f0fbe74 | ||
|
|
9f48831298 | ||
|
|
9c7f662586 | ||
|
|
b3b4fc21da | ||
|
|
0b66c18221 | ||
|
|
9e362f0690 | ||
|
|
c45f97b9f4 | ||
|
|
b4813a1b55 | ||
|
|
8703e9d89e | ||
|
|
5f74cf9b7a | ||
|
|
b9ad90d447 | ||
|
|
8e94856239 | ||
|
|
ef8b5d5d06 | ||
|
|
9fd8f5ef04 | ||
|
|
ce8b1eb2c4 | ||
|
|
0c67777396 | ||
|
|
64fb6ab435 | ||
|
|
8b448c841e | ||
|
|
00b1d9f0a0 | ||
|
|
c908eef782 | ||
|
|
abd5909fb6 | ||
|
|
aff0058b82 | ||
|
|
f5731aa9a2 | ||
|
|
36f23279bf | ||
|
|
ec4c581adc | ||
|
|
cb50eb0370 | ||
|
|
b38fee24d7 | ||
|
|
9987967e82 | ||
|
|
92978dc59c | ||
|
|
11e6a1e6c8 | ||
|
|
b3902c7bf1 | ||
|
|
6681b56375 | ||
|
|
6a1a3fa1cb | ||
|
|
53e3bbdb09 | ||
|
|
410ea6f7cf | ||
|
|
bf7bb0880e | ||
|
|
0fe8358396 | ||
|
|
b36f6ea6f0 | ||
|
|
15658b259f | ||
|
|
c0b219cf46 | ||
|
|
d6359ebac5 | ||
|
|
578022ebe5 | ||
|
|
b4f13afc1a | ||
|
|
f7ebe64b47 | ||
|
|
c7f6700d19 | ||
|
|
a0cfbb1a38 | ||
|
|
fbcef4481f | ||
|
|
52410685bc | ||
|
|
bbbaf4afa0 | ||
|
|
02bdedbeb6 | ||
|
|
97356e9945 | ||
|
|
20ce98f87b | ||
|
|
49fa3e1869 | ||
|
|
a5c9b10083 | ||
|
|
5ab3b9c616 | ||
|
|
5805f9cb93 | ||
|
|
12f77a2fb9 | ||
|
|
b50c557e74 | ||
|
|
86271c364d | ||
|
|
12825ab972 | ||
|
|
3e2f4891c4 | ||
|
|
569631b1d5 | ||
|
|
5663827c7d | ||
|
|
9dfadd3694 | ||
|
|
cdb1d2c4c8 | ||
|
|
f07e4e27ce | ||
|
|
4642570e79 | ||
|
|
a8749a412f | ||
|
|
1d2fbfe99b | ||
|
|
4f3f26cd96 | ||
|
|
4688590733 | ||
|
|
44c2bd35e0 | ||
|
|
eb7d96a8ac | ||
|
|
84a25dc846 | ||
|
|
d891f233cb | ||
|
|
84c4049e3c | ||
|
|
9c20bb18de | ||
|
|
52049bc76e | ||
|
|
e308524097 | ||
|
|
5056aae63a | ||
|
|
602840bfd2 | ||
|
|
71b0edcfe3 | ||
|
|
1763cf115b | ||
|
|
6f3dd6527d | ||
|
|
cadfed692c | ||
|
|
c2cffe6249 | ||
|
|
6f54b90f36 | ||
|
|
db1950e768 | ||
|
|
aa7433982b | ||
|
|
f9d1f36169 | ||
|
|
79122c66b1 | ||
|
|
01ffee0033 | ||
|
|
9cb662df74 | ||
|
|
53ac3c8ba9 | ||
|
|
9178731176 | ||
|
|
2e9a36a8fe | ||
|
|
1a87f122f4 | ||
|
|
490e7c0984 | ||
|
|
27f29ff6ed | ||
|
|
ea19cb2f50 | ||
|
|
df18c9b2ed | ||
|
|
1a461baee1 | ||
|
|
709e228589 | ||
|
|
7d7508fb7a | ||
|
|
991b297011 | ||
|
|
c73f672afd | ||
|
|
e39c497cee | ||
|
|
d000f5943a | ||
|
|
624b54a392 | ||
|
|
d72fc01ffd | ||
|
|
b1f0f1c5a1 | ||
|
|
616109a040 | ||
|
|
3f56dd9927 | ||
|
|
54bb3f54e8 | ||
|
|
0ec28acef9 | ||
|
|
b5dc44c586 | ||
|
|
32ab3ef598 | ||
|
|
8705feb7cc | ||
|
|
aecd2b5d92 | ||
|
|
bdaa8c55d2 | ||
|
|
11919bc471 | ||
|
|
593e0eebeb | ||
|
|
8c2a792d2b | ||
|
|
b540c2419f | ||
|
|
96f0fd3ce0 | ||
|
|
dc6a936d97 | ||
|
|
ac3fc8876c | ||
|
|
375df6c086 | ||
|
|
88e6b7d6b2 | ||
|
|
181ffe30be | ||
|
|
afad1e536e | ||
|
|
fffb54d8f7 | ||
|
|
8b9d401fe4 | ||
|
|
f278a631b0 | ||
|
|
7e61e9650c | ||
|
|
7e7e9d9eab | ||
|
|
863c1b60d2 | ||
|
|
f636ced7d2 | ||
|
|
494953cfb6 |
@@ -8,7 +8,7 @@ BraceWrapping:
|
||||
AfterUnion: true
|
||||
SplitEmptyRecord: false
|
||||
PointerAlignment: Middle
|
||||
FixNamespaceComments: false
|
||||
FixNamespaceComments: true
|
||||
SortIncludes: Never
|
||||
#IndentPPDirectives: BeforeHash
|
||||
SpaceAfterCStyleCast: true
|
||||
@@ -32,3 +32,4 @@ IndentPPDirectives: AfterHash
|
||||
PPIndentWidth: 2
|
||||
BinPackArguments: false
|
||||
BreakBeforeTernaryOperators: true
|
||||
SeparateDefinitionBlocks: Always
|
||||
|
||||
6
.git-blame-ignore-revs
Normal file
6
.git-blame-ignore-revs
Normal file
@@ -0,0 +1,6 @@
|
||||
# bulk initial re-formatting with clang-format
|
||||
a5264aa46eadb89c055b4d1442e814edb2d4414e # !autorebase ./maintainers/format.sh --until-stable
|
||||
# clang-format 18 -> clang-format 19
|
||||
945d9d7264b0dc7d0a8c8edf1cab34f38cd49a7f # !autorebase ./maintainers/format.sh --until-stable
|
||||
# nixfmt 1.0.0
|
||||
448bbbe0fd1fbe09cb46a238fec25b220f172122 # !autorebase ./maintainers/format.sh --until-stable
|
||||
50
.github/actions/install-nix-action/action.yaml
vendored
Normal file
50
.github/actions/install-nix-action/action.yaml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
name: "Install Nix"
|
||||
description: "Helper action for installing Nix with support for dogfooding from master"
|
||||
inputs:
|
||||
dogfood:
|
||||
description: "Whether to use Nix installed from the latest artifact from master branch"
|
||||
required: true # Be explicit about the fact that we are using unreleased artifacts
|
||||
extra_nix_config:
|
||||
description: "Gets appended to `/etc/nix/nix.conf` if passed."
|
||||
install_url:
|
||||
description: "URL of the Nix installer"
|
||||
required: false
|
||||
default: "https://releases.nixos.org/nix/nix-2.29.1/install"
|
||||
github_token:
|
||||
description: "Github token"
|
||||
required: true
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: "Download nix install artifact from master"
|
||||
shell: bash
|
||||
id: download-nix-installer
|
||||
if: inputs.dogfood == 'true'
|
||||
run: |
|
||||
RUN_ID=$(gh run list --repo "$DOGFOOD_REPO" --workflow ci.yml --branch master --status success --json databaseId --jq ".[0].databaseId")
|
||||
|
||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||
INSTALLER_ARTIFACT="installer-linux"
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
INSTALLER_ARTIFACT="installer-darwin"
|
||||
else
|
||||
echo "::error ::Unsupported RUNNER_OS: $RUNNER_OS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
INSTALLER_DOWNLOAD_DIR="$GITHUB_WORKSPACE/$INSTALLER_ARTIFACT"
|
||||
mkdir -p "$INSTALLER_DOWNLOAD_DIR"
|
||||
|
||||
gh run download "$RUN_ID" --repo "$DOGFOOD_REPO" -n "$INSTALLER_ARTIFACT" -D "$INSTALLER_DOWNLOAD_DIR"
|
||||
echo "installer-path=file://$INSTALLER_DOWNLOAD_DIR" >> "$GITHUB_OUTPUT"
|
||||
|
||||
echo "::notice ::Dogfooding Nix installer from master (https://github.com/$DOGFOOD_REPO/actions/runs/$RUN_ID)"
|
||||
env:
|
||||
GH_TOKEN: ${{ inputs.github_token }}
|
||||
DOGFOOD_REPO: "NixOS/nix"
|
||||
- uses: cachix/install-nix-action@c134e4c9e34bac6cab09cf239815f9339aaaf84e # v31.5.1
|
||||
with:
|
||||
# Ternary operator in GHA: https://www.github.com/actions/runner/issues/409#issuecomment-752775072
|
||||
install_url: ${{ inputs.dogfood == 'true' && format('{0}/install', steps.download-nix-installer.outputs.installer-path) || inputs.install_url }}
|
||||
install_options: ${{ inputs.dogfood == 'true' && format('--tarball-url-prefix {0}', steps.download-nix-installer.outputs.installer-path) || '' }}
|
||||
extra_nix_config: ${{ inputs.extra_nix_config }}
|
||||
27
.github/workflows/ci.yml
vendored
27
.github/workflows/ci.yml
vendored
@@ -13,8 +13,13 @@ jobs:
|
||||
- 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
|
||||
- uses: ./.github/actions/install-nix-action
|
||||
with:
|
||||
dogfood: false
|
||||
extra_nix_config:
|
||||
experimental-features = nix-command flakes
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: nix flake show --all-systems --json
|
||||
|
||||
tests:
|
||||
strategy:
|
||||
@@ -34,8 +39,10 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: cachix/install-nix-action@v30
|
||||
- uses: ./.github/actions/install-nix-action
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
dogfood: false
|
||||
# The sandbox would otherwise be disabled by default on Darwin
|
||||
extra_nix_config: |
|
||||
sandbox = true
|
||||
@@ -175,7 +182,12 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
- uses: ./.github/actions/install-nix-action
|
||||
with:
|
||||
dogfood: false
|
||||
extra_nix_config:
|
||||
experimental-features = nix-command flakes
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||
- run: |
|
||||
nix build -L \
|
||||
@@ -201,6 +213,11 @@ jobs:
|
||||
with:
|
||||
repository: NixOS/flake-regressions-data
|
||||
path: flake-regressions/tests
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
- uses: ./.github/actions/install-nix-action
|
||||
with:
|
||||
dogfood: false
|
||||
extra_nix_config:
|
||||
experimental-features = nix-command flakes
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||
- run: nix build -L --out-link ./new-nix && PATH=$(pwd)/new-nix/bin:$PATH MAX_FLAKES=25 flake-regressions/eval-all.sh
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -14,7 +14,7 @@
|
||||
/tests/functional/lang/*.err
|
||||
/tests/functional/lang/*.ast
|
||||
|
||||
outputs/
|
||||
/outputs
|
||||
|
||||
*~
|
||||
|
||||
@@ -47,3 +47,6 @@ result-*
|
||||
.DS_Store
|
||||
|
||||
flake-regressions
|
||||
|
||||
# direnv
|
||||
.direnv/
|
||||
|
||||
11
.mergify.yml
11
.mergify.yml
@@ -117,3 +117,14 @@ pull_request_rules:
|
||||
labels:
|
||||
- automatic backport
|
||||
- merge-queue
|
||||
|
||||
- name: backport patches to 2.27
|
||||
conditions:
|
||||
- label=backport 2.27-maintenance
|
||||
actions:
|
||||
backport:
|
||||
branches:
|
||||
- "2.27-maintenance"
|
||||
labels:
|
||||
- automatic backport
|
||||
- merge-queue
|
||||
|
||||
@@ -14,7 +14,7 @@ import sys
|
||||
# literally. since the rules for these aren't even the same for
|
||||
# all three we will just fail when we encounter any of them (if
|
||||
# asserts are off for some reason the depfile will likely point
|
||||
# to nonexistant paths, making everything phony and thus fine.)
|
||||
# to nonexistent paths, making everything phony and thus fine.)
|
||||
for path in glob.glob(sys.argv[1] + '/**', recursive=True):
|
||||
assert '\\' not in path
|
||||
assert ' ' not in path
|
||||
|
||||
@@ -67,7 +67,7 @@ subdir('source/release-notes')
|
||||
subdir('source')
|
||||
|
||||
# Hacky way to figure out if `nix` is an `ExternalProgram` or
|
||||
# `Exectuable`. Only the latter can occur in custom target input lists.
|
||||
# `Executable`. Only the latter can occur in custom target input lists.
|
||||
if nix.full_path().startswith(meson.build_root())
|
||||
nix_input = nix
|
||||
else
|
||||
|
||||
17
doc/manual/rl-next/outpath-and-sourceinfo-fixes.md
Normal file
17
doc/manual/rl-next/outpath-and-sourceinfo-fixes.md
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
synopsis: Non-flake inputs now contain a `sourceInfo` attribute
|
||||
issues: 13164
|
||||
prs: 13170
|
||||
---
|
||||
|
||||
Flakes have always a `sourceInfo` attribute which describes the source of the flake.
|
||||
The `sourceInfo.outPath` is often identical to the flake's `outPath`, however it can differ when the flake is located in a subdirectory of its source.
|
||||
|
||||
Non-flake inputs (i.e. inputs with `flake = false`) can also be located at some path _within_ a wider source.
|
||||
This usually happens when defining a relative path input within the same source as the parent flake, e.g. `inputs.foo.url = ./some-file.nix`.
|
||||
Such relative inputs will now inherit their parent's `sourceInfo`.
|
||||
|
||||
This also means it is now possible to use `?dir=subdir` on non-flake inputs.
|
||||
|
||||
This iterates on the work done in 2.26 to improve relative path support ([#10089](https://github.com/NixOS/nix/pull/10089)),
|
||||
and resolves a regression introduced in 2.28 relating to nested relative path inputs ([#13164](https://github.com/NixOS/nix/issues/13164)).
|
||||
@@ -22,7 +22,10 @@
|
||||
- [Store Object](store/store-object.md)
|
||||
- [Content-Addressing Store Objects](store/store-object/content-address.md)
|
||||
- [Store Path](store/store-path.md)
|
||||
- [Store Derivation and Deriving Path](store/drv.md)
|
||||
- [Store Derivation and Deriving Path](store/derivation/index.md)
|
||||
- [Derivation Outputs and Types of Derivations](store/derivation/outputs/index.md)
|
||||
- [Content-addressing derivation outputs](store/derivation/outputs/content-address.md)
|
||||
- [Input-addressing derivation outputs](store/derivation/outputs/input-address.md)
|
||||
- [Building](store/building.md)
|
||||
- [Store Types](store/types/index.md)
|
||||
{{#include ./store/types/SUMMARY.md}}
|
||||
@@ -132,6 +135,7 @@
|
||||
- [Contributing](development/contributing.md)
|
||||
- [Releases](release-notes/index.md)
|
||||
{{#include ./SUMMARY-rl-next.md}}
|
||||
- [Release 2.28 (2025-04-02)](release-notes/rl-2.28.md)
|
||||
- [Release 2.27 (2025-03-03)](release-notes/rl-2.27.md)
|
||||
- [Release 2.26 (2025-01-22)](release-notes/rl-2.26.md)
|
||||
- [Release 2.25 (2024-11-07)](release-notes/rl-2.25.md)
|
||||
|
||||
@@ -20,14 +20,14 @@ For a local machine to forward a build to a remote machine, the remote machine m
|
||||
|
||||
## Testing
|
||||
|
||||
To test connecting to a remote Nix instance (in this case `mac`), run:
|
||||
To test connecting to a remote [Nix instance] (in this case `mac`), run:
|
||||
|
||||
```console
|
||||
nix store info --store ssh://username@mac
|
||||
```
|
||||
|
||||
To specify an SSH identity file as part of the remote store URI add a
|
||||
query paramater, e.g.
|
||||
query parameter, e.g.
|
||||
|
||||
```console
|
||||
nix store info --store ssh://username@mac?ssh-key=/home/alice/my-key
|
||||
@@ -106,3 +106,5 @@ file included in `builders` via the syntax `@/path/to/file`. For example,
|
||||
|
||||
causes the list of machines in `/etc/nix/machines` to be included.
|
||||
(This is the default.)
|
||||
|
||||
[Nix instance]: @docroot@/glossary.md#gloss-nix-instance
|
||||
@@ -22,9 +22,9 @@ The following [concept map] shows its main components (rectangles), the objects
|
||||
| |
|
||||
+----------|-------------------|--------------------------------+
|
||||
| Nix | V |
|
||||
| | +-------------------------+ |
|
||||
| | | commmand line interface |------. |
|
||||
| | +-------------------------+ | |
|
||||
| | +------------------------+ |
|
||||
| | | command line interface |------. |
|
||||
| | +------------------------+ | |
|
||||
| | | | |
|
||||
| evaluated by calls manages |
|
||||
| | | | |
|
||||
|
||||
@@ -53,6 +53,11 @@ This command has the following operations:
|
||||
Download the Nix expressions of subscribed channels and create a new generation.
|
||||
Update all channels if none is specified, and only those included in *names* otherwise.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Downloaded channel contents are cached.
|
||||
> Use `--tarball-ttl` or the [`tarball-ttl` configuration option](@docroot@/command-ref/conf-file.md#conf-tarball-ttl) to change the validity period of cached downloads.
|
||||
|
||||
- `--list-generations`
|
||||
|
||||
Prints a list of all the current existing generations for the
|
||||
|
||||
@@ -27,7 +27,7 @@ This operation deletes the specified generations of the current profile.
|
||||
>
|
||||
> Older *and newer* generations will be deleted by this operation.
|
||||
>
|
||||
> One might expect this to just delete older generations than the curent one, but that is only true if the current generation is also the latest.
|
||||
> One might expect this to just delete older generations than the current one, but that is only true if the current generation is also the latest.
|
||||
> Because one can roll back to a previous generation, it is possible to have generations newer than the current one.
|
||||
> They will also be deleted.
|
||||
|
||||
|
||||
@@ -45,10 +45,19 @@ symlink.
|
||||
|
||||
[output paths]: @docroot@/glossary.md#gloss-output-path
|
||||
|
||||
- `--references`
|
||||
|
||||
Prints the set of [references] of the store paths
|
||||
*paths*, that is, their immediate dependencies. (For *all*
|
||||
dependencies, use `--requisites`.)
|
||||
|
||||
[references]: @docroot@/glossary.md#gloss-reference
|
||||
|
||||
- `--requisites` / `-R`
|
||||
|
||||
Prints out the [closure] of the store path *paths*.
|
||||
Prints out the set of [*requisites*][requisite] (better known as the [closure]) of the store path *paths*.
|
||||
|
||||
[requisite]: @docroot@/glossary.md#gloss-requisite
|
||||
[closure]: @docroot@/glossary.md#gloss-closure
|
||||
|
||||
This query has one option:
|
||||
@@ -65,29 +74,25 @@ symlink.
|
||||
dependencies) is obtained by distributing the closure of a store
|
||||
derivation and specifying the option `--include-outputs`.
|
||||
|
||||
- `--references`
|
||||
|
||||
Prints the set of [references] of the store paths
|
||||
*paths*, that is, their immediate dependencies. (For *all*
|
||||
dependencies, use `--requisites`.)
|
||||
|
||||
[references]: @docroot@/glossary.md#gloss-reference
|
||||
|
||||
- `--referrers`
|
||||
|
||||
Prints the set of *referrers* of the store paths *paths*, that is,
|
||||
Prints the set of [*referrers*][referrer] of the store paths *paths*, that is,
|
||||
the store paths currently existing in the Nix store that refer to
|
||||
one of *paths*. Note that contrary to the references, the set of
|
||||
referrers is not constant; it can change as store paths are added or
|
||||
removed.
|
||||
|
||||
[referrer]: @docroot@/glossary.md#gloss-referrer
|
||||
|
||||
- `--referrers-closure`
|
||||
|
||||
Prints the closure of the set of store paths *paths* under the
|
||||
referrers relation; that is, all store paths that directly or
|
||||
[referrers relation][referrer]; that is, all store paths that directly or
|
||||
indirectly refer to one of *paths*. These are all the path currently
|
||||
in the Nix store that are dependent on *paths*.
|
||||
|
||||
[referrer]: @docroot@/glossary.md#gloss-referrer
|
||||
|
||||
- `--deriver` / `-d`
|
||||
|
||||
Prints the [deriver] that was used to build the store paths *paths*. If
|
||||
|
||||
@@ -195,28 +195,38 @@ Nix uses a string with the following format to identify the *system type* or *pl
|
||||
<cpu>-<os>[-<abi>]
|
||||
```
|
||||
|
||||
It is set when Nix is compiled for the given system, and based on the output of [`config.guess`](https://github.com/nixos/nix/blob/master/config/config.guess) ([upstream](https://git.savannah.gnu.org/cgit/config.git/tree/config.guess)):
|
||||
It is set when Nix is compiled for the given system, and based on the output of Meson's [`host_machine` information](https://mesonbuild.com/Reference-manual_builtin_host_machine.html)>
|
||||
|
||||
```
|
||||
<cpu>-<vendor>-<os>[<version>][-<abi>]
|
||||
```
|
||||
|
||||
When Nix is built such that `./configure` is passed any of the `--host`, `--build`, `--target` options, the value is based on the output of [`config.sub`](https://github.com/nixos/nix/blob/master/config/config.sub) ([upstream](https://git.savannah.gnu.org/cgit/config.git/tree/config.sub)):
|
||||
When cross-compiling Nix with Meson for local development, you need to specify a [cross-file](https://mesonbuild.com/Cross-compilation.html) using the `--cross-file` option. Cross-files define the target architecture and toolchain. When cross-compiling Nix with Nix, Nixpkgs takes care of this for you.
|
||||
|
||||
In the nix flake we also have some cross-compilation targets available:
|
||||
|
||||
```
|
||||
<cpu>-<vendor>[-<kernel>]-<os>
|
||||
nix build .#nix-everything-riscv64-unknown-linux-gnu
|
||||
nix build .#nix-everything-armv7l-unknown-linux-gnueabihf
|
||||
nix build .#nix-everything-armv7l-unknown-linux-gnueabihf
|
||||
nix build .#nix-everything-x86_64-unknown-freebsd
|
||||
nix build .#nix-everything-x86_64-w64-mingw32
|
||||
```
|
||||
|
||||
For historic reasons and backward-compatibility, some CPU and OS identifiers are translated from the GNU Autotools naming convention in [`configure.ac`](https://github.com/nixos/nix/blob/master/configure.ac) as follows:
|
||||
For historic reasons and backward-compatibility, some CPU and OS identifiers are translated as follows:
|
||||
|
||||
| `config.guess` | Nix |
|
||||
|----------------------------|---------------------|
|
||||
| `amd64` | `x86_64` |
|
||||
| `i*86` | `i686` |
|
||||
| `arm6` | `arm6l` |
|
||||
| `arm7` | `arm7l` |
|
||||
| `linux-gnu*` | `linux` |
|
||||
| `linux-musl*` | `linux` |
|
||||
| `host_machine.cpu_family()` | `host_machine.endian()` | Nix |
|
||||
|-----------------------------|-------------------------|---------------------|
|
||||
| `x86` | | `i686` |
|
||||
| `arm` | | `host_machine.cpu()`|
|
||||
| `ppc` | `little` | `powerpcle` |
|
||||
| `ppc64` | `little` | `powerpc64le` |
|
||||
| `ppc` | `big` | `powerpc` |
|
||||
| `ppc64` | `big` | `powerpc64` |
|
||||
| `mips` | `little` | `mipsel` |
|
||||
| `mips64` | `little` | `mips64el` |
|
||||
| `mips` | `big` | `mips` |
|
||||
| `mips64` | `big` | `mips64` |
|
||||
|
||||
## Compilation environments
|
||||
|
||||
@@ -230,18 +240,18 @@ Nix can be compiled using multiple environments:
|
||||
To build with one of those environments, you can use
|
||||
|
||||
```console
|
||||
$ nix build .#nix-ccacheStdenv
|
||||
$ nix build .#nix-cli-ccacheStdenv
|
||||
```
|
||||
|
||||
for flake-enabled Nix, or
|
||||
|
||||
```console
|
||||
$ nix-build --attr nix-ccacheStdenv
|
||||
$ nix-build --attr nix-cli-ccacheStdenv
|
||||
```
|
||||
|
||||
for classic Nix.
|
||||
|
||||
You can use any of the other supported environments in place of `nix-ccacheStdenv`.
|
||||
You can use any of the other supported environments in place of `nix-cli-ccacheStdenv`.
|
||||
|
||||
## Editor integration
|
||||
|
||||
|
||||
@@ -170,9 +170,9 @@ sensitive.
|
||||
|
||||
|
||||
```shell
|
||||
$ nix init --template=template#pyton
|
||||
$ nix init --template=template#python
|
||||
------------------------------------------------------------------------
|
||||
Error! Template `template#pyton` not found.
|
||||
Error! Template `template#python` not found.
|
||||
------------------------------------------------------------------------
|
||||
Initializing Nix project at `/path/to/here`.
|
||||
Select a template for you new project:
|
||||
|
||||
@@ -20,8 +20,9 @@ prs: 1238
|
||||
Here's one or more paragraphs that describe the change.
|
||||
|
||||
- It's markdown
|
||||
- Add references to the manual using @docroot@
|
||||
- Add references to the manual using [links like this](@_at_docroot@/example.md)
|
||||
```
|
||||
<!-- for the raw markdown readers: that means using @docroot@ -->
|
||||
|
||||
Significant changes should add the following header, which moves them to the top.
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ The unit tests are defined using the [googletest] and [rapidcheck] frameworks.
|
||||
> src
|
||||
> ├── libexpr
|
||||
> │ ├── meson.build
|
||||
> │ ├── value/context.hh
|
||||
> │ ├── include/nix/expr/value/context.hh
|
||||
> │ ├── value/context.cc
|
||||
> │ …
|
||||
> │
|
||||
@@ -46,8 +46,12 @@ The unit tests are defined using the [googletest] and [rapidcheck] frameworks.
|
||||
> │ │
|
||||
> │ ├── libexpr-test-support
|
||||
> │ │ ├── meson.build
|
||||
> │ │ ├── include/nix/expr
|
||||
> │ │ │ ├── meson.build
|
||||
> │ │ │ └── tests
|
||||
> │ │ │ ├── value/context.hh
|
||||
> │ │ │ …
|
||||
> │ │ └── tests
|
||||
> │ │ ├── value/context.hh
|
||||
> │ │ ├── value/context.cc
|
||||
> │ │ …
|
||||
> │ │
|
||||
@@ -59,7 +63,7 @@ The unit tests are defined using the [googletest] and [rapidcheck] frameworks.
|
||||
> ```
|
||||
|
||||
The tests for each Nix library (`libnixexpr`, `libnixstore`, etc..) live inside a directory `src/${library_name_without-nix}-test`.
|
||||
Given an interface (header) and implementation pair in the original library, say, `src/libexpr/value/context.{hh,cc}`, we write tests for it in `src/libexpr-tests/value/context.cc`, and (possibly) declare/define additional interfaces for testing purposes in `src/libexpr-test-support/tests/value/context.{hh,cc}`.
|
||||
Given an interface (header) and implementation pair in the original library, say, `src/libexpr/include/nix/expr/value/context.hh` and `src/libexpr/value/context.cc`, we write tests for it in `src/libexpr-tests/value/context.cc`, and (possibly) declare/define additional interfaces for testing purposes in `src/libexpr-test-support/include/nix/expr/tests/value/context.hh` and `src/libexpr-test-support/tests/value/context.cc`.
|
||||
|
||||
Data for unit tests is stored in a `data` subdir of the directory for each unit test executable.
|
||||
For example, `libnixstore` code is in `src/libstore`, and its test data is in `src/libstore-tests/data`.
|
||||
@@ -67,7 +71,7 @@ The path to the `src/${library_name_without-nix}-test/data` directory is passed
|
||||
Note that each executable only gets the data for its tests.
|
||||
|
||||
The unit test libraries are in `src/${library_name_without-nix}-test-support`.
|
||||
All headers are in a `tests` subdirectory so they are included with `#include "tests/"`.
|
||||
All headers are in a `tests` subdirectory so they are included with `#include "nix/tests/"`.
|
||||
|
||||
The use of all these separate directories for the unit tests might seem inconvenient, as for example the tests are not "right next to" the part of the code they are testing.
|
||||
But organizing the tests this way has one big benefit:
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# Glossary
|
||||
|
||||
- [build system]{#gloss-build-system}
|
||||
|
||||
Generic term for software that facilitates the building of software by automating the invocation of compilers, linkers, and other tools.
|
||||
|
||||
Nix can be used as a generic build system.
|
||||
It has no knowledge of any particular programming language or toolchain.
|
||||
These details are specified in [derivation expressions](#gloss-derivation-expression).
|
||||
|
||||
- [content address]{#gloss-content-address}
|
||||
|
||||
A
|
||||
@@ -19,18 +27,29 @@
|
||||
|
||||
Besides content addressing, the Nix store also uses [input addressing](#gloss-input-addressed-store-object).
|
||||
|
||||
- [content-addressed storage]{#gloss-content-addressed-store}
|
||||
|
||||
The industry term for storage and retrieval systems using [content addressing](#gloss-content-address). A Nix store also has [input addressing](#gloss-input-addressed-store-object), and metadata.
|
||||
|
||||
- [store derivation]{#gloss-store-derivation}
|
||||
|
||||
A single build task.
|
||||
See [Store Derivation](@docroot@/store/drv.md#store-derivation) for details.
|
||||
See [Store Derivation](@docroot@/store/derivation/index.md#store-derivation) for details.
|
||||
|
||||
[store derivation]: #gloss-store-derivation
|
||||
|
||||
- [directed acyclic graph]{#gloss-directed-acyclic-graph}
|
||||
|
||||
A [directed acyclic graph](https://en.wikipedia.org/wiki/Directed_acyclic_graph) (DAG) is graph whose edges are given a direction ("a to b" is not the same edge as "b to a"), and for which no possible path (created by joining together edges) forms a cycle.
|
||||
|
||||
DAGs are very important to Nix.
|
||||
In particular, the non-self-[references][reference] of [store object][store object] form a cycle.
|
||||
|
||||
- [derivation path]{#gloss-derivation-path}
|
||||
|
||||
A [store path] which uniquely identifies a [store derivation].
|
||||
|
||||
See [Referencing Store Derivations](@docroot@/store/drv.md#derivation-path) for details.
|
||||
See [Referencing Store Derivations](@docroot@/store/derivation/index.md#derivation-path) for details.
|
||||
|
||||
Not to be confused with [deriving path].
|
||||
|
||||
@@ -88,6 +107,12 @@
|
||||
|
||||
[store]: #gloss-store
|
||||
|
||||
- [Nix instance]{#gloss-nix-instance}
|
||||
<!-- ambiguous -->
|
||||
1. An installation of Nix, which includes the presence of a [store], and the Nix package manager which operates on that store.
|
||||
A local Nix installation and a [remote builder](@docroot@/advanced-topics/distributed-builds.md) are two examples of Nix instances.
|
||||
2. A running Nix process, such as the `nix` command.
|
||||
|
||||
- [binary cache]{#gloss-binary-cache}
|
||||
|
||||
A *binary cache* is a Nix store which uses a different format: its
|
||||
@@ -138,6 +163,8 @@
|
||||
non-[fixed-output](#gloss-fixed-output-derivation)
|
||||
derivation.
|
||||
|
||||
See [input-addressing derivation outputs](store/derivation/outputs/input-address.md) for details.
|
||||
|
||||
- [content-addressed store object]{#gloss-content-addressed-store-object}
|
||||
|
||||
A [store object] which is [content-addressed](#gloss-content-address),
|
||||
@@ -201,26 +228,28 @@
|
||||
|
||||
- [reference]{#gloss-reference}
|
||||
|
||||
A [store object] `O` is said to have a *reference* to a store object `P` if a [store path] to `P` appears in the contents of `O`.
|
||||
An edge from one [store object] to another.
|
||||
|
||||
Store objects can refer to both other store objects and themselves.
|
||||
References from a store object to itself are called *self-references*.
|
||||
References other than a self-reference must not form a cycle.
|
||||
See [References](@docroot@/store/store-object.md#references) for details.
|
||||
|
||||
[reference]: #gloss-reference
|
||||
|
||||
See [References](@docroot@/store/store-object.md#references) for details.
|
||||
|
||||
- [reachable]{#gloss-reachable}
|
||||
|
||||
A store path `Q` is reachable from another store path `P` if `Q`
|
||||
is in the *closure* of the *references* relation.
|
||||
|
||||
See [References](@docroot@/store/store-object.md#references) for details.
|
||||
|
||||
- [closure]{#gloss-closure}
|
||||
|
||||
The closure of a store path is the set of store paths that are
|
||||
directly or indirectly “reachable” from that store path; that is,
|
||||
it’s the closure of the path under the *references* relation. For
|
||||
a package, the closure of its derivation is equivalent to the
|
||||
build-time dependencies, while the closure of its output path is
|
||||
build-time dependencies, while the closure of its [output path] is
|
||||
equivalent to its runtime dependencies. For correct deployment it
|
||||
is necessary to deploy whole closures, since otherwise at runtime
|
||||
files could be missing. The command `nix-store --query --requisites ` prints out
|
||||
@@ -230,8 +259,21 @@
|
||||
to a store object at path `Q`, then `Q` is in the closure of `P`. Further, if `Q`
|
||||
references `R` then `R` is also in the closure of `P`.
|
||||
|
||||
See [References](@docroot@/store/store-object.md#references) for details.
|
||||
|
||||
[closure]: #gloss-closure
|
||||
|
||||
- [requisite]{#gloss-requisite}
|
||||
|
||||
A store object [reachable] by a path (chain of references) from a given [store object].
|
||||
The [closure] is the set of requisites.
|
||||
|
||||
See [References](@docroot@/store/store-object.md#references) for details.
|
||||
|
||||
- [referrer]{#gloss-reference}
|
||||
|
||||
A reversed edge from one [store object] to another.
|
||||
|
||||
- [output]{#gloss-output}
|
||||
|
||||
A [store object] produced by a [store derivation].
|
||||
@@ -252,7 +294,7 @@
|
||||
|
||||
Deriving paths are a way to refer to [store objects][store object] that might not yet be [realised][realise].
|
||||
|
||||
See [Deriving Path](./store/drv.md#deriving-path) for details.
|
||||
See [Deriving Path](./store/derivation/index.md#deriving-path) for details.
|
||||
|
||||
Not to be confused with [derivation path].
|
||||
|
||||
@@ -302,7 +344,7 @@
|
||||
|
||||
See [Nix Archive](store/file-system-object/content-address.html#serial-nix-archive) for details.
|
||||
|
||||
- [`∅`]{#gloss-emtpy-set}
|
||||
- [`∅`]{#gloss-empty-set}
|
||||
|
||||
The empty set symbol. In the context of profile history, this denotes a package is not present in a particular version of the profile.
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ This performs the default type of installation for your platform:
|
||||
|
||||
We recommend the multi-user installation if it supports your platform and you can authenticate with `sudo`.
|
||||
|
||||
The installer can configured with various command line arguments and environment variables.
|
||||
The installer can be configured with various command line arguments and environment variables.
|
||||
To show available command line flags:
|
||||
|
||||
```console
|
||||
|
||||
@@ -2,6 +2,85 @@
|
||||
|
||||
Derivations can declare some infrequently used optional attributes.
|
||||
|
||||
## Inputs
|
||||
|
||||
- [`exportReferencesGraph`]{#adv-attr-exportReferencesGraph}\
|
||||
This attribute allows builders access to the references graph of
|
||||
their inputs. The attribute is a list of inputs in the Nix store
|
||||
whose references graph the builder needs to know. The value of
|
||||
this attribute should be a list of pairs `[ name1 path1 name2
|
||||
path2 ... ]`. The references graph of each *pathN* will be stored
|
||||
in a text file *nameN* in the temporary build directory. The text
|
||||
files have the format used by `nix-store --register-validity`
|
||||
(with the deriver fields left empty). For example, when the
|
||||
following derivation is built:
|
||||
|
||||
```nix
|
||||
derivation {
|
||||
...
|
||||
exportReferencesGraph = [ "libfoo-graph" libfoo ];
|
||||
};
|
||||
```
|
||||
|
||||
the references graph of `libfoo` is placed in the file
|
||||
`libfoo-graph` in the temporary build directory.
|
||||
|
||||
`exportReferencesGraph` is useful for builders that want to do
|
||||
something with the closure of a store path. Examples include the
|
||||
builders in NixOS that generate the initial ramdisk for booting
|
||||
Linux (a `cpio` archive containing the closure of the boot script)
|
||||
and the ISO-9660 image for the installation CD (which is populated
|
||||
with a Nix store containing the closure of a bootable NixOS
|
||||
configuration).
|
||||
|
||||
- [`passAsFile`]{#adv-attr-passAsFile}\
|
||||
A list of names of attributes that should be passed via files rather
|
||||
than environment variables. For example, if you have
|
||||
|
||||
```nix
|
||||
passAsFile = ["big"];
|
||||
big = "a very long string";
|
||||
```
|
||||
|
||||
then when the builder runs, the environment variable `bigPath`
|
||||
will contain the absolute path to a temporary file containing `a
|
||||
very long string`. That is, for any attribute *x* listed in
|
||||
`passAsFile`, Nix will pass an environment variable `xPath`
|
||||
holding the path of the file containing the value of attribute
|
||||
*x*. This is useful when you need to pass large strings to a
|
||||
builder, since most operating systems impose a limit on the size
|
||||
of the environment (typically, a few hundred kilobyte).
|
||||
|
||||
- [`__structuredAttrs`]{#adv-attr-structuredAttrs}\
|
||||
If the special attribute `__structuredAttrs` is set to `true`, the other derivation
|
||||
attributes are serialised into a file in JSON format. The environment variable
|
||||
`NIX_ATTRS_JSON_FILE` points to the exact location of that file both in a build
|
||||
and a [`nix-shell`](../command-ref/nix-shell.md). This obviates the need for
|
||||
[`passAsFile`](#adv-attr-passAsFile) since JSON files have no size restrictions,
|
||||
unlike process environments.
|
||||
|
||||
It also makes it possible to tweak derivation settings in a structured way; see
|
||||
[`outputChecks`](#adv-attr-outputChecks) for example.
|
||||
|
||||
As a convenience to Bash builders,
|
||||
Nix writes a script that initialises shell variables
|
||||
corresponding to all attributes that are representable in Bash. The
|
||||
environment variable `NIX_ATTRS_SH_FILE` points to the exact
|
||||
location of the script, both in a build and a
|
||||
[`nix-shell`](../command-ref/nix-shell.md). This includes non-nested
|
||||
(associative) arrays. For example, the attribute `hardening.format = true`
|
||||
ends up as the Bash associative array element `${hardening[format]}`.
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> If set to `true`, other advanced attributes such as [`allowedReferences`](#adv-attr-allowedReferences), [`allowedRequisites`](#adv-attr-allowedRequisites),
|
||||
[`disallowedReferences`](#adv-attr-disallowedReferences) and [`disallowedRequisites`](#adv-attr-disallowedRequisites), maxSize, and maxClosureSize.
|
||||
will have no effect.
|
||||
|
||||
## Output checks
|
||||
|
||||
See the [corresponding section in the derivation output page](@docroot@/store/derivation/outputs/index.md).
|
||||
|
||||
- [`allowedReferences`]{#adv-attr-allowedReferences}\
|
||||
The optional attribute `allowedReferences` specifies a list of legal
|
||||
references (dependencies) of the output of the builder. For example,
|
||||
@@ -55,259 +134,6 @@ Derivations can declare some infrequently used optional attributes.
|
||||
dependency on `foobar` or any other derivation depending recursively
|
||||
on `foobar`.
|
||||
|
||||
- [`exportReferencesGraph`]{#adv-attr-exportReferencesGraph}\
|
||||
This attribute allows builders access to the references graph of
|
||||
their inputs. The attribute is a list of inputs in the Nix store
|
||||
whose references graph the builder needs to know. The value of
|
||||
this attribute should be a list of pairs `[ name1 path1 name2
|
||||
path2 ... ]`. The references graph of each *pathN* will be stored
|
||||
in a text file *nameN* in the temporary build directory. The text
|
||||
files have the format used by `nix-store --register-validity`
|
||||
(with the deriver fields left empty). For example, when the
|
||||
following derivation is built:
|
||||
|
||||
```nix
|
||||
derivation {
|
||||
...
|
||||
exportReferencesGraph = [ "libfoo-graph" libfoo ];
|
||||
};
|
||||
```
|
||||
|
||||
the references graph of `libfoo` is placed in the file
|
||||
`libfoo-graph` in the temporary build directory.
|
||||
|
||||
`exportReferencesGraph` is useful for builders that want to do
|
||||
something with the closure of a store path. Examples include the
|
||||
builders in NixOS that generate the initial ramdisk for booting
|
||||
Linux (a `cpio` archive containing the closure of the boot script)
|
||||
and the ISO-9660 image for the installation CD (which is populated
|
||||
with a Nix store containing the closure of a bootable NixOS
|
||||
configuration).
|
||||
|
||||
- [`impureEnvVars`]{#adv-attr-impureEnvVars}\
|
||||
This attribute allows you to specify a list of environment variables
|
||||
that should be passed from the environment of the calling user to
|
||||
the builder. Usually, the environment is cleared completely when the
|
||||
builder is executed, but with this attribute you can allow specific
|
||||
environment variables to be passed unmodified. For example,
|
||||
`fetchurl` in Nixpkgs has the line
|
||||
|
||||
```nix
|
||||
impureEnvVars = [ "http_proxy" "https_proxy" ... ];
|
||||
```
|
||||
|
||||
to make it use the proxy server configuration specified by the user
|
||||
in the environment variables `http_proxy` and friends.
|
||||
|
||||
This attribute is only allowed in *fixed-output derivations* (see
|
||||
below), where impurities such as these are okay since (the hash
|
||||
of) the output is known in advance. It is ignored for all other
|
||||
derivations.
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> `impureEnvVars` implementation takes environment variables from
|
||||
> the current builder process. When a daemon is building its
|
||||
> environmental variables are used. Without the daemon, the
|
||||
> environmental variables come from the environment of the
|
||||
> `nix-build`.
|
||||
|
||||
If the [`configurable-impure-env` experimental
|
||||
feature](@docroot@/development/experimental-features.md#xp-feature-configurable-impure-env)
|
||||
is enabled, these environment variables can also be controlled
|
||||
through the
|
||||
[`impure-env`](@docroot@/command-ref/conf-file.md#conf-impure-env)
|
||||
configuration setting.
|
||||
|
||||
- [`outputHash`]{#adv-attr-outputHash}; [`outputHashAlgo`]{#adv-attr-outputHashAlgo}; [`outputHashMode`]{#adv-attr-outputHashMode}\
|
||||
These attributes declare that the derivation is a so-called *fixed-output derivation* (FOD), which means that a cryptographic hash of the output is already known in advance.
|
||||
|
||||
As opposed to regular derivations, the [`builder`] executable of a fixed-output derivation has access to the network.
|
||||
Nix computes a cryptographic hash of its output and compares that to the hash declared with these attributes.
|
||||
If there is a mismatch, the derivation fails.
|
||||
|
||||
The rationale for fixed-output derivations is derivations such as
|
||||
those produced by the `fetchurl` function. This function downloads a
|
||||
file from a given URL. To ensure that the downloaded file has not
|
||||
been modified, the caller must also specify a cryptographic hash of
|
||||
the file. For example,
|
||||
|
||||
```nix
|
||||
fetchurl {
|
||||
url = "http://ftp.gnu.org/pub/gnu/hello/hello-2.1.1.tar.gz";
|
||||
sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
|
||||
}
|
||||
```
|
||||
|
||||
It sometimes happens that the URL of the file changes, e.g., because
|
||||
servers are reorganised or no longer available. We then must update
|
||||
the call to `fetchurl`, e.g.,
|
||||
|
||||
```nix
|
||||
fetchurl {
|
||||
url = "ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz";
|
||||
sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
|
||||
}
|
||||
```
|
||||
|
||||
If a `fetchurl` derivation was treated like a normal derivation, the
|
||||
output paths of the derivation and *all derivations depending on it*
|
||||
would change. For instance, if we were to change the URL of the
|
||||
Glibc source distribution in Nixpkgs (a package on which almost all
|
||||
other packages depend) massive rebuilds would be needed. This is
|
||||
unfortunate for a change which we know cannot have a real effect as
|
||||
it propagates upwards through the dependency graph.
|
||||
|
||||
For fixed-output derivations, on the other hand, the name of the
|
||||
output path only depends on the `outputHash*` and `name` attributes,
|
||||
while all other attributes are ignored for the purpose of computing
|
||||
the output path. (The `name` attribute is included because it is
|
||||
part of the path.)
|
||||
|
||||
As an example, here is the (simplified) Nix expression for
|
||||
`fetchurl`:
|
||||
|
||||
```nix
|
||||
{ stdenv, curl }: # The curl program is used for downloading.
|
||||
|
||||
{ url, sha256 }:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = baseNameOf (toString url);
|
||||
builder = ./builder.sh;
|
||||
buildInputs = [ curl ];
|
||||
|
||||
# This is a fixed-output derivation; the output must be a regular
|
||||
# file with SHA256 hash sha256.
|
||||
outputHashMode = "flat";
|
||||
outputHashAlgo = "sha256";
|
||||
outputHash = sha256;
|
||||
|
||||
inherit url;
|
||||
}
|
||||
```
|
||||
|
||||
The `outputHash` attribute must be a string containing the hash in either hexadecimal or "nix32" encoding, or following the format for integrity metadata as defined by [SRI](https://www.w3.org/TR/SRI/).
|
||||
The "nix32" encoding is an adaptation of base-32 encoding.
|
||||
The [`convertHash`](@docroot@/language/builtins.md#builtins-convertHash) function shows how to convert between different encodings, and the [`nix-hash` command](../command-ref/nix-hash.md) has information about obtaining the hash for some contents, as well as converting to and from encodings.
|
||||
|
||||
The `outputHashAlgo` attribute specifies the hash algorithm used to compute the hash.
|
||||
It can currently be `"blake3", "sha1"`, `"sha256"`, `"sha512"`, or `null`.
|
||||
`outputHashAlgo` can only be `null` when `outputHash` follows the SRI format.
|
||||
|
||||
The `outputHashMode` attribute determines how the hash is computed.
|
||||
It must be one of the following values:
|
||||
|
||||
- [`"flat"`](@docroot@/store/store-object/content-address.md#method-flat)
|
||||
|
||||
This is the default.
|
||||
|
||||
- [`"recursive"` or `"nar"`](@docroot@/store/store-object/content-address.md#method-nix-archive)
|
||||
|
||||
> **Compatibility**
|
||||
>
|
||||
> `"recursive"` is the traditional way of indicating this,
|
||||
> and is supported since 2005 (virtually the entire history of Nix).
|
||||
> `"nar"` is more clear, and consistent with other parts of Nix (such as the CLI),
|
||||
> however support for it is only added in Nix version 2.21.
|
||||
|
||||
- [`"text"`](@docroot@/store/store-object/content-address.md#method-text)
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> The use of this method for derivation outputs is part of the [`dynamic-derivations`][xp-feature-dynamic-derivations] experimental feature.
|
||||
|
||||
- [`"git"`](@docroot@/store/store-object/content-address.md#method-git)
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> This method is part of the [`git-hashing`][xp-feature-git-hashing] experimental feature.
|
||||
|
||||
- [`__contentAddressed`]{#adv-attr-__contentAddressed}
|
||||
|
||||
> **Warning**
|
||||
> This attribute is part of an [experimental feature](@docroot@/development/experimental-features.md).
|
||||
>
|
||||
> To use this attribute, you must enable the
|
||||
> [`ca-derivations`][xp-feature-ca-derivations] experimental feature.
|
||||
> For example, in [nix.conf](../command-ref/conf-file.md) you could add:
|
||||
>
|
||||
> ```
|
||||
> extra-experimental-features = ca-derivations
|
||||
> ```
|
||||
|
||||
If this attribute is set to `true`, then the derivation
|
||||
outputs will be stored in a content-addressed location rather than the
|
||||
traditional input-addressed one.
|
||||
|
||||
Setting this attribute also requires setting
|
||||
[`outputHashMode`](#adv-attr-outputHashMode)
|
||||
and
|
||||
[`outputHashAlgo`](#adv-attr-outputHashAlgo)
|
||||
like for *fixed-output derivations* (see above).
|
||||
|
||||
It also implicitly requires that the machine to build the derivation must have the `ca-derivations` [system feature](@docroot@/command-ref/conf-file.md#conf-system-features).
|
||||
|
||||
- [`passAsFile`]{#adv-attr-passAsFile}\
|
||||
A list of names of attributes that should be passed via files rather
|
||||
than environment variables. For example, if you have
|
||||
|
||||
```nix
|
||||
passAsFile = ["big"];
|
||||
big = "a very long string";
|
||||
```
|
||||
|
||||
then when the builder runs, the environment variable `bigPath`
|
||||
will contain the absolute path to a temporary file containing `a
|
||||
very long string`. That is, for any attribute *x* listed in
|
||||
`passAsFile`, Nix will pass an environment variable `xPath`
|
||||
holding the path of the file containing the value of attribute
|
||||
*x*. This is useful when you need to pass large strings to a
|
||||
builder, since most operating systems impose a limit on the size
|
||||
of the environment (typically, a few hundred kilobyte).
|
||||
|
||||
- [`preferLocalBuild`]{#adv-attr-preferLocalBuild}\
|
||||
If this attribute is set to `true` and [distributed building is enabled](@docroot@/command-ref/conf-file.md#conf-builders), then, if possible, the derivation will be built locally instead of being forwarded to a remote machine.
|
||||
This is useful for derivations that are cheapest to build locally.
|
||||
|
||||
- [`allowSubstitutes`]{#adv-attr-allowSubstitutes}\
|
||||
If this attribute is set to `false`, then Nix will always build this derivation (locally or remotely); it will not try to substitute its outputs.
|
||||
This is useful for derivations that are cheaper to build than to substitute.
|
||||
|
||||
This attribute can be ignored by setting [`always-allow-substitutes`](@docroot@/command-ref/conf-file.md#conf-always-allow-substitutes) to `true`.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> If set to `false`, the [`builder`] should be able to run on the system type specified in the [`system` attribute](./derivations.md#attr-system), since the derivation cannot be substituted.
|
||||
|
||||
[`builder`]: ./derivations.md#attr-builder
|
||||
|
||||
- [`__structuredAttrs`]{#adv-attr-structuredAttrs}\
|
||||
If the special attribute `__structuredAttrs` is set to `true`, the other derivation
|
||||
attributes are serialised into a file in JSON format. The environment variable
|
||||
`NIX_ATTRS_JSON_FILE` points to the exact location of that file both in a build
|
||||
and a [`nix-shell`](../command-ref/nix-shell.md). This obviates the need for
|
||||
[`passAsFile`](#adv-attr-passAsFile) since JSON files have no size restrictions,
|
||||
unlike process environments.
|
||||
|
||||
It also makes it possible to tweak derivation settings in a structured way; see
|
||||
[`outputChecks`](#adv-attr-outputChecks) for example.
|
||||
|
||||
As a convenience to Bash builders,
|
||||
Nix writes a script that initialises shell variables
|
||||
corresponding to all attributes that are representable in Bash. The
|
||||
environment variable `NIX_ATTRS_SH_FILE` points to the exact
|
||||
location of the script, both in a build and a
|
||||
[`nix-shell`](../command-ref/nix-shell.md). This includes non-nested
|
||||
(associative) arrays. For example, the attribute `hardening.format = true`
|
||||
ends up as the Bash associative array element `${hardening[format]}`.
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> If set to `true`, other advanced attributes such as [`allowedReferences`](#adv-attr-allowedReferences), [`allowedReferences`](#adv-attr-allowedReferences), [`allowedRequisites`](#adv-attr-allowedRequisites),
|
||||
[`disallowedReferences`](#adv-attr-disallowedReferences) and [`disallowedRequisites`](#adv-attr-disallowedRequisites), maxSize, and maxClosureSize.
|
||||
will have no effect.
|
||||
|
||||
- [`outputChecks`]{#adv-attr-outputChecks}\
|
||||
When using [structured attributes](#adv-attr-structuredAttrs), the `outputChecks`
|
||||
attribute allows defining checks per-output.
|
||||
@@ -341,6 +167,8 @@ Derivations can declare some infrequently used optional attributes.
|
||||
};
|
||||
```
|
||||
|
||||
## Other output modifications
|
||||
|
||||
- [`unsafeDiscardReferences`]{#adv-attr-unsafeDiscardReferences}\
|
||||
|
||||
When using [structured attributes](#adv-attr-structuredAttrs), the
|
||||
@@ -358,6 +186,24 @@ Derivations can declare some infrequently used optional attributes.
|
||||
their own embedded Nix store: hashes found inside such an image refer
|
||||
to the embedded store and not to the host's Nix store.
|
||||
|
||||
## Build scheduling
|
||||
|
||||
- [`preferLocalBuild`]{#adv-attr-preferLocalBuild}\
|
||||
If this attribute is set to `true` and [distributed building is enabled](@docroot@/command-ref/conf-file.md#conf-builders), then, if possible, the derivation will be built locally instead of being forwarded to a remote machine.
|
||||
This is useful for derivations that are cheapest to build locally.
|
||||
|
||||
- [`allowSubstitutes`]{#adv-attr-allowSubstitutes}\
|
||||
If this attribute is set to `false`, then Nix will always build this derivation (locally or remotely); it will not try to substitute its outputs.
|
||||
This is useful for derivations that are cheaper to build than to substitute.
|
||||
|
||||
This attribute can be ignored by setting [`always-allow-substitutes`](@docroot@/command-ref/conf-file.md#conf-always-allow-substitutes) to `true`.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> If set to `false`, the [`builder`] should be able to run on the system type specified in the [`system` attribute](./derivations.md#attr-system), since the derivation cannot be substituted.
|
||||
|
||||
[`builder`]: ./derivations.md#attr-builder
|
||||
|
||||
- [`requiredSystemFeatures`]{#adv-attr-requiredSystemFeatures}\
|
||||
|
||||
If a derivation has the `requiredSystemFeatures` attribute, then Nix will only build it on a machine that has the corresponding features set in its [`system-features` configuration](@docroot@/command-ref/conf-file.md#conf-system-features).
|
||||
@@ -370,6 +216,171 @@ Derivations can declare some infrequently used optional attributes.
|
||||
|
||||
ensures that the derivation can only be built on a machine with the `kvm` feature.
|
||||
|
||||
[xp-feature-ca-derivations]: @docroot@/development/experimental-features.md#xp-feature-ca-derivations
|
||||
# Impure builder configuration
|
||||
|
||||
- [`impureEnvVars`]{#adv-attr-impureEnvVars}\
|
||||
This attribute allows you to specify a list of environment variables
|
||||
that should be passed from the environment of the calling user to
|
||||
the builder. Usually, the environment is cleared completely when the
|
||||
builder is executed, but with this attribute you can allow specific
|
||||
environment variables to be passed unmodified. For example,
|
||||
`fetchurl` in Nixpkgs has the line
|
||||
|
||||
```nix
|
||||
impureEnvVars = [ "http_proxy" "https_proxy" ... ];
|
||||
```
|
||||
|
||||
to make it use the proxy server configuration specified by the user
|
||||
in the environment variables `http_proxy` and friends.
|
||||
|
||||
This attribute is only allowed in [fixed-output derivations][fixed-output derivation],
|
||||
where impurities such as these are okay since (the hash
|
||||
of) the output is known in advance. It is ignored for all other
|
||||
derivations.
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> `impureEnvVars` implementation takes environment variables from
|
||||
> the current builder process. When a daemon is building its
|
||||
> environmental variables are used. Without the daemon, the
|
||||
> environmental variables come from the environment of the
|
||||
> `nix-build`.
|
||||
|
||||
If the [`configurable-impure-env` experimental
|
||||
feature](@docroot@/development/experimental-features.md#xp-feature-configurable-impure-env)
|
||||
is enabled, these environment variables can also be controlled
|
||||
through the
|
||||
[`impure-env`](@docroot@/command-ref/conf-file.md#conf-impure-env)
|
||||
configuration setting.
|
||||
|
||||
## Setting the derivation type
|
||||
|
||||
As discussed in [Derivation Outputs and Types of Derivations](@docroot@/store/derivation/outputs/index.md), there are multiples kinds of derivations / kinds of derivation outputs.
|
||||
The choice of the following attributes determines which kind of derivation we are making.
|
||||
|
||||
- [`__contentAddressed`]
|
||||
|
||||
- [`outputHash`]
|
||||
|
||||
- [`outputHashAlgo`]
|
||||
|
||||
- [`outputHashMode`]
|
||||
|
||||
The three types of derivations are chosen based on the following combinations of these attributes.
|
||||
All other combinations are invalid.
|
||||
|
||||
- [Input-addressing derivations](@docroot@/store/derivation/outputs/input-address.md)
|
||||
|
||||
This is the default for `builtins.derivation`.
|
||||
Nix only currently supports one kind of input-addressing, so no other information is needed.
|
||||
|
||||
`__contentAddressed = false;` may also be included, but is not needed, and will trigger the experimental feature check.
|
||||
|
||||
- [Fixed-output derivations][fixed-output derivation]
|
||||
|
||||
All of [`outputHash`], [`outputHashAlgo`], and [`outputHashMode`].
|
||||
|
||||
<!--
|
||||
|
||||
`__contentAddressed` is ignored, because fixed-output derivations always content-address their outputs, by definition.
|
||||
|
||||
**TODO CHECK**
|
||||
|
||||
-->
|
||||
|
||||
- [(Floating) content-addressing derivations](@docroot@/store/derivation/outputs/content-address.md)
|
||||
|
||||
Both [`outputHashAlgo`] and [`outputHashMode`], `__contentAddressed = true;`, and *not* `outputHash`.
|
||||
|
||||
If an output hash was given, then the derivation output would be "fixed" not "floating".
|
||||
|
||||
Here is more information on the `output*` attributes, and what values they may be set to:
|
||||
|
||||
- [`outputHashMode`]{#adv-attr-outputHashMode}
|
||||
|
||||
This specifies how the files of a content-addressing derivation output are digested to produce a content address.
|
||||
|
||||
This works in conjunction with [`outputHashAlgo`](#adv-attr-outputHashAlgo).
|
||||
Specifying one without the other is an error (unless [`outputHash` is also specified and includes its own hash algorithm as described below).
|
||||
|
||||
The `outputHashMode` attribute determines how the hash is computed.
|
||||
It must be one of the following values:
|
||||
|
||||
- [`"flat"`](@docroot@/store/store-object/content-address.md#method-flat)
|
||||
|
||||
This is the default.
|
||||
|
||||
- [`"recursive"` or `"nar"`](@docroot@/store/store-object/content-address.md#method-nix-archive)
|
||||
|
||||
> **Compatibility**
|
||||
>
|
||||
> `"recursive"` is the traditional way of indicating this,
|
||||
> and is supported since 2005 (virtually the entire history of Nix).
|
||||
> `"nar"` is more clear, and consistent with other parts of Nix (such as the CLI),
|
||||
> however support for it is only added in Nix version 2.21.
|
||||
|
||||
- [`"text"`](@docroot@/store/store-object/content-address.md#method-text)
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> The use of this method for derivation outputs is part of the [`dynamic-derivations`][xp-feature-dynamic-derivations] experimental feature.
|
||||
|
||||
- [`"git"`](@docroot@/store/store-object/content-address.md#method-git)
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> This method is part of the [`git-hashing`][xp-feature-git-hashing] experimental feature.
|
||||
|
||||
See [content-addressing store objects](@docroot@/store/store-object/content-address.md) for more information about the process this flag controls.
|
||||
|
||||
- [`outputHashAlgo`]{#adv-attr-outputHashAlgo}
|
||||
|
||||
This specifies the hash algorithm used to digest the [file system object] data of a content-addressing derivation output.
|
||||
|
||||
This works in conjunction with [`outputHashMode`](#adv-attr-outputHashAlgo).
|
||||
Specifying one without the other is an error (unless `outputHash` is also specified and includes its own hash algorithm as described below).
|
||||
|
||||
The `outputHashAlgo` attribute specifies the hash algorithm used to compute the hash.
|
||||
It can currently be `"blake3"`, `"sha1"`, `"sha256"`, `"sha512"`, or `null`.
|
||||
|
||||
`outputHashAlgo` can only be `null` when `outputHash` follows the SRI format, because in that case the choice of hash algorithm is determined by `outputHash`.
|
||||
|
||||
- [`outputHash`]{#adv-attr-outputHashAlgo}; [`outputHash`]{#adv-attr-outputHashMode}
|
||||
|
||||
This will specify the output hash of the single output of a [fixed-output derivation].
|
||||
|
||||
The `outputHash` attribute must be a string containing the hash in either hexadecimal or "nix32" encoding, or following the format for integrity metadata as defined by [SRI](https://www.w3.org/TR/SRI/).
|
||||
The "nix32" encoding is an adaptation of base-32 encoding.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> The [`convertHash`](@docroot@/language/builtins.md#builtins-convertHash) function shows how to convert between different encodings.
|
||||
> The [`nix-hash` command](../command-ref/nix-hash.md) has information about obtaining the hash for some contents, as well as converting to and from encodings.
|
||||
|
||||
- [`__contentAddressed`]{#adv-attr-__contentAddressed}
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> This attribute is part of an [experimental feature](@docroot@/development/experimental-features.md).
|
||||
>
|
||||
> To use this attribute, you must enable the
|
||||
> [`ca-derivations`][xp-feature-ca-derivations] experimental feature.
|
||||
> For example, in [nix.conf](../command-ref/conf-file.md) you could add:
|
||||
>
|
||||
> ```
|
||||
> extra-experimental-features = ca-derivations
|
||||
> ```
|
||||
|
||||
This is a boolean with a default of `false`.
|
||||
It determines whether the derivation is floating content-addressing.
|
||||
|
||||
[`__contentAddressed`]: #adv-attr-__contentAddressed
|
||||
[`outputHash`]: #adv-attr-outputHash
|
||||
[`outputHashAlgo`]: #adv-attr-outputHashAlgo
|
||||
[`outputHashMode`]: #adv-attr-outputHashMode
|
||||
|
||||
[fixed-output derivation]: @docroot@/glossary.md#gloss-fixed-output-derivation
|
||||
[file system object]: @docroot@/store/file-system-object.md
|
||||
[store object]: @docroot@/store/store-object.md
|
||||
[xp-feature-dynamic-derivations]: @docroot@/development/experimental-features.md#xp-feature-dynamic-derivations
|
||||
[xp-feature-git-hashing]: @docroot@/development/experimental-features.md#xp-feature-git-hashing
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Derivations
|
||||
|
||||
The most important built-in function is `derivation`, which is used to describe a single store-layer [store derivation].
|
||||
Consult the [store chapter](@docroot@/store/drv.md) for what a store derivation is;
|
||||
Consult the [store chapter](@docroot@/store/derivation/index.md) for what a store derivation is;
|
||||
this section just concerns how to create one from the Nix language.
|
||||
|
||||
This builtin function takes as input an attribute set, the attributes of which specify the inputs to the process.
|
||||
@@ -16,7 +16,7 @@ It outputs an attribute set, and produces a [store derivation] as a side effect
|
||||
- [`name`]{#attr-name} ([String](@docroot@/language/types.md#type-string))
|
||||
|
||||
A symbolic name for the derivation.
|
||||
See [derivation outputs](@docroot@/store/drv.md#outputs) for what this is affects.
|
||||
See [derivation outputs](@docroot@/store/derivation/index.md#outputs) for what this is affects.
|
||||
|
||||
[store path]: @docroot@/store/store-path.md
|
||||
|
||||
@@ -34,7 +34,7 @@ It outputs an attribute set, and produces a [store derivation] as a side effect
|
||||
|
||||
- [`system`]{#attr-system} ([String](@docroot@/language/types.md#type-string))
|
||||
|
||||
See [system](@docroot@/store/drv.md#system).
|
||||
See [system](@docroot@/store/derivation/index.md#system).
|
||||
|
||||
> **Example**
|
||||
>
|
||||
@@ -64,7 +64,7 @@ It outputs an attribute set, and produces a [store derivation] as a side effect
|
||||
|
||||
- [`builder`]{#attr-builder} ([Path](@docroot@/language/types.md#type-path) | [String](@docroot@/language/types.md#type-string))
|
||||
|
||||
See [builder](@docroot@/store/drv.md#builder).
|
||||
See [builder](@docroot@/store/derivation/index.md#builder).
|
||||
|
||||
> **Example**
|
||||
>
|
||||
@@ -113,7 +113,7 @@ It outputs an attribute set, and produces a [store derivation] as a side effect
|
||||
|
||||
Default: `[ ]`
|
||||
|
||||
See [args](@docroot@/store/drv.md#args).
|
||||
See [args](@docroot@/store/derivation/index.md#args).
|
||||
|
||||
> **Example**
|
||||
>
|
||||
|
||||
@@ -196,7 +196,7 @@ All comparison operators are implemented in terms of `<`, and the following equi
|
||||
|
||||
## Logical implication
|
||||
|
||||
Equivalent to `!`*b1* `||` *b2*.
|
||||
Equivalent to `!`*b1* `||` *b2* (or `if` *b1* `then` *b2* `else true`)
|
||||
|
||||
[Logical implication]: #logical-implication
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ It creates an [attribute set] representing the string context, which can be insp
|
||||
|
||||
## Clearing string contexts
|
||||
|
||||
[`buitins.unsafeDiscardStringContext`](./builtins.md#builtins-unsafeDiscardStringContext) will make a copy of a string, but with an empty string context.
|
||||
[`builtins.unsafeDiscardStringContext`](./builtins.md#builtins-unsafeDiscardStringContext) will make a copy of a string, but with an empty string context.
|
||||
The returned string can be used in more ways, e.g. by operators that require the string context to be empty.
|
||||
The requirement to explicitly discard the string context in such use cases helps ensure that string context elements are not lost by mistake.
|
||||
The "unsafe" marker is only there to remind that Nix normally guarantees that dependencies are tracked, whereas the returned string has lost them.
|
||||
|
||||
@@ -443,7 +443,7 @@ three kinds of patterns:
|
||||
This works on any set that contains at least the three named
|
||||
attributes.
|
||||
|
||||
It is possible to provide *default values* for attributes, in
|
||||
- It is possible to provide *default values* for attributes, in
|
||||
which case they are allowed to be missing. A default value is
|
||||
specified by writing `name ? e`, where *e* is an arbitrary
|
||||
expression. For example,
|
||||
@@ -503,6 +503,45 @@ three kinds of patterns:
|
||||
> [ 23 {} ]
|
||||
> ```
|
||||
|
||||
- All bindings introduced by the function are in scope in the entire function expression; not just in the body.
|
||||
It can therefore be used in default values.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> A parameter (`x`), is used in the default value for another parameter (`y`):
|
||||
>
|
||||
> ```nix
|
||||
> let
|
||||
> f = { x, y ? [x] }: { inherit y; };
|
||||
> in
|
||||
> f { x = 3; }
|
||||
> ```
|
||||
>
|
||||
> This evaluates to:
|
||||
>
|
||||
> ```nix
|
||||
> {
|
||||
> y = [ 3 ];
|
||||
> }
|
||||
> ```
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> The binding of an `@` pattern, `args`, is used in the default value for a parameter, `x`:
|
||||
>
|
||||
> ```nix
|
||||
> let
|
||||
> f = args@{ x ? args.a, ... }: x;
|
||||
> in
|
||||
> f { a = 1; }
|
||||
> ```
|
||||
>
|
||||
> This evaluates to:
|
||||
>
|
||||
> ```nix
|
||||
> 1
|
||||
> ```
|
||||
|
||||
Note that functions do not have names. If you want to give them a name,
|
||||
you can bind them to an attribute, e.g.,
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ is a JSON object with the following fields:
|
||||
|
||||
|
||||
* `method`:
|
||||
For an output which will be [content addresed], a string representing the [method](@docroot@/store/store-object/content-address.md) of content addressing that is chosen.
|
||||
For an output which will be [content addressed], a string representing the [method](@docroot@/store/store-object/content-address.md) of content addressing that is chosen.
|
||||
Valid method strings are:
|
||||
|
||||
- [`flat`](@docroot@/store/store-object/content-address.md#method-flat)
|
||||
@@ -35,7 +35,7 @@ is a JSON object with the following fields:
|
||||
Otherwise, `null`.
|
||||
|
||||
* `hashAlgo`:
|
||||
For an output which will be [content addresed], the name of the hash algorithm used.
|
||||
For an output which will be [content addressed], the name of the hash algorithm used.
|
||||
Valid algorithm strings are:
|
||||
|
||||
- `blake3`
|
||||
|
||||
@@ -7,7 +7,7 @@ The format of this specification is close to [Extended Backus–Naur form](https
|
||||
Regular users do *not* need to know this information --- store paths can be treated as black boxes computed from the properties of the store objects they refer to.
|
||||
But for those interested in exactly how Nix works, e.g. if they are reimplementing it, this information can be useful.
|
||||
|
||||
[store path](@docroot@/store/store-path.md)
|
||||
[store path]: @docroot@/store/store-path.md
|
||||
|
||||
## Store path proper
|
||||
|
||||
@@ -20,14 +20,17 @@ where
|
||||
|
||||
- `store-dir` = the [store directory](@docroot@/store/store-path.md#store-directory)
|
||||
|
||||
- `digest` = base-32 representation of the first 160 bits of a [SHA-256] hash of `fingerprint`
|
||||
- `digest` = base-32 representation of the compressed to 160 bits [SHA-256] hash of `fingerprint`
|
||||
|
||||
This the hash part of the store name
|
||||
For the definition of the hash compression algorithm, please refer to the section 5.1 of
|
||||
the [Nix thesis](https://edolstra.github.io/pubs/phd-thesis.pdf), which also defines the
|
||||
specifics of base-32 encoding. Note that base-32 encoding processes the hash bytestring from
|
||||
the end, while base-16 processes in from the beginning.
|
||||
|
||||
## Fingerprint
|
||||
|
||||
- ```ebnf
|
||||
fingerprint = type ":" sha256 ":" inner-digest ":" store ":" name
|
||||
fingerprint = type ":sha256:" inner-digest ":" store ":" name
|
||||
```
|
||||
|
||||
Note that it includes the location of the store as well as the name to make sure that changes to either of those are reflected in the hash
|
||||
@@ -53,7 +56,7 @@ where
|
||||
method of content addressing store objects,
|
||||
if the hash algorithm is [SHA-256].
|
||||
Just like in the "Text" case, we can have the store objects referenced by their paths.
|
||||
Additionally, we can have an optional `:self` label to denote self reference.
|
||||
Additionally, we can have an optional `:self` label to denote self-reference.
|
||||
|
||||
- ```ebnf
|
||||
| "output:" id
|
||||
@@ -70,7 +73,8 @@ where
|
||||
`id` is the name of the output (usually, "out").
|
||||
For content-addressed store objects, `id`, is always "out".
|
||||
|
||||
- `inner-digest` = base-16 representation of a SHA-256 hash of `inner-fingerprint`
|
||||
- `inner-digest` = base-16 representation of a SHA-256 hash of `inner-fingerprint`.
|
||||
The base-16 encoding uses lower-cased hex digits.
|
||||
|
||||
## Inner fingerprint
|
||||
|
||||
@@ -82,7 +86,7 @@ where
|
||||
|
||||
- if `type` = `"source:" ...`:
|
||||
|
||||
the hash of the [Nix Archive (NAR)] serialization of the [file system object](@docroot@/store/file-system-object.md) of the store object.
|
||||
the [Nix Archive (NAR)] serialization of the [file system object](@docroot@/store/file-system-object.md) of the store object.
|
||||
|
||||
- if `type` = `"output:" id`:
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ defined as the timestamp of the newest file inside the tarball.
|
||||
This protocol is supported by Gitea since v1.22.1 and by Forgejo since v7.0.4/v8.0.0 and can be used with the following flake URL schema:
|
||||
|
||||
```
|
||||
https://<domain name>/<owner>/<repo>/archive/<reference or revison>.tar.gz
|
||||
https://<domain name>/<owner>/<repo>/archive/<reference or revision>.tar.gz
|
||||
```
|
||||
|
||||
> **Example**
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
- To operate on a flake outside the current directory, you must now pass `--flake path/to/flake`.
|
||||
|
||||
- The flake-specific flags `--recreate-lock-file` and `--update-input` have been removed from all commands operating on installables.
|
||||
They are superceded by `nix flake update`.
|
||||
They are superseded by `nix flake update`.
|
||||
|
||||
- Commit signature verification for the [`builtins.fetchGit`](@docroot@/language/builtins.md#builtins-fetchGit) is added as the new [`verified-fetches` experimental feature](@docroot@/development/experimental-features.md#xp-feature-verified-fetches).
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
- Modify `nix derivation {add,show}` JSON format [#9866](https://github.com/NixOS/nix/issues/9866) [#10722](https://github.com/NixOS/nix/pull/10722)
|
||||
|
||||
The JSON format for derivations has been slightly revised to better conform to our [JSON guidelines](@docroot@/development/cli-guideline.md#returning-future-proof-json).
|
||||
In particular, the hash algorithm and content addressing method of content-addresed derivation outputs are now separated into two fields `hashAlgo` and `method`,
|
||||
In particular, the hash algorithm and content addressing method of content-addressed derivation outputs are now separated into two fields `hashAlgo` and `method`,
|
||||
rather than one field with an arcane `:`-separated format.
|
||||
|
||||
This JSON format is only used by the experimental `nix derivation` family of commands, at this time.
|
||||
|
||||
@@ -173,7 +173,7 @@
|
||||
**Deprecation**: Use `nix32` instead of `base32` as `toHashFormat`
|
||||
|
||||
For the builtin `convertHash`, the `toHashFormat` parameter now accepts the same hash formats as the `--to`/`--from`
|
||||
parameters of the `nix hash conert` command: `"base16"`, `"nix32"`, `"base64"`, and `"sri"`. The former `"base32"` value
|
||||
parameters of the `nix hash convert` command: `"base16"`, `"nix32"`, `"base64"`, and `"sri"`. The former `"base32"` value
|
||||
remains as a deprecated alias for `"nix32"`. Please convert your code from:
|
||||
|
||||
```nix
|
||||
|
||||
@@ -30,14 +30,23 @@
|
||||
|
||||
The evaluator now presents a "union" filesystem view of the `/nix/store` in the host and the chroot.
|
||||
|
||||
This change also removes some hacks that broke `builtins.{path,filterSource}` in chroot stores [#11503](https://github.com/NixOS/nix/issue/11503).
|
||||
This change also removes some hacks that broke `builtins.{path,filterSource}` in chroot stores [#11503](https://github.com/NixOS/nix/issues/11503).
|
||||
|
||||
- `nix flake prefetch` now has a `--out-link` option [#12443](https://github.com/NixOS/nix/issue/12443)
|
||||
- `nix flake prefetch` now has a `--out-link` option [#12443](https://github.com/NixOS/nix/pull/12443)
|
||||
|
||||
- Set `FD_CLOEXEC` on sockets created by curl [#12439](https://github.com/NixOS/nix/pull/12439)
|
||||
|
||||
Curl created sockets without setting `FD_CLOEXEC`/`SOCK_CLOEXEC`. This could previously cause connections to remain open forever when using commands like `nix shell`. This change sets the `FD_CLOEXEC` flag using a `CURLOPT_SOCKOPTFUNCTION` callback.
|
||||
|
||||
- Add BLAKE3 hash algorithm [#12379](https://github.com/NixOS/nix/pull/12379)
|
||||
|
||||
Nix now supports the BLAKE3 hash algorithm as an experimental feature (`blake3-hashes`):
|
||||
|
||||
```console
|
||||
# nix hash file ./file --type blake3 --extra-experimental-features blake3-hashes
|
||||
blake3-34P4p+iZXcbbyB1i4uoF7eWCGcZHjmaRn6Y7QdynLwU=
|
||||
```
|
||||
|
||||
# Contributors
|
||||
|
||||
This release was made possible by the following 21 contributors:
|
||||
|
||||
105
doc/manual/source/release-notes/rl-2.28.md
Normal file
105
doc/manual/source/release-notes/rl-2.28.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# Release 2.28.0 (2025-04-02)
|
||||
|
||||
This is an atypical release, and for almost all intents and purposes, it is just a continuation of 2.27; not a feature release.
|
||||
|
||||
We had originally set the goal of making 2.27 the Nixpkgs default for NixOS 25.05, but dependents that link to Nix need certain _interface breaking_ changes in the C++ headers. This is not something we should do in a patch release, so this is why we branched 2.28 right off 2.27 instead of `master`.
|
||||
|
||||
This completes the infrastructure overhaul for the [RFC 132](https://github.com/NixOS/rfcs/blob/master/rfcs/0132-meson-builds-nix.md) switchover to meson as our build system.
|
||||
|
||||
## Major changes
|
||||
|
||||
- Unstable C++ API reworked
|
||||
[#12836](https://github.com/NixOS/nix/pull/12836)
|
||||
[#12798](https://github.com/NixOS/nix/pull/12798)
|
||||
[#12773](https://github.com/NixOS/nix/pull/12773)
|
||||
|
||||
Now the C++ interface confirms to common conventions much better than before:
|
||||
|
||||
- All headers are expected to be included with the initial `nix/`, e.g. as `#include "nix/....hh"` (what Nix's headers now do) or `#include <nix/....hh>` (what downstream projects may choose to do).
|
||||
Likewise, the pkg-config files have `-I${includedir}` not `-I${includedir}/nix` or similar.
|
||||
|
||||
Including without the `nix/` like before sometimes worked because of how for `#include` C pre-process checks the directory containing the current file, not just the lookup path, but this was not reliable.
|
||||
|
||||
- All configuration headers are included explicitly by the (regular) headers that need them.
|
||||
There is no more need to pass `-include` to force additional files to be included.
|
||||
|
||||
- The public, installed configuration headers no longer contain implementation-specific details that are not relevant to the API.
|
||||
The vast majority of definitions that were previously in there are now moved to new headers that are not installed, but used during Nix's own compilation only.
|
||||
The remaining macro definitions are renamed to have `NIX_` as a prefix.
|
||||
|
||||
- The name of the Nix component the header comes from
|
||||
(e.g. `util`, `store`, `expr`, `flake`, etc.)
|
||||
is now part of the path to the header, coming after `nix` and before the header name
|
||||
(or rest of the header path, if it is already in a directory).
|
||||
|
||||
Here is a contrived diff showing a few of these changes at once:
|
||||
|
||||
```diff
|
||||
@@ @@
|
||||
-#include "derived-path.hh"
|
||||
+#include "nix/store/derived-path.hh"
|
||||
@@ @@
|
||||
+// Would include for the variables used before. But when other headers
|
||||
+// need these variables. those will include these config themselves.
|
||||
+#include "nix/store/config.hh"
|
||||
+#include "nix/expr/config.hh"
|
||||
@@ @@
|
||||
-#include "config.hh"
|
||||
+// Additionally renamed to distinguish from components' config headers.
|
||||
+#include "nix/util/configuration.hh"
|
||||
@@ @@
|
||||
-#if HAVE_ACL_SUPPORT
|
||||
+#if NIX_SUPPORT_ACL
|
||||
@@ @@
|
||||
-#if HAVE_BOEHMGC
|
||||
+#if NIX_USE_BOEHMGC
|
||||
@@ @@
|
||||
#endif
|
||||
#endif
|
||||
@@ @@
|
||||
-const char *s = "hi from " SYSTEM;
|
||||
+const char *s = "hi from " NIX_LOCAL_SYSTEM;
|
||||
```
|
||||
|
||||
- C API `nix_flake_init_global` removed [#5638](https://github.com/NixOS/nix/issues/5638) [#12759](https://github.com/NixOS/nix/pull/12759)
|
||||
|
||||
In order to improve the modularity of the code base, we are removing a use of global state, and therefore the `nix_flake_init_global` function.
|
||||
|
||||
Instead, use `nix_flake_settings_add_to_eval_state_builder`.
|
||||
For example:
|
||||
|
||||
```diff
|
||||
- nix_flake_init_global(ctx, settings);
|
||||
- HANDLE_ERROR(ctx);
|
||||
-
|
||||
nix_eval_state_builder * builder = nix_eval_state_builder_new(ctx, store);
|
||||
HANDLE_ERROR(ctx);
|
||||
|
||||
+ nix_flake_settings_add_to_eval_state_builder(ctx, settings, builder);
|
||||
+ HANDLE_ERROR(ctx);
|
||||
```
|
||||
|
||||
Although this change is not as critical, we figured it would be good to do this API change at the same time, also.
|
||||
Also note that we try to keep the C API compatible, but we decided to break this function because it was young and likely not in widespread use yet. This frees up time to make important progress on the rest of the C API.
|
||||
|
||||
# Contributors
|
||||
|
||||
This earlier-than-usual release was made possible by the following 16 contributors:
|
||||
|
||||
- Farid Zakaria [**(@fzakaria)**](https://github.com/fzakaria)
|
||||
- Jörg Thalheim [**(@Mic92)**](https://github.com/Mic92)
|
||||
- Eelco Dolstra [**(@edolstra)**](https://github.com/edolstra)
|
||||
- Graham Christensen [**(@grahamc)**](https://github.com/grahamc)
|
||||
- Thomas Miedema [**(@thomie)**](https://github.com/thomie)
|
||||
- Brian McKenna [**(@puffnfresh)**](https://github.com/puffnfresh)
|
||||
- Sergei Trofimovich [**(@trofi)**](https://github.com/trofi)
|
||||
- Dmitry Bogatov [**(@KAction)**](https://github.com/KAction)
|
||||
- Erik Nygren [**(@Kirens)**](https://github.com/Kirens)
|
||||
- John Ericson [**(@Ericson2314)**](https://github.com/Ericson2314)
|
||||
- Sergei Zimmerman [**(@xokdvium)**](https://github.com/xokdvium)
|
||||
- Ruby Rose [**(@oldshensheep)**](https://github.com/oldshensheep)
|
||||
- Robert Hensing [**(@roberth)**](https://github.com/roberth)
|
||||
- jade [**(@lf-)**](https://github.com/lf-)
|
||||
- Félix [**(@picnoir)**](https://github.com/picnoir)
|
||||
- Valentin Gagarin [**(@fricklerhandwerk)**](https://github.com/fricklerhandwerk)
|
||||
- Dmitry Bogatov
|
||||
@@ -13,7 +13,7 @@
|
||||
* New command `nix store copy-log` to copy build logs from one store
|
||||
to another.
|
||||
* The `commit-lockfile-summary` option can be set to a non-empty
|
||||
string to override the commit summary used when commiting an updated
|
||||
string to override the commit summary used when committing an updated
|
||||
lockfile. This may be used in conjunction with the `nixConfig`
|
||||
attribute in `flake.nix` to better conform to repository
|
||||
conventions.
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
## Builder Execution
|
||||
|
||||
The [`builder`](./drv.md#builder) is executed as follows:
|
||||
The [`builder`](./derivation/index.md#builder) is executed as follows:
|
||||
|
||||
- A temporary directory is created under the directory specified by
|
||||
`TMPDIR` (default `/tmp`) where the build will take place. The
|
||||
@@ -54,7 +54,7 @@ The [`builder`](./drv.md#builder) is executed as follows:
|
||||
it’s `out`.)
|
||||
|
||||
- If an output path already exists, it is removed. Also, locks are
|
||||
acquired to prevent multiple Nix instances from performing the same
|
||||
acquired to prevent multiple [Nix instances][Nix instance] from performing the same
|
||||
build at the same time.
|
||||
|
||||
- A log of the combined standard output and error is written to
|
||||
@@ -95,3 +95,6 @@ If the builder exited successfully, the following steps happen in order to turn
|
||||
|
||||
Nix also scans for references to other outputs' paths in the same way, because outputs are allowed to refer to each other.
|
||||
If the outputs' references to each other form a cycle, this is an error, because the references of store objects much be acyclic.
|
||||
|
||||
|
||||
[Nix instance]: @docroot@/glossary.md#gloss-nix-instance
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Store Derivation and Deriving Path
|
||||
|
||||
Besides functioning as a [content addressed store] the Nix store layer works as a [build system].
|
||||
Other system (like Git or IPFS) also store and transfer immutable data, but they don't concern themselves with *how* that data was created.
|
||||
Besides functioning as a [content-addressed store], the Nix store layer works as a [build system].
|
||||
Other systems (like Git or IPFS) also store and transfer immutable data, but they don't concern themselves with *how* that data was created.
|
||||
|
||||
This is where Nix distinguishes itself.
|
||||
*Derivations* represent individual build steps, and *deriving paths* are needed to refer to the *outputs* of those build steps before they are built.
|
||||
@@ -9,15 +9,24 @@ This is where Nix distinguishes itself.
|
||||
|
||||
## Store Derivation {#store-derivation}
|
||||
|
||||
A derivation is a specification for running an executable on precisely defined input files to repeatably produce output files at uniquely determined file system paths.
|
||||
A derivation is a specification for running an executable on precisely defined input to produce on more [store objects][store object].
|
||||
These store objects are known as the derivation's *outputs*.
|
||||
|
||||
Derivations are *built*, in which case the process is spawned according to the spec, and when it exits, required to leave behind files which will (after post-processing) become the outputs of the derivation.
|
||||
This process is described in detail in [Building](@docroot@/store/building.md).
|
||||
|
||||
<!--
|
||||
Some of these things are described directly below, but we envision with more material the exposition will probably want to migrate to separate pages benough this.
|
||||
See outputs spec for an example of this one that migrated to its own page.
|
||||
-->
|
||||
|
||||
A derivation consists of:
|
||||
|
||||
- A name
|
||||
|
||||
- A set of [*inputs*][inputs], a set of [deriving paths][deriving path]
|
||||
- An [inputs specification][inputs], a set of [deriving paths][deriving path]
|
||||
|
||||
- A map of [*outputs*][outputs], from names to other data
|
||||
- An [outputs specification][outputs], specifying which outputs should be produced, and various metadata about them.
|
||||
|
||||
- The ["system" type][system] (e.g. `x86_64-linux`) where the executable is to run.
|
||||
|
||||
@@ -26,13 +35,15 @@ A derivation consists of:
|
||||
[store derivation]: #store-derivation
|
||||
[inputs]: #inputs
|
||||
[input]: #inputs
|
||||
[outputs]: #outputs
|
||||
[output]: #outputs
|
||||
[outputs]: ./outputs/index.md
|
||||
[output]: ./outputs/index.md
|
||||
[process creation fields]: #process-creation-fields
|
||||
[builder]: #builder
|
||||
[args]: #args
|
||||
[env]: #env
|
||||
[system]: #system
|
||||
[content-addressed store]: @docroot@/glossary.md#gloss-content-addressed-store
|
||||
[build system]: @docroot@/glossary.md#gloss-build-system
|
||||
|
||||
### Referencing derivations {#derivation-path}
|
||||
|
||||
@@ -69,7 +80,7 @@ type DerivingPath = ConstantPath | OutputPath;
|
||||
```
|
||||
|
||||
Deriving paths are necessary because, in general and particularly for [content-addressing derivations][content-addressing derivation], the [store path] of an [output] is not known in advance.
|
||||
We can use an output deriving path to refer to such an out, instead of the store path which we do not yet know.
|
||||
We can use an output deriving path to refer to such an output, instead of the store path which we do not yet know.
|
||||
|
||||
[deriving path]: #deriving-path
|
||||
[validity]: @docroot@/glossary.md#gloss-validity
|
||||
@@ -80,47 +91,26 @@ A derivation is constructed from the parts documented in the following subsectio
|
||||
|
||||
### Inputs {#inputs}
|
||||
|
||||
The inputs are a set of [deriving paths][deriving path], refering to all store objects needed in order to perform this build step.
|
||||
The inputs are a set of [deriving paths][deriving path], referring to all store objects needed in order to perform this build step.
|
||||
|
||||
The [process creation fields] will presumably include many [store paths][store path]:
|
||||
|
||||
- The path to the executable normally starts with a store path
|
||||
- The arguments and environment variables likely contain many other store paths.
|
||||
|
||||
But rather than somehow scanning all the other fields for inputs, Nix requires that all inputs be explicitly collected in the inputs field. It is instead the responsibility of the creator of a derivation (e.g. the evaluator) to ensure that every store object referenced in another field (e.g. referenced by store path) is included in this inputs field.
|
||||
|
||||
### Outputs {#outputs}
|
||||
|
||||
The outputs are the derivations are the [store objects][store object] it is obligated to produce.
|
||||
|
||||
Outputs are assigned names, and also consistent of other information based on the type of derivation.
|
||||
|
||||
Output names can be any string which is also a valid [store path] name.
|
||||
The store path of the output store object (also called an [output path] for short), has a name based on the derivation name and the output name.
|
||||
In the general case, store paths have name `derivationName + "-" + outputName`.
|
||||
However, an output named "out" has a store path with name is just the derivation name.
|
||||
This is to allow derivations with a single output to avoid a superfluous `"-${outputName}"` in their single output's name when no disambiguation is needed.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> A derivation is named `hello`, and has two outputs, `out`, and `dev`
|
||||
>
|
||||
> - The derivation's path will be: `/nix/store/<hash>-hello.drv`.
|
||||
>
|
||||
> - The store path of `out` will be: `/nix/store/<hash>-hello`.
|
||||
>
|
||||
> - The store path of `dev` will be: `/nix/store/<hash>-hello-dev`.
|
||||
But rather than somehow scanning all the other fields for inputs, Nix requires that all inputs be explicitly collected in the inputs field. It is instead the responsibility of the creator of a derivation (e.g. the evaluator) to ensure that every store object referenced in another field (e.g. referenced by store path) is included in this inputs field.
|
||||
|
||||
### System {#system}
|
||||
|
||||
The system type on which the [`builder`](#attr-builder) executable is meant to be run.
|
||||
|
||||
A necessary condition for Nix to schedule a given derivation on some Nix instance is for the "system" of that derivation to match that instance's [`system` configuration option].
|
||||
A necessary condition for Nix to schedule a given derivation on some [Nix instance] is for the "system" of that derivation to match that instance's [`system` configuration option] or [`extra-platforms` configuration option].
|
||||
|
||||
By putting the `system` in each derivation, Nix allows *heterogenous* build plans, where not all steps can be run on the same machine or same sort of machine.
|
||||
Nix can schedule builds such that it automatically builds on other platforms by [forwarding build requests](@docroot@/advanced-topics/distributed-builds.md) to other Nix instances.
|
||||
|
||||
[`system` configuration option]: @docroot@/command-ref/conf-file.md#conf-system
|
||||
[`extra-platforms` configuration option]: @docroot@/command-ref/conf-file.md#conf-extra-platforms
|
||||
|
||||
[content-addressing derivation]: @docroot@/glossary.md#gloss-content-addressing-derivation
|
||||
[realise]: @docroot@/glossary.md#gloss-realise
|
||||
@@ -172,7 +162,7 @@ There are two types of placeholder, corresponding to the two cases where this pr
|
||||
|
||||
> **Explanation**
|
||||
>
|
||||
> In general, we need to realise [realise] a [store object] in order to be sure to have a store object for it.
|
||||
> In general, we need to [realise] a [store object] in order to be sure to have a store object for it.
|
||||
> But for these two cases this is either impossible or impractical:
|
||||
>
|
||||
> - In the output case this is impossible:
|
||||
@@ -199,7 +189,7 @@ This ensures that there is a canonical [store path] used to refer to the derivat
|
||||
> **Note**
|
||||
>
|
||||
> Currently, the canonical encoding for every derivation is the "ATerm" format,
|
||||
> but this is subject to change for types derivations which are not yet stable.
|
||||
> but this is subject to change for the types of derivations which are not yet stable.
|
||||
|
||||
Regardless of the format used, when serializing a derivation to a store object, that store object will be content-addressed.
|
||||
|
||||
@@ -253,14 +243,14 @@ That works because we've implicitly assumed that all derivations are created *st
|
||||
But what if derivations could also be created dynamically within Nix?
|
||||
In other words, what if derivations could be the outputs of other derivations?
|
||||
|
||||
:::{.note}
|
||||
In the parlance of "Build Systems à la carte", we are generalizing the Nix store layer to be a "Monadic" instead of "Applicative" build system.
|
||||
:::
|
||||
> **Note**
|
||||
>
|
||||
> In the parlance of "Build Systems à la carte", we are generalizing the Nix store layer to be a "Monadic" instead of "Applicative" build system.
|
||||
|
||||
How should we refer to such derivations?
|
||||
A deriving path works, the same as how we refer to other derivation outputs.
|
||||
But what about a dynamic derivations output?
|
||||
(i.e. how do we refer to the output of an output of a derivation?)
|
||||
(i.e. how do we refer to the output of a derivation, which is itself an output of a derivation?)
|
||||
For that we need to generalize the definition of deriving path, replacing the store path used to refer to the derivation with a nested deriving path:
|
||||
|
||||
```diff
|
||||
@@ -292,7 +282,7 @@ type DerivingPath = ConstantPath | OutputPath;
|
||||
|
||||
Under this extended model, `DerivingPath`s are thus inductively built up from a root `ConstantPath`, wrapped with zero or more outer `OutputPath`s.
|
||||
|
||||
### Encoding {#deriving-path-encoding}
|
||||
### Encoding {#deriving-path-encoding-higher-order}
|
||||
|
||||
The encoding is adjusted in the natural way, encoding the `drv` field recursively using the same deriving path encoding.
|
||||
The result of this is that it is possible to have a chain of `^<output-name>` at the end of the final string, as opposed to just a single one.
|
||||
@@ -308,3 +298,5 @@ The result of this is that it is possible to have a chain of `^<output-name>` at
|
||||
> |------------------------------------------------------------| |-----|
|
||||
> innermost constant store path (usual encoding) output name
|
||||
> ```
|
||||
|
||||
[Nix instance]: @docroot@/glossary.md#gloss-nix-instance
|
||||
192
doc/manual/source/store/derivation/outputs/content-address.md
Normal file
192
doc/manual/source/store/derivation/outputs/content-address.md
Normal file
@@ -0,0 +1,192 @@
|
||||
# Content-addressing derivation outputs
|
||||
|
||||
The content-addressing of an output only depends on that store object itself, not any other information external (such has how it was made, when it was made, etc.).
|
||||
As a consequence, a store object will be content-addressed the same way regardless of whether it was manually inserted into the store, outputted by some derivation, or outputted by a some other derivation.
|
||||
|
||||
The output spec for a content-addressed output must contains the following field:
|
||||
|
||||
- *method*: how the data of the store object is digested into a content address
|
||||
|
||||
The possible choices of *method* are described in the [section on content-addressing store objects](@docroot@/store/store-object/content-address.md).
|
||||
Given the method, the output's name (computed from the derivation name and output spec mapping as described above), and the data of the store object, the output's store path will be computed as described in that section.
|
||||
|
||||
## Fixed-output content-addressing {#fixed}
|
||||
|
||||
In this case the content address of the *fixed* in advanced by the derivation itself.
|
||||
In other words, when the derivation has finished [building](@docroot@/store/building.md), and the provisional output' content-address is computed as part of the process to turn it into a *bona fide* store object, the calculated content address must much that given in the derivation, or the build of that derivation will be deemed a failure.
|
||||
|
||||
The output spec for an output with a fixed content addresses additionally contains:
|
||||
|
||||
- *hash*, the hash expected from digesting the store object's file system objects.
|
||||
This hash may be of a freely-chosen hash algorithm (that Nix supports)
|
||||
|
||||
> **Design note**
|
||||
>
|
||||
> In principle, the output spec could also specify the references the store object should have, since the references and file system objects are equally parts of a content-addressed store object proper that contribute to its content-addressed.
|
||||
> However, at this time, the references are not done because all fixed content-addressed outputs are required to have no references (including no self-reference).
|
||||
>
|
||||
> Also in principle, rather than specifying the references and file system object data with separate hashes, a single hash that constraints both could be used.
|
||||
> This could be done with the final store path's digest, or better yet, the hash that will become the store path's digest before it is truncated.
|
||||
>
|
||||
> These possible future extensions are included to elucidate the core property of fixed-output content addressing --- that all parts of the output must be cryptographically fixed with one or more hashes --- separate from the particulars of the currently-supported store object content-addressing schemes.
|
||||
|
||||
### Design rationale
|
||||
|
||||
What is the purpose of fixing an output's content address in advanced?
|
||||
In abstract terms, the answer is carefully controlled impurity.
|
||||
Unlike a regular derivation, the [builder] executable of a derivation that produced fixed outputs has access to the network.
|
||||
The outputs' guaranteed content-addresses are supposed to mitigate the risk of the builder being given these capabilities;
|
||||
regardless of what the builder does *during* the build, it cannot influence downstream builds in unanticipated ways because all information it passed downstream flows through the outputs whose content-addresses are fixed.
|
||||
|
||||
[builder]: @docroot@/store/derivation/index.md#builder
|
||||
|
||||
In concrete terms, the purpose of this feature is fetching fixed input data like source code from the network.
|
||||
For example, consider a family of "fetch URL" derivations.
|
||||
These derivations download files from given URL.
|
||||
To ensure that the downloaded file has not been modified, each derivation must also specify a cryptographic hash of the file.
|
||||
For example,
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"outputs: {
|
||||
"out": {
|
||||
"method": "nar",
|
||||
"hashAlgo": "sha256",
|
||||
"hash: "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465",
|
||||
},
|
||||
},
|
||||
"env": {
|
||||
"url": "http://ftp.gnu.org/pub/gnu/hello/hello-2.1.1.tar.gz"
|
||||
// ...
|
||||
},
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
It sometimes happens that the URL of the file changes,
|
||||
e.g., because servers are reorganised or no longer available.
|
||||
In these cases, we then must update the call to `fetchurl`, e.g.,
|
||||
|
||||
```diff
|
||||
"env": {
|
||||
- "url": "http://ftp.gnu.org/pub/gnu/hello/hello-2.1.1.tar.gz"
|
||||
+ "url": "ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz"
|
||||
// ...
|
||||
},
|
||||
```
|
||||
|
||||
If a `fetchurl` derivation's outputs were [input-addressed][input addressing], the output paths of the derivation and of *all derivations depending on it* would change.
|
||||
For instance, if we were to change the URL of the Glibc source distribution in Nixpkgs (a package on which almost all other packages depend on Linux) massive rebuilds would be needed.
|
||||
This is unfortunate for a change which we know cannot have a real effect as it propagates upwards through the dependency graph.
|
||||
|
||||
For content-addressed outputs (fixed or floating), on the other hand, the outputs' store path only depends on the derivation's name, data, and the `method` of the outputs' specs.
|
||||
The rest of the derivation is ignored for the purpose of computing the output path.
|
||||
|
||||
> **History Note**
|
||||
>
|
||||
> Fixed content-addressing is especially important both today and historically as the *only* form of content-addressing that is stabilized.
|
||||
> This is why the rationale above contrasts it with [input addressing].
|
||||
|
||||
## (Floating) Content-Addressing {#floating}
|
||||
|
||||
> **Warning**
|
||||
> This is part of an [experimental feature](@docroot@/development/experimental-features.md).
|
||||
>
|
||||
> To use this type of output addressing, you must enable the
|
||||
> [`ca-derivations`][xp-feature-ca-derivations] experimental feature.
|
||||
> For example, in [nix.conf](@docroot@/command-ref/conf-file.md) you could add:
|
||||
>
|
||||
> ```
|
||||
> extra-experimental-features = ca-derivations
|
||||
> ```
|
||||
|
||||
With this experimemental feature enabled, derivation outputs can also be content-addressed *without* fixing in the output spec what the outputs' content address must be.
|
||||
|
||||
### Purity
|
||||
|
||||
Because the derivation output is not fixed (just like with [input addressing]), the [builder] is not given any impure capabilities [^purity].
|
||||
|
||||
> **Configuration note**
|
||||
>
|
||||
> Strictly speaking, the extent to which sandboxing and deprivilaging is possible varies with the environment Nix is running in.
|
||||
> Nix's configuration settings indicate what level of sandboxing is required or enabled.
|
||||
> Builds of derivations will fail if they request an absence of sandboxing which is not allowed.
|
||||
> Builds of derivations will also fail if the level of sandboxing specified in the configure exceeds what is possible in the given environment.
|
||||
>
|
||||
> (The "environment", in this case, consists of attributes such as the Operating System Nix runs atop, along with the operating-system-specific privileges that Nix has been granted.
|
||||
> Because of how conventional operating systems like macos, Linux, etc. work, granting builders *fewer* privileges may ironically require that Nix be run with *more* privileges.)
|
||||
|
||||
That said, derivations producing floating content-addressed outputs may declare their builders as impure (like the builders of derivations producing fixed outputs).
|
||||
This is provisionally supported as part of the [`impure-derivations`][xp-feature-impure-derivations] experimental feature.
|
||||
|
||||
### Compatibility negotiation
|
||||
|
||||
Any derivation producing a floating content-addressed output implicitly requires the `ca-derivations` [system feature](@docroot@/command-ref/conf-file.md#conf-system-features).
|
||||
This prevents scheduling the building of the derivation on a machine without the experimental feature enabled.
|
||||
Even once the experimental feature is stabilized, this is still useful in order to be allow using remote builder running odler versions of Nix, or alternative implementations that do not support floating content addressing.
|
||||
|
||||
### Determinism
|
||||
|
||||
In the earlier [discussion of how self-references are handled when content-addressing store objects](@docroot@/store/store-object/content-address.html#self-references), it was pointed out that methods of producing store objects ought to be deterministic regardless of the choice of provisional store path.
|
||||
For store objects produced by manually inserting into the store to create a store object, the "method of production" is an informally concept --- formally, Nix has no idea where the store object came from, and content-addressing is crucial in order to ensure that the derivation is *intrinsically* tamper-proof.
|
||||
But for store objects produced by derivation, the "method is quite formal" --- the whole point of derivations is to be a formal notion of building, after all.
|
||||
In this case, we can elevate this informal property to a formal one.
|
||||
|
||||
A *deterministic* content-addressing derivation should produce outputs with the same content addresses:
|
||||
|
||||
1. Every time the builder is run
|
||||
|
||||
This is because either the builder is completely sandboxed, or because all any remaining impurities that leak inside the build sandbox are ignored by the builder and do not influence its behavior.
|
||||
|
||||
2. Regardless of the choice of any provisional outputs paths
|
||||
|
||||
Provisional store paths must be chosen for any output that has a self-reference.
|
||||
The choice of provisional store path can be thought of as an impurity, since it is an arbitrary choice.
|
||||
|
||||
If provisional outputs paths are deterministically chosen, we are in the first branch of part (1).
|
||||
The builder the data it produces based on it in arbitrary ways, but this gets us closer to [input addressing].
|
||||
Deterministically choosing the provisional path may be considered "complete sandboxing" by removing an impurity, but this is unsatisfactory
|
||||
|
||||
<!--
|
||||
|
||||
TODO
|
||||
(Both these points will be expanded-upon below.)
|
||||
|
||||
-->
|
||||
|
||||
If provisional outputs paths are randomly chosen, we are in the second branch of part (1).
|
||||
The builder *must* not let the random input affect the final outputs it produces, and multiple builds may be performed and the compared in order to ensure that this is in fact the case.
|
||||
|
||||
### Floating versus Fixed
|
||||
|
||||
While the distinction between content- and input-addressing is one of *mechanism*, the distinction between fixed and floating content addressing is more one of *policy*.
|
||||
A fixed output that passes its content address check is just like a floating output.
|
||||
It is only in the potential for that check to fail that they are different.
|
||||
|
||||
> **Design Note**
|
||||
>
|
||||
> In a future world where floating content-addressing is also stable, we in principle no longer need separate [fixed](#fixed) content-addressing.
|
||||
> Instead, we could always use floating content-addressing, and separately assert the precise value content address of a given store object to be used as an input (of another derivation).
|
||||
> A stand-alone assertion object of this sort is not yet implemented, but its possible creation is tracked in [Issue #11955](https://github.com/NixOS/nix/issues/11955).
|
||||
>
|
||||
> In the current version of Nix, fixed outputs which fail their hash check are still registered as valid store objects, just not registered as outputs of the derivation which produced them.
|
||||
> This is an optimization that means if the wrong output hash is specified in a derivation, and then the derivation is recreated with the right output hash, derivation does not need to be rebuilt --- avoiding downloading potentially large amounts of data twice.
|
||||
> This optimisation prefigures the design above:
|
||||
> If the output hash assertion was removed outside the derivation itself, Nix could additionally not only register that outputted store object like today, but could also make note that derivation did in fact successfully download some data.
|
||||
For example, for the "fetch URL" example above, making such a note is tantamount to recording what data is available at the time of download at the given URL.
|
||||
> It would only be when Nix subsequently tries to build something with that (refining our example) downloaded source code that Nix would be forced to check the output hash assertion, preventing it from e.g. building compromised malware.
|
||||
>
|
||||
> Recapping, Nix would
|
||||
>
|
||||
> 1. successfully download data
|
||||
> 2. insert that data into the store
|
||||
> 3. associate (presumably with some sort of expiration policy) the downloaded data with the derivation that downloaded it
|
||||
>
|
||||
> But only use the downloaded store object in subsequent derivations that depended upon the assertion if the assertion passed.
|
||||
>
|
||||
> This possible future extension is included to illustrate this distinction:
|
||||
|
||||
[input addressing]: ./input-address.md
|
||||
[xp-feature-ca-derivations]: @docroot@/development/experimental-features.md#xp-feature-ca-derivations
|
||||
[xp-feature-git-hashing]: @docroot@/development/experimental-features.md#xp-feature-git-hashing
|
||||
[xp-feature-impure-derivations]: @docroot@/development/experimental-features.md#xp-feature-impure-derivations
|
||||
97
doc/manual/source/store/derivation/outputs/index.md
Normal file
97
doc/manual/source/store/derivation/outputs/index.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# Derivation Outputs and Types of Derivations
|
||||
|
||||
As stated on the [main pages on derivations](../index.md#store-derivation),
|
||||
a derivation produces [store objects](@docroot@/store/store-object.md), which are known as the *outputs* of the derivation.
|
||||
Indeed, the entire point of derivations is to produce these outputs, and to reliably and reproducibly produce these derivations each time the derivation is run.
|
||||
|
||||
One of the parts of a derivation is its *outputs specification*, which specifies certain information about the outputs the derivation produces when run.
|
||||
The outputs specification is a map, from names to specifications for individual outputs.
|
||||
|
||||
## Output Names {#outputs}
|
||||
|
||||
Output names can be any string which is also a valid [store path](@docroot@/store/store-path.md) name.
|
||||
The name mapped to each output specification is not actually the name of the output.
|
||||
In the general case, the output store object has name `derivationName + "-" + outputSpecName`, not any other metadata about it.
|
||||
However, an output spec named "out" describes and output store object whose name is just the derivation name.
|
||||
|
||||
> **Example**
|
||||
>
|
||||
> A derivation is named `hello`, and has two outputs, `out`, and `dev`
|
||||
>
|
||||
> - The derivation's path will be: `/nix/store/<hash>-hello.drv`.
|
||||
>
|
||||
> - The store path of `out` will be: `/nix/store/<hash>-hello`.
|
||||
>
|
||||
> - The store path of `dev` will be: `/nix/store/<hash>-hello-dev`.
|
||||
|
||||
The outputs are the derivations are the [store objects](@docroot@/store/store-object.md) it is obligated to produce.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> The formal terminology here is somewhat at odds with everyday communication in the Nix community today.
|
||||
> "output" in casual usage tends to refer to either to the actual output store object, or the notional output spec, depending on context.
|
||||
>
|
||||
> For example "hello's `dev` output" means the store object referred to by the store path `/nix/store/<hash>-hello-dev`.
|
||||
> It is unusual to call this the "`hello-dev` output", even though `hello-dev` is the actual name of that store object.
|
||||
|
||||
## Types of output addressing
|
||||
|
||||
The main information contained in an output specification is how the derivation output is addressed.
|
||||
In particular, the specification decides:
|
||||
|
||||
- whether the output is [content-addressed](./content-address.md) or [input-addressed](./input-address.md)
|
||||
|
||||
- if the content is content-addressed, how is it content addressed
|
||||
|
||||
- if the content is content-addressed, [what is its content address](./content-address.md#fixed-content-addressing) (and thus what is its [store path])
|
||||
|
||||
## Types of derivations
|
||||
|
||||
The sections on each type of derivation output addressing ended up discussing other attributes of the derivation besides its outputs, such as purity, scheduling, determinism, etc.
|
||||
This is no concidence; for the type of a derivation is in fact one-for-one with the type of its outputs:
|
||||
|
||||
- A derivation that produces *xyz-addressed* outputs is an *xyz-addressing* derivations.
|
||||
|
||||
The rules for this are fairly concise:
|
||||
|
||||
- All the outputs must be of the same type / use the same addressing
|
||||
|
||||
- The derivation must have at least one output
|
||||
|
||||
- Additionally, if the outputs are fixed content-addressed, there must be exactly one output, whose specification is mapped from the name `out`.
|
||||
(The name `out` is special, according to the rules described above.
|
||||
Having only one output and calling its specification `out` means the single output is effectively anonymous; the store path just has the derivation name.)
|
||||
|
||||
(This is an arbitrary restriction that could be lifted.)
|
||||
|
||||
- The output is either *fixed* or *floating*, indicating whether the store path is known prior to building it.
|
||||
|
||||
- With fixed content-addressing it is fixed.
|
||||
|
||||
> A *fixed content-addressing* derivation is also called a *fixed-output derivation*, since that is the only currently-implemented form of fixed-output addressing
|
||||
|
||||
- With floating content-addressing or input-addressing it is floating.
|
||||
|
||||
> Thus, historically with Nix, with no experimental features enabled, *all* outputs are fixed.
|
||||
|
||||
- The derivation may be *pure* or *impure*, indicating what read access to the outside world the [builder](../index.md#builder) has.
|
||||
|
||||
- An input-addressing derivation *must* be pure.
|
||||
|
||||
> If it is impure, we would have a large problem, because an input-addressed derivation always produces outputs with the same paths.
|
||||
|
||||
|
||||
- A content-addressing derivation may be pure or impure
|
||||
|
||||
- If it is impure, it may be fixed (typical), or it may be floating if the additional [`impure-derivations`][xp-feature-impure-derivations] experimental feature is enabled.
|
||||
|
||||
- If it is pure, it must be floating.
|
||||
|
||||
- Pure, fixed content-addressing derivations are not supported
|
||||
|
||||
> There is no use for this forth combination.
|
||||
> The sole purpose of an output's store path being fixed is to support the derivation being impure.
|
||||
|
||||
[xp-feature-ca-derivations]: @docroot@/development/experimental-features.md#xp-feature-ca-derivations
|
||||
[xp-feature-git-hashing]: @docroot@/development/experimental-features.md#xp-feature-git-hashing
|
||||
[xp-feature-impure-derivations]: @docroot@/development/experimental-features.md#xp-feature-impure-derivations
|
||||
31
doc/manual/source/store/derivation/outputs/input-address.md
Normal file
31
doc/manual/source/store/derivation/outputs/input-address.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Input-addressing derivation outputs
|
||||
|
||||
[input addressing]: #input-addressing
|
||||
|
||||
"Input addressing" means the address the store object by the *way it was made* rather than *what it is*.
|
||||
That is to say, an input-addressed output's store path is a function not of the output itself, but of the derivation that produced it.
|
||||
Even if two store paths have the same contents, if they are produced in different ways, and one is input-addressed, then they will have different store paths, and thus guaranteed to not be the same store object.
|
||||
|
||||
<!---
|
||||
|
||||
### Modulo fixed-output derivations
|
||||
|
||||
**TODO hash derivation modulo.**
|
||||
|
||||
So how do we compute the hash part of the output path of a derivation?
|
||||
This is done by the function `hashDrv`, shown in Figure 5.10.
|
||||
It distinguishes between two cases.
|
||||
If the derivation is a fixed-output derivation, then it computes a hash over just the `outputHash` attributes.
|
||||
|
||||
If the derivation is not a fixed-output derivation, we replace each element in the derivation’s inputDrvs with the result of a call to `hashDrv` for that element.
|
||||
(The derivation at each store path in `inputDrvs` is converted from its on-disk ATerm representation back to a `StoreDrv` by the function `parseDrv`.) In essence, `hashDrv` partitions store derivations into equivalence classes, and for hashing purpose it replaces each store path in a derivation graph with its equivalence class.
|
||||
|
||||
The recursion in Figure 5.10 is inefficient:
|
||||
it will call itself once for each path by which a subderivation can be reached, i.e., `O(V k)` times for a derivation graph with `V` derivations and with out-degree of at most `k`.
|
||||
In the actual implementation, memoisation is used to reduce this to `O(V + E)` complexity for a graph with E edges.
|
||||
|
||||
-->
|
||||
|
||||
[xp-feature-ca-derivations]: @docroot@/development/experimental-features.md#xp-feature-ca-derivations
|
||||
[xp-feature-git-hashing]: @docroot@/development/experimental-features.md#xp-feature-git-hashing
|
||||
[xp-feature-impure-derivations]: @docroot@/development/experimental-features.md#xp-feature-impure-derivations
|
||||
@@ -46,7 +46,7 @@ be many different serialisations.
|
||||
For these reasons, Nix has its very own archive format—the Nix Archive (NAR) format,
|
||||
which is carefully designed to avoid the problems described above.
|
||||
|
||||
The exact specification of the Nix Archive format is in `protocols/nix-archive.md`
|
||||
The exact specification of the Nix Archive format is in [specified here](../../protocols/nix-archive.md).
|
||||
|
||||
## Content addressing File System Objects beyond a single serialisation pass
|
||||
|
||||
@@ -80,6 +80,7 @@ Thus, Git can encode some, but not all of Nix's "File System Objects", and this
|
||||
|
||||
In the future, we may support a Git-like hash for such file system objects, or we may adopt another Merkle DAG format which is capable of representing all Nix file system objects.
|
||||
|
||||
|
||||
[file system object]: ../file-system-object.md
|
||||
[store object]: ../store-object.md
|
||||
[xp-feature-git-hashing]: @docroot@/development/experimental-features.md#xp-feature-git-hashing
|
||||
|
||||
@@ -4,7 +4,64 @@ A Nix store is a collection of *store objects* with *references* between them.
|
||||
A store object consists of
|
||||
|
||||
- A [file system object](./file-system-object.md) as data
|
||||
- A set of [store paths](./store-path.md) as references to other store objects
|
||||
|
||||
- A set of [store paths](./store-path.md) as references to store objects
|
||||
|
||||
### References
|
||||
|
||||
Store objects can refer to both other store objects and themselves.
|
||||
References from a store object to itself are called *self-references*.
|
||||
|
||||
Store objects and their references form a directed graph, where the store objects are the vertices, and the references are the edges.
|
||||
In particular, the edge corresponding to a reference is from the store object that contains the reference, and to the store object that the store path (which is the reference) refers to.
|
||||
|
||||
References other than a self-reference must not form a cycle.
|
||||
The graph of references excluding self-references thus forms a [directed acyclic graph].
|
||||
|
||||
[directed acyclic graph]: @docroot@/glossary.md#gloss-directed acyclic graph
|
||||
|
||||
We can take the [transitive closure] of the references graph, which any pair of store objects have an edge not if there is a single reference from the first to the second, but a path of one or more references from the first to the second.
|
||||
The *requisites* of a store object are all store objects reachable by paths of references which start with given store object's references.
|
||||
|
||||
[transitive closure]: https://en.wikipedia.org/wiki/Transitive_closure
|
||||
|
||||
We can also take the [transpose graph] ofthe references graph, where we reverse the orientation of all edges.
|
||||
The *referrers* of a store object are the store objects that reference it.
|
||||
|
||||
[transpose graph]: https://en.wikipedia.org/wiki/Transpose_graph
|
||||
|
||||
One can also combine both concepts: taking the transitive closure of the tranposed references graph.
|
||||
The *referrers closure* of a store object are the store objects that can reach the given store object via paths of references.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Care must be taken to distinguish between the intrinsic and extrinsic properties of store objects.
|
||||
> We can create graphs from the store objects in a store, but the contents of the store is not, in general fixed, and may instead change over time.
|
||||
>
|
||||
> - The references of a store object --- the set of store paths called the references --- is a field of a store object, and thus intrinsic by definition.
|
||||
Regardless of what store contains the store object in question, and what else that store may or may not contain, the references are the same.
|
||||
>
|
||||
> - The requisites of a store object are almost intrinsic --- some store paths due not precisely refer to a unique single store object.
|
||||
> Exactly what store object is being referenced, and what in turn *its* references are, depends on the store in question.
|
||||
> Different stores that disagree.
|
||||
>
|
||||
> - The referrers of a store object are completely extrinsic, and depends solely on the store which contains that store object, not the store object itself.
|
||||
> Other store objects which refer to the store object in question may be added or removed from the store.
|
||||
|
||||
### Immutability
|
||||
|
||||
Store objects are [immutable](https://en.wikipedia.org/wiki/Immutable_object):
|
||||
Once created, they do not change until they are deleted.
|
||||
Once created, they do not change nor can any store object they reference be changed.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Stores which support atomically deleting multiple store objects allow more flexibility while still upholding this property.
|
||||
|
||||
### Closure property
|
||||
|
||||
A store can only contain a store object if it also contains all the store objects it refers to.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> The "closure property" isn't meant to prohibit, for example, [lazy loading](https://en.wikipedia.org/wiki/Lazy_loading) of store objects.
|
||||
> However, the "closure property" and immutability in conjunction imply that any such lazy loading ought to be deterministic.
|
||||
|
||||
@@ -24,13 +24,17 @@ For the full specification of the algorithms involved, see the [specification of
|
||||
|
||||
### File System Objects
|
||||
|
||||
With all currently supported store object content addressing methods, the file system object is always [content-addressed][fso-ca] first, and then that hash is incorporated into content address computation for the store object.
|
||||
With all currently-supported store object content-addressing methods, the file system object is always [content-addressed][fso-ca] first, and then that hash is incorporated into content address computation for the store object.
|
||||
|
||||
### References
|
||||
|
||||
#### References to other store objects
|
||||
|
||||
With all currently supported store object content addressing methods,
|
||||
other objects are referred to by their regular (string-encoded-) [store paths][Store Path].
|
||||
|
||||
#### Self-references
|
||||
|
||||
Self-references however cannot be referred to by their path, because we are in the midst of describing how to compute that path!
|
||||
|
||||
> The alternative would require finding as hash function fixed point, i.e. the solution to an equation in the form
|
||||
@@ -40,7 +44,28 @@ Self-references however cannot be referred to by their path, because we are in t
|
||||
> which is computationally infeasible.
|
||||
> As far as we know, this is equivalent to finding a hash collision.
|
||||
|
||||
Instead we just have a "has self reference" boolean, which will end up affecting the digest.
|
||||
Instead we have a "has self-reference" boolean, which ends up affecting the digest:
|
||||
In all currently-supported store object content-addressing methods, when hashing the file system object data, any occurrence of store object's own store path in the digested data is replaced with a [sentinel value](https://en.wikipedia.org/wiki/Sentinel_value).
|
||||
The hashes of these modified input streams are used instead.
|
||||
|
||||
When validating the content address of a store object after the fact, the above process works as written.
|
||||
However, when first creating the store object we don't know the store object's store path, as explained just above.
|
||||
We therefore, strictly speaking, do not know what value we will be replacing with the sentinel value in the inputs to hash functions.
|
||||
What instead happens is that the provisional store object --- the data from which we wish to create a store object --- is paired with a provisional "scratch" store path (that presumably was chosen when the data was created).
|
||||
That provisional store path is instead what is replaced with the sentinel value, rather than the final store object which we do not yet know.
|
||||
|
||||
> **Design note**
|
||||
>
|
||||
> It is an informal property of content-addressed store objects that the choice of provisional store path should not matter.
|
||||
> In other words, if a provisional store object is prepared in the same way except for the choice of provision store path, the provisional data need not be identical.
|
||||
> But, after the sentinel value is substituted in place of each provisional store object's provision store path, the final so-normalized data *should* be identical.
|
||||
>
|
||||
> If, conversely, the data after this normalization process is still different, we'll compute a different content-address.
|
||||
> The method of preparing the provisional self-referenced data has *failed* to be deterministic in the sense of not *leaking* the choice of provisional store path --- a choice which is supposed to be arbitrary --- into the final store object.
|
||||
>
|
||||
> This property is informal because at this stage, we are just described store objects, which have no formal notion of their origin.
|
||||
> Without such a formal notion, there is nothing to formally accuse of being insufficiently deterministic.
|
||||
> Where we cover [derivations](@docroot@/store/derivation/index.md), we will have a chance to make this a formal property, not of content-addressed store objects themselves, but of derivations that *produce* content-addressed store objects.
|
||||
|
||||
### Name and Store Directory
|
||||
|
||||
@@ -63,7 +88,7 @@ References are not supported: store objects with flat hashing *and* references c
|
||||
|
||||
This also uses the corresponding [Flat](../file-system-object/content-address.md#serial-flat) method of file system object content addressing.
|
||||
|
||||
References to other store objects are supported, but self references are not.
|
||||
References to other store objects are supported, but self-references are not.
|
||||
|
||||
This is the only store-object content-addressing method that is not named identically with a corresponding file system object method.
|
||||
It is somewhat obscure, mainly used for "drv files"
|
||||
@@ -74,7 +99,7 @@ Prefer another method if possible.
|
||||
|
||||
This uses the corresponding [Nix Archive](../file-system-object/content-address.md#serial-nix-archive) method of file system object content addressing.
|
||||
|
||||
References (to other store objects and self references alike) are supported so long as the hash algorithm is SHA-256, but not (neither kind) otherwise.
|
||||
References (to other store objects and self-references alike) are supported so long as the hash algorithm is SHA-256, but not (neither kind) otherwise.
|
||||
|
||||
### Git { #method-git }
|
||||
|
||||
|
||||
@@ -57,6 +57,9 @@ def recursive_replace(data: dict[str, t.Any], book_root: Path, search_path: Path
|
||||
).replace(
|
||||
'@docroot@',
|
||||
("../" * len(path_to_chapter.parent.parts) or "./")[:-1]
|
||||
).replace(
|
||||
'@_at_',
|
||||
'@'
|
||||
),
|
||||
sub_items = [
|
||||
recursive_replace(sub_item, book_root, search_path)
|
||||
|
||||
112
docker.nix
112
docker.nix
@@ -38,60 +38,58 @@ let
|
||||
]
|
||||
++ extraPkgs;
|
||||
|
||||
users =
|
||||
{
|
||||
users = {
|
||||
|
||||
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!)";
|
||||
};
|
||||
|
||||
}
|
||||
// lib.optionalAttrs (uid != 0) {
|
||||
"${uname}" = {
|
||||
uid = uid;
|
||||
shell = "${pkgs.bashInteractive}/bin/bash";
|
||||
home = "/home/${uname}";
|
||||
gid = gid;
|
||||
groups = [ "${gname}" ];
|
||||
description = "Nix user";
|
||||
};
|
||||
}
|
||||
// lib.listToAttrs (
|
||||
map (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;
|
||||
nixbld.gid = 30000;
|
||||
nobody.gid = 65534;
|
||||
}
|
||||
// lib.optionalAttrs (gid != 0) {
|
||||
"${gname}".gid = gid;
|
||||
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!)";
|
||||
};
|
||||
|
||||
}
|
||||
// lib.optionalAttrs (uid != 0) {
|
||||
"${uname}" = {
|
||||
uid = uid;
|
||||
shell = "${pkgs.bashInteractive}/bin/bash";
|
||||
home = "/home/${uname}";
|
||||
gid = gid;
|
||||
groups = [ "${gname}" ];
|
||||
description = "Nix user";
|
||||
};
|
||||
}
|
||||
// lib.listToAttrs (
|
||||
map (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;
|
||||
nixbld.gid = 30000;
|
||||
nobody.gid = 65534;
|
||||
}
|
||||
// lib.optionalAttrs (gid != 0) {
|
||||
"${gname}".gid = gid;
|
||||
};
|
||||
|
||||
userToPasswd = (
|
||||
k:
|
||||
{
|
||||
@@ -155,7 +153,7 @@ let
|
||||
|
||||
nixConfContents =
|
||||
(lib.concatStringsSep "\n" (
|
||||
lib.mapAttrsFlatten (
|
||||
lib.mapAttrsToList (
|
||||
n: v:
|
||||
let
|
||||
vStr = if builtins.isList v then lib.concatStringsSep " " v else v;
|
||||
@@ -173,7 +171,12 @@ let
|
||||
channel = pkgs.runCommand "channel-nixos" { inherit bundleNixpkgs; } ''
|
||||
mkdir $out
|
||||
if [ "$bundleNixpkgs" ]; then
|
||||
ln -s ${nixpkgs} $out/nixpkgs
|
||||
ln -s ${
|
||||
builtins.path {
|
||||
path = nixpkgs;
|
||||
name = "source";
|
||||
}
|
||||
} $out/nixpkgs
|
||||
echo "[]" > $out/manifest.nix
|
||||
fi
|
||||
'';
|
||||
@@ -275,7 +278,6 @@ let
|
||||
|
||||
ln -s ${profile} $out/nix/var/nix/profiles/default-1-link
|
||||
ln -s /nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default
|
||||
ln -s /nix/var/nix/profiles/default $out${userHome}/.nix-profile
|
||||
|
||||
ln -s ${channel} $out/nix/var/nix/profiles/per-user/${uname}/channels-1-link
|
||||
ln -s /nix/var/nix/profiles/per-user/${uname}/channels-1-link $out/nix/var/nix/profiles/per-user/${uname}/channels
|
||||
@@ -327,7 +329,7 @@ pkgs.dockerTools.buildLayeredImageWithNixDb {
|
||||
'';
|
||||
|
||||
config = {
|
||||
Cmd = [ "${userHome}/.nix-profile/bin/bash" ];
|
||||
Cmd = [ (lib.getExe pkgs.bashInteractive) ];
|
||||
User = "${toString uid}:${toString gid}";
|
||||
Env = [
|
||||
"USER=${uname}"
|
||||
|
||||
8
flake.lock
generated
8
flake.lock
generated
@@ -63,16 +63,16 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1734359947,
|
||||
"narHash": "sha256-1Noao/H+N8nFB4Beoy8fgwrcOQLVm9o4zKW1ODaqK9E=",
|
||||
"lastModified": 1756178832,
|
||||
"narHash": "sha256-O2CIn7HjZwEGqBrwu9EU76zlmA5dbmna7jL1XUmAId8=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "48d12d5e70ee91fe8481378e540433a7303dbf6a",
|
||||
"rev": "d98ce345cdab58477ca61855540999c86577d19d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "release-24.11",
|
||||
"ref": "nixos-25.05-small",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
|
||||
117
flake.nix
117
flake.nix
@@ -1,7 +1,7 @@
|
||||
{
|
||||
description = "The purely functional package manager";
|
||||
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/release-24.11";
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05-small";
|
||||
|
||||
inputs.nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2";
|
||||
inputs.nixpkgs-23-11.url = "github:NixOS/nixpkgs/a62e6edd6d5e1fa0329b8653c801147986f8d446";
|
||||
@@ -32,7 +32,7 @@
|
||||
let
|
||||
inherit (nixpkgs) lib;
|
||||
|
||||
officialRelease = false;
|
||||
officialRelease = true;
|
||||
|
||||
linux32BitSystems = [ "i686-linux" ];
|
||||
linux64BitSystems = [
|
||||
@@ -143,39 +143,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 =
|
||||
# The `2` suffix is here because otherwise it interferes with `nixVersions.latest`, which is used in daemon compat tests.
|
||||
nixComponents2 =
|
||||
lib.makeScopeWithSplicing'
|
||||
{
|
||||
inherit (final) splicePackages;
|
||||
inherit (final.nixDependencies) newScope;
|
||||
inherit (final.nixDependencies2) newScope;
|
||||
}
|
||||
{
|
||||
otherSplices = final.generateSplicesForMkScope "nixComponents";
|
||||
otherSplices = final.generateSplicesForMkScope "nixComponents2";
|
||||
f = import ./packaging/components.nix {
|
||||
inherit (final) lib;
|
||||
inherit officialRelease;
|
||||
pkgs = final;
|
||||
src = self;
|
||||
maintainers = [ ];
|
||||
};
|
||||
};
|
||||
|
||||
# The dependencies are in their own scope, so that they don't have to be
|
||||
# in Nixpkgs top level `pkgs` or `nixComponents`.
|
||||
nixDependencies =
|
||||
# in Nixpkgs top level `pkgs` or `nixComponents2`.
|
||||
# The `2` suffix is here because otherwise it interferes with `nixVersions.latest`, which is used in daemon compat tests.
|
||||
nixDependencies2 =
|
||||
lib.makeScopeWithSplicing'
|
||||
{
|
||||
inherit (final) splicePackages;
|
||||
inherit (final) newScope; # layered directly on pkgs, unlike nixComponents above
|
||||
inherit (final) newScope; # layered directly on pkgs, unlike nixComponents2 above
|
||||
}
|
||||
{
|
||||
otherSplices = final.generateSplicesForMkScope "nixDependencies";
|
||||
otherSplices = final.generateSplicesForMkScope "nixDependencies2";
|
||||
f = import ./packaging/dependencies.nix {
|
||||
inherit inputs stdenv;
|
||||
pkgs = final;
|
||||
};
|
||||
};
|
||||
|
||||
nix = final.nixComponents.nix-cli;
|
||||
nix = final.nixComponents2.nix-cli;
|
||||
|
||||
# See https://github.com/NixOS/nixpkgs/pull/214409
|
||||
# Remove when fixed in this flake's nixpkgs
|
||||
@@ -230,24 +233,28 @@
|
||||
This shouldn't build anything significant; just check that things
|
||||
(including derivations) are _set up_ correctly.
|
||||
*/
|
||||
packaging-overriding =
|
||||
let
|
||||
pkgs = nixpkgsFor.${system}.native;
|
||||
nix = self.packages.${system}.nix;
|
||||
in
|
||||
assert (nix.appendPatches [ pkgs.emptyFile ]).libs.nix-util.src.patches == [ pkgs.emptyFile ];
|
||||
if pkgs.stdenv.buildPlatform.isDarwin then
|
||||
lib.warn "packaging-overriding check currently disabled because of a permissions issue on macOS" pkgs.emptyFile
|
||||
else
|
||||
# If this fails, something might be wrong with how we've wired the scope,
|
||||
# or something could be broken in Nixpkgs.
|
||||
pkgs.testers.testEqualContents {
|
||||
assertion = "trivial patch does not change source contents";
|
||||
expected = "${./.}";
|
||||
actual =
|
||||
# Same for all components; nix-util is an arbitrary pick
|
||||
(nix.appendPatches [ pkgs.emptyFile ]).libs.nix-util.src;
|
||||
};
|
||||
# Disabled due to a bug in `testEqualContents` (see
|
||||
# https://github.com/NixOS/nix/issues/12690).
|
||||
/*
|
||||
packaging-overriding =
|
||||
let
|
||||
pkgs = nixpkgsFor.${system}.native;
|
||||
nix = self.packages.${system}.nix;
|
||||
in
|
||||
assert (nix.appendPatches [ pkgs.emptyFile ]).libs.nix-util.src.patches == [ pkgs.emptyFile ];
|
||||
if pkgs.stdenv.buildPlatform.isDarwin then
|
||||
lib.warn "packaging-overriding check currently disabled because of a permissions issue on macOS" pkgs.emptyFile
|
||||
else
|
||||
# If this fails, something might be wrong with how we've wired the scope,
|
||||
# or something could be broken in Nixpkgs.
|
||||
pkgs.testers.testEqualContents {
|
||||
assertion = "trivial patch does not change source contents";
|
||||
expected = "${./.}";
|
||||
actual =
|
||||
# Same for all components; nix-util is an arbitrary pick
|
||||
(nix.appendPatches [ pkgs.emptyFile ]).libs.nix-util.src;
|
||||
};
|
||||
*/
|
||||
}
|
||||
// (lib.optionalAttrs (builtins.elem system linux64BitSystems)) {
|
||||
dockerImage = self.hydraJobs.dockerImage.${system};
|
||||
@@ -263,18 +270,46 @@
|
||||
flatMapAttrs
|
||||
(
|
||||
{
|
||||
"" = nixpkgsFor.${system}.native;
|
||||
# Run all tests with UBSAN enabled. Running both with ubsan and
|
||||
# without doesn't seem to have much immediate benefit for doubling
|
||||
# the GHA CI workaround.
|
||||
#
|
||||
# TODO: Work toward enabling "address,undefined" if it seems feasible.
|
||||
# This would maybe require dropping Boost coroutines and ignoring intentional
|
||||
# memory leaks with detect_leaks=0.
|
||||
"" = rec {
|
||||
nixpkgs = nixpkgsFor.${system}.native;
|
||||
nixComponents = nixpkgs.nixComponents2.overrideScope (
|
||||
nixCompFinal: nixCompPrev: {
|
||||
mesonComponentOverrides = _finalAttrs: prevAttrs: {
|
||||
mesonFlags =
|
||||
(prevAttrs.mesonFlags or [ ])
|
||||
# TODO: Macos builds instrumented with ubsan take very long
|
||||
# to run functional tests.
|
||||
++ lib.optionals (!nixpkgs.stdenv.hostPlatform.isDarwin) [
|
||||
(lib.mesonOption "b_sanitize" "undefined")
|
||||
];
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
// 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}.native.pkgsStatic;
|
||||
# "static-" = {
|
||||
# nixpkgs = nixpkgsFor.${system}.native.pkgsStatic;
|
||||
# };
|
||||
}
|
||||
)
|
||||
(
|
||||
nixpkgsPrefix: nixpkgs:
|
||||
flatMapAttrs nixpkgs.nixComponents (
|
||||
nixpkgsPrefix:
|
||||
{
|
||||
nixpkgs,
|
||||
nixComponents ? nixpkgs.nixComponents2,
|
||||
}:
|
||||
flatMapAttrs nixComponents (
|
||||
pkgName: pkg:
|
||||
flatMapAttrs pkg.tests or { } (
|
||||
testName: test: {
|
||||
@@ -283,7 +318,7 @@
|
||||
)
|
||||
)
|
||||
// lib.optionalAttrs (nixpkgs.stdenv.hostPlatform == nixpkgs.stdenv.buildPlatform) {
|
||||
"${nixpkgsPrefix}nix-functional-tests" = nixpkgs.nixComponents.nix-functional-tests;
|
||||
"${nixpkgsPrefix}nix-functional-tests" = nixComponents.nix-functional-tests;
|
||||
}
|
||||
)
|
||||
// devFlake.checks.${system} or { }
|
||||
@@ -302,9 +337,9 @@
|
||||
binaryTarball = self.hydraJobs.binaryTarball.${system};
|
||||
# TODO probably should be `nix-cli`
|
||||
nix = self.packages.${system}.nix-everything;
|
||||
nix-manual = nixpkgsFor.${system}.native.nixComponents.nix-manual;
|
||||
nix-internal-api-docs = nixpkgsFor.${system}.native.nixComponents.nix-internal-api-docs;
|
||||
nix-external-api-docs = nixpkgsFor.${system}.native.nixComponents.nix-external-api-docs;
|
||||
nix-manual = nixpkgsFor.${system}.native.nixComponents2.nix-manual;
|
||||
nix-internal-api-docs = nixpkgsFor.${system}.native.nixComponents2.nix-internal-api-docs;
|
||||
nix-external-api-docs = nixpkgsFor.${system}.native.nixComponents2.nix-external-api-docs;
|
||||
}
|
||||
# We need to flatten recursive attribute sets of derivations to pass `flake check`.
|
||||
//
|
||||
@@ -356,9 +391,9 @@
|
||||
}:
|
||||
{
|
||||
# These attributes go right into `packages.<system>`.
|
||||
"${pkgName}" = nixpkgsFor.${system}.native.nixComponents.${pkgName};
|
||||
"${pkgName}-static" = nixpkgsFor.${system}.native.pkgsStatic.nixComponents.${pkgName};
|
||||
"${pkgName}-llvm" = nixpkgsFor.${system}.native.pkgsLLVM.nixComponents.${pkgName};
|
||||
"${pkgName}" = nixpkgsFor.${system}.native.nixComponents2.${pkgName};
|
||||
"${pkgName}-static" = nixpkgsFor.${system}.native.pkgsStatic.nixComponents2.${pkgName};
|
||||
"${pkgName}-llvm" = nixpkgsFor.${system}.native.pkgsLLVM.nixComponents2.${pkgName};
|
||||
}
|
||||
// lib.optionalAttrs supportsCross (
|
||||
flatMapAttrs (lib.genAttrs crossSystems (_: { })) (
|
||||
@@ -366,7 +401,7 @@
|
||||
{ }:
|
||||
{
|
||||
# These attributes go right into `packages.<system>`.
|
||||
"${pkgName}-${crossSystem}" = nixpkgsFor.${system}.cross.${crossSystem}.nixComponents.${pkgName};
|
||||
"${pkgName}-${crossSystem}" = nixpkgsFor.${system}.cross.${crossSystem}.nixComponents2.${pkgName};
|
||||
}
|
||||
)
|
||||
)
|
||||
@@ -376,7 +411,7 @@
|
||||
{
|
||||
# These attributes go right into `packages.<system>`.
|
||||
"${pkgName}-${stdenvName}" =
|
||||
nixpkgsFor.${system}.nativeForStdenv.${stdenvName}.nixComponents.${pkgName};
|
||||
nixpkgsFor.${system}.nativeForStdenv.${stdenvName}.nixComponents2.${pkgName};
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
@@ -145,5 +145,12 @@
|
||||
"thebenmachine+git@gmail.com": "bmillwood",
|
||||
"leandro@kip93.net": "kip93",
|
||||
"hello@briancamacho.me": "b-camacho",
|
||||
"bcamacho@anduril.com": "bcamacho2"
|
||||
"bcamacho@anduril.com": "bcamacho2",
|
||||
"oldshensheep@gmail.com": "oldshensheep",
|
||||
"thomasmiedema@gmail.com": "thomie",
|
||||
"xokdvium@proton.me": "xokdvium",
|
||||
"kaction@disroot.org": "KAction",
|
||||
"serenity@kaction.cc": null,
|
||||
"dev@erik.work": "Kirens",
|
||||
"felix@alternativebit.fr": "picnoir"
|
||||
}
|
||||
@@ -129,5 +129,9 @@
|
||||
"SomeoneSerge": "Someone",
|
||||
"b-camacho": "Brian Camacho",
|
||||
"MaxHearnden": null,
|
||||
"kip93": "Leandro Emmanuel Reina Kiperman"
|
||||
"kip93": "Leandro Emmanuel Reina Kiperman",
|
||||
"oldshensheep": "Ruby Rose",
|
||||
"KAction": "Dmitry Bogatov",
|
||||
"thomie": "Thomas Miedema",
|
||||
"Kirens": "Erik Nygren"
|
||||
}
|
||||
@@ -77,470 +77,6 @@
|
||||
# Don't format vendored code
|
||||
''^doc/manual/redirects\.js$''
|
||||
''^doc/manual/theme/highlight\.js$''
|
||||
|
||||
# We haven't applied formatting to these files yet
|
||||
''^doc/manual/redirects\.js$''
|
||||
''^doc/manual/theme/highlight\.js$''
|
||||
''^precompiled-headers\.h$''
|
||||
''^src/build-remote/build-remote\.cc$''
|
||||
''^src/libcmd/built-path\.cc$''
|
||||
''^src/libcmd/built-path\.hh$''
|
||||
''^src/libcmd/common-eval-args\.cc$''
|
||||
''^src/libcmd/common-eval-args\.hh$''
|
||||
''^src/libcmd/editor-for\.cc$''
|
||||
''^src/libcmd/installable-attr-path\.cc$''
|
||||
''^src/libcmd/installable-attr-path\.hh$''
|
||||
''^src/libcmd/installable-derived-path\.cc$''
|
||||
''^src/libcmd/installable-derived-path\.hh$''
|
||||
''^src/libcmd/installable-flake\.cc$''
|
||||
''^src/libcmd/installable-flake\.hh$''
|
||||
''^src/libcmd/installable-value\.cc$''
|
||||
''^src/libcmd/installable-value\.hh$''
|
||||
''^src/libcmd/installables\.cc$''
|
||||
''^src/libcmd/installables\.hh$''
|
||||
''^src/libcmd/legacy\.hh$''
|
||||
''^src/libcmd/markdown\.cc$''
|
||||
''^src/libcmd/misc-store-flags\.cc$''
|
||||
''^src/libcmd/repl-interacter\.cc$''
|
||||
''^src/libcmd/repl-interacter\.hh$''
|
||||
''^src/libcmd/repl\.cc$''
|
||||
''^src/libcmd/repl\.hh$''
|
||||
''^src/libexpr-c/nix_api_expr\.cc$''
|
||||
''^src/libexpr-c/nix_api_external\.cc$''
|
||||
''^src/libexpr/attr-path\.cc$''
|
||||
''^src/libexpr/attr-path\.hh$''
|
||||
''^src/libexpr/attr-set\.cc$''
|
||||
''^src/libexpr/attr-set\.hh$''
|
||||
''^src/libexpr/eval-cache\.cc$''
|
||||
''^src/libexpr/eval-cache\.hh$''
|
||||
''^src/libexpr/eval-error\.cc$''
|
||||
''^src/libexpr/eval-inline\.hh$''
|
||||
''^src/libexpr/eval-settings\.cc$''
|
||||
''^src/libexpr/eval-settings\.hh$''
|
||||
''^src/libexpr/eval\.cc$''
|
||||
''^src/libexpr/eval\.hh$''
|
||||
''^src/libexpr/function-trace\.cc$''
|
||||
''^src/libexpr/gc-small-vector\.hh$''
|
||||
''^src/libexpr/get-drvs\.cc$''
|
||||
''^src/libexpr/get-drvs\.hh$''
|
||||
''^src/libexpr/json-to-value\.cc$''
|
||||
''^src/libexpr/nixexpr\.cc$''
|
||||
''^src/libexpr/nixexpr\.hh$''
|
||||
''^src/libexpr/parser-state\.hh$''
|
||||
''^src/libexpr/pos-table\.hh$''
|
||||
''^src/libexpr/primops\.cc$''
|
||||
''^src/libexpr/primops\.hh$''
|
||||
''^src/libexpr/primops/context\.cc$''
|
||||
''^src/libexpr/primops/fetchClosure\.cc$''
|
||||
''^src/libexpr/primops/fetchMercurial\.cc$''
|
||||
''^src/libexpr/primops/fetchTree\.cc$''
|
||||
''^src/libexpr/primops/fromTOML\.cc$''
|
||||
''^src/libexpr/print-ambiguous\.cc$''
|
||||
''^src/libexpr/print-ambiguous\.hh$''
|
||||
''^src/libexpr/print-options\.hh$''
|
||||
''^src/libexpr/print\.cc$''
|
||||
''^src/libexpr/print\.hh$''
|
||||
''^src/libexpr/search-path\.cc$''
|
||||
''^src/libexpr/symbol-table\.hh$''
|
||||
''^src/libexpr/value-to-json\.cc$''
|
||||
''^src/libexpr/value-to-json\.hh$''
|
||||
''^src/libexpr/value-to-xml\.cc$''
|
||||
''^src/libexpr/value-to-xml\.hh$''
|
||||
''^src/libexpr/value\.hh$''
|
||||
''^src/libexpr/value/context\.cc$''
|
||||
''^src/libexpr/value/context\.hh$''
|
||||
''^src/libfetchers/attrs\.cc$''
|
||||
''^src/libfetchers/cache\.cc$''
|
||||
''^src/libfetchers/cache\.hh$''
|
||||
''^src/libfetchers/fetch-settings\.cc$''
|
||||
''^src/libfetchers/fetch-settings\.hh$''
|
||||
''^src/libfetchers/fetch-to-store\.cc$''
|
||||
''^src/libfetchers/fetchers\.cc$''
|
||||
''^src/libfetchers/fetchers\.hh$''
|
||||
''^src/libfetchers/filtering-source-accessor\.cc$''
|
||||
''^src/libfetchers/filtering-source-accessor\.hh$''
|
||||
''^src/libfetchers/fs-source-accessor\.cc$''
|
||||
''^src/libfetchers/fs-source-accessor\.hh$''
|
||||
''^src/libfetchers/git-utils\.cc$''
|
||||
''^src/libfetchers/git-utils\.hh$''
|
||||
''^src/libfetchers/github\.cc$''
|
||||
''^src/libfetchers/indirect\.cc$''
|
||||
''^src/libfetchers/memory-source-accessor\.cc$''
|
||||
''^src/libfetchers/path\.cc$''
|
||||
''^src/libfetchers/registry\.cc$''
|
||||
''^src/libfetchers/registry\.hh$''
|
||||
''^src/libfetchers/tarball\.cc$''
|
||||
''^src/libfetchers/tarball\.hh$''
|
||||
''^src/libfetchers/git\.cc$''
|
||||
''^src/libfetchers/mercurial\.cc$''
|
||||
''^src/libflake/flake/config\.cc$''
|
||||
''^src/libflake/flake/flake\.cc$''
|
||||
''^src/libflake/flake/flake\.hh$''
|
||||
''^src/libflake/flake/flakeref\.cc$''
|
||||
''^src/libflake/flake/flakeref\.hh$''
|
||||
''^src/libflake/flake/lockfile\.cc$''
|
||||
''^src/libflake/flake/lockfile\.hh$''
|
||||
''^src/libflake/flake/url-name\.cc$''
|
||||
''^src/libmain/common-args\.cc$''
|
||||
''^src/libmain/common-args\.hh$''
|
||||
''^src/libmain/loggers\.cc$''
|
||||
''^src/libmain/loggers\.hh$''
|
||||
''^src/libmain/progress-bar\.cc$''
|
||||
''^src/libmain/shared\.cc$''
|
||||
''^src/libmain/shared\.hh$''
|
||||
''^src/libmain/unix/stack\.cc$''
|
||||
''^src/libstore/binary-cache-store\.cc$''
|
||||
''^src/libstore/binary-cache-store\.hh$''
|
||||
''^src/libstore/build-result\.hh$''
|
||||
''^src/libstore/builtins\.hh$''
|
||||
''^src/libstore/builtins/buildenv\.cc$''
|
||||
''^src/libstore/builtins/buildenv\.hh$''
|
||||
''^src/libstore/common-protocol-impl\.hh$''
|
||||
''^src/libstore/common-protocol\.cc$''
|
||||
''^src/libstore/common-protocol\.hh$''
|
||||
''^src/libstore/common-ssh-store-config\.hh$''
|
||||
''^src/libstore/content-address\.cc$''
|
||||
''^src/libstore/content-address\.hh$''
|
||||
''^src/libstore/daemon\.cc$''
|
||||
''^src/libstore/daemon\.hh$''
|
||||
''^src/libstore/derivations\.cc$''
|
||||
''^src/libstore/derivations\.hh$''
|
||||
''^src/libstore/derived-path-map\.cc$''
|
||||
''^src/libstore/derived-path-map\.hh$''
|
||||
''^src/libstore/derived-path\.cc$''
|
||||
''^src/libstore/derived-path\.hh$''
|
||||
''^src/libstore/downstream-placeholder\.cc$''
|
||||
''^src/libstore/downstream-placeholder\.hh$''
|
||||
''^src/libstore/dummy-store\.cc$''
|
||||
''^src/libstore/export-import\.cc$''
|
||||
''^src/libstore/filetransfer\.cc$''
|
||||
''^src/libstore/filetransfer\.hh$''
|
||||
''^src/libstore/gc-store\.hh$''
|
||||
''^src/libstore/globals\.cc$''
|
||||
''^src/libstore/globals\.hh$''
|
||||
''^src/libstore/http-binary-cache-store\.cc$''
|
||||
''^src/libstore/legacy-ssh-store\.cc$''
|
||||
''^src/libstore/legacy-ssh-store\.hh$''
|
||||
''^src/libstore/length-prefixed-protocol-helper\.hh$''
|
||||
''^src/libstore/linux/personality\.cc$''
|
||||
''^src/libstore/linux/personality\.hh$''
|
||||
''^src/libstore/local-binary-cache-store\.cc$''
|
||||
''^src/libstore/local-fs-store\.cc$''
|
||||
''^src/libstore/local-fs-store\.hh$''
|
||||
''^src/libstore/log-store\.cc$''
|
||||
''^src/libstore/log-store\.hh$''
|
||||
''^src/libstore/machines\.cc$''
|
||||
''^src/libstore/machines\.hh$''
|
||||
''^src/libstore/make-content-addressed\.cc$''
|
||||
''^src/libstore/make-content-addressed\.hh$''
|
||||
''^src/libstore/misc\.cc$''
|
||||
''^src/libstore/names\.cc$''
|
||||
''^src/libstore/names\.hh$''
|
||||
''^src/libstore/nar-accessor\.cc$''
|
||||
''^src/libstore/nar-accessor\.hh$''
|
||||
''^src/libstore/nar-info-disk-cache\.cc$''
|
||||
''^src/libstore/nar-info-disk-cache\.hh$''
|
||||
''^src/libstore/nar-info\.cc$''
|
||||
''^src/libstore/nar-info\.hh$''
|
||||
''^src/libstore/outputs-spec\.cc$''
|
||||
''^src/libstore/outputs-spec\.hh$''
|
||||
''^src/libstore/parsed-derivations\.cc$''
|
||||
''^src/libstore/path-info\.cc$''
|
||||
''^src/libstore/path-info\.hh$''
|
||||
''^src/libstore/path-references\.cc$''
|
||||
''^src/libstore/path-regex\.hh$''
|
||||
''^src/libstore/path-with-outputs\.cc$''
|
||||
''^src/libstore/path\.cc$''
|
||||
''^src/libstore/path\.hh$''
|
||||
''^src/libstore/pathlocks\.cc$''
|
||||
''^src/libstore/pathlocks\.hh$''
|
||||
''^src/libstore/profiles\.cc$''
|
||||
''^src/libstore/profiles\.hh$''
|
||||
''^src/libstore/realisation\.cc$''
|
||||
''^src/libstore/realisation\.hh$''
|
||||
''^src/libstore/remote-fs-accessor\.cc$''
|
||||
''^src/libstore/remote-fs-accessor\.hh$''
|
||||
''^src/libstore/remote-store-connection\.hh$''
|
||||
''^src/libstore/remote-store\.cc$''
|
||||
''^src/libstore/remote-store\.hh$''
|
||||
''^src/libstore/s3-binary-cache-store\.cc$''
|
||||
''^src/libstore/s3\.hh$''
|
||||
''^src/libstore/serve-protocol-impl\.cc$''
|
||||
''^src/libstore/serve-protocol-impl\.hh$''
|
||||
''^src/libstore/serve-protocol\.cc$''
|
||||
''^src/libstore/serve-protocol\.hh$''
|
||||
''^src/libstore/sqlite\.cc$''
|
||||
''^src/libstore/sqlite\.hh$''
|
||||
''^src/libstore/ssh-store\.cc$''
|
||||
''^src/libstore/ssh\.cc$''
|
||||
''^src/libstore/ssh\.hh$''
|
||||
''^src/libstore/store-api\.cc$''
|
||||
''^src/libstore/store-api\.hh$''
|
||||
''^src/libstore/store-dir-config\.hh$''
|
||||
''^src/libstore/build/derivation-goal\.cc$''
|
||||
''^src/libstore/build/derivation-goal\.hh$''
|
||||
''^src/libstore/build/drv-output-substitution-goal\.cc$''
|
||||
''^src/libstore/build/drv-output-substitution-goal\.hh$''
|
||||
''^src/libstore/build/entry-points\.cc$''
|
||||
''^src/libstore/build/goal\.cc$''
|
||||
''^src/libstore/build/goal\.hh$''
|
||||
''^src/libstore/unix/build/hook-instance\.cc$''
|
||||
''^src/libstore/unix/build/local-derivation-goal\.cc$''
|
||||
''^src/libstore/unix/build/local-derivation-goal\.hh$''
|
||||
''^src/libstore/build/substitution-goal\.cc$''
|
||||
''^src/libstore/build/substitution-goal\.hh$''
|
||||
''^src/libstore/build/worker\.cc$''
|
||||
''^src/libstore/build/worker\.hh$''
|
||||
''^src/libstore/builtins/fetchurl\.cc$''
|
||||
''^src/libstore/builtins/unpack-channel\.cc$''
|
||||
''^src/libstore/gc\.cc$''
|
||||
''^src/libstore/local-overlay-store\.cc$''
|
||||
''^src/libstore/local-overlay-store\.hh$''
|
||||
''^src/libstore/local-store\.cc$''
|
||||
''^src/libstore/local-store\.hh$''
|
||||
''^src/libstore/unix/user-lock\.cc$''
|
||||
''^src/libstore/unix/user-lock\.hh$''
|
||||
''^src/libstore/optimise-store\.cc$''
|
||||
''^src/libstore/unix/pathlocks\.cc$''
|
||||
''^src/libstore/posix-fs-canonicalise\.cc$''
|
||||
''^src/libstore/posix-fs-canonicalise\.hh$''
|
||||
''^src/libstore/uds-remote-store\.cc$''
|
||||
''^src/libstore/uds-remote-store\.hh$''
|
||||
''^src/libstore/windows/build\.cc$''
|
||||
''^src/libstore/worker-protocol-impl\.hh$''
|
||||
''^src/libstore/worker-protocol\.cc$''
|
||||
''^src/libstore/worker-protocol\.hh$''
|
||||
''^src/libutil-c/nix_api_util_internal\.h$''
|
||||
''^src/libutil/archive\.cc$''
|
||||
''^src/libutil/archive\.hh$''
|
||||
''^src/libutil/args\.cc$''
|
||||
''^src/libutil/args\.hh$''
|
||||
''^src/libutil/args/root\.hh$''
|
||||
''^src/libutil/callback\.hh$''
|
||||
''^src/libutil/canon-path\.cc$''
|
||||
''^src/libutil/canon-path\.hh$''
|
||||
''^src/libutil/chunked-vector\.hh$''
|
||||
''^src/libutil/closure\.hh$''
|
||||
''^src/libutil/comparator\.hh$''
|
||||
''^src/libutil/compute-levels\.cc$''
|
||||
''^src/libutil/config-impl\.hh$''
|
||||
''^src/libutil/config\.cc$''
|
||||
''^src/libutil/config\.hh$''
|
||||
''^src/libutil/current-process\.cc$''
|
||||
''^src/libutil/current-process\.hh$''
|
||||
''^src/libutil/english\.cc$''
|
||||
''^src/libutil/english\.hh$''
|
||||
''^src/libutil/error\.cc$''
|
||||
''^src/libutil/error\.hh$''
|
||||
''^src/libutil/exit\.hh$''
|
||||
''^src/libutil/experimental-features\.cc$''
|
||||
''^src/libutil/experimental-features\.hh$''
|
||||
''^src/libutil/file-content-address\.cc$''
|
||||
''^src/libutil/file-content-address\.hh$''
|
||||
''^src/libutil/file-descriptor\.cc$''
|
||||
''^src/libutil/file-descriptor\.hh$''
|
||||
''^src/libutil/file-path-impl\.hh$''
|
||||
''^src/libutil/file-path\.hh$''
|
||||
''^src/libutil/file-system\.cc$''
|
||||
''^src/libutil/file-system\.hh$''
|
||||
''^src/libutil/finally\.hh$''
|
||||
''^src/libutil/fmt\.hh$''
|
||||
''^src/libutil/fs-sink\.cc$''
|
||||
''^src/libutil/fs-sink\.hh$''
|
||||
''^src/libutil/git\.cc$''
|
||||
''^src/libutil/git\.hh$''
|
||||
''^src/libutil/hash\.cc$''
|
||||
''^src/libutil/hash\.hh$''
|
||||
''^src/libutil/hilite\.cc$''
|
||||
''^src/libutil/hilite\.hh$''
|
||||
''^src/libutil/source-accessor\.hh$''
|
||||
''^src/libutil/json-impls\.hh$''
|
||||
''^src/libutil/json-utils\.cc$''
|
||||
''^src/libutil/json-utils\.hh$''
|
||||
''^src/libutil/linux/cgroup\.cc$''
|
||||
''^src/libutil/linux/namespaces\.cc$''
|
||||
''^src/libutil/logging\.cc$''
|
||||
''^src/libutil/logging\.hh$''
|
||||
''^src/libutil/lru-cache\.hh$''
|
||||
''^src/libutil/memory-source-accessor\.cc$''
|
||||
''^src/libutil/memory-source-accessor\.hh$''
|
||||
''^src/libutil/pool\.hh$''
|
||||
''^src/libutil/position\.cc$''
|
||||
''^src/libutil/position\.hh$''
|
||||
''^src/libutil/posix-source-accessor\.cc$''
|
||||
''^src/libutil/posix-source-accessor\.hh$''
|
||||
''^src/libutil/processes\.hh$''
|
||||
''^src/libutil/ref\.hh$''
|
||||
''^src/libutil/references\.cc$''
|
||||
''^src/libutil/references\.hh$''
|
||||
''^src/libutil/regex-combinators\.hh$''
|
||||
''^src/libutil/serialise\.cc$''
|
||||
''^src/libutil/serialise\.hh$''
|
||||
''^src/libutil/signals\.hh$''
|
||||
''^src/libutil/signature/local-keys\.cc$''
|
||||
''^src/libutil/signature/local-keys\.hh$''
|
||||
''^src/libutil/signature/signer\.cc$''
|
||||
''^src/libutil/signature/signer\.hh$''
|
||||
''^src/libutil/source-accessor\.cc$''
|
||||
''^src/libutil/source-accessor\.hh$''
|
||||
''^src/libutil/source-path\.cc$''
|
||||
''^src/libutil/source-path\.hh$''
|
||||
''^src/libutil/split\.hh$''
|
||||
''^src/libutil/suggestions\.cc$''
|
||||
''^src/libutil/suggestions\.hh$''
|
||||
''^src/libutil/sync\.hh$''
|
||||
''^src/libutil/terminal\.cc$''
|
||||
''^src/libutil/terminal\.hh$''
|
||||
''^src/libutil/thread-pool\.cc$''
|
||||
''^src/libutil/thread-pool\.hh$''
|
||||
''^src/libutil/topo-sort\.hh$''
|
||||
''^src/libutil/types\.hh$''
|
||||
''^src/libutil/unix/file-descriptor\.cc$''
|
||||
''^src/libutil/unix/file-path\.cc$''
|
||||
''^src/libutil/unix/monitor-fd\.hh$''
|
||||
''^src/libutil/unix/processes\.cc$''
|
||||
''^src/libutil/unix/signals-impl\.hh$''
|
||||
''^src/libutil/unix/signals\.cc$''
|
||||
''^src/libutil/unix-domain-socket\.cc$''
|
||||
''^src/libutil/unix/users\.cc$''
|
||||
''^src/libutil/url-parts\.hh$''
|
||||
''^src/libutil/url\.cc$''
|
||||
''^src/libutil/url\.hh$''
|
||||
''^src/libutil/users\.cc$''
|
||||
''^src/libutil/users\.hh$''
|
||||
''^src/libutil/util\.cc$''
|
||||
''^src/libutil/util\.hh$''
|
||||
''^src/libutil/variant-wrapper\.hh$''
|
||||
''^src/libutil/widecharwidth/widechar_width\.h$'' # vendored source
|
||||
''^src/libutil/windows/file-descriptor\.cc$''
|
||||
''^src/libutil/windows/file-path\.cc$''
|
||||
''^src/libutil/windows/processes\.cc$''
|
||||
''^src/libutil/windows/users\.cc$''
|
||||
''^src/libutil/windows/windows-error\.cc$''
|
||||
''^src/libutil/windows/windows-error\.hh$''
|
||||
''^src/libutil/xml-writer\.cc$''
|
||||
''^src/libutil/xml-writer\.hh$''
|
||||
''^src/nix-build/nix-build\.cc$''
|
||||
''^src/nix-channel/nix-channel\.cc$''
|
||||
''^src/nix-collect-garbage/nix-collect-garbage\.cc$''
|
||||
''^src/nix-env/buildenv.nix$''
|
||||
''^src/nix-env/nix-env\.cc$''
|
||||
''^src/nix-env/user-env\.cc$''
|
||||
''^src/nix-env/user-env\.hh$''
|
||||
''^src/nix-instantiate/nix-instantiate\.cc$''
|
||||
''^src/nix-store/dotgraph\.cc$''
|
||||
''^src/nix-store/graphml\.cc$''
|
||||
''^src/nix-store/nix-store\.cc$''
|
||||
''^src/nix/add-to-store\.cc$''
|
||||
''^src/nix/app\.cc$''
|
||||
''^src/nix/build\.cc$''
|
||||
''^src/nix/bundle\.cc$''
|
||||
''^src/nix/cat\.cc$''
|
||||
''^src/nix/config-check\.cc$''
|
||||
''^src/nix/config\.cc$''
|
||||
''^src/nix/copy\.cc$''
|
||||
''^src/nix/derivation-add\.cc$''
|
||||
''^src/nix/derivation-show\.cc$''
|
||||
''^src/nix/derivation\.cc$''
|
||||
''^src/nix/develop\.cc$''
|
||||
''^src/nix/diff-closures\.cc$''
|
||||
''^src/nix/dump-path\.cc$''
|
||||
''^src/nix/edit\.cc$''
|
||||
''^src/nix/eval\.cc$''
|
||||
''^src/nix/flake\.cc$''
|
||||
''^src/nix/fmt\.cc$''
|
||||
''^src/nix/hash\.cc$''
|
||||
''^src/nix/log\.cc$''
|
||||
''^src/nix/ls\.cc$''
|
||||
''^src/nix/main\.cc$''
|
||||
''^src/nix/make-content-addressed\.cc$''
|
||||
''^src/nix/nar\.cc$''
|
||||
''^src/nix/optimise-store\.cc$''
|
||||
''^src/nix/path-from-hash-part\.cc$''
|
||||
''^src/nix/path-info\.cc$''
|
||||
''^src/nix/prefetch\.cc$''
|
||||
''^src/nix/profile\.cc$''
|
||||
''^src/nix/realisation\.cc$''
|
||||
''^src/nix/registry\.cc$''
|
||||
''^src/nix/repl\.cc$''
|
||||
''^src/nix/run\.cc$''
|
||||
''^src/nix/run\.hh$''
|
||||
''^src/nix/search\.cc$''
|
||||
''^src/nix/sigs\.cc$''
|
||||
''^src/nix/store-copy-log\.cc$''
|
||||
''^src/nix/store-delete\.cc$''
|
||||
''^src/nix/store-gc\.cc$''
|
||||
''^src/nix/store-info\.cc$''
|
||||
''^src/nix/store-repair\.cc$''
|
||||
''^src/nix/store\.cc$''
|
||||
''^src/nix/unix/daemon\.cc$''
|
||||
''^src/nix/upgrade-nix\.cc$''
|
||||
''^src/nix/verify\.cc$''
|
||||
''^src/nix/why-depends\.cc$''
|
||||
|
||||
''^tests/functional/plugins/plugintest\.cc''
|
||||
''^tests/functional/test-libstoreconsumer/main\.cc''
|
||||
''^tests/nixos/ca-fd-leak/sender\.c''
|
||||
''^tests/nixos/ca-fd-leak/smuggler\.c''
|
||||
''^tests/nixos/user-sandboxing/attacker\.c''
|
||||
''^src/libexpr-test-support/tests/libexpr\.hh''
|
||||
''^src/libexpr-test-support/tests/value/context\.cc''
|
||||
''^src/libexpr-test-support/tests/value/context\.hh''
|
||||
''^src/libexpr-tests/derived-path\.cc''
|
||||
''^src/libexpr-tests/error_traces\.cc''
|
||||
''^src/libexpr-tests/eval\.cc''
|
||||
''^src/libexpr-tests/json\.cc''
|
||||
''^src/libexpr-tests/main\.cc''
|
||||
''^src/libexpr-tests/primops\.cc''
|
||||
''^src/libexpr-tests/search-path\.cc''
|
||||
''^src/libexpr-tests/trivial\.cc''
|
||||
''^src/libexpr-tests/value/context\.cc''
|
||||
''^src/libexpr-tests/value/print\.cc''
|
||||
''^src/libfetchers-tests/public-key\.cc''
|
||||
''^src/libflake-tests/flakeref\.cc''
|
||||
''^src/libflake-tests/url-name\.cc''
|
||||
''^src/libstore-test-support/tests/derived-path\.cc''
|
||||
''^src/libstore-test-support/tests/derived-path\.hh''
|
||||
''^src/libstore-test-support/tests/nix_api_store\.hh''
|
||||
''^src/libstore-test-support/tests/outputs-spec\.cc''
|
||||
''^src/libstore-test-support/tests/outputs-spec\.hh''
|
||||
''^src/libstore-test-support/tests/path\.cc''
|
||||
''^src/libstore-test-support/tests/path\.hh''
|
||||
''^src/libstore-test-support/tests/protocol\.hh''
|
||||
''^src/libstore-tests/common-protocol\.cc''
|
||||
''^src/libstore-tests/content-address\.cc''
|
||||
''^src/libstore-tests/derivation\.cc''
|
||||
''^src/libstore-tests/derived-path\.cc''
|
||||
''^src/libstore-tests/downstream-placeholder\.cc''
|
||||
''^src/libstore-tests/machines\.cc''
|
||||
''^src/libstore-tests/nar-info-disk-cache\.cc''
|
||||
''^src/libstore-tests/nar-info\.cc''
|
||||
''^src/libstore-tests/outputs-spec\.cc''
|
||||
''^src/libstore-tests/path-info\.cc''
|
||||
''^src/libstore-tests/path\.cc''
|
||||
''^src/libstore-tests/serve-protocol\.cc''
|
||||
''^src/libstore-tests/worker-protocol\.cc''
|
||||
''^src/libutil-test-support/tests/characterization\.hh''
|
||||
''^src/libutil-test-support/tests/hash\.cc''
|
||||
''^src/libutil-test-support/tests/hash\.hh''
|
||||
''^src/libutil-tests/args\.cc''
|
||||
''^src/libutil-tests/canon-path\.cc''
|
||||
''^src/libutil-tests/chunked-vector\.cc''
|
||||
''^src/libutil-tests/closure\.cc''
|
||||
''^src/libutil-tests/compression\.cc''
|
||||
''^src/libutil-tests/config\.cc''
|
||||
''^src/libutil-tests/file-content-address\.cc''
|
||||
''^src/libutil-tests/git\.cc''
|
||||
''^src/libutil-tests/hash\.cc''
|
||||
''^src/libutil-tests/hilite\.cc''
|
||||
''^src/libutil-tests/json-utils\.cc''
|
||||
''^src/libutil-tests/logging\.cc''
|
||||
''^src/libutil-tests/lru-cache\.cc''
|
||||
''^src/libutil-tests/pool\.cc''
|
||||
''^src/libutil-tests/references\.cc''
|
||||
''^src/libutil-tests/suggestions\.cc''
|
||||
''^src/libutil-tests/url\.cc''
|
||||
''^src/libutil-tests/xml-writer\.cc''
|
||||
];
|
||||
};
|
||||
shellcheck = {
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if ! type -p pre-commit &>/dev/null; then
|
||||
echo "format.sh: pre-commit not found. Please use \`nix develop\`.";
|
||||
echo "format.sh: pre-commit not found. Please use \`nix develop -c ./maintainers/format.sh\`.";
|
||||
exit 1;
|
||||
fi;
|
||||
if test -z "$_NIX_PRE_COMMIT_HOOKS_CONFIG"; then
|
||||
echo "format.sh: _NIX_PRE_COMMIT_HOOKS_CONFIG not set. Please use \`nix develop\`.";
|
||||
echo "format.sh: _NIX_PRE_COMMIT_HOOKS_CONFIG not set. Please use \`nix develop -c ./maintainers/format.sh\`.";
|
||||
exit 1;
|
||||
fi;
|
||||
pre-commit run --config "$_NIX_PRE_COMMIT_HOOKS_CONFIG" --all-files
|
||||
|
||||
while ! pre-commit run --config "$_NIX_PRE_COMMIT_HOOKS_CONFIG" --all-files; do
|
||||
if [ "${1:-}" != "--until-stable" ]; then
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
83
maintainers/link-headers
Executable file
83
maintainers/link-headers
Executable file
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# This script must be run from the root of the Nix repository.
|
||||
#
|
||||
# For include path hygiene, we need to put headers in a separate
|
||||
# directory than sources. But during development, it is nice to paths
|
||||
# that are similar for headers and source files, e.g.
|
||||
# `foo/bar/baz.{cc,hh}`, e.g. for less typing when opening one file, and
|
||||
# then opening the other file.
|
||||
#
|
||||
# This script symlinks the headers next to the source files to
|
||||
# facilitate such a development workflows. It also updates
|
||||
# `.git/info/exclude` so that the symlinks are not accidentally committed
|
||||
# by mistake.
|
||||
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
|
||||
def main() -> None:
|
||||
# Path to the source directory
|
||||
GIT_TOPLEVEL = Path(
|
||||
subprocess.run(
|
||||
["git", "rev-parse", "--show-toplevel"],
|
||||
text=True,
|
||||
stdout=subprocess.PIPE,
|
||||
check=True,
|
||||
).stdout.strip()
|
||||
)
|
||||
|
||||
# Get header files from git
|
||||
result = subprocess.run(
|
||||
["git", "-C", str(GIT_TOPLEVEL), "ls-files", "*/include/nix/**.hh"],
|
||||
text=True,
|
||||
stdout=subprocess.PIPE,
|
||||
check=True,
|
||||
)
|
||||
header_files = result.stdout.strip().split("\n")
|
||||
header_files.sort()
|
||||
|
||||
links = []
|
||||
for file_str in header_files:
|
||||
project_str, header_str = file_str.split("/include/nix/", 1)
|
||||
project = Path(project_str)
|
||||
header = Path(header_str)
|
||||
|
||||
# Reconstruct the full path (relative to SRC_DIR) to the header file.
|
||||
file = project / "include" / "nix" / header
|
||||
|
||||
# The symlink should be created at "project/header", i.e. next to the project's sources.
|
||||
link = project / header
|
||||
|
||||
# Compute a relative path from the symlink's parent directory to the actual header file.
|
||||
relative_source = os.path.relpath(
|
||||
GIT_TOPLEVEL / file, GIT_TOPLEVEL / link.parent
|
||||
)
|
||||
|
||||
# Create the symbolic link.
|
||||
full_link_path = GIT_TOPLEVEL / link
|
||||
full_link_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
if full_link_path.is_symlink():
|
||||
full_link_path.unlink()
|
||||
full_link_path.symlink_to(relative_source)
|
||||
links.append(link)
|
||||
|
||||
# Generate .gitignore file
|
||||
gitignore_path = GIT_TOPLEVEL / ".git" / "info" / "exclude"
|
||||
gitignore_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with gitignore_path.open("w") as gitignore:
|
||||
gitignore.write("# DO NOT EDIT! Autogenerated\n")
|
||||
gitignore.write(
|
||||
"# Symlinks for headers to be next to sources for development\n"
|
||||
)
|
||||
gitignore.write('# Run "maintainers/link-headers" to regenerate\n\n')
|
||||
gitignore.write('# Run "maintainers/link-headers" to regenerate\n\n')
|
||||
|
||||
for link in links:
|
||||
gitignore.write(f"/{link}\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -109,15 +109,15 @@ for sample in samples:
|
||||
s = samples[sample]
|
||||
email = s["email"]
|
||||
if not email in email_to_handle_cache.values:
|
||||
print(f"Querying GitHub API for {s['hash']}, to get handle for {s['email']}")
|
||||
print(f"Querying GitHub API for {s['hash']}, to get handle for {s['email']}", file=sys.stderr)
|
||||
ghc = get_github_commit(samples[sample])
|
||||
gha = ghc["author"]
|
||||
if gha and gha["login"]:
|
||||
handle = gha["login"]
|
||||
print(f"Handle: {handle}")
|
||||
print(f"Handle: {handle}", file=sys.stderr)
|
||||
email_to_handle_cache.values[email] = handle
|
||||
else:
|
||||
print(f"Found no handle for {s['email']}")
|
||||
print(f"Found no handle for {s['email']}", file=sys.stderr)
|
||||
email_to_handle_cache.values[email] = None
|
||||
handle = email_to_handle_cache.values[email]
|
||||
if handle is not None:
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
# vim: set filetype=bash:
|
||||
#!nix shell .#changelog-d --command bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# --- CONFIGURATION ---
|
||||
|
||||
# This does double duty for
|
||||
|
||||
@@ -25,7 +25,7 @@ subproject('nix')
|
||||
if get_option('doc-gen')
|
||||
subproject('internal-api-docs')
|
||||
subproject('external-api-docs')
|
||||
if not meson.is_cross_build()
|
||||
if meson.can_run_host_binaries()
|
||||
subproject('nix-manual')
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -10,6 +10,7 @@ add_project_arguments(
|
||||
'-Werror=suggest-override',
|
||||
'-Werror=switch',
|
||||
'-Werror=switch-enum',
|
||||
'-Werror=undef',
|
||||
'-Werror=unused-result',
|
||||
'-Wignored-qualifiers',
|
||||
'-Wimplicit-fallthrough',
|
||||
|
||||
19
nix-meson-build-support/default-system-cpu/meson.build
Normal file
19
nix-meson-build-support/default-system-cpu/meson.build
Normal file
@@ -0,0 +1,19 @@
|
||||
# This attempts to translate meson cpu_family and cpu_name specified via
|
||||
# --cross-file [1] into a nix *system double*. Nixpkgs mostly respects ([2]) the
|
||||
# conventions outlined in [1].
|
||||
#
|
||||
# [1]: https://mesonbuild.com/Reference-tables.html#cpu-families
|
||||
# [2]: https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/lib/meson.nix
|
||||
|
||||
nix_system_cpu = {'ppc64' : 'powerpc64', 'ppc' : 'powerpc', 'x86' : 'i686'}.get(
|
||||
host_machine.cpu_family(),
|
||||
host_machine.cpu_family(),
|
||||
)
|
||||
|
||||
if (host_machine.cpu_family() in [ 'ppc64', 'ppc' ]) and host_machine.endian() == 'little'
|
||||
nix_system_cpu += 'le'
|
||||
elif host_machine.cpu_family() in [ 'mips64', 'mips' ] and host_machine.endian() == 'little'
|
||||
nix_system_cpu += 'el'
|
||||
elif host_machine.cpu_family() == 'arm'
|
||||
nix_system_cpu = host_machine.cpu()
|
||||
endif
|
||||
@@ -11,13 +11,18 @@ endforeach
|
||||
requires_public += deps_public
|
||||
|
||||
extra_pkg_config_variables = get_variable('extra_pkg_config_variables', {})
|
||||
|
||||
extra_cflags = []
|
||||
if not meson.project_name().endswith('-c')
|
||||
extra_cflags += ['-std=c++2a']
|
||||
endif
|
||||
|
||||
import('pkgconfig').generate(
|
||||
this_library,
|
||||
filebase : meson.project_name(),
|
||||
name : 'Nix',
|
||||
description : 'Nix Package Manager',
|
||||
subdirs : ['nix'],
|
||||
extra_cflags : ['-std=c++2a'],
|
||||
extra_cflags : extra_cflags,
|
||||
requires : requires_public,
|
||||
requires_private : requires_private,
|
||||
libraries_private : libraries_private,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
pkgs,
|
||||
src,
|
||||
officialRelease,
|
||||
maintainers,
|
||||
}:
|
||||
|
||||
scope:
|
||||
@@ -51,14 +52,14 @@ let
|
||||
|
||||
setVersionLayer = finalAttrs: prevAttrs: {
|
||||
preConfigure =
|
||||
prevAttrs.prevAttrs or ""
|
||||
prevAttrs.preConfigure or ""
|
||||
+
|
||||
# Update the repo-global .version file.
|
||||
# Symlink ./.version points there, but by default only workDir is writable.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${finalAttrs.version} > ./.version
|
||||
'';
|
||||
# Update the repo-global .version file.
|
||||
# Symlink ./.version points there, but by default only workDir is writable.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${finalAttrs.version} > ./.version
|
||||
'';
|
||||
};
|
||||
|
||||
localSourceLayer =
|
||||
@@ -110,7 +111,7 @@ let
|
||||
let
|
||||
n = lib.length finalScope.patches;
|
||||
in
|
||||
if n == 0 then finalAttrs.version else finalAttrs.version + "+${toString n}";
|
||||
if n == 0 then prevAttrs.version else prevAttrs.version + "+${toString n}";
|
||||
|
||||
# Clear what `derivation` can't/shouldn't serialize; see prevAttrs.workDir.
|
||||
fileset = null;
|
||||
@@ -147,7 +148,8 @@ let
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
] ++ prevAttrs.nativeBuildInputs or [ ];
|
||||
]
|
||||
++ prevAttrs.nativeBuildInputs or [ ];
|
||||
mesonCheckFlags = prevAttrs.mesonCheckFlags or [ ] ++ [
|
||||
"--print-errorlogs"
|
||||
];
|
||||
@@ -172,6 +174,17 @@ let
|
||||
outputs = prevAttrs.outputs or [ "out" ] ++ [ "dev" ];
|
||||
};
|
||||
|
||||
fixupStaticLayer = finalAttrs: prevAttrs: {
|
||||
postFixup =
|
||||
prevAttrs.postFixup or ""
|
||||
+ lib.optionalString (stdenv.hostPlatform.isStatic) ''
|
||||
# HACK: Otherwise the result will have the entire buildInputs closure
|
||||
# injected by the pkgsStatic stdenv
|
||||
# <https://github.com/NixOS/nixpkgs/issues/83667>
|
||||
rm -f $out/nix-support/propagated-build-inputs
|
||||
'';
|
||||
};
|
||||
|
||||
# Work around weird `--as-needed` linker behavior with BSD, see
|
||||
# https://github.com/mesonbuild/meson/issues/3593
|
||||
bsdNoLinkAsNeeded =
|
||||
@@ -180,9 +193,24 @@ let
|
||||
mesonFlags = [ (lib.mesonBool "b_asneeded" false) ] ++ prevAttrs.mesonFlags or [ ];
|
||||
};
|
||||
|
||||
miscGoodPractice = finalAttrs: prevAttrs: {
|
||||
nixDefaultsLayer = finalAttrs: prevAttrs: {
|
||||
strictDeps = prevAttrs.strictDeps or true;
|
||||
enableParallelBuilding = true;
|
||||
pos = builtins.unsafeGetAttrPos "pname" prevAttrs;
|
||||
meta = prevAttrs.meta or { } // {
|
||||
homepage = prevAttrs.meta.homepage or "https://nixos.org/nix";
|
||||
longDescription =
|
||||
prevAttrs.longDescription or ''
|
||||
Nix is a powerful package manager for mainly Linux and other Unix systems that
|
||||
makes package management reliable and reproducible. It provides atomic
|
||||
upgrades and rollbacks, side-by-side installation of multiple versions of
|
||||
a package, multi-user package management and easy setup of build
|
||||
environments.
|
||||
'';
|
||||
license = prevAttrs.meta.license or lib.licenses.lgpl21Plus;
|
||||
maintainers = prevAttrs.meta.maintainers or [ ] ++ scope.maintainers;
|
||||
platforms = prevAttrs.meta.platforms or (lib.platforms.unix ++ lib.platforms.windows);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -202,6 +230,7 @@ in
|
||||
{
|
||||
version = baseVersion + versionSuffix;
|
||||
inherit versionSuffix;
|
||||
inherit maintainers;
|
||||
|
||||
inherit filesetToSource;
|
||||
|
||||
@@ -237,6 +266,10 @@ in
|
||||
but it does make the build non-granular; all components will use a complete source.
|
||||
|
||||
Packaging expressions will be ignored.
|
||||
|
||||
Single argument: the source to use.
|
||||
|
||||
See also `appendPatches`
|
||||
*/
|
||||
overrideSource =
|
||||
src:
|
||||
@@ -265,6 +298,7 @@ in
|
||||
}
|
||||
);
|
||||
resolvePath = p: finalScope.patchedSrc + "/${resolveRelPath p}";
|
||||
filesetToSource = { root, fileset }: finalScope.resolvePath root;
|
||||
appendPatches = appendPatches finalScope;
|
||||
}
|
||||
);
|
||||
@@ -281,29 +315,32 @@ in
|
||||
(scope.overrideSource "${./..}").appendPatches patches;
|
||||
|
||||
mkMesonDerivation = mkPackageBuilder [
|
||||
miscGoodPractice
|
||||
nixDefaultsLayer
|
||||
scope.sourceLayer
|
||||
setVersionLayer
|
||||
mesonLayer
|
||||
fixupStaticLayer
|
||||
scope.mesonComponentOverrides
|
||||
];
|
||||
mkMesonExecutable = mkPackageBuilder [
|
||||
miscGoodPractice
|
||||
nixDefaultsLayer
|
||||
bsdNoLinkAsNeeded
|
||||
scope.sourceLayer
|
||||
setVersionLayer
|
||||
mesonLayer
|
||||
mesonBuildLayer
|
||||
fixupStaticLayer
|
||||
scope.mesonComponentOverrides
|
||||
];
|
||||
mkMesonLibrary = mkPackageBuilder [
|
||||
miscGoodPractice
|
||||
nixDefaultsLayer
|
||||
bsdNoLinkAsNeeded
|
||||
scope.sourceLayer
|
||||
mesonLayer
|
||||
setVersionLayer
|
||||
mesonBuildLayer
|
||||
mesonLibraryLayer
|
||||
fixupStaticLayer
|
||||
scope.mesonComponentOverrides
|
||||
];
|
||||
|
||||
@@ -347,7 +384,7 @@ in
|
||||
nix-perl-bindings = callPackage ../src/perl/package.nix { };
|
||||
|
||||
nix-everything = callPackage ../packaging/everything.nix { } // {
|
||||
# Note: no `passthru.overrideAllMesonComponents`
|
||||
# Note: no `passthru.overrideAllMesonComponents` etc
|
||||
# This would propagate into `nix.overrideAttrs f`, but then discard
|
||||
# `f` when `.overrideAllMesonComponents` is used.
|
||||
# Both "methods" should be views on the same fixpoint overriding mechanism
|
||||
@@ -355,6 +392,8 @@ in
|
||||
# two-fixpoint solution.
|
||||
/**
|
||||
Apply an extension function (i.e. overlay-shaped) to all component derivations, and return the nix package.
|
||||
|
||||
Single argument: the extension function to apply (finalAttrs: prevAttrs: { ... })
|
||||
*/
|
||||
overrideAllMesonComponents = f: (scope.overrideAllMesonComponents f).nix-everything;
|
||||
|
||||
@@ -363,6 +402,10 @@ in
|
||||
This affects all components.
|
||||
|
||||
Changes to the packaging expressions will be ignored.
|
||||
|
||||
Single argument: list of patches to apply
|
||||
|
||||
See also `overrideSource`
|
||||
*/
|
||||
appendPatches = ps: (scope.appendPatches ps).nix-everything;
|
||||
|
||||
@@ -371,8 +414,26 @@ in
|
||||
but it does make the build non-granular; all components will use a complete source.
|
||||
|
||||
Packaging expressions will be ignored.
|
||||
|
||||
Filesets in the packaging expressions will be ignored.
|
||||
|
||||
Single argument: the source to use.
|
||||
|
||||
See also `appendPatches`
|
||||
*/
|
||||
overrideSource = src: (scope.overrideSource src).nix-everything;
|
||||
|
||||
/**
|
||||
Override any internals of the Nix package set.
|
||||
|
||||
Single argument: the extension function to apply to the package set (finalScope: prevScope: { ... })
|
||||
|
||||
Example:
|
||||
```
|
||||
overrideScope (finalScope: prevScope: { aws-sdk-cpp = null; })
|
||||
```
|
||||
*/
|
||||
overrideScope = f: (scope.overrideScope f).nix-everything;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -26,6 +26,9 @@ let
|
||||
# Despite the use of the 10.13 deployment target here, the aligned
|
||||
# allocation function Clang uses with this setting actually works
|
||||
# all the way back to 10.6.
|
||||
# NOTE: this is not just a version constraint, but a request to make Darwin
|
||||
# provide this version level of support. Removing this minimum version
|
||||
# request will regress the above error.
|
||||
darwinStdenv = pkgs.overrideSDK prevStdenv { darwinMinVersion = "10.13"; };
|
||||
|
||||
in
|
||||
@@ -65,39 +68,37 @@ scope: {
|
||||
installPhase = lib.replaceStrings [ "--without-python" ] [ "" ] old.installPhase;
|
||||
});
|
||||
|
||||
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") {
|
||||
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
|
||||
];
|
||||
}
|
||||
);
|
||||
libgit2 =
|
||||
if lib.versionAtLeast pkgs.libgit2.version "1.9.0" then
|
||||
pkgs.libgit2
|
||||
else
|
||||
pkgs.libgit2.overrideAttrs (attrs: {
|
||||
# libgit2: Nixpkgs 24.11 has < 1.9.0, which needs our patches
|
||||
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
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
|
||||
{ pkgs }:
|
||||
|
||||
pkgs.nixComponents.nix-util.overrideAttrs (
|
||||
pkgs.nixComponents2.nix-util.overrideAttrs (
|
||||
attrs:
|
||||
|
||||
let
|
||||
stdenv = pkgs.nixDependencies.stdenv;
|
||||
stdenv = pkgs.nixDependencies2.stdenv;
|
||||
buildCanExecuteHost = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
|
||||
modular = devFlake.getSystem stdenv.buildPlatform.system;
|
||||
transformFlag =
|
||||
@@ -72,10 +72,6 @@ pkgs.nixComponents.nix-util.overrideAttrs (
|
||||
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
|
||||
@@ -83,26 +79,26 @@ pkgs.nixComponents.nix-util.overrideAttrs (
|
||||
};
|
||||
|
||||
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)
|
||||
map (transformFlag "libutil") (ignoreCrossFile pkgs.nixComponents2.nix-util.mesonFlags)
|
||||
++ map (transformFlag "libstore") (ignoreCrossFile pkgs.nixComponents2.nix-store.mesonFlags)
|
||||
++ map (transformFlag "libfetchers") (ignoreCrossFile pkgs.nixComponents2.nix-fetchers.mesonFlags)
|
||||
++ lib.optionals havePerl (
|
||||
map (transformFlag "perl") (ignoreCrossFile pkgs.nixComponents.nix-perl-bindings.mesonFlags)
|
||||
map (transformFlag "perl") (ignoreCrossFile pkgs.nixComponents2.nix-perl-bindings.mesonFlags)
|
||||
)
|
||||
++ map (transformFlag "libexpr") (ignoreCrossFile pkgs.nixComponents.nix-expr.mesonFlags)
|
||||
++ map (transformFlag "libcmd") (ignoreCrossFile pkgs.nixComponents.nix-cmd.mesonFlags);
|
||||
++ map (transformFlag "libexpr") (ignoreCrossFile pkgs.nixComponents2.nix-expr.mesonFlags)
|
||||
++ map (transformFlag "libcmd") (ignoreCrossFile pkgs.nixComponents2.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
|
||||
++ pkgs.nixComponents2.nix-util.nativeBuildInputs
|
||||
++ pkgs.nixComponents2.nix-store.nativeBuildInputs
|
||||
++ pkgs.nixComponents2.nix-fetchers.nativeBuildInputs
|
||||
++ pkgs.nixComponents2.nix-expr.nativeBuildInputs
|
||||
++ lib.optionals havePerl pkgs.nixComponents2.nix-perl-bindings.nativeBuildInputs
|
||||
++ lib.optionals buildCanExecuteHost pkgs.nixComponents2.nix-manual.externalNativeBuildInputs
|
||||
++ pkgs.nixComponents2.nix-internal-api-docs.nativeBuildInputs
|
||||
++ pkgs.nixComponents2.nix-external-api-docs.nativeBuildInputs
|
||||
++ pkgs.nixComponents2.nix-functional-tests.externalNativeBuildInputs
|
||||
++ lib.optional (
|
||||
!buildCanExecuteHost
|
||||
# Hack around https://github.com/nixos/nixpkgs/commit/bf7ad8cfbfa102a90463433e2c5027573b462479
|
||||
@@ -112,29 +108,27 @@ pkgs.nixComponents.nix-util.overrideAttrs (
|
||||
) pkgs.buildPackages.mesonEmulatorHook
|
||||
++ [
|
||||
pkgs.buildPackages.cmake
|
||||
pkgs.buildPackages.gnused
|
||||
pkgs.buildPackages.shellcheck
|
||||
pkgs.buildPackages.changelog-d
|
||||
modular.pre-commit.settings.package
|
||||
(pkgs.writeScriptBin "pre-commit-hooks-install" modular.pre-commit.settings.installationScript)
|
||||
pkgs.buildPackages.nixfmt-rfc-style
|
||||
]
|
||||
# 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-store-tests.externalBuildInputs
|
||||
++ pkgs.nixComponents.nix-fetchers.buildInputs
|
||||
++ pkgs.nixComponents.nix-expr.buildInputs
|
||||
++ pkgs.nixComponents.nix-expr.externalPropagatedBuildInputs
|
||||
++ pkgs.nixComponents.nix-cmd.buildInputs
|
||||
++ lib.optionals havePerl pkgs.nixComponents.nix-perl-bindings.externalBuildInputs
|
||||
++ pkgs.nixComponents2.nix-util.buildInputs
|
||||
++ pkgs.nixComponents2.nix-store.buildInputs
|
||||
++ pkgs.nixComponents2.nix-store-tests.externalBuildInputs
|
||||
++ pkgs.nixComponents2.nix-fetchers.buildInputs
|
||||
++ pkgs.nixComponents2.nix-expr.buildInputs
|
||||
++ pkgs.nixComponents2.nix-expr.externalPropagatedBuildInputs
|
||||
++ pkgs.nixComponents2.nix-cmd.buildInputs
|
||||
++ lib.optionals havePerl pkgs.nixComponents2.nix-perl-bindings.externalBuildInputs
|
||||
++ lib.optional havePerl pkgs.perl;
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
lndir,
|
||||
buildEnv,
|
||||
|
||||
maintainers,
|
||||
|
||||
nix-util,
|
||||
nix-util-c,
|
||||
nix-util-tests,
|
||||
@@ -38,28 +41,29 @@
|
||||
nix-perl-bindings,
|
||||
|
||||
testers,
|
||||
runCommand,
|
||||
|
||||
patchedSrc ? null,
|
||||
}:
|
||||
|
||||
let
|
||||
libs =
|
||||
{
|
||||
inherit
|
||||
nix-util
|
||||
nix-util-c
|
||||
nix-store
|
||||
nix-store-c
|
||||
nix-fetchers
|
||||
nix-expr
|
||||
nix-expr-c
|
||||
nix-flake
|
||||
nix-flake-c
|
||||
nix-main
|
||||
nix-main-c
|
||||
nix-cmd
|
||||
;
|
||||
}
|
||||
// lib.optionalAttrs
|
||||
libs = {
|
||||
inherit
|
||||
nix-util
|
||||
nix-util-c
|
||||
nix-store
|
||||
nix-store-c
|
||||
nix-fetchers
|
||||
nix-expr
|
||||
nix-expr-c
|
||||
nix-flake
|
||||
nix-flake-c
|
||||
nix-main
|
||||
nix-main-c
|
||||
nix-cmd
|
||||
;
|
||||
}
|
||||
//
|
||||
lib.optionalAttrs
|
||||
(!stdenv.hostPlatform.isStatic && stdenv.buildPlatform.canExecute stdenv.hostPlatform)
|
||||
{
|
||||
# Currently fails in static build
|
||||
@@ -68,48 +72,6 @@ let
|
||||
;
|
||||
};
|
||||
|
||||
dev = stdenv.mkDerivation (finalAttrs: {
|
||||
name = "nix-${nix-cli.version}-dev";
|
||||
pname = "nix";
|
||||
version = nix-cli.version;
|
||||
dontUnpack = true;
|
||||
dontBuild = true;
|
||||
libs = map lib.getDev (lib.attrValues libs);
|
||||
installPhase = ''
|
||||
mkdir -p $out/nix-support
|
||||
echo $libs >> $out/nix-support/propagated-build-inputs
|
||||
'';
|
||||
passthru = {
|
||||
tests = {
|
||||
pkg-config = testers.hasPkgConfigModules {
|
||||
package = finalAttrs.finalPackage;
|
||||
};
|
||||
};
|
||||
|
||||
# If we were to fully emulate output selection here, we'd confuse the Nix CLIs,
|
||||
# because they rely on `drvPath`.
|
||||
dev = finalAttrs.finalPackage.out;
|
||||
|
||||
libs = throw "`nix.dev.libs` is not meant to be used; use `nix.libs` instead.";
|
||||
};
|
||||
meta = {
|
||||
mainProgram = "nix";
|
||||
pkgConfigModules = [
|
||||
"nix-cmd"
|
||||
"nix-expr"
|
||||
"nix-expr-c"
|
||||
"nix-fetchers"
|
||||
"nix-flake"
|
||||
"nix-flake-c"
|
||||
"nix-main"
|
||||
"nix-main-c"
|
||||
"nix-store"
|
||||
"nix-store-c"
|
||||
"nix-util"
|
||||
"nix-util-c"
|
||||
];
|
||||
};
|
||||
});
|
||||
devdoc = buildEnv {
|
||||
name = "nix-${nix-cli.version}-devdoc";
|
||||
paths = [
|
||||
@@ -119,92 +81,163 @@ let
|
||||
};
|
||||
|
||||
in
|
||||
(buildEnv {
|
||||
name = "nix-${nix-cli.version}";
|
||||
paths = [
|
||||
nix-cli
|
||||
nix-manual.man
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "nix";
|
||||
version = nix-cli.version;
|
||||
|
||||
/**
|
||||
This package uses a multi-output derivation, even though some outputs could
|
||||
have been provided directly by the constituent component that provides it.
|
||||
|
||||
This is because not all tooling handles packages composed of arbitrary
|
||||
outputs yet. This includes nix itself, https://github.com/NixOS/nix/issues/6507.
|
||||
|
||||
`devdoc` is also available, but not listed here, because this attribute is
|
||||
not an output of the same derivation that provides `out`, `dev`, etc.
|
||||
*/
|
||||
outputs = [
|
||||
"out"
|
||||
"dev"
|
||||
"doc"
|
||||
"man"
|
||||
];
|
||||
|
||||
meta.mainProgram = "nix";
|
||||
}).overrideAttrs
|
||||
(
|
||||
finalAttrs: prevAttrs: {
|
||||
doCheck = true;
|
||||
doInstallCheck = true;
|
||||
/**
|
||||
Unpacking is handled in this package's constituent components
|
||||
*/
|
||||
dontUnpack = true;
|
||||
/**
|
||||
Building is handled in this package's constituent components
|
||||
*/
|
||||
dontBuild = true;
|
||||
|
||||
checkInputs =
|
||||
[
|
||||
# Make sure the unit tests have passed
|
||||
nix-util-tests.tests.run
|
||||
nix-store-tests.tests.run
|
||||
nix-expr-tests.tests.run
|
||||
nix-fetchers-tests.tests.run
|
||||
nix-flake-tests.tests.run
|
||||
/**
|
||||
`doCheck` controles whether tests are added as build gate for the combined package.
|
||||
This includes both the unit tests and the functional tests, but not the
|
||||
integration tests that run in CI (the flake's `hydraJobs` and some of the `checks`).
|
||||
*/
|
||||
doCheck = true;
|
||||
|
||||
# Make sure the functional tests have passed
|
||||
nix-functional-tests
|
||||
/**
|
||||
`fixupPhase` currently doesn't understand that a symlink output isn't writable.
|
||||
|
||||
# dev bundle is ok
|
||||
# (checkInputs must be empty paths??)
|
||||
(runCommand "check-pkg-config" { checked = dev.tests.pkg-config; } "mkdir $out")
|
||||
]
|
||||
++ lib.optionals
|
||||
(!stdenv.hostPlatform.isStatic && stdenv.buildPlatform.canExecute stdenv.hostPlatform)
|
||||
[
|
||||
# Perl currently fails in static build
|
||||
# TODO: Split out tests into a separate derivation?
|
||||
nix-perl-bindings
|
||||
];
|
||||
passthru = prevAttrs.passthru // {
|
||||
inherit (nix-cli) version;
|
||||
We don't compile or link anything in this derivation, so fixups aren't needed.
|
||||
*/
|
||||
dontFixup = true;
|
||||
|
||||
/**
|
||||
These are the libraries that are part of the Nix project. They are used
|
||||
by the Nix CLI and other tools.
|
||||
checkInputs = [
|
||||
# Make sure the unit tests have passed
|
||||
nix-util-tests.tests.run
|
||||
nix-store-tests.tests.run
|
||||
nix-expr-tests.tests.run
|
||||
nix-fetchers-tests.tests.run
|
||||
nix-flake-tests.tests.run
|
||||
|
||||
If you need to use these libraries in your project, we recommend to use
|
||||
the `-c` C API libraries exclusively, if possible.
|
||||
# Make sure the functional tests have passed
|
||||
nix-functional-tests
|
||||
]
|
||||
++
|
||||
lib.optionals (!stdenv.hostPlatform.isStatic && stdenv.buildPlatform.canExecute stdenv.hostPlatform)
|
||||
[
|
||||
# Perl currently fails in static build
|
||||
# TODO: Split out tests into a separate derivation?
|
||||
nix-perl-bindings
|
||||
];
|
||||
|
||||
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:
|
||||
nativeBuildInputs = [
|
||||
lndir
|
||||
];
|
||||
|
||||
```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;
|
||||
```
|
||||
*/
|
||||
inherit libs;
|
||||
installPhase =
|
||||
let
|
||||
devPaths = lib.mapAttrsToList (_k: lib.getDev) finalAttrs.finalPackage.libs;
|
||||
in
|
||||
''
|
||||
mkdir -p $out $dev/nix-support
|
||||
|
||||
tests = prevAttrs.passthru.tests or { } // {
|
||||
# TODO: create a proper fixpoint and:
|
||||
# pkg-config =
|
||||
# testers.hasPkgConfigModules {
|
||||
# package = finalPackage;
|
||||
# };
|
||||
};
|
||||
# Custom files
|
||||
echo $libs >> $dev/nix-support/propagated-build-inputs
|
||||
echo ${nix-cli} ${lib.escapeShellArgs devPaths} >> $dev/nix-support/propagated-build-inputs
|
||||
|
||||
/**
|
||||
A derivation referencing the `dev` outputs of the Nix libraries.
|
||||
*/
|
||||
inherit dev;
|
||||
inherit devdoc;
|
||||
doc = nix-manual;
|
||||
outputs = [
|
||||
"out"
|
||||
"dev"
|
||||
"devdoc"
|
||||
"doc"
|
||||
];
|
||||
all = lib.attrValues (
|
||||
lib.genAttrs finalAttrs.passthru.outputs (outName: finalAttrs.finalPackage.${outName})
|
||||
);
|
||||
# Merged outputs
|
||||
lndir ${nix-cli} $out
|
||||
|
||||
for lib in ${lib.escapeShellArgs devPaths}; do
|
||||
lndir $lib $dev
|
||||
done
|
||||
|
||||
# Forwarded outputs
|
||||
ln -sT ${nix-manual} $doc
|
||||
ln -sT ${nix-manual.man} $man
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
inherit (nix-cli) version;
|
||||
src = patchedSrc;
|
||||
|
||||
/**
|
||||
These are the libraries that are part of the Nix project. They are used
|
||||
by the Nix CLI and other tools.
|
||||
|
||||
If you need to use these libraries in your project, we recommend to use
|
||||
the `-c` C API libraries exclusively, if possible.
|
||||
|
||||
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;
|
||||
```
|
||||
*/
|
||||
inherit libs;
|
||||
|
||||
/**
|
||||
Developer documentation for `nix`, in `share/doc/nix/{internal,external}-api/`.
|
||||
|
||||
This is not a proper output; see `outputs` for context.
|
||||
*/
|
||||
inherit devdoc;
|
||||
|
||||
/**
|
||||
Extra tests that test this package, but do not run as part of the build.
|
||||
See <https://nixos.org/manual/nixpkgs/stable/index.html#var-passthru-tests>
|
||||
*/
|
||||
tests = {
|
||||
pkg-config = testers.hasPkgConfigModules {
|
||||
package = finalAttrs.finalPackage;
|
||||
};
|
||||
meta = prevAttrs.meta // {
|
||||
description = "The Nix package manager";
|
||||
pkgConfigModules = dev.meta.pkgConfigModules;
|
||||
};
|
||||
}
|
||||
)
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
mainProgram = "nix";
|
||||
description = "The Nix package manager";
|
||||
longDescription = nix-cli.meta.longDescription;
|
||||
homepage = nix-cli.meta.homepage;
|
||||
license = nix-cli.meta.license;
|
||||
maintainers = maintainers;
|
||||
platforms = nix-cli.meta.platforms;
|
||||
outputsToInstall = [
|
||||
"out"
|
||||
"man"
|
||||
];
|
||||
pkgConfigModules = [
|
||||
"nix-cmd"
|
||||
"nix-expr"
|
||||
"nix-expr-c"
|
||||
"nix-fetchers"
|
||||
"nix-flake"
|
||||
"nix-flake-c"
|
||||
"nix-main"
|
||||
"nix-main-c"
|
||||
"nix-store"
|
||||
"nix-store-c"
|
||||
"nix-util"
|
||||
"nix-util-c"
|
||||
];
|
||||
};
|
||||
|
||||
})
|
||||
|
||||
@@ -19,45 +19,99 @@ let
|
||||
|
||||
testNixVersions =
|
||||
pkgs: daemon:
|
||||
pkgs.nixComponents.nix-functional-tests.override {
|
||||
pkgs.nixComponents2.nix-functional-tests.override {
|
||||
pname = "nix-daemon-compat-tests";
|
||||
version = "${pkgs.nix.version}-with-daemon-${daemon.version}";
|
||||
|
||||
test-daemon = daemon;
|
||||
};
|
||||
|
||||
# Technically we could just return `pkgs.nixComponents`, but for Hydra it's
|
||||
# Technically we could just return `pkgs.nixComponents2`, but for Hydra it's
|
||||
# convention to transpose it, and to transpose it efficiently, we need to
|
||||
# enumerate them manually, so that we don't evaluate unnecessary package sets.
|
||||
forAllPackages = lib.genAttrs [
|
||||
"nix-everything"
|
||||
"nix-util"
|
||||
"nix-util-c"
|
||||
"nix-util-test-support"
|
||||
"nix-util-tests"
|
||||
"nix-store"
|
||||
"nix-store-c"
|
||||
"nix-store-test-support"
|
||||
"nix-store-tests"
|
||||
"nix-fetchers"
|
||||
"nix-fetchers-tests"
|
||||
"nix-expr"
|
||||
"nix-expr-c"
|
||||
"nix-expr-test-support"
|
||||
"nix-expr-tests"
|
||||
"nix-flake"
|
||||
"nix-flake-tests"
|
||||
"nix-main"
|
||||
"nix-main-c"
|
||||
"nix-cmd"
|
||||
"nix-cli"
|
||||
"nix-functional-tests"
|
||||
];
|
||||
# See listingIsComplete below.
|
||||
forAllPackages = forAllPackages' { };
|
||||
forAllPackages' =
|
||||
{
|
||||
enableBindings ? false,
|
||||
enableDocs ? false, # already have separate attrs for these
|
||||
}:
|
||||
lib.genAttrs (
|
||||
[
|
||||
"nix-everything"
|
||||
"nix-util"
|
||||
"nix-util-c"
|
||||
"nix-util-test-support"
|
||||
"nix-util-tests"
|
||||
"nix-store"
|
||||
"nix-store-c"
|
||||
"nix-store-test-support"
|
||||
"nix-store-tests"
|
||||
"nix-fetchers"
|
||||
"nix-fetchers-tests"
|
||||
"nix-expr"
|
||||
"nix-expr-c"
|
||||
"nix-expr-test-support"
|
||||
"nix-expr-tests"
|
||||
"nix-flake"
|
||||
"nix-flake-c"
|
||||
"nix-flake-tests"
|
||||
"nix-main"
|
||||
"nix-main-c"
|
||||
"nix-cmd"
|
||||
"nix-cli"
|
||||
"nix-functional-tests"
|
||||
]
|
||||
++ lib.optionals enableBindings [
|
||||
"nix-perl-bindings"
|
||||
]
|
||||
++ lib.optionals enableDocs [
|
||||
"nix-manual"
|
||||
"nix-internal-api-docs"
|
||||
"nix-external-api-docs"
|
||||
]
|
||||
);
|
||||
in
|
||||
{
|
||||
/**
|
||||
An internal check to make sure our package listing is complete.
|
||||
*/
|
||||
listingIsComplete =
|
||||
let
|
||||
arbitrarySystem = "x86_64-linux";
|
||||
listedPkgs = forAllPackages' {
|
||||
enableBindings = true;
|
||||
enableDocs = true;
|
||||
} (_: null);
|
||||
actualPkgs = lib.concatMapAttrs (
|
||||
k: v: if lib.strings.hasPrefix "nix-" k then { ${k} = null; } else { }
|
||||
) nixpkgsFor.${arbitrarySystem}.native.nixComponents2;
|
||||
diff = lib.concatStringsSep "\n" (
|
||||
lib.concatLists (
|
||||
lib.mapAttrsToList (
|
||||
k: _:
|
||||
if (listedPkgs ? ${k}) && !(actualPkgs ? ${k}) then
|
||||
[ "- ${k}: redundant?" ]
|
||||
else if !(listedPkgs ? ${k}) && (actualPkgs ? ${k}) then
|
||||
[ "- ${k}: missing?" ]
|
||||
else
|
||||
[ ]
|
||||
) (listedPkgs // actualPkgs)
|
||||
)
|
||||
);
|
||||
in
|
||||
if listedPkgs == actualPkgs then
|
||||
{ }
|
||||
else
|
||||
throw ''
|
||||
Please update the components list in hydra.nix (or fix this check)
|
||||
Differences:
|
||||
${diff}
|
||||
'';
|
||||
|
||||
# Binary package for various platforms.
|
||||
build = forAllPackages (
|
||||
pkgName: forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.${pkgName})
|
||||
pkgName: forAllSystems (system: nixpkgsFor.${system}.native.nixComponents2.${pkgName})
|
||||
);
|
||||
|
||||
shellInputs = removeAttrs (forAllSystems (
|
||||
@@ -67,7 +121,7 @@ in
|
||||
buildStatic = forAllPackages (
|
||||
pkgName:
|
||||
lib.genAttrs linux64BitSystems (
|
||||
system: nixpkgsFor.${system}.native.pkgsStatic.nixComponents.${pkgName}
|
||||
system: nixpkgsFor.${system}.native.pkgsStatic.nixComponents2.${pkgName}
|
||||
)
|
||||
);
|
||||
|
||||
@@ -84,7 +138,7 @@ in
|
||||
forAllCrossSystems (
|
||||
crossSystem:
|
||||
lib.genAttrs [ "x86_64-linux" ] (
|
||||
system: nixpkgsFor.${system}.cross.${crossSystem}.nixComponents.${pkgName}
|
||||
system: nixpkgsFor.${system}.cross.${crossSystem}.nixComponents2.${pkgName}
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -94,7 +148,7 @@ in
|
||||
let
|
||||
components = forAllSystems (
|
||||
system:
|
||||
nixpkgsFor.${system}.native.nixComponents.overrideScope (
|
||||
nixpkgsFor.${system}.native.nixComponents2.overrideScope (
|
||||
self: super: {
|
||||
nix-expr = super.nix-expr.override { enableGC = false; };
|
||||
}
|
||||
@@ -103,7 +157,7 @@ in
|
||||
in
|
||||
forAllPackages (pkgName: forAllSystems (system: components.${system}.${pkgName}));
|
||||
|
||||
buildNoTests = forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.nix-cli);
|
||||
buildNoTests = forAllSystems (system: nixpkgsFor.${system}.native.nixComponents2.nix-cli);
|
||||
|
||||
# Toggles some settings for better coverage. Windows needs these
|
||||
# library combinations, and Debian build Nix with GNU readline too.
|
||||
@@ -111,7 +165,7 @@ in
|
||||
let
|
||||
components = forAllSystems (
|
||||
system:
|
||||
nixpkgsFor.${system}.native.nixComponents.overrideScope (
|
||||
nixpkgsFor.${system}.native.nixComponents2.overrideScope (
|
||||
self: super: {
|
||||
nix-cmd = super.nix-cmd.override {
|
||||
enableMarkdown = false;
|
||||
@@ -124,7 +178,7 @@ in
|
||||
forAllPackages (pkgName: forAllSystems (system: components.${system}.${pkgName}));
|
||||
|
||||
# Perl bindings for various platforms.
|
||||
perlBindings = forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.nix-perl-bindings);
|
||||
perlBindings = forAllSystems (system: nixpkgsFor.${system}.native.nixComponents2.nix-perl-bindings);
|
||||
|
||||
# Binary tarball for various platforms, containing a Nix store
|
||||
# with the closure of 'nix' package, and the second half of
|
||||
@@ -174,13 +228,13 @@ in
|
||||
# };
|
||||
|
||||
# Nix's manual
|
||||
manual = nixpkgsFor.x86_64-linux.native.nixComponents.nix-manual;
|
||||
manual = nixpkgsFor.x86_64-linux.native.nixComponents2.nix-manual;
|
||||
|
||||
# API docs for Nix's unstable internal C++ interfaces.
|
||||
internal-api-docs = nixpkgsFor.x86_64-linux.native.nixComponents.nix-internal-api-docs;
|
||||
internal-api-docs = nixpkgsFor.x86_64-linux.native.nixComponents2.nix-internal-api-docs;
|
||||
|
||||
# API docs for Nix's C bindings.
|
||||
external-api-docs = nixpkgsFor.x86_64-linux.native.nixComponents.nix-external-api-docs;
|
||||
external-api-docs = nixpkgsFor.x86_64-linux.native.nixComponents2.nix-external-api-docs;
|
||||
|
||||
# System tests.
|
||||
tests =
|
||||
|
||||
@@ -49,15 +49,15 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <grp.h>
|
||||
# include <netdb.h>
|
||||
# include <pwd.h>
|
||||
# include <sys/resource.h>
|
||||
# include <sys/select.h>
|
||||
# include <sys/socket.h>
|
||||
# include <sys/utsname.h>
|
||||
# include <sys/wait.h>
|
||||
# include <termios.h>
|
||||
# include <grp.h>
|
||||
# include <netdb.h>
|
||||
# include <pwd.h>
|
||||
# include <sys/resource.h>
|
||||
# include <sys/select.h>
|
||||
# include <sys/socket.h>
|
||||
# include <sys/utsname.h>
|
||||
# include <sys/wait.h>
|
||||
# include <termios.h>
|
||||
#endif
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
@@ -24,7 +24,33 @@ end
|
||||
|
||||
# Set up the per-user profile.
|
||||
|
||||
set --local NIX_LINK $HOME/.nix-profile
|
||||
set --local NIX_LINK "$HOME/.nix-profile"
|
||||
set --local NIX_LINK_NEW
|
||||
if test -n "$XDG_STATE_HOME"
|
||||
set NIX_LINK_NEW "$XDG_STATE_HOME/nix/profile"
|
||||
else
|
||||
set NIX_LINK_NEW "$HOME/.local/state/nix/profile"
|
||||
end
|
||||
if test -e "$NIX_LINK_NEW"
|
||||
if test -t 2; and test -e "$NIX_LINK"
|
||||
set --local warning "\033[1;35mwarning:\033[0m "
|
||||
printf "$warning Both %s and legacy %s exist; using the former.\n" "$NIX_LINK_NEW" "$NIX_LINK" 1>&2
|
||||
|
||||
if test (realpath "$NIX_LINK") = (realpath "$NIX_LINK_NEW")
|
||||
printf " Since the profiles match, you can safely delete either of them.\n" 1>&2
|
||||
else
|
||||
# This should be an exceptionally rare occasion: the only way to get it would be to
|
||||
# 1. Update to newer Nix;
|
||||
# 2. Remove .nix-profile;
|
||||
# 3. Set the $NIX_LINK_NEW to something other than the default user profile;
|
||||
# 4. Roll back to older Nix.
|
||||
# If someone did all that, they can probably figure out how to migrate the profile.
|
||||
printf "$warning Profiles do not match. You should manually migrate from %s to %s.\n" "$NIX_LINK" "$NIX_LINK_NEW" 1>&2
|
||||
end
|
||||
end
|
||||
|
||||
set NIX_LINK "$NIX_LINK_NEW"
|
||||
end
|
||||
|
||||
# Set up environment.
|
||||
# This part should be kept in sync with nixpkgs:nixos/modules/programs/environment.nix
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -24,7 +24,38 @@ end
|
||||
|
||||
# Set up the per-user profile.
|
||||
|
||||
set --local NIX_LINK $HOME/.nix-profile
|
||||
set --local NIX_LINK
|
||||
if test -n "$NIX_STATE_HOME"
|
||||
set NIX_LINK "$NIX_STATE_HOME/.nix-profile"
|
||||
else
|
||||
set NIX_LINK "$HOME/.nix-profile"
|
||||
set --local NIX_LINK_NEW
|
||||
if test -n "$XDG_STATE_HOME"
|
||||
set NIX_LINK_NEW "$XDG_STATE_HOME/nix/profile"
|
||||
else
|
||||
set NIX_LINK_NEW "$HOME/.local/state/nix/profile"
|
||||
end
|
||||
if test -e "$NIX_LINK_NEW"
|
||||
if test -t 2; and test -e "$NIX_LINK"
|
||||
set --local warning "\033[1;35mwarning:\033[0m "
|
||||
printf "$warning Both %s and legacy %s exist; using the former.\n" "$NIX_LINK_NEW" "$NIX_LINK" 1>&2
|
||||
|
||||
if test (realpath "$NIX_LINK") = (realpath "$NIX_LINK_NEW")
|
||||
printf " Since the profiles match, you can safely delete either of them.\n" 1>&2
|
||||
else
|
||||
# This should be an exceptionally rare occasion: the only way to get it would be to
|
||||
# 1. Update to newer Nix;
|
||||
# 2. Remove .nix-profile;
|
||||
# 3. Set the $NIX_LINK_NEW to something other than the default user profile;
|
||||
# 4. Roll back to older Nix.
|
||||
# If someone did all that, they can probably figure out how to migrate the profile.
|
||||
printf "$warning Profiles do not match. You should manually migrate from %s to %s.\n" "$NIX_LINK" "$NIX_LINK_NEW" 1>&2
|
||||
end
|
||||
end
|
||||
|
||||
set NIX_LINK "$NIX_LINK_NEW"
|
||||
end
|
||||
end
|
||||
|
||||
# Set up environment.
|
||||
# This part should be kept in sync with nixpkgs:nixos/modules/programs/environment.nix
|
||||
|
||||
@@ -5,29 +5,28 @@
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <iomanip>
|
||||
#if __APPLE__
|
||||
#include <sys/time.h>
|
||||
#ifdef __APPLE__
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include "machines.hh"
|
||||
#include "shared.hh"
|
||||
#include "plugin.hh"
|
||||
#include "pathlocks.hh"
|
||||
#include "globals.hh"
|
||||
#include "serialise.hh"
|
||||
#include "build-result.hh"
|
||||
#include "store-api.hh"
|
||||
#include "strings.hh"
|
||||
#include "derivations.hh"
|
||||
#include "local-store.hh"
|
||||
#include "legacy.hh"
|
||||
#include "experimental-features.hh"
|
||||
#include "nix/store/machines.hh"
|
||||
#include "nix/main/shared.hh"
|
||||
#include "nix/main/plugin.hh"
|
||||
#include "nix/store/pathlocks.hh"
|
||||
#include "nix/store/globals.hh"
|
||||
#include "nix/util/serialise.hh"
|
||||
#include "nix/store/build-result.hh"
|
||||
#include "nix/store/store-api.hh"
|
||||
#include "nix/util/strings.hh"
|
||||
#include "nix/store/derivations.hh"
|
||||
#include "nix/store/local-store.hh"
|
||||
#include "nix/cmd/legacy.hh"
|
||||
#include "nix/util/experimental-features.hh"
|
||||
|
||||
using namespace nix;
|
||||
using std::cin;
|
||||
|
||||
static void handleAlarm(int sig) {
|
||||
}
|
||||
static void handleAlarm(int sig) {}
|
||||
|
||||
std::string escapeUri(std::string uri)
|
||||
{
|
||||
@@ -42,13 +41,15 @@ static AutoCloseFD openSlotLock(const Machine & m, uint64_t slot)
|
||||
return openLockFile(fmt("%s/%s-%d", currentLoad, escapeUri(m.storeUri.render()), slot), true);
|
||||
}
|
||||
|
||||
static bool allSupportedLocally(Store & store, const std::set<std::string>& requiredFeatures) {
|
||||
static bool allSupportedLocally(Store & store, const std::set<std::string> & requiredFeatures)
|
||||
{
|
||||
for (auto & feature : requiredFeatures)
|
||||
if (!store.systemFeatures.get().count(feature)) return false;
|
||||
if (!store.systemFeatures.get().count(feature))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int main_build_remote(int argc, char * * argv)
|
||||
static int main_build_remote(int argc, char ** argv)
|
||||
{
|
||||
{
|
||||
logger = makeJSONLogger(getStandardError());
|
||||
@@ -85,7 +86,7 @@ static int main_build_remote(int argc, char * * argv)
|
||||
that gets cleared on reboot, but it wouldn't work on macOS. */
|
||||
auto currentLoadName = "/current-load";
|
||||
if (auto localStore = store.dynamic_pointer_cast<LocalFSStore>())
|
||||
currentLoad = std::string { localStore->stateDir } + currentLoadName;
|
||||
currentLoad = std::string{localStore->stateDir} + currentLoadName;
|
||||
else
|
||||
currentLoad = settings.nixStateDir + currentLoadName;
|
||||
|
||||
@@ -107,8 +108,11 @@ static int main_build_remote(int argc, char * * argv)
|
||||
|
||||
try {
|
||||
auto s = readString(source);
|
||||
if (s != "try") return 0;
|
||||
} catch (EndOfFile &) { return 0; }
|
||||
if (s != "try")
|
||||
return 0;
|
||||
} catch (EndOfFile &) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto amWilling = readInt(source);
|
||||
auto neededSystem = readString(source);
|
||||
@@ -117,10 +121,10 @@ static int main_build_remote(int argc, char * * argv)
|
||||
|
||||
/* It would be possible to build locally after some builds clear out,
|
||||
so don't show the warning now: */
|
||||
bool couldBuildLocally = maxBuildJobs > 0
|
||||
&& ( neededSystem == settings.thisSystem
|
||||
|| settings.extraPlatforms.get().count(neededSystem) > 0)
|
||||
&& allSupportedLocally(*store, requiredFeatures);
|
||||
bool couldBuildLocally =
|
||||
maxBuildJobs > 0
|
||||
&& (neededSystem == settings.thisSystem || settings.extraPlatforms.get().count(neededSystem) > 0)
|
||||
&& allSupportedLocally(*store, requiredFeatures);
|
||||
/* It's possible to build this locally right now: */
|
||||
bool canBuildLocally = amWilling && couldBuildLocally;
|
||||
|
||||
@@ -139,11 +143,8 @@ static int main_build_remote(int argc, char * * argv)
|
||||
for (auto & m : machines) {
|
||||
debug("considering building on remote machine '%s'", m.storeUri.render());
|
||||
|
||||
if (m.enabled &&
|
||||
m.systemSupported(neededSystem) &&
|
||||
m.allSupported(requiredFeatures) &&
|
||||
m.mandatoryMet(requiredFeatures))
|
||||
{
|
||||
if (m.enabled && m.systemSupported(neededSystem) && m.allSupported(requiredFeatures)
|
||||
&& m.mandatoryMet(requiredFeatures)) {
|
||||
rightType = true;
|
||||
AutoCloseFD free;
|
||||
uint64_t load = 0;
|
||||
@@ -185,8 +186,7 @@ static int main_build_remote(int argc, char * * argv)
|
||||
if (!bestSlotLock) {
|
||||
if (rightType && !canBuildLocally)
|
||||
std::cerr << "# postpone\n";
|
||||
else
|
||||
{
|
||||
else {
|
||||
// build the hint template.
|
||||
std::string errorText =
|
||||
"Failed to find a machine for remote build!\n"
|
||||
@@ -205,16 +205,11 @@ static int main_build_remote(int argc, char * * argv)
|
||||
drvstr = "<unknown>";
|
||||
|
||||
auto error = HintFmt::fromFormatString(errorText);
|
||||
error
|
||||
% drvstr
|
||||
% neededSystem
|
||||
% concatStringsSep<StringSet>(", ", requiredFeatures)
|
||||
error % drvstr % neededSystem % concatStringsSep<StringSet>(", ", requiredFeatures)
|
||||
% machines.size();
|
||||
|
||||
for (auto & m : machines)
|
||||
error
|
||||
% concatStringsSep<StringSet>(", ", m.systemTypes)
|
||||
% m.maxJobs
|
||||
error % concatStringsSep<StringSet>(", ", m.systemTypes) % m.maxJobs
|
||||
% concatStringsSep<StringSet>(", ", m.supportedFeatures)
|
||||
% concatStringsSep<StringSet>(", ", m.mandatoryFeatures);
|
||||
|
||||
@@ -225,7 +220,7 @@ static int main_build_remote(int argc, char * * argv)
|
||||
break;
|
||||
}
|
||||
|
||||
#if __APPLE__
|
||||
#ifdef __APPLE__
|
||||
futimes(bestSlotLock.get(), NULL);
|
||||
#else
|
||||
futimens(bestSlotLock.get(), NULL);
|
||||
@@ -242,9 +237,7 @@ static int main_build_remote(int argc, char * * argv)
|
||||
sshStore->connect();
|
||||
} catch (std::exception & e) {
|
||||
auto msg = chomp(drainFD(5, false));
|
||||
printError("cannot build on '%s': %s%s",
|
||||
storeUri, e.what(),
|
||||
msg.empty() ? "" : ": " + msg);
|
||||
printError("cannot build on '%s': %s%s", storeUri, e.what(), msg.empty() ? "" : ": " + msg);
|
||||
bestMachine->enabled = false;
|
||||
continue;
|
||||
}
|
||||
@@ -253,7 +246,7 @@ static int main_build_remote(int argc, char * * argv)
|
||||
}
|
||||
}
|
||||
|
||||
connected:
|
||||
connected:
|
||||
close(5);
|
||||
|
||||
assert(sshStore);
|
||||
@@ -265,13 +258,14 @@ connected:
|
||||
|
||||
AutoCloseFD uploadLock;
|
||||
{
|
||||
auto setUpdateLock = [&](auto && fileName){
|
||||
auto setUpdateLock = [&](auto && fileName) {
|
||||
uploadLock = openLockFile(currentLoad + "/" + escapeUri(fileName) + ".upload-lock", true);
|
||||
};
|
||||
try {
|
||||
setUpdateLock(storeUri);
|
||||
} catch (SysError & e) {
|
||||
if (e.errNo != ENAMETOOLONG) throw;
|
||||
if (e.errNo != ENAMETOOLONG)
|
||||
throw;
|
||||
// Try again hashing the store URL so we have a shorter path
|
||||
auto h = hashString(HashAlgorithm::MD5, storeUri);
|
||||
setUpdateLock(h.to_string(HashFormat::Base64, false));
|
||||
@@ -315,7 +309,7 @@ connected:
|
||||
//
|
||||
// This condition mirrors that: that code enforces the "rules" outlined there;
|
||||
// we do the best we can given those "rules".
|
||||
if (trustedOrLegacy || drv.type().isCA()) {
|
||||
if (trustedOrLegacy || drv.type().isCA()) {
|
||||
// Hijack the inputs paths of the derivation to include all
|
||||
// the paths that come from the `inputDrvs` set. We don’t do
|
||||
// that for the derivations whose `inputDrvs` is empty
|
||||
@@ -330,28 +324,26 @@ connected:
|
||||
optResult = sshStore->buildDerivation(*drvPath, (const BasicDerivation &) drv);
|
||||
auto & result = *optResult;
|
||||
if (!result.success())
|
||||
throw Error("build of '%s' on '%s' failed: %s", store->printStorePath(*drvPath), storeUri, result.errorMsg);
|
||||
throw Error(
|
||||
"build of '%s' on '%s' failed: %s", store->printStorePath(*drvPath), storeUri, result.errorMsg);
|
||||
} else {
|
||||
copyClosure(*store, *sshStore, StorePathSet {*drvPath}, NoRepair, NoCheckSigs, substitute);
|
||||
auto res = sshStore->buildPathsWithResults({
|
||||
DerivedPath::Built {
|
||||
.drvPath = makeConstantStorePathRef(*drvPath),
|
||||
.outputs = OutputsSpec::All {},
|
||||
}
|
||||
});
|
||||
copyClosure(*store, *sshStore, StorePathSet{*drvPath}, NoRepair, NoCheckSigs, substitute);
|
||||
auto res = sshStore->buildPathsWithResults({DerivedPath::Built{
|
||||
.drvPath = makeConstantStorePathRef(*drvPath),
|
||||
.outputs = OutputsSpec::All{},
|
||||
}});
|
||||
// One path to build should produce exactly one build result
|
||||
assert(res.size() == 1);
|
||||
optResult = std::move(res[0]);
|
||||
}
|
||||
|
||||
|
||||
auto outputHashes = staticOutputHashes(*store, drv);
|
||||
std::set<Realisation> missingRealisations;
|
||||
StorePathSet missingPaths;
|
||||
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations) && !drv.type().hasKnownOutputPaths()) {
|
||||
for (auto & outputName : wantedOutputs) {
|
||||
auto thisOutputHash = outputHashes.at(outputName);
|
||||
auto thisOutputId = DrvOutput{ thisOutputHash, outputName };
|
||||
auto thisOutputId = DrvOutput{thisOutputHash, outputName};
|
||||
if (!store->queryRealisation(thisOutputId)) {
|
||||
debug("missing output %s", outputName);
|
||||
assert(optResult);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "built-path.hh"
|
||||
#include "derivations.hh"
|
||||
#include "store-api.hh"
|
||||
#include "comparator.hh"
|
||||
#include "nix/cmd/built-path.hh"
|
||||
#include "nix/store/derivations.hh"
|
||||
#include "nix/store/store-api.hh"
|
||||
#include "nix/util/comparator.hh"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
@@ -10,23 +10,13 @@
|
||||
namespace nix {
|
||||
|
||||
// Custom implementation to avoid `ref` ptr equality
|
||||
GENERATE_CMP_EXT(
|
||||
,
|
||||
std::strong_ordering,
|
||||
SingleBuiltPathBuilt,
|
||||
*me->drvPath,
|
||||
me->output);
|
||||
GENERATE_CMP_EXT(, std::strong_ordering, SingleBuiltPathBuilt, *me->drvPath, me->output);
|
||||
|
||||
// Custom implementation to avoid `ref` ptr equality
|
||||
|
||||
// TODO no `GENERATE_CMP_EXT` because no `std::set::operator<=>` on
|
||||
// Darwin, per header.
|
||||
GENERATE_EQUAL(
|
||||
,
|
||||
BuiltPathBuilt ::,
|
||||
BuiltPathBuilt,
|
||||
*me->drvPath,
|
||||
me->outputs);
|
||||
GENERATE_EQUAL(, BuiltPathBuilt ::, BuiltPathBuilt, *me->drvPath, me->outputs);
|
||||
|
||||
StorePath SingleBuiltPath::outPath() const
|
||||
{
|
||||
@@ -34,8 +24,8 @@ StorePath SingleBuiltPath::outPath() const
|
||||
overloaded{
|
||||
[](const SingleBuiltPath::Opaque & p) { return p.path; },
|
||||
[](const SingleBuiltPath::Built & b) { return b.output.second; },
|
||||
}, raw()
|
||||
);
|
||||
},
|
||||
raw());
|
||||
}
|
||||
|
||||
StorePathSet BuiltPath::outPaths() const
|
||||
@@ -49,13 +39,13 @@ StorePathSet BuiltPath::outPaths() const
|
||||
res.insert(path);
|
||||
return res;
|
||||
},
|
||||
}, raw()
|
||||
);
|
||||
},
|
||||
raw());
|
||||
}
|
||||
|
||||
SingleDerivedPath::Built SingleBuiltPath::Built::discardOutputPath() const
|
||||
{
|
||||
return SingleDerivedPath::Built {
|
||||
return SingleDerivedPath::Built{
|
||||
.drvPath = make_ref<SingleDerivedPath>(drvPath->discardOutputPath()),
|
||||
.output = output.first,
|
||||
};
|
||||
@@ -65,14 +55,10 @@ SingleDerivedPath SingleBuiltPath::discardOutputPath() const
|
||||
{
|
||||
return std::visit(
|
||||
overloaded{
|
||||
[](const SingleBuiltPath::Opaque & p) -> SingleDerivedPath {
|
||||
return p;
|
||||
},
|
||||
[](const SingleBuiltPath::Built & b) -> SingleDerivedPath {
|
||||
return b.discardOutputPath();
|
||||
},
|
||||
}, raw()
|
||||
);
|
||||
[](const SingleBuiltPath::Opaque & p) -> SingleDerivedPath { return p; },
|
||||
[](const SingleBuiltPath::Built & b) -> SingleDerivedPath { return b.discardOutputPath(); },
|
||||
},
|
||||
raw());
|
||||
}
|
||||
|
||||
nlohmann::json BuiltPath::Built::toJSON(const StoreDirConfig & store) const
|
||||
@@ -97,16 +83,12 @@ nlohmann::json SingleBuiltPath::Built::toJSON(const StoreDirConfig & store) cons
|
||||
|
||||
nlohmann::json SingleBuiltPath::toJSON(const StoreDirConfig & store) const
|
||||
{
|
||||
return std::visit([&](const auto & buildable) {
|
||||
return buildable.toJSON(store);
|
||||
}, raw());
|
||||
return std::visit([&](const auto & buildable) { return buildable.toJSON(store); }, raw());
|
||||
}
|
||||
|
||||
nlohmann::json BuiltPath::toJSON(const StoreDirConfig & store) const
|
||||
{
|
||||
return std::visit([&](const auto & buildable) {
|
||||
return buildable.toJSON(store);
|
||||
}, raw());
|
||||
return std::visit([&](const auto & buildable) { return buildable.toJSON(store); }, raw());
|
||||
}
|
||||
|
||||
RealisedPath::Set BuiltPath::toRealisedPaths(Store & store) const
|
||||
@@ -116,20 +98,18 @@ RealisedPath::Set BuiltPath::toRealisedPaths(Store & store) const
|
||||
overloaded{
|
||||
[&](const BuiltPath::Opaque & p) { res.insert(p.path); },
|
||||
[&](const BuiltPath::Built & p) {
|
||||
auto drvHashes =
|
||||
staticOutputHashes(store, store.readDerivation(p.drvPath->outPath()));
|
||||
for (auto& [outputName, outputPath] : p.outputs) {
|
||||
if (experimentalFeatureSettings.isEnabled(
|
||||
Xp::CaDerivations)) {
|
||||
auto drvHashes = staticOutputHashes(store, store.readDerivation(p.drvPath->outPath()));
|
||||
for (auto & [outputName, outputPath] : p.outputs) {
|
||||
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
|
||||
auto drvOutput = get(drvHashes, outputName);
|
||||
if (!drvOutput)
|
||||
throw Error(
|
||||
"the derivation '%s' has unrealised output '%s' (derived-path.cc/toRealisedPaths)",
|
||||
store.printStorePath(p.drvPath->outPath()), outputName);
|
||||
auto thisRealisation = store.queryRealisation(
|
||||
DrvOutput{*drvOutput, outputName});
|
||||
assert(thisRealisation); // We’ve built it, so we must
|
||||
// have the realisation
|
||||
store.printStorePath(p.drvPath->outPath()),
|
||||
outputName);
|
||||
auto thisRealisation = store.queryRealisation(DrvOutput{*drvOutput, outputName});
|
||||
assert(thisRealisation); // We’ve built it, so we must
|
||||
// have the realisation
|
||||
res.insert(*thisRealisation);
|
||||
} else {
|
||||
res.insert(outputPath);
|
||||
@@ -141,4 +121,4 @@ RealisedPath::Set BuiltPath::toRealisedPaths(Store & store) const
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "command-installable-value.hh"
|
||||
#include "nix/cmd/command-installable-value.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -8,4 +8,4 @@ void InstallableValueCommand::run(ref<Store> store, ref<Installable> installable
|
||||
run(store, installableValue);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
#include <algorithm>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "command.hh"
|
||||
#include "markdown.hh"
|
||||
#include "store-api.hh"
|
||||
#include "local-fs-store.hh"
|
||||
#include "derivations.hh"
|
||||
#include "nixexpr.hh"
|
||||
#include "profiles.hh"
|
||||
#include "repl.hh"
|
||||
#include "strings.hh"
|
||||
#include "environment-variables.hh"
|
||||
#include "nix/cmd/command.hh"
|
||||
#include "nix/cmd/markdown.hh"
|
||||
#include "nix/store/store-api.hh"
|
||||
#include "nix/store/local-fs-store.hh"
|
||||
#include "nix/store/derivations.hh"
|
||||
#include "nix/expr/nixexpr.hh"
|
||||
#include "nix/store/profiles.hh"
|
||||
#include "nix/cmd/repl.hh"
|
||||
#include "nix/util/strings.hh"
|
||||
#include "nix/util/environment-variables.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -237,12 +237,13 @@ void StorePathCommand::run(ref<Store> store, StorePaths && storePaths)
|
||||
|
||||
MixProfile::MixProfile()
|
||||
{
|
||||
addFlag(
|
||||
{.longName = "profile",
|
||||
.description = "The profile to operate on.",
|
||||
.labels = {"path"},
|
||||
.handler = {&profile},
|
||||
.completer = completePath});
|
||||
addFlag({
|
||||
.longName = "profile",
|
||||
.description = "The profile to operate on.",
|
||||
.labels = {"path"},
|
||||
.handler = {&profile},
|
||||
.completer = completePath,
|
||||
});
|
||||
}
|
||||
|
||||
void MixProfile::updateProfile(const StorePath & storePath)
|
||||
@@ -396,4 +397,4 @@ void createOutLinks(const std::filesystem::path & outLink, const BuiltPaths & bu
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
||||
@@ -1,30 +1,32 @@
|
||||
#include "fetch-settings.hh"
|
||||
#include "eval-settings.hh"
|
||||
#include "common-eval-args.hh"
|
||||
#include "shared.hh"
|
||||
#include "config-global.hh"
|
||||
#include "filetransfer.hh"
|
||||
#include "eval.hh"
|
||||
#include "fetchers.hh"
|
||||
#include "registry.hh"
|
||||
#include "flake/flakeref.hh"
|
||||
#include "flake/settings.hh"
|
||||
#include "store-api.hh"
|
||||
#include "command.hh"
|
||||
#include "tarball.hh"
|
||||
#include "fetch-to-store.hh"
|
||||
#include "compatibility-settings.hh"
|
||||
#include "eval-settings.hh"
|
||||
#include "nix/fetchers/fetch-settings.hh"
|
||||
#include "nix/expr/eval-settings.hh"
|
||||
#include "nix/cmd/common-eval-args.hh"
|
||||
#include "nix/main/shared.hh"
|
||||
#include "nix/util/config-global.hh"
|
||||
#include "nix/store/filetransfer.hh"
|
||||
#include "nix/expr/eval.hh"
|
||||
#include "nix/fetchers/fetchers.hh"
|
||||
#include "nix/fetchers/registry.hh"
|
||||
#include "nix/flake/flakeref.hh"
|
||||
#include "nix/flake/settings.hh"
|
||||
#include "nix/store/store-api.hh"
|
||||
#include "nix/cmd/command.hh"
|
||||
#include "nix/fetchers/tarball.hh"
|
||||
#include "nix/fetchers/fetch-to-store.hh"
|
||||
#include "nix/cmd/compatibility-settings.hh"
|
||||
#include "nix/expr/eval-settings.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
namespace fs { using namespace std::filesystem; }
|
||||
namespace fs {
|
||||
using namespace std::filesystem;
|
||||
}
|
||||
|
||||
fetchers::Settings fetchSettings;
|
||||
|
||||
static GlobalConfig::Register rFetchSettings(&fetchSettings);
|
||||
|
||||
EvalSettings evalSettings {
|
||||
EvalSettings evalSettings{
|
||||
settings.readOnlyMode,
|
||||
{
|
||||
{
|
||||
@@ -32,10 +34,11 @@ EvalSettings evalSettings {
|
||||
[](EvalState & state, std::string_view rest) {
|
||||
experimentalFeatureSettings.require(Xp::Flakes);
|
||||
// FIXME `parseFlakeRef` should take a `std::string_view`.
|
||||
auto flakeRef = parseFlakeRef(fetchSettings, std::string { rest }, {}, true, false);
|
||||
auto flakeRef = parseFlakeRef(fetchSettings, std::string{rest}, {}, true, false);
|
||||
debug("fetching flake search path element '%s''", rest);
|
||||
auto [accessor, lockedRef] = flakeRef.resolve(state.store).lazyFetch(state.store);
|
||||
auto storePath = nix::fetchToStore(*state.store, SourcePath(accessor), FetchMode::Copy, lockedRef.input.getName());
|
||||
auto storePath =
|
||||
nix::fetchToStore(*state.store, SourcePath(accessor), FetchMode::Copy, lockedRef.input.getName());
|
||||
state.allowPath(storePath);
|
||||
return state.storePath(storePath);
|
||||
},
|
||||
@@ -45,17 +48,14 @@ EvalSettings evalSettings {
|
||||
|
||||
static GlobalConfig::Register rEvalSettings(&evalSettings);
|
||||
|
||||
|
||||
flake::Settings flakeSettings;
|
||||
|
||||
static GlobalConfig::Register rFlakeSettings(&flakeSettings);
|
||||
|
||||
|
||||
CompatibilitySettings compatibilitySettings {};
|
||||
CompatibilitySettings compatibilitySettings{};
|
||||
|
||||
static GlobalConfig::Register rCompatibilitySettings(&compatibilitySettings);
|
||||
|
||||
|
||||
MixEvalArgs::MixEvalArgs()
|
||||
{
|
||||
addFlag({
|
||||
@@ -63,7 +63,9 @@ MixEvalArgs::MixEvalArgs()
|
||||
.description = "Pass the value *expr* as the argument *name* to Nix functions.",
|
||||
.category = category,
|
||||
.labels = {"name", "expr"},
|
||||
.handler = {[&](std::string name, std::string expr) { autoArgs.insert_or_assign(name, AutoArg{AutoArgExpr{expr}}); }}
|
||||
.handler = {[&](std::string name, std::string expr) {
|
||||
autoArgs.insert_or_assign(name, AutoArg{AutoArgExpr{expr}});
|
||||
}},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
@@ -71,7 +73,9 @@ MixEvalArgs::MixEvalArgs()
|
||||
.description = "Pass the string *string* as the argument *name* to Nix functions.",
|
||||
.category = category,
|
||||
.labels = {"name", "string"},
|
||||
.handler = {[&](std::string name, std::string s) { autoArgs.insert_or_assign(name, AutoArg{AutoArgString{s}}); }},
|
||||
.handler = {[&](std::string name, std::string s) {
|
||||
autoArgs.insert_or_assign(name, AutoArg{AutoArgString{s}});
|
||||
}},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
@@ -79,8 +83,10 @@ MixEvalArgs::MixEvalArgs()
|
||||
.description = "Pass the contents of file *path* as the argument *name* to Nix functions.",
|
||||
.category = category,
|
||||
.labels = {"name", "path"},
|
||||
.handler = {[&](std::string name, std::string path) { autoArgs.insert_or_assign(name, AutoArg{AutoArgFile{path}}); }},
|
||||
.completer = completePath
|
||||
.handler = {[&](std::string name, std::string path) {
|
||||
autoArgs.insert_or_assign(name, AutoArg{AutoArgFile{path}});
|
||||
}},
|
||||
.completer = completePath,
|
||||
});
|
||||
|
||||
addFlag({
|
||||
@@ -103,18 +109,14 @@ MixEvalArgs::MixEvalArgs()
|
||||
)",
|
||||
.category = category,
|
||||
.labels = {"path"},
|
||||
.handler = {[&](std::string s) {
|
||||
lookupPath.elements.emplace_back(LookupPath::Elem::parse(s));
|
||||
}}
|
||||
.handler = {[&](std::string s) { lookupPath.elements.emplace_back(LookupPath::Elem::parse(s)); }},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
.longName = "impure",
|
||||
.description = "Allow access to mutable paths and repositories.",
|
||||
.category = category,
|
||||
.handler = {[&]() {
|
||||
evalSettings.pureEval = false;
|
||||
}},
|
||||
.handler = {[&]() { evalSettings.pureEval = false; }},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
@@ -126,18 +128,19 @@ MixEvalArgs::MixEvalArgs()
|
||||
auto from = parseFlakeRef(fetchSettings, _from, fs::current_path().string());
|
||||
auto to = parseFlakeRef(fetchSettings, _to, fs::current_path().string());
|
||||
fetchers::Attrs extraAttrs;
|
||||
if (to.subdir != "") extraAttrs["dir"] = to.subdir;
|
||||
if (to.subdir != "")
|
||||
extraAttrs["dir"] = to.subdir;
|
||||
fetchers::overrideRegistry(from.input, to.input, extraAttrs);
|
||||
}},
|
||||
.completer = {[&](AddCompletions & completions, size_t, std::string_view prefix) {
|
||||
completeFlakeRef(completions, openStore(), prefix);
|
||||
}}
|
||||
}},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
.longName = "eval-store",
|
||||
.description =
|
||||
R"(
|
||||
R"(
|
||||
The [URL of the Nix store](@docroot@/store/types/index.md#store-url-format)
|
||||
to use for evaluation, i.e. to store derivations (`.drv` files) and inputs referenced by them.
|
||||
)",
|
||||
@@ -152,20 +155,21 @@ Bindings * MixEvalArgs::getAutoArgs(EvalState & state)
|
||||
auto res = state.buildBindings(autoArgs.size());
|
||||
for (auto & [name, arg] : autoArgs) {
|
||||
auto v = state.allocValue();
|
||||
std::visit(overloaded {
|
||||
[&](const AutoArgExpr & arg) {
|
||||
state.mkThunk_(*v, state.parseExprFromString(arg.expr, compatibilitySettings.nixShellShebangArgumentsRelativeToScript ? state.rootPath(absPath(getCommandBaseDir())) : state.rootPath(".")));
|
||||
},
|
||||
[&](const AutoArgString & arg) {
|
||||
v->mkString(arg.s);
|
||||
},
|
||||
[&](const AutoArgFile & arg) {
|
||||
v->mkString(readFile(arg.path.string()));
|
||||
},
|
||||
[&](const AutoArgStdin & arg) {
|
||||
v->mkString(readFile(STDIN_FILENO));
|
||||
}
|
||||
}, arg);
|
||||
std::visit(
|
||||
overloaded{
|
||||
[&](const AutoArgExpr & arg) {
|
||||
state.mkThunk_(
|
||||
*v,
|
||||
state.parseExprFromString(
|
||||
arg.expr,
|
||||
compatibilitySettings.nixShellShebangArgumentsRelativeToScript
|
||||
? state.rootPath(absPath(getCommandBaseDir()))
|
||||
: state.rootPath(".")));
|
||||
},
|
||||
[&](const AutoArgString & arg) { v->mkString(arg.s); },
|
||||
[&](const AutoArgFile & arg) { v->mkString(readFile(arg.path.string())); },
|
||||
[&](const AutoArgStdin & arg) { v->mkString(readFile(STDIN_FILENO)); }},
|
||||
arg);
|
||||
res.insert(state.symbols.create(name), v);
|
||||
}
|
||||
return res.finish();
|
||||
@@ -174,10 +178,7 @@ Bindings * MixEvalArgs::getAutoArgs(EvalState & state)
|
||||
SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * baseDir)
|
||||
{
|
||||
if (EvalSettings::isPseudoUrl(s)) {
|
||||
auto accessor = fetchers::downloadTarball(
|
||||
state.store,
|
||||
state.fetchSettings,
|
||||
EvalSettings::resolvePseudoUrl(s));
|
||||
auto accessor = fetchers::downloadTarball(state.store, state.fetchSettings, EvalSettings::resolvePseudoUrl(s));
|
||||
auto storePath = fetchToStore(*state.store, SourcePath(accessor), FetchMode::Copy);
|
||||
return state.storePath(storePath);
|
||||
}
|
||||
@@ -186,7 +187,8 @@ SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * bas
|
||||
experimentalFeatureSettings.require(Xp::Flakes);
|
||||
auto flakeRef = parseFlakeRef(fetchSettings, std::string(s.substr(6)), {}, true, false);
|
||||
auto [accessor, lockedRef] = flakeRef.resolve(state.store).lazyFetch(state.store);
|
||||
auto storePath = nix::fetchToStore(*state.store, SourcePath(accessor), FetchMode::Copy, lockedRef.input.getName());
|
||||
auto storePath =
|
||||
nix::fetchToStore(*state.store, SourcePath(accessor), FetchMode::Copy, lockedRef.input.getName());
|
||||
state.allowPath(storePath);
|
||||
return state.storePath(storePath);
|
||||
}
|
||||
@@ -200,4 +202,4 @@ SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * bas
|
||||
return state.rootPath(baseDir ? absPath(s, *baseDir) : absPath(s));
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "editor-for.hh"
|
||||
#include "environment-variables.hh"
|
||||
#include "source-path.hh"
|
||||
#include "nix/cmd/editor-for.hh"
|
||||
#include "nix/util/environment-variables.hh"
|
||||
#include "nix/util/source-path.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -11,14 +11,12 @@ Strings editorFor(const SourcePath & file, uint32_t line)
|
||||
throw Error("cannot open '%s' in an editor because it has no physical path", file);
|
||||
auto editor = getEnv("EDITOR").value_or("cat");
|
||||
auto args = tokenizeString<Strings>(editor);
|
||||
if (line > 0 && (
|
||||
editor.find("emacs") != std::string::npos ||
|
||||
editor.find("nano") != std::string::npos ||
|
||||
editor.find("vim") != std::string::npos ||
|
||||
editor.find("kak") != std::string::npos))
|
||||
if (line > 0
|
||||
&& (editor.find("emacs") != std::string::npos || editor.find("nano") != std::string::npos
|
||||
|| editor.find("vim") != std::string::npos || editor.find("kak") != std::string::npos))
|
||||
args.push_back(fmt("+%d", line));
|
||||
args.push_back(path->string());
|
||||
return args;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "derived-path.hh"
|
||||
#include "realisation.hh"
|
||||
#include "nix/store/derived-path.hh"
|
||||
#include "nix/store/realisation.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
struct SingleBuiltPath;
|
||||
|
||||
struct SingleBuiltPathBuilt {
|
||||
struct SingleBuiltPathBuilt
|
||||
{
|
||||
ref<SingleBuiltPath> drvPath;
|
||||
std::pair<std::string, StorePath> output;
|
||||
|
||||
@@ -18,26 +19,25 @@ struct SingleBuiltPathBuilt {
|
||||
static SingleBuiltPathBuilt parse(const StoreDirConfig & store, std::string_view, std::string_view);
|
||||
nlohmann::json toJSON(const StoreDirConfig & store) const;
|
||||
|
||||
bool operator ==(const SingleBuiltPathBuilt &) const noexcept;
|
||||
std::strong_ordering operator <=>(const SingleBuiltPathBuilt &) const noexcept;
|
||||
bool operator==(const SingleBuiltPathBuilt &) const noexcept;
|
||||
std::strong_ordering operator<=>(const SingleBuiltPathBuilt &) const noexcept;
|
||||
};
|
||||
|
||||
using _SingleBuiltPathRaw = std::variant<
|
||||
DerivedPathOpaque,
|
||||
SingleBuiltPathBuilt
|
||||
>;
|
||||
using _SingleBuiltPathRaw = std::variant<DerivedPathOpaque, SingleBuiltPathBuilt>;
|
||||
|
||||
struct SingleBuiltPath : _SingleBuiltPathRaw {
|
||||
struct SingleBuiltPath : _SingleBuiltPathRaw
|
||||
{
|
||||
using Raw = _SingleBuiltPathRaw;
|
||||
using Raw::Raw;
|
||||
|
||||
using Opaque = DerivedPathOpaque;
|
||||
using Built = SingleBuiltPathBuilt;
|
||||
|
||||
bool operator == (const SingleBuiltPath &) const = default;
|
||||
auto operator <=> (const SingleBuiltPath &) const = default;
|
||||
bool operator==(const SingleBuiltPath &) const = default;
|
||||
auto operator<=>(const SingleBuiltPath &) const = default;
|
||||
|
||||
inline const Raw & raw() const {
|
||||
inline const Raw & raw() const
|
||||
{
|
||||
return static_cast<const Raw &>(*this);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ struct SingleBuiltPath : _SingleBuiltPathRaw {
|
||||
|
||||
static inline ref<SingleBuiltPath> staticDrv(StorePath drvPath)
|
||||
{
|
||||
return make_ref<SingleBuiltPath>(SingleBuiltPath::Opaque { drvPath });
|
||||
return make_ref<SingleBuiltPath>(SingleBuiltPath::Opaque{drvPath});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,40 +59,41 @@ static inline ref<SingleBuiltPath> staticDrv(StorePath drvPath)
|
||||
*
|
||||
* See 'BuiltPath' for more an explanation.
|
||||
*/
|
||||
struct BuiltPathBuilt {
|
||||
struct BuiltPathBuilt
|
||||
{
|
||||
ref<SingleBuiltPath> drvPath;
|
||||
std::map<std::string, StorePath> outputs;
|
||||
|
||||
bool operator == (const BuiltPathBuilt &) const noexcept;
|
||||
bool operator==(const BuiltPathBuilt &) const noexcept;
|
||||
// TODO libc++ 16 (used by darwin) missing `std::map::operator <=>`, can't do yet.
|
||||
//std::strong_ordering operator <=> (const BuiltPathBuilt &) const noexcept;
|
||||
// std::strong_ordering operator <=> (const BuiltPathBuilt &) const noexcept;
|
||||
|
||||
std::string to_string(const StoreDirConfig & store) const;
|
||||
static BuiltPathBuilt parse(const StoreDirConfig & store, std::string_view, std::string_view);
|
||||
nlohmann::json toJSON(const StoreDirConfig & store) const;
|
||||
};
|
||||
|
||||
using _BuiltPathRaw = std::variant<
|
||||
DerivedPath::Opaque,
|
||||
BuiltPathBuilt
|
||||
>;
|
||||
using _BuiltPathRaw = std::variant<DerivedPath::Opaque, BuiltPathBuilt>;
|
||||
|
||||
/**
|
||||
* A built path. Similar to a DerivedPath, but enriched with the corresponding
|
||||
* output path(s).
|
||||
*/
|
||||
struct BuiltPath : _BuiltPathRaw {
|
||||
struct BuiltPath : _BuiltPathRaw
|
||||
{
|
||||
using Raw = _BuiltPathRaw;
|
||||
using Raw::Raw;
|
||||
|
||||
using Opaque = DerivedPathOpaque;
|
||||
using Built = BuiltPathBuilt;
|
||||
|
||||
bool operator == (const BuiltPath &) const = default;
|
||||
// TODO libc++ 16 (used by darwin) missing `std::map::operator <=>`, can't do yet.
|
||||
//auto operator <=> (const BuiltPath &) const = default;
|
||||
bool operator==(const BuiltPath &) const = default;
|
||||
|
||||
inline const Raw & raw() const {
|
||||
// TODO libc++ 16 (used by darwin) missing `std::map::operator <=>`, can't do yet.
|
||||
// auto operator <=> (const BuiltPath &) const = default;
|
||||
|
||||
inline const Raw & raw() const
|
||||
{
|
||||
return static_cast<const Raw &>(*this);
|
||||
}
|
||||
|
||||
@@ -104,4 +105,4 @@ struct BuiltPath : _BuiltPathRaw {
|
||||
|
||||
typedef std::vector<BuiltPath> BuiltPaths;
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "installable-value.hh"
|
||||
#include "command.hh"
|
||||
#include "nix/cmd/installable-value.hh"
|
||||
#include "nix/cmd/command.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -20,4 +20,4 @@ struct InstallableValueCommand : InstallableCommand
|
||||
void run(ref<Store> store, ref<Installable> installable) override;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "installable-value.hh"
|
||||
#include "args.hh"
|
||||
#include "common-eval-args.hh"
|
||||
#include "path.hh"
|
||||
#include "flake/lockfile.hh"
|
||||
#include "nix/cmd/installable-value.hh"
|
||||
#include "nix/util/args.hh"
|
||||
#include "nix/cmd/common-eval-args.hh"
|
||||
#include "nix/store/path.hh"
|
||||
#include "nix/flake/lockfile.hh"
|
||||
|
||||
#include <optional>
|
||||
|
||||
@@ -374,4 +374,4 @@ void printClosureDiff(
|
||||
*/
|
||||
void createOutLinks(const std::filesystem::path & outLink, const BuiltPaths & buildables, LocalFSStore & store);
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "args.hh"
|
||||
#include "canon-path.hh"
|
||||
#include "common-args.hh"
|
||||
#include "search-path.hh"
|
||||
#include "nix/util/args.hh"
|
||||
#include "nix/util/canon-path.hh"
|
||||
#include "nix/main/common-args.hh"
|
||||
#include "nix/expr/search-path.hh"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
@@ -12,7 +12,9 @@ namespace nix {
|
||||
|
||||
class Store;
|
||||
|
||||
namespace fetchers { struct Settings; }
|
||||
namespace fetchers {
|
||||
struct Settings;
|
||||
}
|
||||
|
||||
class EvalState;
|
||||
struct EvalSettings;
|
||||
@@ -20,7 +22,9 @@ struct CompatibilitySettings;
|
||||
class Bindings;
|
||||
struct SourcePath;
|
||||
|
||||
namespace flake { struct Settings; }
|
||||
namespace flake {
|
||||
struct Settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Get rid of global setttings variables
|
||||
@@ -55,10 +59,23 @@ struct MixEvalArgs : virtual Args, virtual MixRepair
|
||||
std::optional<std::string> evalStoreUrl;
|
||||
|
||||
private:
|
||||
struct AutoArgExpr { std::string expr; };
|
||||
struct AutoArgString { std::string s; };
|
||||
struct AutoArgFile { std::filesystem::path path; };
|
||||
struct AutoArgStdin { };
|
||||
struct AutoArgExpr
|
||||
{
|
||||
std::string expr;
|
||||
};
|
||||
|
||||
struct AutoArgString
|
||||
{
|
||||
std::string s;
|
||||
};
|
||||
|
||||
struct AutoArgFile
|
||||
{
|
||||
std::filesystem::path path;
|
||||
};
|
||||
|
||||
struct AutoArgStdin
|
||||
{};
|
||||
|
||||
using AutoArg = std::variant<AutoArgExpr, AutoArgString, AutoArgFile, AutoArgStdin>;
|
||||
|
||||
@@ -70,4 +87,4 @@ private:
|
||||
*/
|
||||
SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * baseDir = nullptr);
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "config.hh"
|
||||
#include "nix/util/configuration.hh"
|
||||
|
||||
namespace nix {
|
||||
struct CompatibilitySettings : public Config
|
||||
@@ -33,4 +33,4 @@ struct CompatibilitySettings : public Config
|
||||
)"};
|
||||
};
|
||||
|
||||
};
|
||||
}; // namespace nix
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "types.hh"
|
||||
#include "source-path.hh"
|
||||
#include "nix/util/types.hh"
|
||||
#include "nix/util/source-path.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -12,4 +12,4 @@ namespace nix {
|
||||
*/
|
||||
Strings editorFor(const SourcePath & file, uint32_t line);
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
@@ -1,22 +1,22 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "globals.hh"
|
||||
#include "installable-value.hh"
|
||||
#include "outputs-spec.hh"
|
||||
#include "command.hh"
|
||||
#include "attr-path.hh"
|
||||
#include "common-eval-args.hh"
|
||||
#include "derivations.hh"
|
||||
#include "eval-inline.hh"
|
||||
#include "eval.hh"
|
||||
#include "get-drvs.hh"
|
||||
#include "store-api.hh"
|
||||
#include "shared.hh"
|
||||
#include "eval-cache.hh"
|
||||
#include "url.hh"
|
||||
#include "registry.hh"
|
||||
#include "build-result.hh"
|
||||
#include "nix/store/globals.hh"
|
||||
#include "nix/cmd/installable-value.hh"
|
||||
#include "nix/store/outputs-spec.hh"
|
||||
#include "nix/cmd/command.hh"
|
||||
#include "nix/expr/attr-path.hh"
|
||||
#include "nix/cmd/common-eval-args.hh"
|
||||
#include "nix/store/derivations.hh"
|
||||
#include "nix/expr/eval-inline.hh"
|
||||
#include "nix/expr/eval.hh"
|
||||
#include "nix/expr/get-drvs.hh"
|
||||
#include "nix/store/store-api.hh"
|
||||
#include "nix/main/shared.hh"
|
||||
#include "nix/expr/eval-cache.hh"
|
||||
#include "nix/util/url.hh"
|
||||
#include "nix/fetchers/registry.hh"
|
||||
#include "nix/store/build-result.hh"
|
||||
|
||||
#include <regex>
|
||||
#include <queue>
|
||||
@@ -39,7 +39,10 @@ class InstallableAttrPath : public InstallableValue
|
||||
const std::string & attrPath,
|
||||
ExtendedOutputsSpec extendedOutputsSpec);
|
||||
|
||||
std::string what() const override { return attrPath; };
|
||||
std::string what() const override
|
||||
{
|
||||
return attrPath;
|
||||
};
|
||||
|
||||
std::pair<Value *, PosIdx> toValue(EvalState & state) override;
|
||||
|
||||
@@ -55,4 +58,4 @@ public:
|
||||
ExtendedOutputsSpec extendedOutputsSpec);
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "installables.hh"
|
||||
#include "nix/cmd/installables.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -11,8 +11,10 @@ struct InstallableDerivedPath : Installable
|
||||
DerivedPath derivedPath;
|
||||
|
||||
InstallableDerivedPath(ref<Store> store, DerivedPath && derivedPath)
|
||||
: store(store), derivedPath(std::move(derivedPath))
|
||||
{ }
|
||||
: store(store)
|
||||
, derivedPath(std::move(derivedPath))
|
||||
{
|
||||
}
|
||||
|
||||
std::string what() const override;
|
||||
|
||||
@@ -20,10 +22,8 @@ struct InstallableDerivedPath : Installable
|
||||
|
||||
std::optional<StorePath> getStorePath() override;
|
||||
|
||||
static InstallableDerivedPath parse(
|
||||
ref<Store> store,
|
||||
std::string_view prefix,
|
||||
ExtendedOutputsSpec extendedOutputsSpec);
|
||||
static InstallableDerivedPath
|
||||
parse(ref<Store> store, std::string_view prefix, ExtendedOutputsSpec extendedOutputsSpec);
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "common-eval-args.hh"
|
||||
#include "installable-value.hh"
|
||||
#include "nix/cmd/common-eval-args.hh"
|
||||
#include "nix/cmd/installable-value.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -18,7 +18,8 @@ struct ExtraPathInfoFlake : ExtraPathInfoValue
|
||||
/**
|
||||
* Extra struct to get around C++ designated initializer limitations
|
||||
*/
|
||||
struct Flake {
|
||||
struct Flake
|
||||
{
|
||||
FlakeRef originalRef;
|
||||
FlakeRef lockedRef;
|
||||
};
|
||||
@@ -26,8 +27,10 @@ struct ExtraPathInfoFlake : ExtraPathInfoValue
|
||||
Flake flake;
|
||||
|
||||
ExtraPathInfoFlake(Value && v, Flake && f)
|
||||
: ExtraPathInfoValue(std::move(v)), flake(std::move(f))
|
||||
{ }
|
||||
: ExtraPathInfoValue(std::move(v))
|
||||
, flake(std::move(f))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct InstallableFlake : InstallableValue
|
||||
@@ -49,7 +52,10 @@ struct InstallableFlake : InstallableValue
|
||||
Strings prefixes,
|
||||
const flake::LockFlags & lockFlags);
|
||||
|
||||
std::string what() const override { return flakeRef.to_string() + "#" + *attrPaths.begin(); }
|
||||
std::string what() const override
|
||||
{
|
||||
return flakeRef.to_string() + "#" + *attrPaths.begin();
|
||||
}
|
||||
|
||||
std::vector<std::string> getActualAttrPaths();
|
||||
|
||||
@@ -61,8 +67,7 @@ struct InstallableFlake : InstallableValue
|
||||
* Get a cursor to every attrpath in getActualAttrPaths() that
|
||||
* exists. However if none exists, throw an exception.
|
||||
*/
|
||||
std::vector<ref<eval_cache::AttrCursor>>
|
||||
getCursors(EvalState & state) override;
|
||||
std::vector<ref<eval_cache::AttrCursor>> getCursors(EvalState & state) override;
|
||||
|
||||
std::shared_ptr<flake::LockedFlake> getLockedFlake() const;
|
||||
|
||||
@@ -79,11 +84,9 @@ struct InstallableFlake : InstallableValue
|
||||
*/
|
||||
static inline FlakeRef defaultNixpkgsFlakeRef()
|
||||
{
|
||||
return FlakeRef::fromAttrs(fetchSettings, {{"type","indirect"}, {"id", "nixpkgs"}});
|
||||
return FlakeRef::fromAttrs(fetchSettings, {{"type", "indirect"}, {"id", "nixpkgs"}});
|
||||
}
|
||||
|
||||
ref<eval_cache::EvalCache> openEvalCache(
|
||||
EvalState & state,
|
||||
std::shared_ptr<flake::LockedFlake> lockedFlake);
|
||||
ref<eval_cache::EvalCache> openEvalCache(EvalState & state, std::shared_ptr<flake::LockedFlake> lockedFlake);
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
@@ -1,15 +1,18 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "installables.hh"
|
||||
#include "flake/flake.hh"
|
||||
#include "nix/cmd/installables.hh"
|
||||
#include "nix/flake/flake.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
struct PackageInfo;
|
||||
struct SourceExprCommand;
|
||||
|
||||
namespace eval_cache { class EvalCache; class AttrCursor; }
|
||||
namespace eval_cache {
|
||||
class EvalCache;
|
||||
class AttrCursor;
|
||||
} // namespace eval_cache
|
||||
|
||||
struct App
|
||||
{
|
||||
@@ -36,7 +39,8 @@ struct ExtraPathInfoValue : ExtraPathInfo
|
||||
/**
|
||||
* Extra struct to get around C++ designated initializer limitations
|
||||
*/
|
||||
struct Value {
|
||||
struct Value
|
||||
{
|
||||
/**
|
||||
* An optional priority for use with "build envs". See Package
|
||||
*/
|
||||
@@ -60,7 +64,8 @@ struct ExtraPathInfoValue : ExtraPathInfo
|
||||
|
||||
ExtraPathInfoValue(Value && v)
|
||||
: value(std::move(v))
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~ExtraPathInfoValue() = default;
|
||||
};
|
||||
@@ -73,9 +78,12 @@ struct InstallableValue : Installable
|
||||
{
|
||||
ref<EvalState> state;
|
||||
|
||||
InstallableValue(ref<EvalState> state) : state(state) {}
|
||||
InstallableValue(ref<EvalState> state)
|
||||
: state(state)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~InstallableValue() { }
|
||||
virtual ~InstallableValue() {}
|
||||
|
||||
virtual std::pair<Value *, PosIdx> toValue(EvalState & state) = 0;
|
||||
|
||||
@@ -84,15 +92,13 @@ struct InstallableValue : Installable
|
||||
* However if none exists, throw exception instead of returning
|
||||
* empty vector.
|
||||
*/
|
||||
virtual std::vector<ref<eval_cache::AttrCursor>>
|
||||
getCursors(EvalState & state);
|
||||
virtual std::vector<ref<eval_cache::AttrCursor>> getCursors(EvalState & state);
|
||||
|
||||
/**
|
||||
* Get the first and most preferred cursor this Installable could
|
||||
* refer to, or throw an exception if none exists.
|
||||
*/
|
||||
virtual ref<eval_cache::AttrCursor>
|
||||
getCursor(EvalState & state);
|
||||
virtual ref<eval_cache::AttrCursor> getCursor(EvalState & state);
|
||||
|
||||
UnresolvedApp toApp(EvalState & state);
|
||||
|
||||
@@ -115,7 +121,8 @@ protected:
|
||||
* @result A derived path (with empty info, for now) if the value
|
||||
* matched the above criteria.
|
||||
*/
|
||||
std::optional<DerivedPathWithInfo> trySinglePathToDerivedPaths(Value & v, const PosIdx pos, std::string_view errorCtx);
|
||||
std::optional<DerivedPathWithInfo>
|
||||
trySinglePathToDerivedPaths(Value & v, const PosIdx pos, std::string_view errorCtx);
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
@@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "path.hh"
|
||||
#include "outputs-spec.hh"
|
||||
#include "derived-path.hh"
|
||||
#include "built-path.hh"
|
||||
#include "store-api.hh"
|
||||
#include "build-result.hh"
|
||||
#include "nix/store/path.hh"
|
||||
#include "nix/store/outputs-spec.hh"
|
||||
#include "nix/store/derived-path.hh"
|
||||
#include "nix/cmd/built-path.hh"
|
||||
#include "nix/store/store-api.hh"
|
||||
#include "nix/store/build-result.hh"
|
||||
|
||||
#include <optional>
|
||||
|
||||
@@ -112,7 +112,7 @@ typedef std::vector<ref<Installable>> Installables;
|
||||
*/
|
||||
struct Installable
|
||||
{
|
||||
virtual ~Installable() { }
|
||||
virtual ~Installable() {}
|
||||
|
||||
/**
|
||||
* What Installable is this?
|
||||
@@ -168,37 +168,19 @@ struct Installable
|
||||
BuildMode bMode = bmNormal);
|
||||
|
||||
static std::set<StorePath> toStorePathSet(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
OperateOn operateOn,
|
||||
const Installables & installables);
|
||||
ref<Store> evalStore, ref<Store> store, Realise mode, OperateOn operateOn, const Installables & installables);
|
||||
|
||||
static std::vector<StorePath> toStorePaths(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
OperateOn operateOn,
|
||||
const Installables & installables);
|
||||
ref<Store> evalStore, ref<Store> store, Realise mode, OperateOn operateOn, const Installables & installables);
|
||||
|
||||
static StorePath toStorePath(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
OperateOn operateOn,
|
||||
ref<Installable> installable);
|
||||
ref<Store> evalStore, ref<Store> store, Realise mode, OperateOn operateOn, ref<Installable> installable);
|
||||
|
||||
static std::set<StorePath> toDerivations(
|
||||
ref<Store> store,
|
||||
const Installables & installables,
|
||||
bool useDeriver = false);
|
||||
static std::set<StorePath>
|
||||
toDerivations(ref<Store> store, const Installables & installables, bool useDeriver = false);
|
||||
|
||||
static BuiltPaths toBuiltPaths(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
OperateOn operateOn,
|
||||
const Installables & installables);
|
||||
ref<Store> evalStore, ref<Store> store, Realise mode, OperateOn operateOn, const Installables & installables);
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
typedef std::function<void(int, char * *)> MainFunction;
|
||||
typedef std::function<void(int, char **)> MainFunction;
|
||||
|
||||
struct RegisterLegacyCommand
|
||||
{
|
||||
@@ -16,9 +16,10 @@ struct RegisterLegacyCommand
|
||||
|
||||
RegisterLegacyCommand(const std::string & name, MainFunction fun)
|
||||
{
|
||||
if (!commands) commands = new Commands;
|
||||
if (!commands)
|
||||
commands = new Commands;
|
||||
(*commands)[name] = fun;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
@@ -14,4 +14,4 @@ namespace nix {
|
||||
*/
|
||||
std::string renderMarkdownToTerminal(std::string_view markdown);
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
23
src/libcmd/include/nix/cmd/meson.build
Normal file
23
src/libcmd/include/nix/cmd/meson.build
Normal file
@@ -0,0 +1,23 @@
|
||||
# Public headers directory
|
||||
|
||||
include_dirs = [include_directories('../..')]
|
||||
|
||||
headers = files(
|
||||
'built-path.hh',
|
||||
'command-installable-value.hh',
|
||||
'command.hh',
|
||||
'common-eval-args.hh',
|
||||
'compatibility-settings.hh',
|
||||
'editor-for.hh',
|
||||
'installable-attr-path.hh',
|
||||
'installable-derived-path.hh',
|
||||
'installable-flake.hh',
|
||||
'installable-value.hh',
|
||||
'installables.hh',
|
||||
'legacy.hh',
|
||||
'markdown.hh',
|
||||
'misc-store-flags.hh',
|
||||
'network-proxy.hh',
|
||||
'repl-interacter.hh',
|
||||
'repl.hh',
|
||||
)
|
||||
@@ -1,21 +1,25 @@
|
||||
#include "args.hh"
|
||||
#include "content-address.hh"
|
||||
#include "nix/util/args.hh"
|
||||
#include "nix/store/content-address.hh"
|
||||
|
||||
namespace nix::flag {
|
||||
|
||||
Args::Flag hashAlgo(std::string && longName, HashAlgorithm * ha);
|
||||
|
||||
static inline Args::Flag hashAlgo(HashAlgorithm * ha)
|
||||
{
|
||||
return hashAlgo("hash-algo", ha);
|
||||
}
|
||||
|
||||
Args::Flag hashAlgoOpt(std::string && longName, std::optional<HashAlgorithm> * oha);
|
||||
Args::Flag hashFormatWithDefault(std::string && longName, HashFormat * hf);
|
||||
Args::Flag hashFormatOpt(std::string && longName, std::optional<HashFormat> * ohf);
|
||||
|
||||
static inline Args::Flag hashAlgoOpt(std::optional<HashAlgorithm> * oha)
|
||||
{
|
||||
return hashAlgoOpt("hash-algo", oha);
|
||||
}
|
||||
|
||||
Args::Flag fileIngestionMethod(FileIngestionMethod * method);
|
||||
Args::Flag contentAddressMethod(ContentAddressMethod * method);
|
||||
|
||||
}
|
||||
} // namespace nix::flag
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "types.hh"
|
||||
#include "nix/util/types.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -19,4 +19,4 @@ extern const StringSet networkProxyVariables;
|
||||
*/
|
||||
bool haveNetworkProxyConnection();
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
/// @file
|
||||
|
||||
#include "finally.hh"
|
||||
#include "types.hh"
|
||||
#include "nix/util/finally.hh"
|
||||
#include "nix/util/types.hh"
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
@@ -11,10 +11,11 @@ namespace nix {
|
||||
namespace detail {
|
||||
/** Provides the completion hooks for the repl, without exposing its complete
|
||||
* internals. */
|
||||
struct ReplCompleterMixin {
|
||||
struct ReplCompleterMixin
|
||||
{
|
||||
virtual StringSet completePrefix(const std::string & prefix) = 0;
|
||||
};
|
||||
};
|
||||
}; // namespace detail
|
||||
|
||||
enum class ReplPromptType {
|
||||
ReplPrompt,
|
||||
@@ -29,7 +30,7 @@ public:
|
||||
virtual Guard init(detail::ReplCompleterMixin * repl) = 0;
|
||||
/** Returns a boolean of whether the interacter got EOF */
|
||||
virtual bool getLine(std::string & input, ReplPromptType promptType) = 0;
|
||||
virtual ~ReplInteracter(){};
|
||||
virtual ~ReplInteracter() {};
|
||||
};
|
||||
|
||||
class ReadlineLikeInteracter : public virtual ReplInteracter
|
||||
@@ -40,9 +41,10 @@ public:
|
||||
: historyFile(historyFile)
|
||||
{
|
||||
}
|
||||
|
||||
virtual Guard init(detail::ReplCompleterMixin * repl) override;
|
||||
virtual bool getLine(std::string & input, ReplPromptType promptType) override;
|
||||
virtual ~ReadlineLikeInteracter() override;
|
||||
};
|
||||
|
||||
};
|
||||
}; // namespace nix
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "eval.hh"
|
||||
#include "nix/expr/eval.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -12,12 +12,12 @@ struct AbstractNixRepl
|
||||
|
||||
AbstractNixRepl(ref<EvalState> state)
|
||||
: state(state)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~AbstractNixRepl()
|
||||
{ }
|
||||
virtual ~AbstractNixRepl() {}
|
||||
|
||||
typedef std::vector<std::pair<Value*,std::string>> AnnotatedValues;
|
||||
typedef std::vector<std::pair<Value *, std::string>> AnnotatedValues;
|
||||
|
||||
using RunNix = void(Path program, const Strings & args, const std::optional<std::string> & input);
|
||||
|
||||
@@ -33,13 +33,11 @@ struct AbstractNixRepl
|
||||
std::function<AnnotatedValues()> getValues,
|
||||
RunNix * runNix = nullptr);
|
||||
|
||||
static ReplExitStatus runSimple(
|
||||
ref<EvalState> evalState,
|
||||
const ValMap & extraEnv);
|
||||
static ReplExitStatus runSimple(ref<EvalState> evalState, const ValMap & extraEnv);
|
||||
|
||||
virtual void initEnv() = 0;
|
||||
|
||||
virtual ReplExitStatus mainLoop() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
@@ -1,21 +1,21 @@
|
||||
#include "globals.hh"
|
||||
#include "installable-attr-path.hh"
|
||||
#include "outputs-spec.hh"
|
||||
#include "util.hh"
|
||||
#include "command.hh"
|
||||
#include "attr-path.hh"
|
||||
#include "common-eval-args.hh"
|
||||
#include "derivations.hh"
|
||||
#include "eval-inline.hh"
|
||||
#include "eval.hh"
|
||||
#include "get-drvs.hh"
|
||||
#include "store-api.hh"
|
||||
#include "shared.hh"
|
||||
#include "flake/flake.hh"
|
||||
#include "eval-cache.hh"
|
||||
#include "url.hh"
|
||||
#include "registry.hh"
|
||||
#include "build-result.hh"
|
||||
#include "nix/store/globals.hh"
|
||||
#include "nix/cmd/installable-attr-path.hh"
|
||||
#include "nix/store/outputs-spec.hh"
|
||||
#include "nix/util/util.hh"
|
||||
#include "nix/cmd/command.hh"
|
||||
#include "nix/expr/attr-path.hh"
|
||||
#include "nix/cmd/common-eval-args.hh"
|
||||
#include "nix/store/derivations.hh"
|
||||
#include "nix/expr/eval-inline.hh"
|
||||
#include "nix/expr/eval.hh"
|
||||
#include "nix/expr/get-drvs.hh"
|
||||
#include "nix/store/store-api.hh"
|
||||
#include "nix/main/shared.hh"
|
||||
#include "nix/flake/flake.hh"
|
||||
#include "nix/expr/eval-cache.hh"
|
||||
#include "nix/util/url.hh"
|
||||
#include "nix/fetchers/registry.hh"
|
||||
#include "nix/store/build-result.hh"
|
||||
|
||||
#include <regex>
|
||||
#include <queue>
|
||||
@@ -35,7 +35,8 @@ InstallableAttrPath::InstallableAttrPath(
|
||||
, v(allocRootValue(v))
|
||||
, attrPath(attrPath)
|
||||
, extendedOutputsSpec(std::move(extendedOutputsSpec))
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
std::pair<Value *, PosIdx> InstallableAttrPath::toValue(EvalState & state)
|
||||
{
|
||||
@@ -48,12 +49,9 @@ DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths()
|
||||
{
|
||||
auto [v, pos] = toValue(*state);
|
||||
|
||||
if (std::optional derivedPathWithInfo = trySinglePathToDerivedPaths(
|
||||
*v,
|
||||
pos,
|
||||
fmt("while evaluating the attribute '%s'", attrPath)))
|
||||
{
|
||||
return { *derivedPathWithInfo };
|
||||
if (std::optional derivedPathWithInfo =
|
||||
trySinglePathToDerivedPaths(*v, pos, fmt("while evaluating the attribute '%s'", attrPath))) {
|
||||
return {*derivedPathWithInfo};
|
||||
}
|
||||
|
||||
Bindings & autoArgs = *cmd.getAutoArgs(*state);
|
||||
@@ -70,19 +68,19 @@ DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths()
|
||||
if (!drvPath)
|
||||
throw Error("'%s' is not a derivation", what());
|
||||
|
||||
auto newOutputs = std::visit(overloaded {
|
||||
[&](const ExtendedOutputsSpec::Default & d) -> OutputsSpec {
|
||||
std::set<std::string> outputsToInstall;
|
||||
for (auto & output : packageInfo.queryOutputs(false, true))
|
||||
outputsToInstall.insert(output.first);
|
||||
if (outputsToInstall.empty())
|
||||
outputsToInstall.insert("out");
|
||||
return OutputsSpec::Names { std::move(outputsToInstall) };
|
||||
auto newOutputs = std::visit(
|
||||
overloaded{
|
||||
[&](const ExtendedOutputsSpec::Default & d) -> OutputsSpec {
|
||||
std::set<std::string> outputsToInstall;
|
||||
for (auto & output : packageInfo.queryOutputs(false, true))
|
||||
outputsToInstall.insert(output.first);
|
||||
if (outputsToInstall.empty())
|
||||
outputsToInstall.insert("out");
|
||||
return OutputsSpec::Names{std::move(outputsToInstall)};
|
||||
},
|
||||
[&](const ExtendedOutputsSpec::Explicit & e) -> OutputsSpec { return e; },
|
||||
},
|
||||
[&](const ExtendedOutputsSpec::Explicit & e) -> OutputsSpec {
|
||||
return e;
|
||||
},
|
||||
}, extendedOutputsSpec.raw);
|
||||
extendedOutputsSpec.raw);
|
||||
|
||||
auto [iter, didInsert] = byDrvPath.emplace(*drvPath, newOutputs);
|
||||
|
||||
@@ -93,11 +91,12 @@ DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths()
|
||||
DerivedPathsWithInfo res;
|
||||
for (auto & [drvPath, outputs] : byDrvPath)
|
||||
res.push_back({
|
||||
.path = DerivedPath::Built {
|
||||
.drvPath = makeConstantStorePathRef(drvPath),
|
||||
.outputs = outputs,
|
||||
},
|
||||
.info = make_ref<ExtraPathInfoValue>(ExtraPathInfoValue::Value {
|
||||
.path =
|
||||
DerivedPath::Built{
|
||||
.drvPath = makeConstantStorePathRef(drvPath),
|
||||
.outputs = outputs,
|
||||
},
|
||||
.info = make_ref<ExtraPathInfoValue>(ExtraPathInfoValue::Value{
|
||||
.extendedOutputsSpec = outputs,
|
||||
/* FIXME: reconsider backwards compatibility above
|
||||
so we can fill in this info. */
|
||||
@@ -115,10 +114,12 @@ InstallableAttrPath InstallableAttrPath::parse(
|
||||
ExtendedOutputsSpec extendedOutputsSpec)
|
||||
{
|
||||
return {
|
||||
state, cmd, v,
|
||||
prefix == "." ? "" : std::string { prefix },
|
||||
state,
|
||||
cmd,
|
||||
v,
|
||||
prefix == "." ? "" : std::string{prefix},
|
||||
std::move(extendedOutputsSpec),
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "installable-derived-path.hh"
|
||||
#include "derivations.hh"
|
||||
#include "nix/cmd/installable-derived-path.hh"
|
||||
#include "nix/store/derivations.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -21,35 +21,35 @@ std::optional<StorePath> InstallableDerivedPath::getStorePath()
|
||||
return derivedPath.getBaseStorePath();
|
||||
}
|
||||
|
||||
InstallableDerivedPath InstallableDerivedPath::parse(
|
||||
ref<Store> store,
|
||||
std::string_view prefix,
|
||||
ExtendedOutputsSpec extendedOutputsSpec)
|
||||
InstallableDerivedPath
|
||||
InstallableDerivedPath::parse(ref<Store> store, std::string_view prefix, ExtendedOutputsSpec extendedOutputsSpec)
|
||||
{
|
||||
auto derivedPath = std::visit(overloaded {
|
||||
// If the user did not use ^, we treat the output more
|
||||
// liberally: we accept a symlink chain or an actual
|
||||
// store path.
|
||||
[&](const ExtendedOutputsSpec::Default &) -> DerivedPath {
|
||||
auto storePath = store->followLinksToStorePath(prefix);
|
||||
return DerivedPath::Opaque {
|
||||
.path = std::move(storePath),
|
||||
};
|
||||
auto derivedPath = std::visit(
|
||||
overloaded{
|
||||
// If the user did not use ^, we treat the output more
|
||||
// liberally: we accept a symlink chain or an actual
|
||||
// store path.
|
||||
[&](const ExtendedOutputsSpec::Default &) -> DerivedPath {
|
||||
auto storePath = store->followLinksToStorePath(prefix);
|
||||
return DerivedPath::Opaque{
|
||||
.path = std::move(storePath),
|
||||
};
|
||||
},
|
||||
// If the user did use ^, we just do exactly what is written.
|
||||
[&](const ExtendedOutputsSpec::Explicit & outputSpec) -> DerivedPath {
|
||||
auto drv = make_ref<SingleDerivedPath>(SingleDerivedPath::parse(*store, prefix));
|
||||
drvRequireExperiment(*drv);
|
||||
return DerivedPath::Built{
|
||||
.drvPath = std::move(drv),
|
||||
.outputs = outputSpec,
|
||||
};
|
||||
},
|
||||
},
|
||||
// If the user did use ^, we just do exactly what is written.
|
||||
[&](const ExtendedOutputsSpec::Explicit & outputSpec) -> DerivedPath {
|
||||
auto drv = make_ref<SingleDerivedPath>(SingleDerivedPath::parse(*store, prefix));
|
||||
drvRequireExperiment(*drv);
|
||||
return DerivedPath::Built {
|
||||
.drvPath = std::move(drv),
|
||||
.outputs = outputSpec,
|
||||
};
|
||||
},
|
||||
}, extendedOutputsSpec.raw);
|
||||
return InstallableDerivedPath {
|
||||
extendedOutputsSpec.raw);
|
||||
return InstallableDerivedPath{
|
||||
store,
|
||||
std::move(derivedPath),
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
#include "globals.hh"
|
||||
#include "installable-flake.hh"
|
||||
#include "installable-derived-path.hh"
|
||||
#include "outputs-spec.hh"
|
||||
#include "util.hh"
|
||||
#include "command.hh"
|
||||
#include "attr-path.hh"
|
||||
#include "common-eval-args.hh"
|
||||
#include "derivations.hh"
|
||||
#include "eval-inline.hh"
|
||||
#include "eval.hh"
|
||||
#include "get-drvs.hh"
|
||||
#include "store-api.hh"
|
||||
#include "shared.hh"
|
||||
#include "flake/flake.hh"
|
||||
#include "eval-cache.hh"
|
||||
#include "url.hh"
|
||||
#include "registry.hh"
|
||||
#include "build-result.hh"
|
||||
#include "nix/store/globals.hh"
|
||||
#include "nix/cmd/installable-flake.hh"
|
||||
#include "nix/cmd/installable-derived-path.hh"
|
||||
#include "nix/store/outputs-spec.hh"
|
||||
#include "nix/util/util.hh"
|
||||
#include "nix/cmd/command.hh"
|
||||
#include "nix/expr/attr-path.hh"
|
||||
#include "nix/cmd/common-eval-args.hh"
|
||||
#include "nix/store/derivations.hh"
|
||||
#include "nix/expr/eval-inline.hh"
|
||||
#include "nix/expr/eval.hh"
|
||||
#include "nix/expr/get-drvs.hh"
|
||||
#include "nix/store/store-api.hh"
|
||||
#include "nix/main/shared.hh"
|
||||
#include "nix/flake/flake.hh"
|
||||
#include "nix/expr/eval-cache.hh"
|
||||
#include "nix/util/url.hh"
|
||||
#include "nix/fetchers/registry.hh"
|
||||
#include "nix/store/build-result.hh"
|
||||
|
||||
#include <regex>
|
||||
#include <queue>
|
||||
@@ -28,8 +28,8 @@ namespace nix {
|
||||
std::vector<std::string> InstallableFlake::getActualAttrPaths()
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
if (attrPaths.size() == 1 && attrPaths.front().starts_with(".")){
|
||||
attrPaths.front().erase(0,1);
|
||||
if (attrPaths.size() == 1 && attrPaths.front().starts_with(".")) {
|
||||
attrPaths.front().erase(0, 1);
|
||||
res.push_back(attrPaths.front());
|
||||
return res;
|
||||
}
|
||||
@@ -47,8 +47,11 @@ static std::string showAttrPaths(const std::vector<std::string> & paths)
|
||||
{
|
||||
std::string s;
|
||||
for (const auto & [n, i] : enumerate(paths)) {
|
||||
if (n > 0) s += n + 1 == paths.size() ? " or " : ", ";
|
||||
s += '\''; s += i; s += '\'';
|
||||
if (n > 0)
|
||||
s += n + 1 == paths.size() ? " or " : ", ";
|
||||
s += '\'';
|
||||
s += i;
|
||||
s += '\'';
|
||||
}
|
||||
return s;
|
||||
}
|
||||
@@ -62,12 +65,12 @@ InstallableFlake::InstallableFlake(
|
||||
Strings attrPaths,
|
||||
Strings prefixes,
|
||||
const flake::LockFlags & lockFlags)
|
||||
: InstallableValue(state),
|
||||
flakeRef(flakeRef),
|
||||
attrPaths(fragment == "" ? attrPaths : Strings{(std::string) fragment}),
|
||||
prefixes(fragment == "" ? Strings{} : prefixes),
|
||||
extendedOutputsSpec(std::move(extendedOutputsSpec)),
|
||||
lockFlags(lockFlags)
|
||||
: InstallableValue(state)
|
||||
, flakeRef(flakeRef)
|
||||
, attrPaths(fragment == "" ? attrPaths : Strings{(std::string) fragment})
|
||||
, prefixes(fragment == "" ? Strings{} : prefixes)
|
||||
, extendedOutputsSpec(std::move(extendedOutputsSpec))
|
||||
, lockFlags(lockFlags)
|
||||
{
|
||||
if (cmd && cmd->getAutoArgs(*state)->size())
|
||||
throw UsageError("'--arg' and '--argstr' are incompatible with flakes");
|
||||
@@ -87,18 +90,14 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
|
||||
auto v = attr->forceValue();
|
||||
|
||||
if (std::optional derivedPathWithInfo = trySinglePathToDerivedPaths(
|
||||
v,
|
||||
noPos,
|
||||
fmt("while evaluating the flake output attribute '%s'", attrPath)))
|
||||
{
|
||||
return { *derivedPathWithInfo };
|
||||
v, noPos, fmt("while evaluating the flake output attribute '%s'", attrPath))) {
|
||||
return {*derivedPathWithInfo};
|
||||
} else {
|
||||
throw Error(
|
||||
"expected flake output attribute '%s' to be a derivation or path but found %s: %s",
|
||||
attrPath,
|
||||
showType(v),
|
||||
ValuePrinter(*this->state, v, errorPrintOptions)
|
||||
);
|
||||
ValuePrinter(*this->state, v, errorPrintOptions));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,39 +112,40 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
|
||||
}
|
||||
|
||||
return {{
|
||||
.path = DerivedPath::Built {
|
||||
.drvPath = makeConstantStorePathRef(std::move(drvPath)),
|
||||
.outputs = std::visit(overloaded {
|
||||
[&](const ExtendedOutputsSpec::Default & d) -> OutputsSpec {
|
||||
std::set<std::string> outputsToInstall;
|
||||
if (auto aOutputSpecified = attr->maybeGetAttr(state->sOutputSpecified)) {
|
||||
if (aOutputSpecified->getBool()) {
|
||||
if (auto aOutputName = attr->maybeGetAttr("outputName"))
|
||||
outputsToInstall = { aOutputName->getString() };
|
||||
}
|
||||
} else if (auto aMeta = attr->maybeGetAttr(state->sMeta)) {
|
||||
if (auto aOutputsToInstall = aMeta->maybeGetAttr("outputsToInstall"))
|
||||
for (auto & s : aOutputsToInstall->getListOfStrings())
|
||||
outputsToInstall.insert(s);
|
||||
}
|
||||
.path =
|
||||
DerivedPath::Built{
|
||||
.drvPath = makeConstantStorePathRef(std::move(drvPath)),
|
||||
.outputs = std::visit(
|
||||
overloaded{
|
||||
[&](const ExtendedOutputsSpec::Default & d) -> OutputsSpec {
|
||||
std::set<std::string> outputsToInstall;
|
||||
if (auto aOutputSpecified = attr->maybeGetAttr(state->sOutputSpecified)) {
|
||||
if (aOutputSpecified->getBool()) {
|
||||
if (auto aOutputName = attr->maybeGetAttr("outputName"))
|
||||
outputsToInstall = {aOutputName->getString()};
|
||||
}
|
||||
} else if (auto aMeta = attr->maybeGetAttr(state->sMeta)) {
|
||||
if (auto aOutputsToInstall = aMeta->maybeGetAttr("outputsToInstall"))
|
||||
for (auto & s : aOutputsToInstall->getListOfStrings())
|
||||
outputsToInstall.insert(s);
|
||||
}
|
||||
|
||||
if (outputsToInstall.empty())
|
||||
outputsToInstall.insert("out");
|
||||
if (outputsToInstall.empty())
|
||||
outputsToInstall.insert("out");
|
||||
|
||||
return OutputsSpec::Names { std::move(outputsToInstall) };
|
||||
},
|
||||
[&](const ExtendedOutputsSpec::Explicit & e) -> OutputsSpec {
|
||||
return e;
|
||||
},
|
||||
}, extendedOutputsSpec.raw),
|
||||
},
|
||||
return OutputsSpec::Names{std::move(outputsToInstall)};
|
||||
},
|
||||
[&](const ExtendedOutputsSpec::Explicit & e) -> OutputsSpec { return e; },
|
||||
},
|
||||
extendedOutputsSpec.raw),
|
||||
},
|
||||
.info = make_ref<ExtraPathInfoFlake>(
|
||||
ExtraPathInfoValue::Value {
|
||||
ExtraPathInfoValue::Value{
|
||||
.priority = priority,
|
||||
.attrPath = attrPath,
|
||||
.extendedOutputsSpec = extendedOutputsSpec,
|
||||
},
|
||||
ExtraPathInfoFlake::Flake {
|
||||
ExtraPathInfoFlake::Flake{
|
||||
.originalRef = flakeRef,
|
||||
.lockedRef = getLockedFlake()->flake.lockedRef,
|
||||
}),
|
||||
@@ -157,8 +157,7 @@ std::pair<Value *, PosIdx> InstallableFlake::toValue(EvalState & state)
|
||||
return {&getCursor(state)->forceValue(), noPos};
|
||||
}
|
||||
|
||||
std::vector<ref<eval_cache::AttrCursor>>
|
||||
InstallableFlake::getCursors(EvalState & state)
|
||||
std::vector<ref<eval_cache::AttrCursor>> InstallableFlake::getCursors(EvalState & state)
|
||||
{
|
||||
auto evalCache = openEvalCache(state, getLockedFlake());
|
||||
|
||||
@@ -181,11 +180,7 @@ InstallableFlake::getCursors(EvalState & state)
|
||||
}
|
||||
|
||||
if (res.size() == 0)
|
||||
throw Error(
|
||||
suggestions,
|
||||
"flake '%s' does not provide attribute %s",
|
||||
flakeRef,
|
||||
showAttrPaths(attrPaths));
|
||||
throw Error(suggestions, "flake '%s' does not provide attribute %s", flakeRef, showAttrPaths(attrPaths));
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -196,8 +191,8 @@ std::shared_ptr<flake::LockedFlake> InstallableFlake::getLockedFlake() const
|
||||
flake::LockFlags lockFlagsApplyConfig = lockFlags;
|
||||
// FIXME why this side effect?
|
||||
lockFlagsApplyConfig.applyNixConfig = true;
|
||||
_lockedFlake = std::make_shared<flake::LockedFlake>(lockFlake(
|
||||
flakeSettings, *state, flakeRef, lockFlagsApplyConfig));
|
||||
_lockedFlake =
|
||||
std::make_shared<flake::LockedFlake>(lockFlake(flakeSettings, *state, flakeRef, lockFlagsApplyConfig));
|
||||
}
|
||||
return _lockedFlake;
|
||||
}
|
||||
@@ -216,4 +211,4 @@ FlakeRef InstallableFlake::nixpkgsFlakeRef() const
|
||||
return defaultNixpkgsFlakeRef();
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
#include "installable-value.hh"
|
||||
#include "eval-cache.hh"
|
||||
#include "fetch-to-store.hh"
|
||||
#include "nix/cmd/installable-value.hh"
|
||||
#include "nix/expr/eval-cache.hh"
|
||||
#include "nix/fetchers/fetch-to-store.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
std::vector<ref<eval_cache::AttrCursor>>
|
||||
InstallableValue::getCursors(EvalState & state)
|
||||
std::vector<ref<eval_cache::AttrCursor>> InstallableValue::getCursors(EvalState & state)
|
||||
{
|
||||
auto evalCache =
|
||||
std::make_shared<nix::eval_cache::EvalCache>(std::nullopt, state,
|
||||
[&]() { return toValue(state).first; });
|
||||
std::make_shared<nix::eval_cache::EvalCache>(std::nullopt, state, [&]() { return toValue(state).first; });
|
||||
return {evalCache->getRoot()};
|
||||
}
|
||||
|
||||
ref<eval_cache::AttrCursor>
|
||||
InstallableValue::getCursor(EvalState & state)
|
||||
ref<eval_cache::AttrCursor> InstallableValue::getCursor(EvalState & state)
|
||||
{
|
||||
/* Although getCursors should return at least one element, in case it doesn't,
|
||||
bound check to avoid an undefined behavior for vector[0] */
|
||||
@@ -39,30 +36,32 @@ ref<InstallableValue> InstallableValue::require(ref<Installable> installable)
|
||||
auto castedInstallable = installable.dynamic_pointer_cast<InstallableValue>();
|
||||
if (!castedInstallable)
|
||||
throw nonValueInstallable(*installable);
|
||||
return ref { castedInstallable };
|
||||
return ref{castedInstallable};
|
||||
}
|
||||
|
||||
std::optional<DerivedPathWithInfo> InstallableValue::trySinglePathToDerivedPaths(Value & v, const PosIdx pos, std::string_view errorCtx)
|
||||
std::optional<DerivedPathWithInfo>
|
||||
InstallableValue::trySinglePathToDerivedPaths(Value & v, const PosIdx pos, std::string_view errorCtx)
|
||||
{
|
||||
if (v.type() == nPath) {
|
||||
auto storePath = fetchToStore(*state->store, v.path(), FetchMode::Copy);
|
||||
return {{
|
||||
.path = DerivedPath::Opaque {
|
||||
.path = std::move(storePath),
|
||||
},
|
||||
.path =
|
||||
DerivedPath::Opaque{
|
||||
.path = std::move(storePath),
|
||||
},
|
||||
.info = make_ref<ExtraPathInfo>(),
|
||||
}};
|
||||
}
|
||||
|
||||
else if (v.type() == nString) {
|
||||
return {{
|
||||
.path = DerivedPath::fromSingle(
|
||||
state->coerceToSingleDerivedPath(pos, v, errorCtx)),
|
||||
.path = DerivedPath::fromSingle(state->coerceToSingleDerivedPath(pos, v, errorCtx)),
|
||||
.info = make_ref<ExtraPathInfo>(),
|
||||
}};
|
||||
}
|
||||
|
||||
else return std::nullopt;
|
||||
else
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
||||
@@ -1,37 +1,39 @@
|
||||
#include "globals.hh"
|
||||
#include "installables.hh"
|
||||
#include "installable-derived-path.hh"
|
||||
#include "installable-attr-path.hh"
|
||||
#include "installable-flake.hh"
|
||||
#include "outputs-spec.hh"
|
||||
#include "users.hh"
|
||||
#include "util.hh"
|
||||
#include "command.hh"
|
||||
#include "attr-path.hh"
|
||||
#include "common-eval-args.hh"
|
||||
#include "derivations.hh"
|
||||
#include "eval-inline.hh"
|
||||
#include "eval.hh"
|
||||
#include "eval-settings.hh"
|
||||
#include "get-drvs.hh"
|
||||
#include "store-api.hh"
|
||||
#include "shared.hh"
|
||||
#include "flake/flake.hh"
|
||||
#include "eval-cache.hh"
|
||||
#include "url.hh"
|
||||
#include "registry.hh"
|
||||
#include "build-result.hh"
|
||||
#include "nix/store/globals.hh"
|
||||
#include "nix/cmd/installables.hh"
|
||||
#include "nix/cmd/installable-derived-path.hh"
|
||||
#include "nix/cmd/installable-attr-path.hh"
|
||||
#include "nix/cmd/installable-flake.hh"
|
||||
#include "nix/store/outputs-spec.hh"
|
||||
#include "nix/util/users.hh"
|
||||
#include "nix/util/util.hh"
|
||||
#include "nix/cmd/command.hh"
|
||||
#include "nix/expr/attr-path.hh"
|
||||
#include "nix/cmd/common-eval-args.hh"
|
||||
#include "nix/store/derivations.hh"
|
||||
#include "nix/expr/eval-inline.hh"
|
||||
#include "nix/expr/eval.hh"
|
||||
#include "nix/expr/eval-settings.hh"
|
||||
#include "nix/expr/get-drvs.hh"
|
||||
#include "nix/store/store-api.hh"
|
||||
#include "nix/main/shared.hh"
|
||||
#include "nix/flake/flake.hh"
|
||||
#include "nix/expr/eval-cache.hh"
|
||||
#include "nix/util/url.hh"
|
||||
#include "nix/fetchers/registry.hh"
|
||||
#include "nix/store/build-result.hh"
|
||||
|
||||
#include <regex>
|
||||
#include <queue>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "strings-inline.hh"
|
||||
#include "nix/util/strings-inline.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
namespace fs { using namespace std::filesystem; }
|
||||
namespace fs {
|
||||
using namespace std::filesystem;
|
||||
}
|
||||
|
||||
void completeFlakeInputAttrPath(
|
||||
AddCompletions & completions,
|
||||
@@ -40,7 +42,7 @@ void completeFlakeInputAttrPath(
|
||||
std::string_view prefix)
|
||||
{
|
||||
for (auto & flakeRef : flakeRefs) {
|
||||
auto flake = flake::getFlake(*evalState, flakeRef, true);
|
||||
auto flake = flake::getFlake(*evalState, flakeRef, fetchers::UseRegistries::All);
|
||||
for (auto & input : flake.inputs)
|
||||
if (hasPrefix(input.first, prefix))
|
||||
completions.add(input.first);
|
||||
@@ -63,22 +65,23 @@ MixFlakeOptions::MixFlakeOptions()
|
||||
.category = category,
|
||||
.handler = {[&]() {
|
||||
lockFlags.recreateLockFile = true;
|
||||
warn("'--recreate-lock-file' is deprecated and will be removed in a future version; use 'nix flake update' instead.");
|
||||
}}
|
||||
warn(
|
||||
"'--recreate-lock-file' is deprecated and will be removed in a future version; use 'nix flake update' instead.");
|
||||
}},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
.longName = "no-update-lock-file",
|
||||
.description = "Do not allow any updates to the flake's lock file.",
|
||||
.category = category,
|
||||
.handler = {&lockFlags.updateLockFile, false}
|
||||
.handler = {&lockFlags.updateLockFile, false},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
.longName = "no-write-lock-file",
|
||||
.description = "Do not write the flake's newly generated lock file.",
|
||||
.category = category,
|
||||
.handler = {&lockFlags.writeLockFile, false}
|
||||
.handler = {&lockFlags.writeLockFile, false},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
@@ -94,14 +97,14 @@ MixFlakeOptions::MixFlakeOptions()
|
||||
.handler = {[&]() {
|
||||
lockFlags.useRegistries = false;
|
||||
warn("'--no-registries' is deprecated; use '--no-use-registries'");
|
||||
}}
|
||||
}},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
.longName = "commit-lock-file",
|
||||
.description = "Commit changes to the flake's lock file.",
|
||||
.category = category,
|
||||
.handler = {&lockFlags.commitLockFile, true}
|
||||
.handler = {&lockFlags.commitLockFile, true},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
@@ -121,7 +124,7 @@ MixFlakeOptions::MixFlakeOptions()
|
||||
}},
|
||||
.completer = {[&](AddCompletions & completions, size_t, std::string_view prefix) {
|
||||
completeFlakeInputAttrPath(completions, getEvalState(), getFlakeRefsForCompletion(), prefix);
|
||||
}}
|
||||
}},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
@@ -141,7 +144,7 @@ MixFlakeOptions::MixFlakeOptions()
|
||||
} else if (n == 1) {
|
||||
completeFlakeRef(completions, getEvalState()->store, prefix);
|
||||
}
|
||||
}}
|
||||
}},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
@@ -152,7 +155,7 @@ MixFlakeOptions::MixFlakeOptions()
|
||||
.handler = {[&](std::string lockFilePath) {
|
||||
lockFlags.referenceLockFilePath = {getFSSourceAccessor(), CanonPath(absPath(lockFilePath))};
|
||||
}},
|
||||
.completer = completePath
|
||||
.completer = completePath,
|
||||
});
|
||||
|
||||
addFlag({
|
||||
@@ -160,10 +163,8 @@ MixFlakeOptions::MixFlakeOptions()
|
||||
.description = "Write the given lock file instead of `flake.lock` within the top-level flake.",
|
||||
.category = category,
|
||||
.labels = {"flake-lock-path"},
|
||||
.handler = {[&](std::string lockFilePath) {
|
||||
lockFlags.outputLockFilePath = lockFilePath;
|
||||
}},
|
||||
.completer = completePath
|
||||
.handler = {[&](std::string lockFilePath) { lockFlags.outputLockFilePath = lockFilePath; }},
|
||||
.completer = completePath,
|
||||
});
|
||||
|
||||
addFlag({
|
||||
@@ -177,12 +178,12 @@ MixFlakeOptions::MixFlakeOptions()
|
||||
flakeSettings,
|
||||
*evalState,
|
||||
parseFlakeRef(fetchSettings, flakeRef, absPath(getCommandBaseDir())),
|
||||
{ .writeLockFile = false });
|
||||
{.writeLockFile = false});
|
||||
for (auto & [inputName, input] : flake.lockFile.root->inputs) {
|
||||
auto input2 = flake.lockFile.findInput({inputName}); // resolve 'follows' nodes
|
||||
if (auto input3 = std::dynamic_pointer_cast<const flake::LockedNode>(input2)) {
|
||||
overrideRegistry(
|
||||
fetchers::Input::fromAttrs(fetchSettings, {{"type","indirect"}, {"id", inputName}}),
|
||||
fetchers::Input::fromAttrs(fetchSettings, {{"type", "indirect"}, {"id", inputName}}),
|
||||
input3->lockedRef.input,
|
||||
{});
|
||||
}
|
||||
@@ -190,7 +191,7 @@ MixFlakeOptions::MixFlakeOptions()
|
||||
}},
|
||||
.completer = {[&](AddCompletions & completions, size_t, std::string_view prefix) {
|
||||
completeFlakeRef(completions, getEvalState()->store, prefix);
|
||||
}}
|
||||
}},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -206,15 +207,16 @@ SourceExprCommand::SourceExprCommand()
|
||||
.category = installablesCategory,
|
||||
.labels = {"file"},
|
||||
.handler = {&file},
|
||||
.completer = completePath
|
||||
.completer = completePath,
|
||||
});
|
||||
|
||||
addFlag({
|
||||
.longName = "expr",
|
||||
.description = "Interpret [*installables*](@docroot@/command-ref/new-cli/nix.md#installables) as attribute paths relative to the Nix expression *expr*.",
|
||||
.description =
|
||||
"Interpret [*installables*](@docroot@/command-ref/new-cli/nix.md#installables) as attribute paths relative to the Nix expression *expr*.",
|
||||
.category = installablesCategory,
|
||||
.labels = {"expr"},
|
||||
.handler = {&expr}
|
||||
.handler = {&expr},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -222,32 +224,26 @@ MixReadOnlyOption::MixReadOnlyOption()
|
||||
{
|
||||
addFlag({
|
||||
.longName = "read-only",
|
||||
.description =
|
||||
"Do not instantiate each evaluated derivation. "
|
||||
"This improves performance, but can cause errors when accessing "
|
||||
"store paths of derivations during evaluation.",
|
||||
.description = "Do not instantiate each evaluated derivation. "
|
||||
"This improves performance, but can cause errors when accessing "
|
||||
"store paths of derivations during evaluation.",
|
||||
.handler = {&settings.readOnlyMode, true},
|
||||
});
|
||||
}
|
||||
|
||||
Strings SourceExprCommand::getDefaultFlakeAttrPaths()
|
||||
{
|
||||
return {
|
||||
"packages." + settings.thisSystem.get() + ".default",
|
||||
"defaultPackage." + settings.thisSystem.get()
|
||||
};
|
||||
return {"packages." + settings.thisSystem.get() + ".default", "defaultPackage." + settings.thisSystem.get()};
|
||||
}
|
||||
|
||||
Strings SourceExprCommand::getDefaultFlakeAttrPathPrefixes()
|
||||
{
|
||||
return {
|
||||
// As a convenience, look for the attribute in
|
||||
// 'outputs.packages'.
|
||||
"packages." + settings.thisSystem.get() + ".",
|
||||
// As a temporary hack until Nixpkgs is properly converted
|
||||
// to provide a clean 'packages' set, look in 'legacyPackages'.
|
||||
"legacyPackages." + settings.thisSystem.get() + "."
|
||||
};
|
||||
return {// As a convenience, look for the attribute in
|
||||
// 'outputs.packages'.
|
||||
"packages." + settings.thisSystem.get() + ".",
|
||||
// As a temporary hack until Nixpkgs is properly converted
|
||||
// to provide a clean 'packages' set, look in 'legacyPackages'.
|
||||
"legacyPackages." + settings.thisSystem.get() + "."};
|
||||
}
|
||||
|
||||
Args::CompleterClosure SourceExprCommand::getCompleteInstallable()
|
||||
@@ -265,10 +261,7 @@ void SourceExprCommand::completeInstallable(AddCompletions & completions, std::s
|
||||
|
||||
evalSettings.pureEval = false;
|
||||
auto state = getEvalState();
|
||||
auto e =
|
||||
state->parseExprFromFile(
|
||||
resolveExprPath(
|
||||
lookupFileArg(*state, *file)));
|
||||
auto e = state->parseExprFromFile(resolveExprPath(lookupFileArg(*state, *file)));
|
||||
|
||||
Value root;
|
||||
state->eval(e, root);
|
||||
@@ -287,7 +280,7 @@ void SourceExprCommand::completeInstallable(AddCompletions & completions, std::s
|
||||
}
|
||||
|
||||
auto [v, pos] = findAlongAttrPath(*state, prefix_, *autoArgs, root);
|
||||
Value &v1(*v);
|
||||
Value & v1(*v);
|
||||
state->forceValue(v1, pos);
|
||||
Value v2;
|
||||
state->autoCallFunction(*autoArgs, v1, v2);
|
||||
@@ -312,7 +305,7 @@ void SourceExprCommand::completeInstallable(AddCompletions & completions, std::s
|
||||
getDefaultFlakeAttrPaths(),
|
||||
prefix);
|
||||
}
|
||||
} catch (EvalError&) {
|
||||
} catch (EvalError &) {
|
||||
// Don't want eval errors to mess-up with the completion engine, so let's just swallow them
|
||||
}
|
||||
}
|
||||
@@ -336,7 +329,7 @@ void completeFlakeRefWithFragment(
|
||||
|
||||
auto fragment = prefix.substr(hash + 1);
|
||||
std::string prefixRoot = "";
|
||||
if (fragment.starts_with(".")){
|
||||
if (fragment.starts_with(".")) {
|
||||
fragment = fragment.substr(1);
|
||||
prefixRoot = ".";
|
||||
}
|
||||
@@ -345,13 +338,13 @@ void completeFlakeRefWithFragment(
|
||||
// TODO: ideally this would use the command base directory instead of assuming ".".
|
||||
auto flakeRef = parseFlakeRef(fetchSettings, expandTilde(flakeRefS), fs::current_path().string());
|
||||
|
||||
auto evalCache = openEvalCache(*evalState,
|
||||
std::make_shared<flake::LockedFlake>(lockFlake(
|
||||
flakeSettings, *evalState, flakeRef, lockFlags)));
|
||||
auto evalCache = openEvalCache(
|
||||
*evalState,
|
||||
std::make_shared<flake::LockedFlake>(lockFlake(flakeSettings, *evalState, flakeRef, lockFlags)));
|
||||
|
||||
auto root = evalCache->getRoot();
|
||||
|
||||
if (prefixRoot == "."){
|
||||
if (prefixRoot == ".") {
|
||||
attrPathPrefixes.clear();
|
||||
}
|
||||
/* Complete 'fragment' relative to all the
|
||||
@@ -371,7 +364,8 @@ void completeFlakeRefWithFragment(
|
||||
}
|
||||
|
||||
auto attr = root->findAlongAttrPath(attrPath);
|
||||
if (!attr) continue;
|
||||
if (!attr)
|
||||
continue;
|
||||
|
||||
for (auto & attr2 : (*attr)->getAttrs()) {
|
||||
if (hasPrefix(evalState->symbols[attr2], lastAttr)) {
|
||||
@@ -379,7 +373,9 @@ void completeFlakeRefWithFragment(
|
||||
/* Strip the attrpath prefix. */
|
||||
attrPath2.erase(attrPath2.begin(), attrPath2.begin() + attrPathPrefix.size());
|
||||
// FIXME: handle names with dots
|
||||
completions.add(flakeRefS + "#" + prefixRoot + concatStringsSep(".", evalState->symbols.resolve(attrPath2)));
|
||||
completions.add(
|
||||
flakeRefS + "#" + prefixRoot
|
||||
+ concatStringsSep(".", evalState->symbols.resolve(attrPath2)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -389,7 +385,8 @@ void completeFlakeRefWithFragment(
|
||||
if (fragment.empty()) {
|
||||
for (auto & attrPath : defaultFlakeAttrPaths) {
|
||||
auto attr = root->findAlongAttrPath(parseAttrPath(*evalState, attrPath));
|
||||
if (!attr) continue;
|
||||
if (!attr)
|
||||
continue;
|
||||
completions.add(flakeRefS + "#" + prefixRoot);
|
||||
}
|
||||
}
|
||||
@@ -429,14 +426,12 @@ DerivedPathWithInfo Installable::toDerivedPath()
|
||||
{
|
||||
auto buildables = toDerivedPaths();
|
||||
if (buildables.size() != 1)
|
||||
throw Error("installable '%s' evaluates to %d derivations, where only one is expected", what(), buildables.size());
|
||||
throw Error(
|
||||
"installable '%s' evaluates to %d derivations, where only one is expected", what(), buildables.size());
|
||||
return std::move(buildables[0]);
|
||||
}
|
||||
|
||||
static StorePath getDeriver(
|
||||
ref<Store> store,
|
||||
const Installable & i,
|
||||
const StorePath & drvPath)
|
||||
static StorePath getDeriver(ref<Store> store, const Installable & i, const StorePath & drvPath)
|
||||
{
|
||||
auto derivers = store->queryValidDerivers(drvPath);
|
||||
if (derivers.empty())
|
||||
@@ -445,35 +440,35 @@ static StorePath getDeriver(
|
||||
return *derivers.begin();
|
||||
}
|
||||
|
||||
ref<eval_cache::EvalCache> openEvalCache(
|
||||
EvalState & state,
|
||||
std::shared_ptr<flake::LockedFlake> lockedFlake)
|
||||
ref<eval_cache::EvalCache> openEvalCache(EvalState & state, std::shared_ptr<flake::LockedFlake> lockedFlake)
|
||||
{
|
||||
auto fingerprint = evalSettings.useEvalCache && evalSettings.pureEval
|
||||
? lockedFlake->getFingerprint(state.store, state.fetchSettings)
|
||||
: std::nullopt;
|
||||
auto rootLoader = [&state, lockedFlake]()
|
||||
{
|
||||
/* For testing whether the evaluation cache is
|
||||
complete. */
|
||||
if (getEnv("NIX_ALLOW_EVAL").value_or("1") == "0")
|
||||
throw Error("not everything is cached, but evaluation is not allowed");
|
||||
? lockedFlake->getFingerprint(state.store, state.fetchSettings)
|
||||
: std::nullopt;
|
||||
auto rootLoader = [&state, lockedFlake]() {
|
||||
/* For testing whether the evaluation cache is
|
||||
complete. */
|
||||
if (getEnv("NIX_ALLOW_EVAL").value_or("1") == "0")
|
||||
throw Error("not everything is cached, but evaluation is not allowed");
|
||||
|
||||
auto vFlake = state.allocValue();
|
||||
flake::callFlake(state, *lockedFlake, *vFlake);
|
||||
auto vFlake = state.allocValue();
|
||||
flake::callFlake(state, *lockedFlake, *vFlake);
|
||||
|
||||
state.forceAttrs(*vFlake, noPos, "while parsing cached flake data");
|
||||
state.forceAttrs(*vFlake, noPos, "while parsing cached flake data");
|
||||
|
||||
auto aOutputs = vFlake->attrs()->get(state.symbols.create("outputs"));
|
||||
assert(aOutputs);
|
||||
auto aOutputs = vFlake->attrs()->get(state.symbols.create("outputs"));
|
||||
assert(aOutputs);
|
||||
|
||||
return aOutputs->value;
|
||||
};
|
||||
return aOutputs->value;
|
||||
};
|
||||
|
||||
if (fingerprint) {
|
||||
auto search = state.evalCaches.find(fingerprint.value());
|
||||
if (search == state.evalCaches.end()) {
|
||||
search = state.evalCaches.emplace(fingerprint.value(), make_ref<nix::eval_cache::EvalCache>(fingerprint, state, rootLoader)).first;
|
||||
search =
|
||||
state.evalCaches
|
||||
.emplace(fingerprint.value(), make_ref<nix::eval_cache::EvalCache>(fingerprint, state, rootLoader))
|
||||
.first;
|
||||
}
|
||||
return search->second;
|
||||
} else {
|
||||
@@ -481,8 +476,7 @@ ref<eval_cache::EvalCache> openEvalCache(
|
||||
}
|
||||
}
|
||||
|
||||
Installables SourceExprCommand::parseInstallables(
|
||||
ref<Store> store, std::vector<std::string> ss)
|
||||
Installables SourceExprCommand::parseInstallables(ref<Store> store, std::vector<std::string> ss)
|
||||
{
|
||||
Installables result;
|
||||
|
||||
@@ -491,7 +485,8 @@ Installables SourceExprCommand::parseInstallables(
|
||||
throw UsageError("'--file' and '--expr' are exclusive");
|
||||
|
||||
// FIXME: backward compatibility hack
|
||||
if (file) evalSettings.pureEval = false;
|
||||
if (file)
|
||||
evalSettings.pureEval = false;
|
||||
|
||||
auto state = getEvalState();
|
||||
auto vFile = state->allocValue();
|
||||
@@ -499,12 +494,10 @@ Installables SourceExprCommand::parseInstallables(
|
||||
if (file == "-") {
|
||||
auto e = state->parseStdin();
|
||||
state->eval(e, *vFile);
|
||||
}
|
||||
else if (file) {
|
||||
} else if (file) {
|
||||
auto dir = absPath(getCommandBaseDir());
|
||||
state->evalFile(lookupFileArg(*state, *file, &dir), *vFile);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Path dir = absPath(getCommandBaseDir());
|
||||
auto e = state->parseExprFromString(*expr, state->rootPath(dir));
|
||||
state->eval(e, *vFile);
|
||||
@@ -513,9 +506,8 @@ Installables SourceExprCommand::parseInstallables(
|
||||
for (auto & s : ss) {
|
||||
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse(s);
|
||||
result.push_back(
|
||||
make_ref<InstallableAttrPath>(
|
||||
InstallableAttrPath::parse(
|
||||
state, *this, vFile, std::move(prefix), std::move(extendedOutputsSpec))));
|
||||
make_ref<InstallableAttrPath>(InstallableAttrPath::parse(
|
||||
state, *this, vFile, std::move(prefix), std::move(extendedOutputsSpec))));
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -530,8 +522,9 @@ Installables SourceExprCommand::parseInstallables(
|
||||
|
||||
if (prefix.find('/') != std::string::npos) {
|
||||
try {
|
||||
result.push_back(make_ref<InstallableDerivedPath>(
|
||||
InstallableDerivedPath::parse(store, prefix, extendedOutputsSpec.raw)));
|
||||
result.push_back(
|
||||
make_ref<InstallableDerivedPath>(
|
||||
InstallableDerivedPath::parse(store, prefix, extendedOutputsSpec.raw)));
|
||||
continue;
|
||||
} catch (BadStorePath &) {
|
||||
} catch (...) {
|
||||
@@ -541,9 +534,10 @@ Installables SourceExprCommand::parseInstallables(
|
||||
}
|
||||
|
||||
try {
|
||||
auto [flakeRef, fragment] = parseFlakeRefWithFragment(
|
||||
fetchSettings, std::string { prefix }, absPath(getCommandBaseDir()));
|
||||
result.push_back(make_ref<InstallableFlake>(
|
||||
auto [flakeRef, fragment] =
|
||||
parseFlakeRefWithFragment(fetchSettings, std::string{prefix}, absPath(getCommandBaseDir()));
|
||||
result.push_back(
|
||||
make_ref<InstallableFlake>(
|
||||
this,
|
||||
getEvalState(),
|
||||
std::move(flakeRef),
|
||||
@@ -564,8 +558,7 @@ Installables SourceExprCommand::parseInstallables(
|
||||
return result;
|
||||
}
|
||||
|
||||
ref<Installable> SourceExprCommand::parseInstallable(
|
||||
ref<Store> store, const std::string & installable)
|
||||
ref<Installable> SourceExprCommand::parseInstallable(ref<Store> store, const std::string & installable)
|
||||
{
|
||||
auto installables = parseInstallables(store, {installable});
|
||||
assert(installables.size() == 1);
|
||||
@@ -576,20 +569,18 @@ static SingleBuiltPath getBuiltPath(ref<Store> evalStore, ref<Store> store, cons
|
||||
{
|
||||
return std::visit(
|
||||
overloaded{
|
||||
[&](const SingleDerivedPath::Opaque & bo) -> SingleBuiltPath {
|
||||
return SingleBuiltPath::Opaque { bo.path };
|
||||
},
|
||||
[&](const SingleDerivedPath::Opaque & bo) -> SingleBuiltPath { return SingleBuiltPath::Opaque{bo.path}; },
|
||||
[&](const SingleDerivedPath::Built & bfd) -> SingleBuiltPath {
|
||||
auto drvPath = getBuiltPath(evalStore, store, *bfd.drvPath);
|
||||
// Resolving this instead of `bfd` will yield the same result, but avoid duplicative work.
|
||||
SingleDerivedPath::Built truncatedBfd {
|
||||
SingleDerivedPath::Built truncatedBfd{
|
||||
.drvPath = makeConstantStorePathRef(drvPath.outPath()),
|
||||
.output = bfd.output,
|
||||
};
|
||||
auto outputPath = resolveDerivedPath(*store, truncatedBfd, &*evalStore);
|
||||
return SingleBuiltPath::Built {
|
||||
return SingleBuiltPath::Built{
|
||||
.drvPath = make_ref<SingleBuiltPath>(std::move(drvPath)),
|
||||
.output = { bfd.output, outputPath },
|
||||
.output = {bfd.output, outputPath},
|
||||
};
|
||||
},
|
||||
},
|
||||
@@ -597,11 +588,7 @@ static SingleBuiltPath getBuiltPath(ref<Store> evalStore, ref<Store> store, cons
|
||||
}
|
||||
|
||||
std::vector<BuiltPathWithResult> Installable::build(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
const Installables & installables,
|
||||
BuildMode bMode)
|
||||
ref<Store> evalStore, ref<Store> store, Realise mode, const Installables & installables, BuildMode bMode)
|
||||
{
|
||||
std::vector<BuiltPathWithResult> res;
|
||||
for (auto & [_, builtPathWithResult] : build2(evalStore, store, mode, installables, bMode))
|
||||
@@ -609,9 +596,7 @@ std::vector<BuiltPathWithResult> Installable::build(
|
||||
return res;
|
||||
}
|
||||
|
||||
static void throwBuildErrors(
|
||||
std::vector<KeyedBuildResult> & buildResults,
|
||||
const Store & store)
|
||||
static void throwBuildErrors(std::vector<KeyedBuildResult> & buildResults, const Store & store)
|
||||
{
|
||||
std::vector<KeyedBuildResult> failed;
|
||||
for (auto & buildResult : buildResults) {
|
||||
@@ -628,10 +613,11 @@ static void throwBuildErrors(
|
||||
StringSet failedPaths;
|
||||
for (; failedResult != failed.end(); failedResult++) {
|
||||
if (!failedResult->errorMsg.empty()) {
|
||||
logError(ErrorInfo{
|
||||
.level = lvlError,
|
||||
.msg = failedResult->errorMsg,
|
||||
});
|
||||
logError(
|
||||
ErrorInfo{
|
||||
.level = lvlError,
|
||||
.msg = failedResult->errorMsg,
|
||||
});
|
||||
}
|
||||
failedPaths.insert(failedResult->path.to_string(store));
|
||||
}
|
||||
@@ -641,11 +627,7 @@ static void throwBuildErrors(
|
||||
}
|
||||
|
||||
std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build2(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
const Installables & installables,
|
||||
BuildMode bMode)
|
||||
ref<Store> evalStore, ref<Store> store, Realise mode, const Installables & installables, BuildMode bMode)
|
||||
{
|
||||
if (mode == Realise::Nothing)
|
||||
settings.readOnlyMode = true;
|
||||
@@ -676,22 +658,25 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build
|
||||
|
||||
for (auto & path : pathsToBuild) {
|
||||
for (auto & aux : backmap[path]) {
|
||||
std::visit(overloaded {
|
||||
[&](const DerivedPath::Built & bfd) {
|
||||
auto outputs = resolveDerivedPath(*store, bfd, &*evalStore);
|
||||
res.push_back({aux.installable, {
|
||||
.path = BuiltPath::Built {
|
||||
.drvPath = make_ref<SingleBuiltPath>(getBuiltPath(evalStore, store, *bfd.drvPath)),
|
||||
.outputs = outputs,
|
||||
},
|
||||
.info = aux.info}});
|
||||
std::visit(
|
||||
overloaded{
|
||||
[&](const DerivedPath::Built & bfd) {
|
||||
auto outputs = resolveDerivedPath(*store, bfd, &*evalStore);
|
||||
res.push_back(
|
||||
{aux.installable,
|
||||
{.path =
|
||||
BuiltPath::Built{
|
||||
.drvPath =
|
||||
make_ref<SingleBuiltPath>(getBuiltPath(evalStore, store, *bfd.drvPath)),
|
||||
.outputs = outputs,
|
||||
},
|
||||
.info = aux.info}});
|
||||
},
|
||||
[&](const DerivedPath::Opaque & bo) {
|
||||
res.push_back({aux.installable, {.path = BuiltPath::Opaque{bo.path}, .info = aux.info}});
|
||||
},
|
||||
},
|
||||
[&](const DerivedPath::Opaque & bo) {
|
||||
res.push_back({aux.installable, {
|
||||
.path = BuiltPath::Opaque { bo.path },
|
||||
.info = aux.info}});
|
||||
},
|
||||
}, path.raw());
|
||||
path.raw());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -705,26 +690,30 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build
|
||||
throwBuildErrors(buildResults, *store);
|
||||
for (auto & buildResult : buildResults) {
|
||||
for (auto & aux : backmap[buildResult.path]) {
|
||||
std::visit(overloaded {
|
||||
[&](const DerivedPath::Built & bfd) {
|
||||
std::map<std::string, StorePath> outputs;
|
||||
for (auto & [outputName, realisation] : buildResult.builtOutputs)
|
||||
outputs.emplace(outputName, realisation.outPath);
|
||||
res.push_back({aux.installable, {
|
||||
.path = BuiltPath::Built {
|
||||
.drvPath = make_ref<SingleBuiltPath>(getBuiltPath(evalStore, store, *bfd.drvPath)),
|
||||
.outputs = outputs,
|
||||
},
|
||||
.info = aux.info,
|
||||
.result = buildResult}});
|
||||
std::visit(
|
||||
overloaded{
|
||||
[&](const DerivedPath::Built & bfd) {
|
||||
std::map<std::string, StorePath> outputs;
|
||||
for (auto & [outputName, realisation] : buildResult.builtOutputs)
|
||||
outputs.emplace(outputName, realisation.outPath);
|
||||
res.push_back(
|
||||
{aux.installable,
|
||||
{.path =
|
||||
BuiltPath::Built{
|
||||
.drvPath =
|
||||
make_ref<SingleBuiltPath>(getBuiltPath(evalStore, store, *bfd.drvPath)),
|
||||
.outputs = outputs,
|
||||
},
|
||||
.info = aux.info,
|
||||
.result = buildResult}});
|
||||
},
|
||||
[&](const DerivedPath::Opaque & bo) {
|
||||
res.push_back(
|
||||
{aux.installable,
|
||||
{.path = BuiltPath::Opaque{bo.path}, .info = aux.info, .result = buildResult}});
|
||||
},
|
||||
},
|
||||
[&](const DerivedPath::Opaque & bo) {
|
||||
res.push_back({aux.installable, {
|
||||
.path = BuiltPath::Opaque { bo.path },
|
||||
.info = aux.info,
|
||||
.result = buildResult}});
|
||||
},
|
||||
}, buildResult.path.raw());
|
||||
buildResult.path.raw());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -739,11 +728,7 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build
|
||||
}
|
||||
|
||||
BuiltPaths Installable::toBuiltPaths(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
OperateOn operateOn,
|
||||
const Installables & installables)
|
||||
ref<Store> evalStore, ref<Store> store, Realise mode, OperateOn operateOn, const Installables & installables)
|
||||
{
|
||||
if (operateOn == OperateOn::Output) {
|
||||
BuiltPaths res;
|
||||
@@ -762,10 +747,7 @@ BuiltPaths Installable::toBuiltPaths(
|
||||
}
|
||||
|
||||
StorePathSet Installable::toStorePathSet(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode, OperateOn operateOn,
|
||||
const Installables & installables)
|
||||
ref<Store> evalStore, ref<Store> store, Realise mode, OperateOn operateOn, const Installables & installables)
|
||||
{
|
||||
StorePathSet outPaths;
|
||||
for (auto & path : toBuiltPaths(evalStore, store, mode, operateOn, installables)) {
|
||||
@@ -776,10 +758,7 @@ StorePathSet Installable::toStorePathSet(
|
||||
}
|
||||
|
||||
StorePaths Installable::toStorePaths(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode, OperateOn operateOn,
|
||||
const Installables & installables)
|
||||
ref<Store> evalStore, ref<Store> store, Realise mode, OperateOn operateOn, const Installables & installables)
|
||||
{
|
||||
StorePaths outPaths;
|
||||
for (auto & path : toBuiltPaths(evalStore, store, mode, operateOn, installables)) {
|
||||
@@ -790,10 +769,7 @@ StorePaths Installable::toStorePaths(
|
||||
}
|
||||
|
||||
StorePath Installable::toStorePath(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode, OperateOn operateOn,
|
||||
ref<Installable> installable)
|
||||
ref<Store> evalStore, ref<Store> store, Realise mode, OperateOn operateOn, ref<Installable> installable)
|
||||
{
|
||||
auto paths = toStorePathSet(evalStore, store, mode, operateOn, {installable});
|
||||
|
||||
@@ -803,28 +779,23 @@ StorePath Installable::toStorePath(
|
||||
return *paths.begin();
|
||||
}
|
||||
|
||||
StorePathSet Installable::toDerivations(
|
||||
ref<Store> store,
|
||||
const Installables & installables,
|
||||
bool useDeriver)
|
||||
StorePathSet Installable::toDerivations(ref<Store> store, const Installables & installables, bool useDeriver)
|
||||
{
|
||||
StorePathSet drvPaths;
|
||||
|
||||
for (const auto & i : installables)
|
||||
for (const auto & b : i->toDerivedPaths())
|
||||
std::visit(overloaded {
|
||||
[&](const DerivedPath::Opaque & bo) {
|
||||
drvPaths.insert(
|
||||
bo.path.isDerivation()
|
||||
? bo.path
|
||||
: useDeriver
|
||||
? getDeriver(store, *i, bo.path)
|
||||
: throw Error("argument '%s' did not evaluate to a derivation", i->what()));
|
||||
std::visit(
|
||||
overloaded{
|
||||
[&](const DerivedPath::Opaque & bo) {
|
||||
drvPaths.insert(
|
||||
bo.path.isDerivation() ? bo.path
|
||||
: useDeriver ? getDeriver(store, *i, bo.path)
|
||||
: throw Error("argument '%s' did not evaluate to a derivation", i->what()));
|
||||
},
|
||||
[&](const DerivedPath::Built & bfd) { drvPaths.insert(resolveDerivedPath(*store, *bfd.drvPath)); },
|
||||
},
|
||||
[&](const DerivedPath::Built & bfd) {
|
||||
drvPaths.insert(resolveDerivedPath(*store, *bfd.drvPath));
|
||||
},
|
||||
}, b.path.raw());
|
||||
b.path.raw());
|
||||
|
||||
return drvPaths;
|
||||
}
|
||||
@@ -834,7 +805,7 @@ RawInstallablesCommand::RawInstallablesCommand()
|
||||
addFlag({
|
||||
.longName = "stdin",
|
||||
.description = "Read installables from the standard input. No default installable applied.",
|
||||
.handler = {&readFromStdIn, true}
|
||||
.handler = {&readFromStdIn, true},
|
||||
});
|
||||
|
||||
expectArgs({
|
||||
@@ -859,10 +830,7 @@ std::vector<FlakeRef> RawInstallablesCommand::getFlakeRefsForCompletion()
|
||||
std::vector<FlakeRef> res;
|
||||
res.reserve(rawInstallables.size());
|
||||
for (const auto & i : rawInstallables)
|
||||
res.push_back(parseFlakeRefWithFragment(
|
||||
fetchSettings,
|
||||
expandTilde(i),
|
||||
absPath(getCommandBaseDir())).first);
|
||||
res.push_back(parseFlakeRefWithFragment(fetchSettings, expandTilde(i), absPath(getCommandBaseDir())).first);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -881,12 +849,7 @@ void RawInstallablesCommand::run(ref<Store> store)
|
||||
|
||||
std::vector<FlakeRef> InstallableCommand::getFlakeRefsForCompletion()
|
||||
{
|
||||
return {
|
||||
parseFlakeRefWithFragment(
|
||||
fetchSettings,
|
||||
expandTilde(_installable),
|
||||
absPath(getCommandBaseDir())).first
|
||||
};
|
||||
return {parseFlakeRefWithFragment(fetchSettings, expandTilde(_installable), absPath(getCommandBaseDir())).first};
|
||||
}
|
||||
|
||||
void InstallablesCommand::run(ref<Store> store, std::vector<std::string> && rawInstallables)
|
||||
@@ -926,4 +889,4 @@ BuiltPaths toBuiltPaths(const std::vector<BuiltPathWithResult> & builtPathsWithR
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "legacy.hh"
|
||||
#include "nix/cmd/legacy.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#include "markdown.hh"
|
||||
#include "environment-variables.hh"
|
||||
#include "error.hh"
|
||||
#include "finally.hh"
|
||||
#include "terminal.hh"
|
||||
#include "nix/cmd/markdown.hh"
|
||||
#include "nix/util/environment-variables.hh"
|
||||
#include "nix/util/error.hh"
|
||||
#include "nix/util/finally.hh"
|
||||
#include "nix/util/terminal.hh"
|
||||
|
||||
#include "cmd-config-private.hh"
|
||||
|
||||
#if HAVE_LOWDOWN
|
||||
# include <sys/queue.h>
|
||||
@@ -16,25 +18,24 @@ static std::string doRenderMarkdownToTerminal(std::string_view markdown)
|
||||
{
|
||||
int windowWidth = getWindowSize().second;
|
||||
|
||||
#if HAVE_LOWDOWN_1_4
|
||||
struct lowdown_opts_term opts_term {
|
||||
# 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
|
||||
{
|
||||
# endif
|
||||
struct lowdown_opts opts{
|
||||
.type = LOWDOWN_TERM,
|
||||
#if HAVE_LOWDOWN_1_4
|
||||
# if HAVE_LOWDOWN_1_4
|
||||
.term = opts_term,
|
||||
#endif
|
||||
# endif
|
||||
.maxdepth = 20,
|
||||
#if !HAVE_LOWDOWN_1_4
|
||||
# if !HAVE_LOWDOWN_1_4
|
||||
.cols = (size_t) std::max(windowWidth - 5, 60),
|
||||
.hmargin = 0,
|
||||
.vmargin = 0,
|
||||
#endif
|
||||
# endif
|
||||
.feat = LOWDOWN_COMMONMARK | LOWDOWN_FENCED | LOWDOWN_DEFLIST | LOWDOWN_TABLES,
|
||||
.oflags = LOWDOWN_TERM_NOLINK,
|
||||
};
|
||||
|
||||
@@ -44,30 +44,18 @@ if readline_flavor == 'editline'
|
||||
elif readline_flavor == 'readline'
|
||||
readline = dependency('readline')
|
||||
deps_private += readline
|
||||
configdata.set(
|
||||
'USE_READLINE',
|
||||
1,
|
||||
description: 'Use readline instead of editline',
|
||||
)
|
||||
else
|
||||
error('illegal editline flavor', readline_flavor)
|
||||
endif
|
||||
|
||||
config_h = configure_file(
|
||||
configuration : configdata,
|
||||
output : 'config-cmd.hh',
|
||||
configdata.set(
|
||||
'USE_READLINE',
|
||||
(readline_flavor == 'readline').to_int(),
|
||||
description: 'Use readline instead of editline',
|
||||
)
|
||||
|
||||
add_project_arguments(
|
||||
# TODO(Qyriad): Yes this is how the autoconf+Make system did it.
|
||||
# It would be nice for our headers to be idempotent instead.
|
||||
'-include', 'config-util.hh',
|
||||
'-include', 'config-store.hh',
|
||||
# '-include', 'config-fetchers.h',
|
||||
'-include', 'config-expr.hh',
|
||||
'-include', 'config-main.hh',
|
||||
'-include', 'config-cmd.hh',
|
||||
language : 'cpp',
|
||||
config_priv_h = configure_file(
|
||||
configuration : configdata,
|
||||
output : 'cmd-config-private.hh',
|
||||
)
|
||||
|
||||
subdir('nix-meson-build-support/common')
|
||||
@@ -91,37 +79,23 @@ sources = files(
|
||||
'repl.cc',
|
||||
)
|
||||
|
||||
include_dirs = [include_directories('.')]
|
||||
subdir('include/nix/cmd')
|
||||
|
||||
headers = [config_h] + files(
|
||||
'built-path.hh',
|
||||
'command-installable-value.hh',
|
||||
'command.hh',
|
||||
'common-eval-args.hh',
|
||||
'compatibility-settings.hh',
|
||||
'editor-for.hh',
|
||||
'installable-attr-path.hh',
|
||||
'installable-derived-path.hh',
|
||||
'installable-flake.hh',
|
||||
'installable-value.hh',
|
||||
'installables.hh',
|
||||
'legacy.hh',
|
||||
'markdown.hh',
|
||||
'misc-store-flags.hh',
|
||||
'network-proxy.hh',
|
||||
'repl-interacter.hh',
|
||||
'repl.hh',
|
||||
)
|
||||
subdir('nix-meson-build-support/export-all-symbols')
|
||||
subdir('nix-meson-build-support/windows-version')
|
||||
|
||||
this_library = library(
|
||||
'nixcmd',
|
||||
sources,
|
||||
config_priv_h,
|
||||
dependencies : deps_public + deps_private + deps_other,
|
||||
include_directories : include_dirs,
|
||||
link_args: linker_export_flags,
|
||||
prelink : true, # For C++ static initializers
|
||||
install : true,
|
||||
)
|
||||
|
||||
install_headers(headers, subdir : 'nix', preserve_path : true)
|
||||
install_headers(headers, subdir : 'nix/cmd', preserve_path : true)
|
||||
|
||||
libraries_private = []
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user