mirror of
https://github.com/NixOS/nix.git
synced 2025-11-08 19:46:02 +01:00
Compare commits
59 commits
f029b14eaa
...
e6afa20c67
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6afa20c67 | ||
|
|
5b15544bdd | ||
|
|
8cc3ede0fa | ||
|
|
caa196e31d | ||
|
|
0c37a62207 | ||
|
|
147e183c68 | ||
|
|
52b2909fd2 | ||
|
|
34c77ffe38 | ||
|
|
af8e44821e | ||
|
|
70fbd1cdf4 | ||
|
|
daace78239 | ||
|
|
d596b9754e | ||
|
|
c1317017e9 | ||
|
|
3f18cad5f1 | ||
|
|
41b62aa979 | ||
|
|
af41eccb31 | ||
|
|
e7b274f85a | ||
|
|
6bd92d47e5 | ||
|
|
b5302fc111 | ||
|
|
724086005a | ||
|
|
038d74edf7 | ||
|
|
b177354c35 | ||
|
|
2039235f6e | ||
|
|
0fd3b6fee6 | ||
|
|
b2f0472fe2 | ||
|
|
91af29f37a | ||
|
|
099af7578f | ||
|
|
948c89b367 | ||
|
|
7e84ce3904 | ||
|
|
a828cf777a | ||
|
|
687dd38998 | ||
|
|
62729ff472 | ||
|
|
0507674a13 | ||
|
|
4f85cfe824 | ||
|
|
7d5567a8d7 | ||
|
|
3ed42cd354 | ||
|
|
4a888b4138 | ||
|
|
f2436a47bb | ||
|
|
83ddfaebf4 | ||
|
|
2b382b171c | ||
|
|
b7553378a4 | ||
|
|
d40f66109b | ||
|
|
9657feaf8c | ||
|
|
d05e85e5be | ||
|
|
9daef9cca2 | ||
|
|
341c42f321 | ||
|
|
631fb6c9ad | ||
|
|
11e19ee690 | ||
|
|
9f322398b4 | ||
|
|
e07510e504 | ||
|
|
ae15d4eaf3 | ||
|
|
469123eda1 | ||
|
|
389bcba97a | ||
|
|
c3d4c5f69d | ||
|
|
144c66215b | ||
|
|
0d7b16da4d | ||
|
|
d8cec03fce | ||
|
|
ccc06451df | ||
|
|
3775a2a226 |
137 changed files with 2274 additions and 851 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
|
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
|
||||||
# Disable CodeRabbit auto-review to prevent verbose comments on PRs.
|
# Disable CodeRabbit auto-review to prevent verbose comments on PRs.
|
||||||
# When enabled: false, CodeRabbit won't attempt reviews and won't post
|
# When enabled: false, CodeRabbit won't attempt reviews and won't post
|
||||||
# "Review skipped" or other automated comments.
|
# "Review skipped" or other automated comments.
|
||||||
|
|
@ -12,3 +13,6 @@ reviews:
|
||||||
tools:
|
tools:
|
||||||
github-checks:
|
github-checks:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
chat:
|
||||||
|
art: false
|
||||||
|
auto_reply: false
|
||||||
|
|
|
||||||
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
|
|
@ -125,13 +125,13 @@ jobs:
|
||||||
cat coverage-reports/index.txt >> $GITHUB_STEP_SUMMARY
|
cat coverage-reports/index.txt >> $GITHUB_STEP_SUMMARY
|
||||||
if: ${{ matrix.instrumented }}
|
if: ${{ matrix.instrumented }}
|
||||||
- name: Upload coverage reports
|
- name: Upload coverage reports
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v5
|
||||||
with:
|
with:
|
||||||
name: coverage-reports
|
name: coverage-reports
|
||||||
path: coverage-reports/
|
path: coverage-reports/
|
||||||
if: ${{ matrix.instrumented }}
|
if: ${{ matrix.instrumented }}
|
||||||
- name: Upload installer tarball
|
- name: Upload installer tarball
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v5
|
||||||
with:
|
with:
|
||||||
name: installer-${{matrix.os}}
|
name: installer-${{matrix.os}}
|
||||||
path: out/*
|
path: out/*
|
||||||
|
|
@ -164,7 +164,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
- name: Download installer tarball
|
- name: Download installer tarball
|
||||||
uses: actions/download-artifact@v5
|
uses: actions/download-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: installer-${{matrix.os}}
|
name: installer-${{matrix.os}}
|
||||||
path: out
|
path: out
|
||||||
|
|
@ -174,7 +174,7 @@ jobs:
|
||||||
echo "installer-url=file://$GITHUB_WORKSPACE/out" >> "$GITHUB_OUTPUT"
|
echo "installer-url=file://$GITHUB_WORKSPACE/out" >> "$GITHUB_OUTPUT"
|
||||||
TARBALL_PATH="$(find "$GITHUB_WORKSPACE/out" -name 'nix*.tar.xz' -print | head -n 1)"
|
TARBALL_PATH="$(find "$GITHUB_WORKSPACE/out" -name 'nix*.tar.xz' -print | head -n 1)"
|
||||||
echo "tarball-path=file://$TARBALL_PATH" >> "$GITHUB_OUTPUT"
|
echo "tarball-path=file://$TARBALL_PATH" >> "$GITHUB_OUTPUT"
|
||||||
- uses: cachix/install-nix-action@c134e4c9e34bac6cab09cf239815f9339aaaf84e # v31.5.1
|
- uses: cachix/install-nix-action@456688f15bc354bef6d396e4a35f4f89d40bf2b7 # v31.8.2
|
||||||
if: ${{ !matrix.experimental-installer }}
|
if: ${{ !matrix.experimental-installer }}
|
||||||
with:
|
with:
|
||||||
install_url: ${{ format('{0}/install', steps.installer-tarball-url.outputs.installer-url) }}
|
install_url: ${{ format('{0}/install', steps.installer-tarball-url.outputs.installer-url) }}
|
||||||
|
|
|
||||||
|
|
@ -107,12 +107,29 @@ rec {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
disable =
|
||||||
|
let
|
||||||
|
inherit (pkgs.stdenv) hostPlatform;
|
||||||
|
in
|
||||||
|
args@{
|
||||||
|
pkgName,
|
||||||
|
testName,
|
||||||
|
test,
|
||||||
|
}:
|
||||||
|
lib.any (b: b) [
|
||||||
|
# FIXME: Nix manual is impure and does not produce all settings on darwin
|
||||||
|
(hostPlatform.isDarwin && pkgName == "nix-manual" && testName == "linkcheck")
|
||||||
|
];
|
||||||
|
|
||||||
componentTests =
|
componentTests =
|
||||||
(lib.concatMapAttrs (
|
(lib.concatMapAttrs (
|
||||||
pkgName: pkg:
|
pkgName: pkg:
|
||||||
lib.concatMapAttrs (testName: test: {
|
lib.concatMapAttrs (
|
||||||
"${componentTestsPrefix}${pkgName}-${testName}" = test;
|
testName: test:
|
||||||
}) (pkg.tests or { })
|
lib.optionalAttrs (!disable { inherit pkgName testName test; }) {
|
||||||
|
"${componentTestsPrefix}${pkgName}-${testName}" = test;
|
||||||
|
}
|
||||||
|
) (pkg.tests or { })
|
||||||
) nixComponentsInstrumented)
|
) nixComponentsInstrumented)
|
||||||
// lib.optionalAttrs (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) {
|
// lib.optionalAttrs (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) {
|
||||||
"${componentTestsPrefix}nix-functional-tests" = nixComponentsInstrumented.nix-functional-tests;
|
"${componentTestsPrefix}nix-functional-tests" = nixComponentsInstrumented.nix-functional-tests;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
|
|
||||||
def transform_anchors_html:
|
def transform_anchors_html:
|
||||||
. | gsub($empty_anchor_regex; "<a name=\"" + .anchor + "\"></a>")
|
. | gsub($empty_anchor_regex; "<a id=\"" + .anchor + "\"></a>")
|
||||||
| gsub($anchor_regex; "<a href=\"#" + .anchor + "\" id=\"" + .anchor + "\">" + .text + "</a>");
|
| gsub($anchor_regex; "<a href=\"#" + .anchor + "\" id=\"" + .anchor + "\">" + .text + "</a>");
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,9 @@
|
||||||
# Configuration Options
|
# Configuration Options
|
||||||
|
|
||||||
version,
|
version,
|
||||||
|
|
||||||
|
# `tests` attribute
|
||||||
|
testers,
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
@ -37,9 +40,11 @@ mkMesonDerivation (finalAttrs: {
|
||||||
../../src/libutil-tests/data/hash
|
../../src/libutil-tests/data/hash
|
||||||
../../src/libstore-tests/data/content-address
|
../../src/libstore-tests/data/content-address
|
||||||
../../src/libstore-tests/data/store-path
|
../../src/libstore-tests/data/store-path
|
||||||
|
../../src/libstore-tests/data/realisation
|
||||||
../../src/libstore-tests/data/derived-path
|
../../src/libstore-tests/data/derived-path
|
||||||
../../src/libstore-tests/data/path-info
|
../../src/libstore-tests/data/path-info
|
||||||
../../src/libstore-tests/data/nar-info
|
../../src/libstore-tests/data/nar-info
|
||||||
|
../../src/libstore-tests/data/build-result
|
||||||
# Too many different types of files to filter for now
|
# Too many different types of files to filter for now
|
||||||
../../doc/manual
|
../../doc/manual
|
||||||
./.
|
./.
|
||||||
|
|
@ -87,6 +92,29 @@ mkMesonDerivation (finalAttrs: {
|
||||||
echo "doc manual ''$out/share/doc/nix/manual" >> ''$out/nix-support/hydra-build-products
|
echo "doc manual ''$out/share/doc/nix/manual" >> ''$out/nix-support/hydra-build-products
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
/**
|
||||||
|
The root of the HTML manual.
|
||||||
|
E.g. "${nix-manual.site}/index.html" exists.
|
||||||
|
*/
|
||||||
|
passthru.site = finalAttrs.finalPackage + "/share/doc/nix/manual";
|
||||||
|
|
||||||
|
passthru.tests = {
|
||||||
|
# https://nixos.org/manual/nixpkgs/stable/index.html#tester-lycheeLinkCheck
|
||||||
|
linkcheck = testers.lycheeLinkCheck {
|
||||||
|
inherit (finalAttrs.finalPackage) site;
|
||||||
|
extraConfig = {
|
||||||
|
exclude = [
|
||||||
|
# Exclude auto-generated JSON schema documentation which has
|
||||||
|
# auto-generated fragment IDs that don't match the link references
|
||||||
|
".*/protocols/json/.*\\.html"
|
||||||
|
# Exclude undocumented builtins
|
||||||
|
".*/language/builtins\\.html#builtins-addErrorContext"
|
||||||
|
".*/language/builtins\\.html#builtins-appendContext"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
platforms = lib.platforms.all;
|
platforms = lib.platforms.all;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
47
doc/manual/rl-next/json-format-changes.md
Normal file
47
doc/manual/rl-next/json-format-changes.md
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
---
|
||||||
|
synopsis: "JSON format changes for store path info and derivations"
|
||||||
|
prs: []
|
||||||
|
issues: []
|
||||||
|
---
|
||||||
|
|
||||||
|
JSON formats for store path info and derivations have been updated with new versions and structured fields.
|
||||||
|
|
||||||
|
## Store Path Info JSON (Version 2)
|
||||||
|
|
||||||
|
The store path info JSON format has been updated from version 1 to version 2:
|
||||||
|
|
||||||
|
- **Added `version` field**:
|
||||||
|
|
||||||
|
All store path info JSON now includes `"version": 2`.
|
||||||
|
|
||||||
|
- **Structured `ca` field**:
|
||||||
|
|
||||||
|
Content address is now a structured JSON object instead of a string:
|
||||||
|
|
||||||
|
- Old: `"ca": "fixed:r:sha256:1abc..."`
|
||||||
|
- New: `"ca": {"method": "nar", "hash": {"algorithm": "sha256", "format": "base64", "hash": "EMIJ+giQ..."}}`
|
||||||
|
- Still `null` values for input-addressed store objects
|
||||||
|
|
||||||
|
Version 1 format is still accepted when reading for backward compatibility.
|
||||||
|
|
||||||
|
**Affected command**: `nix path-info --json`
|
||||||
|
|
||||||
|
## Derivation JSON (Version 4)
|
||||||
|
|
||||||
|
The derivation JSON format has been updated from version 3 to version 4:
|
||||||
|
|
||||||
|
- **Restructured inputs**:
|
||||||
|
|
||||||
|
Inputs are now nested under an `inputs` object:
|
||||||
|
|
||||||
|
- Old: `"inputSrcs": [...], "inputDrvs": {...}`
|
||||||
|
- New: `"inputs": {"srcs": [...], "drvs": {...}}`
|
||||||
|
|
||||||
|
- **Consistent content addresses**:
|
||||||
|
|
||||||
|
Floating content-addressed outputs now use structured JSON format.
|
||||||
|
This is the same format as `ca` in in store path info (after the new version).
|
||||||
|
|
||||||
|
Version 3 and earlier formats are *not* accepted when reading.
|
||||||
|
|
||||||
|
**Affected command**: `nix derivation`, namely it's `show` and `add` sub-commands.
|
||||||
|
|
@ -126,6 +126,8 @@
|
||||||
- [Store Object Info](protocols/json/store-object-info.md)
|
- [Store Object Info](protocols/json/store-object-info.md)
|
||||||
- [Derivation](protocols/json/derivation.md)
|
- [Derivation](protocols/json/derivation.md)
|
||||||
- [Deriving Path](protocols/json/deriving-path.md)
|
- [Deriving Path](protocols/json/deriving-path.md)
|
||||||
|
- [Build Trace Entry](protocols/json/build-trace-entry.md)
|
||||||
|
- [Build Result](protocols/json/build-result.md)
|
||||||
- [Serving Tarball Flakes](protocols/tarball-fetcher.md)
|
- [Serving Tarball Flakes](protocols/tarball-fetcher.md)
|
||||||
- [Store Path Specification](protocols/store-path.md)
|
- [Store Path Specification](protocols/store-path.md)
|
||||||
- [Nix Archive (NAR) Format](protocols/nix-archive/index.md)
|
- [Nix Archive (NAR) Format](protocols/nix-archive/index.md)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ The moving parts of channels are:
|
||||||
- The official channels listed at <https://nixos.org/channels>
|
- The official channels listed at <https://nixos.org/channels>
|
||||||
- The user-specific list of [subscribed channels](#subscribed-channels)
|
- The user-specific list of [subscribed channels](#subscribed-channels)
|
||||||
- The [downloaded channel contents](#channels)
|
- The [downloaded channel contents](#channels)
|
||||||
- The [Nix expression search path](@docroot@/command-ref/conf-file.md#conf-nix-path), set with the [`-I` option](#opt-i) or the [`NIX_PATH` environment variable](#env-NIX_PATH)
|
- The [Nix expression search path](@docroot@/command-ref/conf-file.md#conf-nix-path), set with the [`-I` option](#opt-I) or the [`NIX_PATH` environment variable](#env-NIX_PATH)
|
||||||
|
|
||||||
> **Note**
|
> **Note**
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ left untouched; this is not an error. It is also not an error if an
|
||||||
element of *args* matches no installed derivations.
|
element of *args* matches no installed derivations.
|
||||||
|
|
||||||
For a description of how *args* is mapped to a set of store paths, see
|
For a description of how *args* is mapped to a set of store paths, see
|
||||||
[`--install`](#operation---install). If *args* describes multiple
|
[`--install`](./install.md). If *args* describes multiple
|
||||||
store paths with the same symbolic name, only the one with the highest
|
store paths with the same symbolic name, only the one with the highest
|
||||||
version is installed.
|
version is installed.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ You can also build Nix for one of the [supported platforms](#platforms).
|
||||||
This section assumes you are using Nix with the [`flakes`] and [`nix-command`] experimental features enabled.
|
This section assumes you are using Nix with the [`flakes`] and [`nix-command`] experimental features enabled.
|
||||||
|
|
||||||
[`flakes`]: @docroot@/development/experimental-features.md#xp-feature-flakes
|
[`flakes`]: @docroot@/development/experimental-features.md#xp-feature-flakes
|
||||||
[`nix-command`]: @docroot@/development/experimental-features.md#xp-nix-command
|
[`nix-command`]: @docroot@/development/experimental-features.md#xp-feature-nix-command
|
||||||
|
|
||||||
To build all dependencies and start a shell in which all environment variables are set up so that those dependencies can be found:
|
To build all dependencies and start a shell in which all environment variables are set up so that those dependencies can be found:
|
||||||
|
|
||||||
|
|
@ -256,7 +256,7 @@ You can use any of the other supported environments in place of `nix-cli-ccacheS
|
||||||
## Editor integration
|
## Editor integration
|
||||||
|
|
||||||
The `clangd` LSP server is installed by default on the `clang`-based `devShell`s.
|
The `clangd` LSP server is installed by default on the `clang`-based `devShell`s.
|
||||||
See [supported compilation environments](#compilation-environments) and instructions how to set up a shell [with flakes](#nix-with-flakes) or in [classic Nix](#classic-nix).
|
See [supported compilation environments](#compilation-environments) and instructions how to set up a shell [with flakes](#building-nix-with-flakes) or in [classic Nix](#building-nix).
|
||||||
|
|
||||||
To use the LSP with your editor, you will want a `compile_commands.json` file telling `clangd` how we are compiling the code.
|
To use the LSP with your editor, you will want a `compile_commands.json` file telling `clangd` how we are compiling the code.
|
||||||
Meson's configure always produces this inside the build directory.
|
Meson's configure always produces this inside the build directory.
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ This will:
|
||||||
|
|
||||||
3. Stop the program when the test fails, allowing the user to then issue arbitrary commands to GDB.
|
3. Stop the program when the test fails, allowing the user to then issue arbitrary commands to GDB.
|
||||||
|
|
||||||
### Characterisation testing { #characaterisation-testing-unit }
|
### Characterisation testing { #characterisation-testing-unit }
|
||||||
|
|
||||||
See [functional characterisation testing](#characterisation-testing-functional) for a broader discussion of characterisation testing.
|
See [functional characterisation testing](#characterisation-testing-functional) for a broader discussion of characterisation testing.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -208,7 +208,7 @@
|
||||||
|
|
||||||
- [impure derivation]{#gloss-impure-derivation}
|
- [impure derivation]{#gloss-impure-derivation}
|
||||||
|
|
||||||
[An experimental feature](#@docroot@/development/experimental-features.md#xp-feature-impure-derivations) that allows derivations to be explicitly marked as impure,
|
[An experimental feature](@docroot@/development/experimental-features.md#xp-feature-impure-derivations) that allows derivations to be explicitly marked as impure,
|
||||||
so that they are always rebuilt, and their outputs not reused by subsequent calls to realise them.
|
so that they are always rebuilt, and their outputs not reused by subsequent calls to realise them.
|
||||||
|
|
||||||
- [Nix database]{#gloss-nix-database}
|
- [Nix database]{#gloss-nix-database}
|
||||||
|
|
@ -279,7 +279,7 @@
|
||||||
|
|
||||||
See [References](@docroot@/store/store-object.md#references) for details.
|
See [References](@docroot@/store/store-object.md#references) for details.
|
||||||
|
|
||||||
- [referrer]{#gloss-reference}
|
- [referrer]{#gloss-referrer}
|
||||||
|
|
||||||
A reversed edge from one [store object] to another.
|
A reversed edge from one [store object] to another.
|
||||||
|
|
||||||
|
|
@ -367,8 +367,8 @@
|
||||||
|
|
||||||
Nix represents files as [file system objects][file system object], and how they belong together is encoded as [references][reference] between [store objects][store object] that contain these file system objects.
|
Nix represents files as [file system objects][file system object], and how they belong together is encoded as [references][reference] between [store objects][store object] that contain these file system objects.
|
||||||
|
|
||||||
The [Nix language] allows denoting packages in terms of [attribute sets](@docroot@/language/types.md#attribute-set) containing:
|
The [Nix language] allows denoting packages in terms of [attribute sets](@docroot@/language/types.md#type-attrs) containing:
|
||||||
- attributes that refer to the files of a package, typically in the form of [derivation outputs](#output),
|
- attributes that refer to the files of a package, typically in the form of [derivation outputs](#gloss-output),
|
||||||
- attributes with metadata, such as information about how the package is supposed to be used.
|
- attributes with metadata, such as information about how the package is supposed to be used.
|
||||||
|
|
||||||
The exact shape of these attribute sets is up to convention.
|
The exact shape of these attribute sets is up to convention.
|
||||||
|
|
@ -383,7 +383,7 @@
|
||||||
|
|
||||||
[string]: ./language/types.md#type-string
|
[string]: ./language/types.md#type-string
|
||||||
[path]: ./language/types.md#type-path
|
[path]: ./language/types.md#type-path
|
||||||
[attribute name]: ./language/types.md#attribute-set
|
[attribute name]: ./language/types.md#type-attrs
|
||||||
|
|
||||||
- [base directory]{#gloss-base-directory}
|
- [base directory]{#gloss-base-directory}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,7 @@ Here is more information on the `output*` attributes, and what values they may b
|
||||||
|
|
||||||
`outputHashAlgo` can only be `null` when `outputHash` follows the SRI format, because in that case the choice of hash algorithm is determined by `outputHash`.
|
`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}
|
- [`outputHash`]{#adv-attr-outputHash}
|
||||||
|
|
||||||
This will specify the output hash of the single output of a [fixed-output derivation].
|
This will specify the output hash of the single output of a [fixed-output derivation].
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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))
|
- [`name`]{#attr-name} ([String](@docroot@/language/types.md#type-string))
|
||||||
|
|
||||||
A symbolic name for the derivation.
|
A symbolic name for the derivation.
|
||||||
See [derivation outputs](@docroot@/store/derivation/index.md#outputs) for what this is affects.
|
See [derivation outputs](@docroot@/store/derivation/outputs/index.md#outputs) for what this is affects.
|
||||||
|
|
||||||
[store path]: @docroot@/store/store-path.md
|
[store path]: @docroot@/store/store-path.md
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ An *identifier* is an [ASCII](https://en.wikipedia.org/wiki/ASCII) character seq
|
||||||
|
|
||||||
# Names
|
# Names
|
||||||
|
|
||||||
A *name* can be written as an [identifier](#identifier) or a [string literal](./string-literals.md).
|
A *name* can be written as an [identifier](#identifiers) or a [string literal](./string-literals.md).
|
||||||
|
|
||||||
> **Syntax**
|
> **Syntax**
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ This is an incomplete overview of language features, by example.
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
[Booleans](@docroot@/language/types.md#type-boolean)
|
[Booleans](@docroot@/language/types.md#type-bool)
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -245,7 +245,7 @@ This is an incomplete overview of language features, by example.
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
An [attribute set](@docroot@/language/types.md#attribute-set) with attributes named `x` and `y`
|
An [attribute set](@docroot@/language/types.md#type-attrs) with attributes named `x` and `y`
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -285,7 +285,7 @@ This is an incomplete overview of language features, by example.
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
[Lists](@docroot@/language/types.md#list) with three elements.
|
[Lists](@docroot@/language/types.md#type-list) with three elements.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -369,7 +369,7 @@ This is an incomplete overview of language features, by example.
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
[Attribute selection](@docroot@/language/types.md#attribute-set) (evaluates to `1`)
|
[Attribute selection](@docroot@/language/types.md#type-attrs) (evaluates to `1`)
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -381,7 +381,7 @@ This is an incomplete overview of language features, by example.
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
[Attribute selection](@docroot@/language/types.md#attribute-set) with default (evaluates to `3`)
|
[Attribute selection](@docroot@/language/types.md#type-attrs) with default (evaluates to `3`)
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ It creates an [attribute set] representing the string context, which can be insp
|
||||||
|
|
||||||
[`builtins.hasContext`]: ./builtins.md#builtins-hasContext
|
[`builtins.hasContext`]: ./builtins.md#builtins-hasContext
|
||||||
[`builtins.getContext`]: ./builtins.md#builtins-getContext
|
[`builtins.getContext`]: ./builtins.md#builtins-getContext
|
||||||
[attribute set]: ./types.md#attribute-set
|
[attribute set]: ./types.md#type-attrs
|
||||||
|
|
||||||
## Clearing string contexts
|
## Clearing string contexts
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ Such a construct is called *interpolated string*, and the expression inside is a
|
||||||
|
|
||||||
[string]: ./types.md#type-string
|
[string]: ./types.md#type-string
|
||||||
[path]: ./types.md#type-path
|
[path]: ./types.md#type-path
|
||||||
[attribute set]: ./types.md#attribute-set
|
[attribute set]: ./types.md#type-attrs
|
||||||
|
|
||||||
> **Syntax**
|
> **Syntax**
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ See [String literals](string-literals.md).
|
||||||
|
|
||||||
Path literals can also include [string interpolation], besides being [interpolated into other expressions].
|
Path literals can also include [string interpolation], besides being [interpolated into other expressions].
|
||||||
|
|
||||||
[interpolated into other expressions]: ./string-interpolation.md#interpolated-expressions
|
[interpolated into other expressions]: ./string-interpolation.md#interpolated-expression
|
||||||
|
|
||||||
At least one slash (`/`) must appear *before* any interpolated expression for the result to be recognized as a path.
|
At least one slash (`/`) must appear *before* any interpolated expression for the result to be recognized as a path.
|
||||||
|
|
||||||
|
|
@ -235,7 +235,7 @@ of object-oriented programming, for example.
|
||||||
|
|
||||||
## Recursive sets
|
## Recursive sets
|
||||||
|
|
||||||
Recursive sets are like normal [attribute sets](./types.md#attribute-set), but the attributes can refer to each other.
|
Recursive sets are like normal [attribute sets](./types.md#type-attrs), but the attributes can refer to each other.
|
||||||
|
|
||||||
> *rec-attrset* = `rec {` [ *name* `=` *expr* `;` `]`... `}`
|
> *rec-attrset* = `rec {` [ *name* `=` *expr* `;` `]`... `}`
|
||||||
|
|
||||||
|
|
@ -287,7 +287,7 @@ This evaluates to `"foobar"`.
|
||||||
|
|
||||||
## Inheriting attributes
|
## Inheriting attributes
|
||||||
|
|
||||||
When defining an [attribute set](./types.md#attribute-set) or in a [let-expression](#let-expressions) it is often convenient to copy variables from the surrounding lexical scope (e.g., when you want to propagate attributes).
|
When defining an [attribute set](./types.md#type-attrs) or in a [let-expression](#let-expressions) it is often convenient to copy variables from the surrounding lexical scope (e.g., when you want to propagate attributes).
|
||||||
This can be shortened using the `inherit` keyword.
|
This can be shortened using the `inherit` keyword.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
|
||||||
21
doc/manual/source/protocols/json/build-result.md
Normal file
21
doc/manual/source/protocols/json/build-result.md
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
{{#include build-result-v1-fixed.md}}
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Successful build
|
||||||
|
|
||||||
|
```json
|
||||||
|
{{#include schema/build-result-v1/success.json}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Failed build (output rejected)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{{#include schema/build-result-v1/output-rejected.json}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Failed build (non-deterministic)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{{#include schema/build-result-v1/not-deterministic.json}}
|
||||||
|
```
|
||||||
27
doc/manual/source/protocols/json/build-trace-entry.md
Normal file
27
doc/manual/source/protocols/json/build-trace-entry.md
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
{{#include build-trace-entry-v1-fixed.md}}
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Simple build trace entry
|
||||||
|
|
||||||
|
```json
|
||||||
|
{{#include schema/build-trace-entry-v1/simple.json}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build trace entry with dependencies
|
||||||
|
|
||||||
|
```json
|
||||||
|
{{#include schema/build-trace-entry-v1/with-dependent-realisations.json}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build trace entry with signature
|
||||||
|
|
||||||
|
```json
|
||||||
|
{{#include schema/build-trace-entry-v1/with-signature.json}}
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--
|
||||||
|
## Raw Schema
|
||||||
|
|
||||||
|
[JSON Schema for Build Trace Entry v1](schema/build-trace-entry-v1.json)
|
||||||
|
-->
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{{#include derivation-v3-fixed.md}}
|
{{#include derivation-v4-fixed.md}}
|
||||||
|
|
||||||
<!-- need to convert YAML to JSON first
|
<!-- need to convert YAML to JSON first
|
||||||
## Raw Schema
|
## Raw Schema
|
||||||
|
|
||||||
[JSON Schema for Derivation v3](schema/derivation-v3.json)
|
[JSON Schema for Derivation v3](schema/derivation-v4.json)
|
||||||
-->
|
-->
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,11 @@ schemas = [
|
||||||
'hash-v1',
|
'hash-v1',
|
||||||
'content-address-v1',
|
'content-address-v1',
|
||||||
'store-path-v1',
|
'store-path-v1',
|
||||||
'store-object-info-v1',
|
'store-object-info-v2',
|
||||||
'derivation-v3',
|
'derivation-v4',
|
||||||
'deriving-path-v1',
|
'deriving-path-v1',
|
||||||
|
'build-trace-entry-v1',
|
||||||
|
'build-result-v1',
|
||||||
]
|
]
|
||||||
|
|
||||||
schema_files = files()
|
schema_files = files()
|
||||||
|
|
|
||||||
1
doc/manual/source/protocols/json/schema/build-result-v1
Symbolic link
1
doc/manual/source/protocols/json/schema/build-result-v1
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../../../src/libstore-tests/data/build-result
|
||||||
136
doc/manual/source/protocols/json/schema/build-result-v1.yaml
Normal file
136
doc/manual/source/protocols/json/schema/build-result-v1.yaml
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
"$schema": "http://json-schema.org/draft-04/schema"
|
||||||
|
"$id": "https://nix.dev/manual/nix/latest/protocols/json/schema/build-result-v1.json"
|
||||||
|
title: Build Result
|
||||||
|
description: |
|
||||||
|
This schema describes the JSON representation of Nix's `BuildResult` type, which represents the result of building a derivation or substituting store paths.
|
||||||
|
|
||||||
|
Build results can represent either successful builds (with built outputs) or various types of failures.
|
||||||
|
|
||||||
|
oneOf:
|
||||||
|
- "$ref": "#/$defs/success"
|
||||||
|
- "$ref": "#/$defs/failure"
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- success
|
||||||
|
- status
|
||||||
|
properties:
|
||||||
|
timesBuilt:
|
||||||
|
type: integer
|
||||||
|
minimum: 0
|
||||||
|
title: Times built
|
||||||
|
description: |
|
||||||
|
How many times this build was performed.
|
||||||
|
|
||||||
|
startTime:
|
||||||
|
type: integer
|
||||||
|
minimum: 0
|
||||||
|
title: Start time
|
||||||
|
description: |
|
||||||
|
The start time of the build (or one of the rounds, if it was repeated), as a Unix timestamp.
|
||||||
|
|
||||||
|
stopTime:
|
||||||
|
type: integer
|
||||||
|
minimum: 0
|
||||||
|
title: Stop time
|
||||||
|
description: |
|
||||||
|
The stop time of the build (or one of the rounds, if it was repeated), as a Unix timestamp.
|
||||||
|
|
||||||
|
cpuUser:
|
||||||
|
type: integer
|
||||||
|
minimum: 0
|
||||||
|
title: User CPU time
|
||||||
|
description: |
|
||||||
|
User CPU time the build took, in microseconds.
|
||||||
|
|
||||||
|
cpuSystem:
|
||||||
|
type: integer
|
||||||
|
minimum: 0
|
||||||
|
title: System CPU time
|
||||||
|
description: |
|
||||||
|
System CPU time the build took, in microseconds.
|
||||||
|
|
||||||
|
"$defs":
|
||||||
|
success:
|
||||||
|
type: object
|
||||||
|
title: Successful Build Result
|
||||||
|
description: |
|
||||||
|
Represents a successful build with built outputs.
|
||||||
|
required:
|
||||||
|
- success
|
||||||
|
- status
|
||||||
|
- builtOutputs
|
||||||
|
properties:
|
||||||
|
success:
|
||||||
|
const: true
|
||||||
|
title: Success indicator
|
||||||
|
description: |
|
||||||
|
Always true for successful build results.
|
||||||
|
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
title: Success status
|
||||||
|
description: |
|
||||||
|
Status string for successful builds.
|
||||||
|
enum:
|
||||||
|
- "Built"
|
||||||
|
- "Substituted"
|
||||||
|
- "AlreadyValid"
|
||||||
|
- "ResolvesToAlreadyValid"
|
||||||
|
|
||||||
|
builtOutputs:
|
||||||
|
type: object
|
||||||
|
title: Built outputs
|
||||||
|
description: |
|
||||||
|
A mapping from output names to their build trace entries.
|
||||||
|
additionalProperties:
|
||||||
|
"$ref": "build-trace-entry-v1.yaml"
|
||||||
|
|
||||||
|
failure:
|
||||||
|
type: object
|
||||||
|
title: Failed Build Result
|
||||||
|
description: |
|
||||||
|
Represents a failed build with error information.
|
||||||
|
required:
|
||||||
|
- success
|
||||||
|
- status
|
||||||
|
- errorMsg
|
||||||
|
properties:
|
||||||
|
success:
|
||||||
|
const: false
|
||||||
|
title: Success indicator
|
||||||
|
description: |
|
||||||
|
Always false for failed build results.
|
||||||
|
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
title: Failure status
|
||||||
|
description: |
|
||||||
|
Status string for failed builds.
|
||||||
|
enum:
|
||||||
|
- "PermanentFailure"
|
||||||
|
- "InputRejected"
|
||||||
|
- "OutputRejected"
|
||||||
|
- "TransientFailure"
|
||||||
|
- "CachedFailure"
|
||||||
|
- "TimedOut"
|
||||||
|
- "MiscFailure"
|
||||||
|
- "DependencyFailed"
|
||||||
|
- "LogLimitExceeded"
|
||||||
|
- "NotDeterministic"
|
||||||
|
- "NoSubstituters"
|
||||||
|
- "HashMismatch"
|
||||||
|
|
||||||
|
errorMsg:
|
||||||
|
type: string
|
||||||
|
title: Error message
|
||||||
|
description: |
|
||||||
|
Information about the error if the build failed.
|
||||||
|
|
||||||
|
isNonDeterministic:
|
||||||
|
type: boolean
|
||||||
|
title: Non-deterministic flag
|
||||||
|
description: |
|
||||||
|
If timesBuilt > 1, whether some builds did not produce the same result.
|
||||||
|
|
||||||
|
Note that 'isNonDeterministic = false' does not mean the build is deterministic,
|
||||||
|
just that we don't have evidence of non-determinism.
|
||||||
1
doc/manual/source/protocols/json/schema/build-trace-entry-v1
Symbolic link
1
doc/manual/source/protocols/json/schema/build-trace-entry-v1
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../../../src/libstore-tests/data/realisation
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
"$schema": "http://json-schema.org/draft-04/schema"
|
||||||
|
"$id": "https://nix.dev/manual/nix/latest/protocols/json/schema/build-trace-entry-v1.json"
|
||||||
|
title: Build Trace Entry
|
||||||
|
description: |
|
||||||
|
A record of a successful build outcome for a specific derivation output.
|
||||||
|
|
||||||
|
This schema describes the JSON representation of a [build trace entry](@docroot@/store/build-trace.md) entry.
|
||||||
|
|
||||||
|
> **Warning**
|
||||||
|
>
|
||||||
|
> This JSON format is currently
|
||||||
|
> [**experimental**](@docroot@/development/experimental-features.md#xp-feature-ca-derivations)
|
||||||
|
> and subject to change.
|
||||||
|
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- outPath
|
||||||
|
- dependentRealisations
|
||||||
|
- signatures
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
title: Derivation Output ID
|
||||||
|
pattern: "^sha256:[0-9a-f]{64}![a-zA-Z_][a-zA-Z0-9_-]*$"
|
||||||
|
description: |
|
||||||
|
Unique identifier for the derivation output that was built.
|
||||||
|
|
||||||
|
Format: `{hash-quotient-drv}!{output-name}`
|
||||||
|
|
||||||
|
- **hash-quotient-drv**: SHA-256 [hash of the quotient derivation](@docroot@/store/derivation/outputs/input-address.md#hash-quotient-drv).
|
||||||
|
Begins with `sha256:`.
|
||||||
|
|
||||||
|
- **output-name**: Name of the specific output (e.g., "out", "dev", "doc")
|
||||||
|
|
||||||
|
Example: `"sha256:ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad!foo"`
|
||||||
|
|
||||||
|
outPath:
|
||||||
|
"$ref": "store-path-v1.yaml"
|
||||||
|
title: Output Store Path
|
||||||
|
description: |
|
||||||
|
The path to the store object that resulted from building this derivation for the given output name.
|
||||||
|
|
||||||
|
dependentRealisations:
|
||||||
|
type: object
|
||||||
|
title: Underlying Base Build Trace
|
||||||
|
description: |
|
||||||
|
This is for [*derived*](@docroot@/store/build-trace.md#derived) build trace entries to ensure coherence.
|
||||||
|
|
||||||
|
Keys are derivation output IDs (same format as the main `id` field).
|
||||||
|
Values are the store paths that those dependencies resolved to.
|
||||||
|
|
||||||
|
As described in the linked section on derived build trace traces, derived build trace entries must be kept in addition and not instead of the underlying base build entries.
|
||||||
|
This is the set of base build trace entries that this derived build trace is derived from.
|
||||||
|
(The set is also a map since this miniature base build trace must be coherent, mapping each key to a single value.)
|
||||||
|
|
||||||
|
patternProperties:
|
||||||
|
"^sha256:[0-9a-f]{64}![a-zA-Z_][a-zA-Z0-9_-]*$":
|
||||||
|
$ref: "store-path-v1.yaml"
|
||||||
|
title: Dependent Store Path
|
||||||
|
description: Store path that this dependency resolved to during the build
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
signatures:
|
||||||
|
type: array
|
||||||
|
title: Build Signatures
|
||||||
|
description: |
|
||||||
|
A set of cryptographic signatures attesting to the authenticity of this build trace entry.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
title: Signature
|
||||||
|
description: A single cryptographic signature
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
"$schema": "http://json-schema.org/draft-04/schema"
|
"$schema": "http://json-schema.org/draft-04/schema"
|
||||||
"$id": "https://nix.dev/manual/nix/latest/protocols/json/schema/derivation-v3.json"
|
"$id": "https://nix.dev/manual/nix/latest/protocols/json/schema/derivation-v4.json"
|
||||||
title: Derivation
|
title: Derivation
|
||||||
description: |
|
description: |
|
||||||
Experimental JSON representation of a Nix derivation (version 3).
|
Experimental JSON representation of a Nix derivation (version 4).
|
||||||
|
|
||||||
This schema describes the JSON representation of Nix's `Derivation` type.
|
This schema describes the JSON representation of Nix's `Derivation` type.
|
||||||
|
|
||||||
|
|
@ -17,8 +17,7 @@ required:
|
||||||
- name
|
- name
|
||||||
- version
|
- version
|
||||||
- outputs
|
- outputs
|
||||||
- inputSrcs
|
- inputs
|
||||||
- inputDrvs
|
|
||||||
- system
|
- system
|
||||||
- builder
|
- builder
|
||||||
- args
|
- args
|
||||||
|
|
@ -32,10 +31,10 @@ properties:
|
||||||
Used when calculating store paths for the derivation’s outputs.
|
Used when calculating store paths for the derivation’s outputs.
|
||||||
|
|
||||||
version:
|
version:
|
||||||
const: 3
|
const: 4
|
||||||
title: Format version (must be 3)
|
title: Format version (must be 4)
|
||||||
description: |
|
description: |
|
||||||
Must be `3`.
|
Must be `4`.
|
||||||
This is a guard that allows us to continue evolving this format.
|
This is a guard that allows us to continue evolving this format.
|
||||||
The choice of `3` is fairly arbitrary, but corresponds to this informal version:
|
The choice of `3` is fairly arbitrary, but corresponds to this informal version:
|
||||||
|
|
||||||
|
|
@ -47,6 +46,12 @@ properties:
|
||||||
|
|
||||||
- Version 3: Drop store dir from store paths, just include base name.
|
- Version 3: Drop store dir from store paths, just include base name.
|
||||||
|
|
||||||
|
- Version 4: Two cleanups, batched together to lesson churn:
|
||||||
|
|
||||||
|
- Reorganize inputs into nested structure (`inputs.srcs` and `inputs.drvs`)
|
||||||
|
|
||||||
|
- Use canonical content address JSON format for floating content addressed derivation outputs.
|
||||||
|
|
||||||
Note that while this format is experimental, the maintenance of versions is best-effort, and not promised to identify every change.
|
Note that while this format is experimental, the maintenance of versions is best-effort, and not promised to identify every change.
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
|
|
@ -70,47 +75,56 @@ properties:
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
"$ref": "#/$defs/output/overall"
|
"$ref": "#/$defs/output/overall"
|
||||||
|
|
||||||
inputSrcs:
|
inputs:
|
||||||
type: array
|
|
||||||
title: Input source paths
|
|
||||||
description: |
|
|
||||||
List of store paths on which this derivation depends.
|
|
||||||
|
|
||||||
> **Example**
|
|
||||||
>
|
|
||||||
> ```json
|
|
||||||
> "inputSrcs": [
|
|
||||||
> "47y241wqdhac3jm5l7nv0x4975mb1975-separate-debug-info.sh",
|
|
||||||
> "56d0w71pjj9bdr363ym3wj1zkwyqq97j-fix-pop-var-context-error.patch"
|
|
||||||
> ]
|
|
||||||
> ```
|
|
||||||
items:
|
|
||||||
$ref: "store-path-v1.yaml"
|
|
||||||
|
|
||||||
inputDrvs:
|
|
||||||
type: object
|
type: object
|
||||||
title: Input derivations
|
title: Derivation inputs
|
||||||
description: |
|
description: |
|
||||||
Mapping of derivation paths to lists of output names they provide.
|
Input dependencies for the derivation, organized into source paths and derivation dependencies.
|
||||||
|
required:
|
||||||
> **Example**
|
- srcs
|
||||||
>
|
- drvs
|
||||||
> ```json
|
properties:
|
||||||
> "inputDrvs": {
|
srcs:
|
||||||
> "6lkh5yi7nlb7l6dr8fljlli5zfd9hq58-curl-7.73.0.drv": ["dev"],
|
type: array
|
||||||
> "fn3kgnfzl5dzym26j8g907gq3kbm8bfh-unzip-6.0.drv": ["out"]
|
title: Input source paths
|
||||||
> }
|
|
||||||
> ```
|
|
||||||
>
|
|
||||||
> specifies that this derivation depends on the `dev` output of `curl`, and the `out` output of `unzip`.
|
|
||||||
patternProperties:
|
|
||||||
"^[0123456789abcdfghijklmnpqrsvwxyz]{32}-.+\\.drv$":
|
|
||||||
title: Store Path
|
|
||||||
description: |
|
description: |
|
||||||
A store path to a derivation, mapped to the outputs of that derivation.
|
List of store paths on which this derivation depends.
|
||||||
oneOf:
|
|
||||||
- "$ref": "#/$defs/outputNames"
|
> **Example**
|
||||||
- "$ref": "#/$defs/dynamicOutputs"
|
>
|
||||||
|
> ```json
|
||||||
|
> "srcs": [
|
||||||
|
> "47y241wqdhac3jm5l7nv0x4975mb1975-separate-debug-info.sh",
|
||||||
|
> "56d0w71pjj9bdr363ym3wj1zkwyqq97j-fix-pop-var-context-error.patch"
|
||||||
|
> ]
|
||||||
|
> ```
|
||||||
|
items:
|
||||||
|
$ref: "store-path-v1.yaml"
|
||||||
|
drvs:
|
||||||
|
type: object
|
||||||
|
title: Input derivations
|
||||||
|
description: |
|
||||||
|
Mapping of derivation paths to lists of output names they provide.
|
||||||
|
|
||||||
|
> **Example**
|
||||||
|
>
|
||||||
|
> ```json
|
||||||
|
> "drvs": {
|
||||||
|
> "6lkh5yi7nlb7l6dr8fljlli5zfd9hq58-curl-7.73.0.drv": ["dev"],
|
||||||
|
> "fn3kgnfzl5dzym26j8g907gq3kbm8bfh-unzip-6.0.drv": ["out"]
|
||||||
|
> }
|
||||||
|
> ```
|
||||||
|
>
|
||||||
|
> specifies that this derivation depends on the `dev` output of `curl`, and the `out` output of `unzip`.
|
||||||
|
patternProperties:
|
||||||
|
"^[0123456789abcdfghijklmnpqrsvwxyz]{32}-.+\\.drv$":
|
||||||
|
title: Store Path
|
||||||
|
description: |
|
||||||
|
A store path to a derivation, mapped to the outputs of that derivation.
|
||||||
|
oneOf:
|
||||||
|
- "$ref": "#/$defs/outputNames"
|
||||||
|
- "$ref": "#/$defs/dynamicOutputs"
|
||||||
|
additionalProperties: false
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
system:
|
system:
|
||||||
|
|
@ -189,24 +203,18 @@ properties:
|
||||||
The output is content-addressed, and the content-address is fixed in advance.
|
The output is content-addressed, and the content-address is fixed in advance.
|
||||||
|
|
||||||
See [Fixed-output content-addressing](@docroot@/store/derivation/outputs/content-address.md#fixed) for more details.
|
See [Fixed-output content-addressing](@docroot@/store/derivation/outputs/content-address.md#fixed) for more details.
|
||||||
type: object
|
"$ref": "./content-address-v1.yaml"
|
||||||
required:
|
required:
|
||||||
- method
|
- method
|
||||||
- hashAlgo
|
|
||||||
- hash
|
- hash
|
||||||
properties:
|
properties:
|
||||||
method:
|
method:
|
||||||
"$ref": "./content-address-v1.yaml#/$defs/method"
|
|
||||||
description: |
|
description: |
|
||||||
Method of content addressing used for this output.
|
Method of content addressing used for this output.
|
||||||
hashAlgo:
|
|
||||||
title: Hash algorithm
|
|
||||||
"$ref": "./hash-v1.yaml#/$defs/algorithm"
|
|
||||||
hash:
|
hash:
|
||||||
type: string
|
|
||||||
title: Expected hash value
|
title: Expected hash value
|
||||||
description: |
|
description: |
|
||||||
The expected content hash in base-16.
|
The expected content hash.
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
caFloating:
|
caFloating:
|
||||||
|
|
@ -51,4 +51,4 @@ additionalProperties: false
|
||||||
description: |
|
description: |
|
||||||
The hash algorithm used to compute the hash value.
|
The hash algorithm used to compute the hash value.
|
||||||
|
|
||||||
`blake3` is currently experimental and requires the [`blake-hashing`](@docroot@/development/experimental-features.md#xp-feature-blake-hashing) experimental feature.
|
`blake3` is currently experimental and requires the [`blake-hashing`](@docroot@/development/experimental-features.md#xp-feature-blake3-hashes) experimental feature.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"$schema": "http://json-schema.org/draft-07/schema"
|
"$schema": "http://json-schema.org/draft-04/schema"
|
||||||
"$id": "https://nix.dev/manual/nix/latest/protocols/json/schema/store-object-info-v1.json"
|
"$id": "https://nix.dev/manual/nix/latest/protocols/json/schema/store-object-info-v2.json"
|
||||||
title: Store Object Info
|
title: Store Object Info v2
|
||||||
description: |
|
description: |
|
||||||
Information about a [store object](@docroot@/store/store-object.md).
|
Information about a [store object](@docroot@/store/store-object.md).
|
||||||
|
|
||||||
|
|
@ -41,11 +41,27 @@ $defs:
|
||||||
This is the minimal set of fields that describe what a store object contains.
|
This is the minimal set of fields that describe what a store object contains.
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
|
- version
|
||||||
- narHash
|
- narHash
|
||||||
- narSize
|
- narSize
|
||||||
- references
|
- references
|
||||||
- ca
|
- ca
|
||||||
properties:
|
properties:
|
||||||
|
version:
|
||||||
|
type: integer
|
||||||
|
const: 2
|
||||||
|
title: Format version (must be 2)
|
||||||
|
description: |
|
||||||
|
Must be `2`.
|
||||||
|
This is a guard that allows us to continue evolving this format.
|
||||||
|
Here is the rough version history:
|
||||||
|
|
||||||
|
- Version 0: `.narinfo` line-oriented format
|
||||||
|
|
||||||
|
- Version 1: Original JSON format, with ugly `"r:sha256"` inherited from `.narinfo` format.
|
||||||
|
|
||||||
|
- Version 2: Use structured JSON type for `ca`
|
||||||
|
|
||||||
path:
|
path:
|
||||||
type: string
|
type: string
|
||||||
title: Store Path
|
title: Store Path
|
||||||
|
|
@ -76,7 +92,10 @@ $defs:
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
ca:
|
ca:
|
||||||
type: ["string", "null"]
|
oneOf:
|
||||||
|
- type: "null"
|
||||||
|
const: null
|
||||||
|
- "$ref": "./content-address-v1.yaml"
|
||||||
title: Content Address
|
title: Content Address
|
||||||
description: |
|
description: |
|
||||||
If the store object is [content-addressed](@docroot@/store/store-object/content-address.md),
|
If the store object is [content-addressed](@docroot@/store/store-object/content-address.md),
|
||||||
|
|
@ -91,6 +110,7 @@ $defs:
|
||||||
In other words, the same store object in different stores could have different values for these impure fields.
|
In other words, the same store object in different stores could have different values for these impure fields.
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
|
- version
|
||||||
- narHash
|
- narHash
|
||||||
- narSize
|
- narSize
|
||||||
- references
|
- references
|
||||||
|
|
@ -101,6 +121,7 @@ $defs:
|
||||||
- ultimate
|
- ultimate
|
||||||
- signatures
|
- signatures
|
||||||
properties:
|
properties:
|
||||||
|
version: { $ref: "#/$defs/base/properties/version" }
|
||||||
path: { $ref: "#/$defs/base/properties/path" }
|
path: { $ref: "#/$defs/base/properties/path" }
|
||||||
narHash: { $ref: "#/$defs/base/properties/narHash" }
|
narHash: { $ref: "#/$defs/base/properties/narHash" }
|
||||||
narSize: { $ref: "#/$defs/base/properties/narSize" }
|
narSize: { $ref: "#/$defs/base/properties/narSize" }
|
||||||
|
|
@ -164,6 +185,7 @@ $defs:
|
||||||
This download information, being specific to how the store object happens to be stored and transferred, is also considered to be non-intrinsic / impure.
|
This download information, being specific to how the store object happens to be stored and transferred, is also considered to be non-intrinsic / impure.
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
|
- version
|
||||||
- narHash
|
- narHash
|
||||||
- narSize
|
- narSize
|
||||||
- references
|
- references
|
||||||
|
|
@ -179,6 +201,7 @@ $defs:
|
||||||
- downloadHash
|
- downloadHash
|
||||||
- downloadSize
|
- downloadSize
|
||||||
properties:
|
properties:
|
||||||
|
version: { $ref: "#/$defs/base/properties/version" }
|
||||||
path: { $ref: "#/$defs/base/properties/path" }
|
path: { $ref: "#/$defs/base/properties/path" }
|
||||||
narHash: { $ref: "#/$defs/base/properties/narHash" }
|
narHash: { $ref: "#/$defs/base/properties/narHash" }
|
||||||
narSize: { $ref: "#/$defs/base/properties/narSize" }
|
narSize: { $ref: "#/$defs/base/properties/narSize" }
|
||||||
|
|
@ -1,29 +1,29 @@
|
||||||
{{#include store-object-info-v1-fixed.md}}
|
{{#include store-object-info-v2-fixed.md}}
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
### Minimal store object (content-addressed)
|
### Minimal store object (content-addressed)
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{{#include schema/store-object-info-v1/pure.json}}
|
{{#include schema/store-object-info-v2/pure.json}}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Store object with impure fields
|
### Store object with impure fields
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{{#include schema/store-object-info-v1/impure.json}}
|
{{#include schema/store-object-info-v2/impure.json}}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Minimal store object (empty)
|
### Minimal store object (empty)
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{{#include schema/store-object-info-v1/empty_pure.json}}
|
{{#include schema/store-object-info-v2/empty_pure.json}}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Store object with all impure fields
|
### Store object with all impure fields
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{{#include schema/store-object-info-v1/empty_impure.json}}
|
{{#include schema/store-object-info-v2/empty_impure.json}}
|
||||||
```
|
```
|
||||||
|
|
||||||
### NAR info (minimal)
|
### NAR info (minimal)
|
||||||
|
|
@ -41,5 +41,5 @@
|
||||||
<!-- need to convert YAML to JSON first
|
<!-- need to convert YAML to JSON first
|
||||||
## Raw Schema
|
## Raw Schema
|
||||||
|
|
||||||
[JSON Schema for Store Object Info v1](schema/store-object-info-v1.json)
|
[JSON Schema for Store Object Info v1](schema/store-object-info-v2.json)
|
||||||
-->
|
-->
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ This is the complete specification of the [Nix Archive] format.
|
||||||
The Nix Archive format closely follows the abstract specification of a [file system object] tree,
|
The Nix Archive format closely follows the abstract specification of a [file system object] tree,
|
||||||
because it is designed to serialize exactly that data structure.
|
because it is designed to serialize exactly that data structure.
|
||||||
|
|
||||||
[Nix Archive]: @docroot@/store/file-system-object/content-address.md#nix-archive
|
[Nix Archive]: @docroot@/store/file-system-object/content-address.md#serial-nix-archive
|
||||||
[file system object]: @docroot@/store/file-system-object.md
|
[file system object]: @docroot@/store/file-system-object.md
|
||||||
|
|
||||||
The format of this specification is close to [Extended Backus–Naur form](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form), with the exception of the `str(..)` function / parameterized rule, which length-prefixes and pads strings.
|
The format of this specification is close to [Extended Backus–Naur form](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form), with the exception of the `str(..)` function / parameterized rule, which length-prefixes and pads strings.
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
- The `discard-references` feature has been stabilized.
|
- The `discard-references` feature has been stabilized.
|
||||||
This means that the
|
This means that the
|
||||||
[unsafeDiscardReferences](@docroot@/development/experimental-features.md#xp-feature-discard-references)
|
[unsafeDiscardReferences](@docroot@/language/advanced-attributes.md#adv-attr-unsafeDiscardReferences)
|
||||||
attribute is no longer guarded by an experimental flag and can be used
|
attribute is no longer guarded by an experimental flag and can be used
|
||||||
freely.
|
freely.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@
|
||||||
|
|
||||||
- `nix-shell` shebang lines now support single-quoted arguments.
|
- `nix-shell` shebang lines now support single-quoted arguments.
|
||||||
|
|
||||||
- `builtins.fetchTree` is now its own experimental feature, [`fetch-tree`](@docroot@/development/experimental-features.md#xp-fetch-tree).
|
- `builtins.fetchTree` is now its own experimental feature, [`fetch-tree`](@docroot@/development/experimental-features.md#xp-feature-fetch-tree).
|
||||||
This allows stabilising it independently of the rest of what is encompassed by [`flakes`](@docroot@/development/experimental-features.md#xp-fetch-tree).
|
This allows stabilising it independently of the rest of what is encompassed by [`flakes`](@docroot@/development/experimental-features.md#xp-feature-flakes).
|
||||||
|
|
||||||
- The interface for creating and updating lock files has been overhauled:
|
- The interface for creating and updating lock files has been overhauled:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
- Modify `nix derivation {add,show}` JSON format [#9866](https://github.com/NixOS/nix/issues/9866) [#10722](https://github.com/NixOS/nix/pull/10722)
|
- 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).
|
The JSON format for derivations has been slightly revised to better conform to our [JSON guidelines](@docroot@/development/json-guideline.md).
|
||||||
In particular, the hash algorithm and content addressing method of content-addressed 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.
|
rather than one field with an arcane `:`-separated format.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@
|
||||||
|
|
||||||
- Support unit prefixes in configuration settings [#10668](https://github.com/NixOS/nix/pull/10668)
|
- Support unit prefixes in configuration settings [#10668](https://github.com/NixOS/nix/pull/10668)
|
||||||
|
|
||||||
Configuration settings in Nix now support unit prefixes, allowing for more intuitive and readable configurations. For example, you can now specify [`--min-free 1G`](@docroot@/command-ref/opt-common.md#opt-min-free) to set the minimum free space to 1 gigabyte.
|
Configuration settings in Nix now support unit prefixes, allowing for more intuitive and readable configurations. For example, you can now specify [`--min-free 1G`](@docroot@/command-ref/conf-file.md#conf-min-free) to set the minimum free space to 1 gigabyte.
|
||||||
|
|
||||||
This enhancement was extracted from [#7851](https://github.com/NixOS/nix/pull/7851) and is also useful for PR [#10661](https://github.com/NixOS/nix/pull/10661).
|
This enhancement was extracted from [#7851](https://github.com/NixOS/nix/pull/7851) and is also useful for PR [#10661](https://github.com/NixOS/nix/pull/10661).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ And even in that case, a different result doesn't mean the original entry was a
|
||||||
As such, the decision of whether to trust a counterparty's build trace is a fundamentally subject policy choice.
|
As such, the decision of whether to trust a counterparty's build trace is a fundamentally subject policy choice.
|
||||||
Build trace entries are typically *signed* in order to enable arbitrary public-key-based trust polices.
|
Build trace entries are typically *signed* in order to enable arbitrary public-key-based trust polices.
|
||||||
|
|
||||||
## Derived build traces
|
## Derived build traces {#derived}
|
||||||
|
|
||||||
Implementations that wish to memoize the above may also keep additional *derived* build trace entries that do map unresolved derivations.
|
Implementations that wish to memoize the above may also keep additional *derived* build trace entries that do map unresolved derivations.
|
||||||
But if they do so, they *must* also keep the underlying base entries with resolved derivation keys around.
|
But if they do so, they *must* also keep the underlying base entries with resolved derivation keys around.
|
||||||
|
|
@ -40,13 +40,13 @@ Unlike with base build traces, incoherence with derived build traces is possible
|
||||||
The key ingredient is that derivation resolution is only deterministic with respect to a fixed base build trace.
|
The key ingredient is that derivation resolution is only deterministic with respect to a fixed base build trace.
|
||||||
Without fixing the base build trace, it inherits the subjectivity of base build traces themselves.
|
Without fixing the base build trace, it inherits the subjectivity of base build traces themselves.
|
||||||
|
|
||||||
Concretely, suppose there are three derivations \\(a\\), \\(b\\), and \((c\\).
|
Concretely, suppose there are three derivations \\(a\\), \\(b\\), and \\(c\\).
|
||||||
Let \\(a\\) be a resolved derivation, but let \\(b\\) and \((c\\) be unresolved and both take as an input an output of \\(a\\).
|
Let \\(a\\) be a resolved derivation, but let \\(b\\) and \\(c\\) be unresolved and both take as an input an output of \\(a\\).
|
||||||
Now suppose that derived entries are made for \\(b\\) and \((c\\) based on two different entries of \\(a\\).
|
Now suppose that derived entries are made for \\(b\\) and \\(c\\) based on two different entries of \\(a\\).
|
||||||
(This could happen if \\(a\\) is non-deterministic, \\(a\\) and \\(b\\) are built in one store, \\(a\\) and \\(c\\) are built in another store, and then a third store substitutes from both of the first two stores.)
|
(This could happen if \\(a\\) is non-deterministic, \\(a\\) and \\(b\\) are built in one store, \\(a\\) and \\(c\\) are built in another store, and then a third store substitutes from both of the first two stores.)
|
||||||
|
|
||||||
If trusting the derived build trace entries for \\(b\\) and \((c\\) requires that each's underlying entry for \\(a\\) be also trusted, the two different mappings for \\(a\\) will be caught.
|
If trusting the derived build trace entries for \\(b\\) and \\(c\\) requires that each's underlying entry for \\(a\\) be also trusted, the two different mappings for \\(a\\) will be caught.
|
||||||
However, if \\(b\\) and \((c\\)'s entries can be combined in isolation, there will be nothing to catch the contradiction in their hidden assumptions about \\(a\\)'s output.
|
However, if \\(b\\) and \\(c\\)'s entries can be combined in isolation, there will be nothing to catch the contradiction in their hidden assumptions about \\(a\\)'s output.
|
||||||
|
|
||||||
[derivation]: ./derivation/index.md
|
[derivation]: ./derivation/index.md
|
||||||
[output]: ./derivation/outputs/index.md
|
[output]: ./derivation/outputs/index.md
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
- Once this is done, the derivation is *normalized*, replacing each input deriving path with its store path, which we now know from realising the input.
|
- Once this is done, the derivation is *normalized*, replacing each input deriving path with its store path, which we now know from realising the input.
|
||||||
|
|
||||||
## Builder Execution
|
## Builder Execution {#builder-execution}
|
||||||
|
|
||||||
The [`builder`](./derivation/index.md#builder) is executed as follows:
|
The [`builder`](./derivation/index.md#builder) is executed as follows:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ But rather than somehow scanning all the other fields for inputs, Nix requires t
|
||||||
|
|
||||||
### System {#system}
|
### System {#system}
|
||||||
|
|
||||||
The system type on which the [`builder`](#attr-builder) executable is meant to be run.
|
The system type on which the [`builder`](#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] or [`extra-platforms` 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].
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ In particular, the specification decides:
|
||||||
|
|
||||||
- if the content is content-addressed, how is it content addressed
|
- 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])
|
- if the content is content-addressed, [what is its content address](./content-address.md#fixed) (and thus what is its [store path])
|
||||||
|
|
||||||
## Types of derivations
|
## Types of derivations
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# Content-Addressing Store Objects
|
# Content-Addressing Store Objects
|
||||||
|
|
||||||
Just [like][fso-ca] [File System Objects][File System Object],
|
Just [like][fso-ca] [File System Objects][File System Object],
|
||||||
[Store Objects][Store Object] can also be [content-addressed](@docroot@/glossary.md#gloss-content-addressed),
|
[Store Objects][Store Object] can also be [content-addressed](@docroot@/glossary.md#gloss-content-address),
|
||||||
unless they are [input-addressed](@docroot@/glossary.md#gloss-input-addressed-store-object).
|
unless they are [input-addressed](@docroot@/glossary.md#gloss-input-addressed-store-object).
|
||||||
|
|
||||||
For store objects, the content address we produce will take the form of a [Store Path] rather than regular hash.
|
For store objects, the content address we produce will take the form of a [Store Path] rather than regular hash.
|
||||||
|
|
@ -107,7 +107,7 @@ References (to other store objects and self-references alike) are supported so l
|
||||||
>
|
>
|
||||||
> This method is part of the [`git-hashing`][xp-feature-git-hashing] experimental feature.
|
> This method is part of the [`git-hashing`][xp-feature-git-hashing] experimental feature.
|
||||||
|
|
||||||
This uses the corresponding [Git](../file-system-object/content-address.md#serial-git) method of file system object content addressing.
|
This uses the corresponding [Git](../file-system-object/content-address.md#git) method of file system object content addressing.
|
||||||
|
|
||||||
References are not supported.
|
References are not supported.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
>
|
>
|
||||||
> A rendered store path
|
> A rendered store path
|
||||||
|
|
||||||
Nix implements references to [store objects](./index.md#store-object) as *store paths*.
|
Nix implements references to [store objects](./store-object.md) as *store paths*.
|
||||||
|
|
||||||
Think of a store path as an [opaque], [unique identifier]:
|
Think of a store path as an [opaque], [unique identifier]:
|
||||||
The only way to obtain store path is by adding or building store objects.
|
The only way to obtain store path is by adding or building store objects.
|
||||||
|
|
|
||||||
|
|
@ -485,10 +485,10 @@
|
||||||
open-manual = {
|
open-manual = {
|
||||||
type = "app";
|
type = "app";
|
||||||
program = "${pkgs.writeShellScript "open-nix-manual" ''
|
program = "${pkgs.writeShellScript "open-nix-manual" ''
|
||||||
manual_path="${self.packages.${system}.nix-manual}/share/doc/nix/manual/index.html"
|
path="${self.packages.${system}.nix-manual.site}/index.html"
|
||||||
if ! ${opener} "$manual_path"; then
|
if ! ${opener} "$path"; then
|
||||||
echo "Failed to open manual with ${opener}. Manual is located at:"
|
echo "Failed to open manual with ${opener}. Manual is located at:"
|
||||||
echo "$manual_path"
|
echo "$path"
|
||||||
fi
|
fi
|
||||||
''}";
|
''}";
|
||||||
meta.description = "Open the Nix manual in your browser";
|
meta.description = "Open the Nix manual in your browser";
|
||||||
|
|
|
||||||
|
|
@ -61,4 +61,3 @@ if get_option('unit-tests')
|
||||||
endif
|
endif
|
||||||
subproject('nix-functional-tests')
|
subproject('nix-functional-tests')
|
||||||
subproject('json-schema-checks')
|
subproject('json-schema-checks')
|
||||||
subproject('kaitai-struct-checks')
|
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,6 @@ pkgs.nixComponents2.nix-util.overrideAttrs (
|
||||||
++ pkgs.nixComponents2.nix-external-api-docs.nativeBuildInputs
|
++ pkgs.nixComponents2.nix-external-api-docs.nativeBuildInputs
|
||||||
++ pkgs.nixComponents2.nix-functional-tests.externalNativeBuildInputs
|
++ pkgs.nixComponents2.nix-functional-tests.externalNativeBuildInputs
|
||||||
++ pkgs.nixComponents2.nix-json-schema-checks.externalNativeBuildInputs
|
++ pkgs.nixComponents2.nix-json-schema-checks.externalNativeBuildInputs
|
||||||
++ pkgs.nixComponents2.nix-kaitai-struct-checks.externalNativeBuildInputs
|
|
||||||
++ lib.optional (
|
++ lib.optional (
|
||||||
!buildCanExecuteHost
|
!buildCanExecuteHost
|
||||||
# Hack around https://github.com/nixos/nixpkgs/commit/bf7ad8cfbfa102a90463433e2c5027573b462479
|
# Hack around https://github.com/nixos/nixpkgs/commit/bf7ad8cfbfa102a90463433e2c5027573b462479
|
||||||
|
|
@ -149,7 +148,6 @@ pkgs.nixComponents2.nix-util.overrideAttrs (
|
||||||
++ pkgs.nixComponents2.nix-expr.externalPropagatedBuildInputs
|
++ pkgs.nixComponents2.nix-expr.externalPropagatedBuildInputs
|
||||||
++ pkgs.nixComponents2.nix-cmd.buildInputs
|
++ pkgs.nixComponents2.nix-cmd.buildInputs
|
||||||
++ lib.optionals havePerl pkgs.nixComponents2.nix-perl-bindings.externalBuildInputs
|
++ lib.optionals havePerl pkgs.nixComponents2.nix-perl-bindings.externalBuildInputs
|
||||||
++ lib.optional havePerl pkgs.perl
|
++ lib.optional havePerl pkgs.perl;
|
||||||
++ pkgs.nixComponents2.nix-kaitai-struct-checks.externalBuildInputs;
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
1
src/json-schema-checks/build-result
Symbolic link
1
src/json-schema-checks/build-result
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../src/libstore-tests/data/build-result
|
||||||
1
src/json-schema-checks/build-trace-entry
Symbolic link
1
src/json-schema-checks/build-trace-entry
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../src/libstore-tests/data/realisation
|
||||||
|
|
@ -54,6 +54,15 @@ schemas = [
|
||||||
'single_built_built.json',
|
'single_built_built.json',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'stem' : 'build-trace-entry',
|
||||||
|
'schema' : schema_dir / 'build-trace-entry-v1.yaml',
|
||||||
|
'files' : [
|
||||||
|
'simple.json',
|
||||||
|
'with-dependent-realisations.json',
|
||||||
|
'with-signature.json',
|
||||||
|
],
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
# Derivation and Derivation output
|
# Derivation and Derivation output
|
||||||
|
|
@ -61,7 +70,7 @@ schemas += [
|
||||||
# Match overall
|
# Match overall
|
||||||
{
|
{
|
||||||
'stem' : 'derivation',
|
'stem' : 'derivation',
|
||||||
'schema' : schema_dir / 'derivation-v3.yaml',
|
'schema' : schema_dir / 'derivation-v4.yaml',
|
||||||
'files' : [
|
'files' : [
|
||||||
'dyn-dep-derivation.json',
|
'dyn-dep-derivation.json',
|
||||||
'simple-derivation.json',
|
'simple-derivation.json',
|
||||||
|
|
@ -69,7 +78,7 @@ schemas += [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'stem' : 'derivation',
|
'stem' : 'derivation',
|
||||||
'schema' : schema_dir / 'derivation-v3.yaml#/$defs/output/overall',
|
'schema' : schema_dir / 'derivation-v4.yaml#/$defs/output/overall',
|
||||||
'files' : [
|
'files' : [
|
||||||
'output-caFixedFlat.json',
|
'output-caFixedFlat.json',
|
||||||
'output-caFixedNAR.json',
|
'output-caFixedNAR.json',
|
||||||
|
|
@ -83,14 +92,14 @@ schemas += [
|
||||||
# Match exact variant
|
# Match exact variant
|
||||||
{
|
{
|
||||||
'stem' : 'derivation',
|
'stem' : 'derivation',
|
||||||
'schema' : schema_dir / 'derivation-v3.yaml#/$defs/output/inputAddressed',
|
'schema' : schema_dir / 'derivation-v4.yaml#/$defs/output/inputAddressed',
|
||||||
'files' : [
|
'files' : [
|
||||||
'output-inputAddressed.json',
|
'output-inputAddressed.json',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'stem' : 'derivation',
|
'stem' : 'derivation',
|
||||||
'schema' : schema_dir / 'derivation-v3.yaml#/$defs/output/caFixed',
|
'schema' : schema_dir / 'derivation-v4.yaml#/$defs/output/caFixed',
|
||||||
'files' : [
|
'files' : [
|
||||||
'output-caFixedFlat.json',
|
'output-caFixedFlat.json',
|
||||||
'output-caFixedNAR.json',
|
'output-caFixedNAR.json',
|
||||||
|
|
@ -99,21 +108,21 @@ schemas += [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'stem' : 'derivation',
|
'stem' : 'derivation',
|
||||||
'schema' : schema_dir / 'derivation-v3.yaml#/$defs/output/caFloating',
|
'schema' : schema_dir / 'derivation-v4.yaml#/$defs/output/caFloating',
|
||||||
'files' : [
|
'files' : [
|
||||||
'output-caFloating.json',
|
'output-caFloating.json',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'stem' : 'derivation',
|
'stem' : 'derivation',
|
||||||
'schema' : schema_dir / 'derivation-v3.yaml#/$defs/output/deferred',
|
'schema' : schema_dir / 'derivation-v4.yaml#/$defs/output/deferred',
|
||||||
'files' : [
|
'files' : [
|
||||||
'output-deferred.json',
|
'output-deferred.json',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'stem' : 'derivation',
|
'stem' : 'derivation',
|
||||||
'schema' : schema_dir / 'derivation-v3.yaml#/$defs/output/impure',
|
'schema' : schema_dir / 'derivation-v4.yaml#/$defs/output/impure',
|
||||||
'files' : [
|
'files' : [
|
||||||
'output-impure.json',
|
'output-impure.json',
|
||||||
],
|
],
|
||||||
|
|
@ -125,7 +134,7 @@ schemas += [
|
||||||
# Match overall
|
# Match overall
|
||||||
{
|
{
|
||||||
'stem' : 'store-object-info',
|
'stem' : 'store-object-info',
|
||||||
'schema' : schema_dir / 'store-object-info-v1.yaml',
|
'schema' : schema_dir / 'store-object-info-v2.yaml',
|
||||||
'files' : [
|
'files' : [
|
||||||
'pure.json',
|
'pure.json',
|
||||||
'impure.json',
|
'impure.json',
|
||||||
|
|
@ -135,16 +144,25 @@ schemas += [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'stem' : 'nar-info',
|
'stem' : 'nar-info',
|
||||||
'schema' : schema_dir / 'store-object-info-v1.yaml',
|
'schema' : schema_dir / 'store-object-info-v2.yaml',
|
||||||
'files' : [
|
'files' : [
|
||||||
'pure.json',
|
'pure.json',
|
||||||
'impure.json',
|
'impure.json',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'stem' : 'build-result',
|
||||||
|
'schema' : schema_dir / 'build-result-v1.yaml',
|
||||||
|
'files' : [
|
||||||
|
'success.json',
|
||||||
|
'output-rejected.json',
|
||||||
|
'not-deterministic.json',
|
||||||
|
],
|
||||||
|
},
|
||||||
# Match exact variant
|
# Match exact variant
|
||||||
{
|
{
|
||||||
'stem' : 'store-object-info',
|
'stem' : 'store-object-info',
|
||||||
'schema' : schema_dir / 'store-object-info-v1.yaml#/$defs/base',
|
'schema' : schema_dir / 'store-object-info-v2.yaml#/$defs/base',
|
||||||
'files' : [
|
'files' : [
|
||||||
'pure.json',
|
'pure.json',
|
||||||
'empty_pure.json',
|
'empty_pure.json',
|
||||||
|
|
@ -152,7 +170,7 @@ schemas += [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'stem' : 'store-object-info',
|
'stem' : 'store-object-info',
|
||||||
'schema' : schema_dir / 'store-object-info-v1.yaml#/$defs/impure',
|
'schema' : schema_dir / 'store-object-info-v2.yaml#/$defs/impure',
|
||||||
'files' : [
|
'files' : [
|
||||||
'impure.json',
|
'impure.json',
|
||||||
'empty_impure.json',
|
'empty_impure.json',
|
||||||
|
|
@ -160,14 +178,14 @@ schemas += [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'stem' : 'nar-info',
|
'stem' : 'nar-info',
|
||||||
'schema' : schema_dir / 'store-object-info-v1.yaml#/$defs/base',
|
'schema' : schema_dir / 'store-object-info-v2.yaml#/$defs/base',
|
||||||
'files' : [
|
'files' : [
|
||||||
'pure.json',
|
'pure.json',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'stem' : 'nar-info',
|
'stem' : 'nar-info',
|
||||||
'schema' : schema_dir / 'store-object-info-v1.yaml#/$defs/narInfo',
|
'schema' : schema_dir / 'store-object-info-v2.yaml#/$defs/narInfo',
|
||||||
'files' : [
|
'files' : [
|
||||||
'impure.json',
|
'impure.json',
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,12 @@ mkMesonDerivation (finalAttrs: {
|
||||||
../../src/libutil-tests/data/hash
|
../../src/libutil-tests/data/hash
|
||||||
../../src/libstore-tests/data/content-address
|
../../src/libstore-tests/data/content-address
|
||||||
../../src/libstore-tests/data/store-path
|
../../src/libstore-tests/data/store-path
|
||||||
|
../../src/libstore-tests/data/realisation
|
||||||
../../src/libstore-tests/data/derivation
|
../../src/libstore-tests/data/derivation
|
||||||
../../src/libstore-tests/data/derived-path
|
../../src/libstore-tests/data/derived-path
|
||||||
../../src/libstore-tests/data/path-info
|
../../src/libstore-tests/data/path-info
|
||||||
../../src/libstore-tests/data/nar-info
|
../../src/libstore-tests/data/nar-info
|
||||||
|
../../src/libstore-tests/data/build-result
|
||||||
./.
|
./.
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
# Run with: nix build .#nix-kaitai-struct-checks
|
# Run with: nix build .#nix-kaitai-struct-checks
|
||||||
|
# or: `nix develop .#nix-kaitai-struct-checks` to enter a dev shell
|
||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
mkMesonDerivation,
|
mkMesonDerivation,
|
||||||
|
|
|
||||||
|
|
@ -136,17 +136,19 @@ struct AttrDb
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
AttrId setString(AttrKey key, std::string_view s, const char ** context = nullptr)
|
AttrId setString(AttrKey key, std::string_view s, const Value::StringWithContext::Context * context = nullptr)
|
||||||
{
|
{
|
||||||
return doSQLite([&]() {
|
return doSQLite([&]() {
|
||||||
auto state(_state->lock());
|
auto state(_state->lock());
|
||||||
|
|
||||||
if (context) {
|
if (context) {
|
||||||
std::string ctx;
|
std::string ctx;
|
||||||
for (const char ** p = context; *p; ++p) {
|
bool first = true;
|
||||||
if (p != context)
|
for (auto * elem : *context) {
|
||||||
|
if (!first)
|
||||||
ctx.push_back(' ');
|
ctx.push_back(' ');
|
||||||
ctx.append(*p);
|
ctx.append(elem);
|
||||||
|
first = false;
|
||||||
}
|
}
|
||||||
state->insertAttributeWithContext.use()(key.first)(symbols[key.second])(AttrType::String) (s) (ctx)
|
state->insertAttributeWithContext.use()(key.first)(symbols[key.second])(AttrType::String) (s) (ctx)
|
||||||
.exec();
|
.exec();
|
||||||
|
|
|
||||||
|
|
@ -821,15 +821,18 @@ void Value::mkString(std::string_view s)
|
||||||
mkStringNoCopy(makeImmutableString(s));
|
mkStringNoCopy(makeImmutableString(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char ** encodeContext(const NixStringContext & context)
|
Value::StringWithContext::Context * Value::StringWithContext::Context::fromBuilder(const NixStringContext & context)
|
||||||
{
|
{
|
||||||
if (!context.empty()) {
|
if (!context.empty()) {
|
||||||
size_t n = 0;
|
auto ctx = (Value::StringWithContext::Context *) allocBytes(sizeof(size_t) + context.size() * sizeof(char *));
|
||||||
auto ctx = (const char **) allocBytes((context.size() + 1) * sizeof(char *));
|
ctx->size = context.size();
|
||||||
for (auto & i : context) {
|
/* Mapping the original iterator to turn references into
|
||||||
ctx[n++] = makeImmutableString({i.to_string()});
|
pointers is necessary to make sure that enumerate doesn't
|
||||||
|
accidently copy the elements when it returns tuples by value.
|
||||||
|
*/
|
||||||
|
for (auto [n, i] : enumerate(context | std::views::transform([](const auto & r) { return &r; }))) {
|
||||||
|
ctx->elems[n] = makeImmutableString({i->to_string()});
|
||||||
}
|
}
|
||||||
ctx[n] = nullptr;
|
|
||||||
return ctx;
|
return ctx;
|
||||||
} else
|
} else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
@ -837,12 +840,12 @@ static const char ** encodeContext(const NixStringContext & context)
|
||||||
|
|
||||||
void Value::mkString(std::string_view s, const NixStringContext & context)
|
void Value::mkString(std::string_view s, const NixStringContext & context)
|
||||||
{
|
{
|
||||||
mkStringNoCopy(makeImmutableString(s), encodeContext(context));
|
mkStringNoCopy(makeImmutableString(s), Value::StringWithContext::Context::fromBuilder(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Value::mkStringMove(const char * s, const NixStringContext & context)
|
void Value::mkStringMove(const char * s, const NixStringContext & context)
|
||||||
{
|
{
|
||||||
mkStringNoCopy(s, encodeContext(context));
|
mkStringNoCopy(s, Value::StringWithContext::Context::fromBuilder(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Value::mkPath(const SourcePath & path)
|
void Value::mkPath(const SourcePath & path)
|
||||||
|
|
@ -2287,9 +2290,9 @@ std::string_view EvalState::forceString(Value & v, const PosIdx pos, std::string
|
||||||
|
|
||||||
void copyContext(const Value & v, NixStringContext & context, const ExperimentalFeatureSettings & xpSettings)
|
void copyContext(const Value & v, NixStringContext & context, const ExperimentalFeatureSettings & xpSettings)
|
||||||
{
|
{
|
||||||
if (v.context())
|
if (auto * ctx = v.context())
|
||||||
for (const char ** p = v.context(); *p; ++p)
|
for (auto * elem : *ctx)
|
||||||
context.insert(NixStringContextElem::parse(*p, xpSettings));
|
context.insert(NixStringContextElem::parse(elem, xpSettings));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view EvalState::forceString(
|
std::string_view EvalState::forceString(
|
||||||
|
|
@ -2309,7 +2312,9 @@ std::string_view EvalState::forceStringNoCtx(Value & v, const PosIdx pos, std::s
|
||||||
auto s = forceString(v, pos, errorCtx);
|
auto s = forceString(v, pos, errorCtx);
|
||||||
if (v.context()) {
|
if (v.context()) {
|
||||||
error<EvalError>(
|
error<EvalError>(
|
||||||
"the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string_view(), v.context()[0])
|
"the string '%1%' is not allowed to refer to a store path (such as '%2%')",
|
||||||
|
v.string_view(),
|
||||||
|
*v.context()->begin())
|
||||||
.withTrace(pos, errorCtx)
|
.withTrace(pos, errorCtx)
|
||||||
.debugThrow();
|
.debugThrow();
|
||||||
}
|
}
|
||||||
|
|
@ -3216,8 +3221,8 @@ Expr * EvalState::parse(
|
||||||
docComments = &it->second;
|
docComments = &it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = parseExprFromBuf(
|
auto result =
|
||||||
text, length, origin, basePath, mem.exprs.alloc, symbols, settings, positions, *docComments, rootFS);
|
parseExprFromBuf(text, length, origin, basePath, mem.exprs, symbols, settings, positions, *docComments, rootFS);
|
||||||
|
|
||||||
result->bindVars(*this, staticEnv);
|
result->bindVars(*this, staticEnv);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,13 +91,6 @@ std::string showAttrPath(const SymbolTable & symbols, std::span<const AttrName>
|
||||||
|
|
||||||
using UpdateQueue = SmallTemporaryValueVector<conservativeStackReservation>;
|
using UpdateQueue = SmallTemporaryValueVector<conservativeStackReservation>;
|
||||||
|
|
||||||
class Exprs
|
|
||||||
{
|
|
||||||
std::pmr::monotonic_buffer_resource buffer;
|
|
||||||
public:
|
|
||||||
std::pmr::polymorphic_allocator<char> alloc{&buffer};
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Abstract syntax of Nix expressions. */
|
/* Abstract syntax of Nix expressions. */
|
||||||
|
|
||||||
struct Expr
|
struct Expr
|
||||||
|
|
@ -637,8 +630,8 @@ struct ExprLet : Expr
|
||||||
struct ExprWith : Expr
|
struct ExprWith : Expr
|
||||||
{
|
{
|
||||||
PosIdx pos;
|
PosIdx pos;
|
||||||
|
uint32_t prevWith;
|
||||||
Expr *attrs, *body;
|
Expr *attrs, *body;
|
||||||
size_t prevWith;
|
|
||||||
ExprWith * parentWith;
|
ExprWith * parentWith;
|
||||||
ExprWith(const PosIdx & pos, Expr * attrs, Expr * body)
|
ExprWith(const PosIdx & pos, Expr * attrs, Expr * body)
|
||||||
: pos(pos)
|
: pos(pos)
|
||||||
|
|
@ -760,11 +753,19 @@ struct ExprConcatStrings : Expr
|
||||||
{
|
{
|
||||||
PosIdx pos;
|
PosIdx pos;
|
||||||
bool forceString;
|
bool forceString;
|
||||||
std::vector<std::pair<PosIdx, Expr *>> es;
|
std::span<std::pair<PosIdx, Expr *>> es;
|
||||||
ExprConcatStrings(const PosIdx & pos, bool forceString, std::vector<std::pair<PosIdx, Expr *>> && es)
|
|
||||||
|
ExprConcatStrings(
|
||||||
|
std::pmr::polymorphic_allocator<char> & alloc,
|
||||||
|
const PosIdx & pos,
|
||||||
|
bool forceString,
|
||||||
|
const std::vector<std::pair<PosIdx, Expr *>> & es)
|
||||||
: pos(pos)
|
: pos(pos)
|
||||||
, forceString(forceString)
|
, forceString(forceString)
|
||||||
, es(std::move(es)) {};
|
, es({alloc.allocate_object<std::pair<PosIdx, Expr *>>(es.size()), es.size()})
|
||||||
|
{
|
||||||
|
std::ranges::copy(es, this->es.begin());
|
||||||
|
};
|
||||||
|
|
||||||
PosIdx getPos() const override
|
PosIdx getPos() const override
|
||||||
{
|
{
|
||||||
|
|
@ -802,6 +803,49 @@ struct ExprBlackHole : Expr
|
||||||
|
|
||||||
extern ExprBlackHole eBlackHole;
|
extern ExprBlackHole eBlackHole;
|
||||||
|
|
||||||
|
class Exprs
|
||||||
|
{
|
||||||
|
std::pmr::monotonic_buffer_resource buffer;
|
||||||
|
public:
|
||||||
|
std::pmr::polymorphic_allocator<char> alloc{&buffer};
|
||||||
|
|
||||||
|
template<class C>
|
||||||
|
[[gnu::always_inline]]
|
||||||
|
C * add(auto &&... args)
|
||||||
|
{
|
||||||
|
return alloc.new_object<C>(std::forward<decltype(args)>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
// we define some calls to add explicitly so that the argument can be passed in as initializer lists
|
||||||
|
template<class C>
|
||||||
|
[[gnu::always_inline]]
|
||||||
|
C * add(const PosIdx & pos, Expr * fun, std::vector<Expr *> && args)
|
||||||
|
requires(std::same_as<C, ExprCall>)
|
||||||
|
{
|
||||||
|
return alloc.new_object<C>(pos, fun, std::move(args));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class C>
|
||||||
|
[[gnu::always_inline]]
|
||||||
|
C * add(const PosIdx & pos, Expr * fun, std::vector<Expr *> && args, PosIdx && cursedOrEndPos)
|
||||||
|
requires(std::same_as<C, ExprCall>)
|
||||||
|
{
|
||||||
|
return alloc.new_object<C>(pos, fun, std::move(args), std::move(cursedOrEndPos));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class C>
|
||||||
|
[[gnu::always_inline]]
|
||||||
|
C *
|
||||||
|
add(std::pmr::polymorphic_allocator<char> & alloc,
|
||||||
|
const PosIdx & pos,
|
||||||
|
bool forceString,
|
||||||
|
const std::vector<std::pair<PosIdx, Expr *>> & es)
|
||||||
|
requires(std::same_as<C, ExprConcatStrings>)
|
||||||
|
{
|
||||||
|
return alloc.new_object<C>(alloc, pos, forceString, es);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/* Static environments are used to map variable names onto (level,
|
/* Static environments are used to map variable names onto (level,
|
||||||
displacement) pairs used to obtain the value of the variable at
|
displacement) pairs used to obtain the value of the variable at
|
||||||
runtime. */
|
runtime. */
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ struct LexerState
|
||||||
struct ParserState
|
struct ParserState
|
||||||
{
|
{
|
||||||
const LexerState & lexerState;
|
const LexerState & lexerState;
|
||||||
std::pmr::polymorphic_allocator<char> & alloc;
|
Exprs & exprs;
|
||||||
SymbolTable & symbols;
|
SymbolTable & symbols;
|
||||||
PosTable & positions;
|
PosTable & positions;
|
||||||
Expr * result;
|
Expr * result;
|
||||||
|
|
@ -132,11 +132,11 @@ inline void ParserState::addAttr(
|
||||||
dupAttr(attrPath, pos, j->second.pos);
|
dupAttr(attrPath, pos, j->second.pos);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nested = new ExprAttrs;
|
nested = exprs.add<ExprAttrs>();
|
||||||
attrs->attrs[i->symbol] = ExprAttrs::AttrDef(nested, pos);
|
attrs->attrs[i->symbol] = ExprAttrs::AttrDef(nested, pos);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nested = new ExprAttrs;
|
nested = exprs.add<ExprAttrs>();
|
||||||
attrs->dynamicAttrs.push_back(ExprAttrs::DynamicAttrDef(i->expr, nested, pos));
|
attrs->dynamicAttrs.push_back(ExprAttrs::DynamicAttrDef(i->expr, nested, pos));
|
||||||
}
|
}
|
||||||
attrs = nested;
|
attrs = nested;
|
||||||
|
|
@ -240,7 +240,7 @@ inline Expr *
|
||||||
ParserState::stripIndentation(const PosIdx pos, std::vector<std::pair<PosIdx, std::variant<Expr *, StringToken>>> && es)
|
ParserState::stripIndentation(const PosIdx pos, std::vector<std::pair<PosIdx, std::variant<Expr *, StringToken>>> && es)
|
||||||
{
|
{
|
||||||
if (es.empty())
|
if (es.empty())
|
||||||
return new ExprString("");
|
return exprs.add<ExprString>("");
|
||||||
|
|
||||||
/* Figure out the minimum indentation. Note that by design
|
/* Figure out the minimum indentation. Note that by design
|
||||||
whitespace-only final lines are not taken into account. (So
|
whitespace-only final lines are not taken into account. (So
|
||||||
|
|
@ -322,7 +322,7 @@ ParserState::stripIndentation(const PosIdx pos, std::vector<std::pair<PosIdx, st
|
||||||
|
|
||||||
// Ignore empty strings for a minor optimisation and AST simplification
|
// Ignore empty strings for a minor optimisation and AST simplification
|
||||||
if (s2 != "") {
|
if (s2 != "") {
|
||||||
es2.emplace_back(i->first, new ExprString(alloc, s2));
|
es2.emplace_back(i->first, exprs.add<ExprString>(exprs.alloc, s2));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
for (; i != es.end(); ++i, --n) {
|
for (; i != es.end(); ++i, --n) {
|
||||||
|
|
@ -332,7 +332,7 @@ ParserState::stripIndentation(const PosIdx pos, std::vector<std::pair<PosIdx, st
|
||||||
// If there is nothing at all, return the empty string directly.
|
// If there is nothing at all, return the empty string directly.
|
||||||
// This also ensures that equivalent empty strings result in the same ast, which is helpful when testing formatters.
|
// This also ensures that equivalent empty strings result in the same ast, which is helpful when testing formatters.
|
||||||
if (es2.size() == 0) {
|
if (es2.size() == 0) {
|
||||||
auto * const result = new ExprString("");
|
auto * const result = exprs.add<ExprString>("");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -341,7 +341,7 @@ ParserState::stripIndentation(const PosIdx pos, std::vector<std::pair<PosIdx, st
|
||||||
auto * const result = (es2)[0].second;
|
auto * const result = (es2)[0].second;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return new ExprConcatStrings(pos, true, std::move(es2));
|
return exprs.add<ExprConcatStrings>(exprs.alloc, pos, true, std::move(es2));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PosIdx LexerState::at(const ParserLocation & loc)
|
inline PosIdx LexerState::at(const ParserLocation & loc)
|
||||||
|
|
|
||||||
|
|
@ -220,7 +220,55 @@ struct ValueBase
|
||||||
struct StringWithContext
|
struct StringWithContext
|
||||||
{
|
{
|
||||||
const char * c_str;
|
const char * c_str;
|
||||||
const char ** context; // must be in sorted order
|
|
||||||
|
/**
|
||||||
|
* The type of the context itself.
|
||||||
|
*
|
||||||
|
* Currently, it is length-prefixed array of pointers to
|
||||||
|
* null-terminated strings. The strings are specially formatted
|
||||||
|
* to represent a flattening of the recursive sum type that is a
|
||||||
|
* context element.
|
||||||
|
*
|
||||||
|
* @See NixStringContext for an more easily understood type,
|
||||||
|
* that of the "builder" for this data structure.
|
||||||
|
*/
|
||||||
|
struct Context
|
||||||
|
{
|
||||||
|
using Elem = const char *;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of items in the array
|
||||||
|
*/
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* must be in sorted order
|
||||||
|
*/
|
||||||
|
Elem elems[/*size*/];
|
||||||
|
public:
|
||||||
|
|
||||||
|
const Elem * begin() const
|
||||||
|
{
|
||||||
|
return elems;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Elem * end() const
|
||||||
|
{
|
||||||
|
return &elems[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @note returns a null pointer to more concisely encode the
|
||||||
|
* empty context
|
||||||
|
*/
|
||||||
|
static Context * fromBuilder(const NixStringContext & context);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* May be null for a string without context.
|
||||||
|
*/
|
||||||
|
const Context * context;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Path
|
struct Path
|
||||||
|
|
@ -991,7 +1039,7 @@ public:
|
||||||
setStorage(b);
|
setStorage(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mkStringNoCopy(const char * s, const char ** context = 0) noexcept
|
void mkStringNoCopy(const char * s, const Value::StringWithContext::Context * context = nullptr) noexcept
|
||||||
{
|
{
|
||||||
setStorage(StringWithContext{.c_str = s, .context = context});
|
setStorage(StringWithContext{.c_str = s, .context = context});
|
||||||
}
|
}
|
||||||
|
|
@ -1117,7 +1165,7 @@ public:
|
||||||
return getStorage<StringWithContext>().c_str;
|
return getStorage<StringWithContext>().c_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char ** context() const noexcept
|
const Value::StringWithContext::Context * context() const noexcept
|
||||||
{
|
{
|
||||||
return getStorage<StringWithContext>().context;
|
return getStorage<StringWithContext>().context;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,14 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo This should be reamed to `StringContextBuilderElem`, since:
|
||||||
|
*
|
||||||
|
* 1. We use `*Builder` for off-heap temporary data structures
|
||||||
|
*
|
||||||
|
* 2. The `Nix*` is totally redundant. (And my mistake from a long time
|
||||||
|
* ago.)
|
||||||
|
*/
|
||||||
struct NixStringContextElem
|
struct NixStringContextElem
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
@ -77,6 +85,11 @@ struct NixStringContextElem
|
||||||
std::string to_string() const;
|
std::string to_string() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo This should be renamed to `StringContextBuilder`.
|
||||||
|
*
|
||||||
|
* @see NixStringContextElem for explanation why.
|
||||||
|
*/
|
||||||
typedef std::set<NixStringContextElem> NixStringContext;
|
typedef std::set<NixStringContextElem> NixStringContext;
|
||||||
|
|
||||||
} // namespace nix
|
} // namespace nix
|
||||||
|
|
|
||||||
|
|
@ -523,6 +523,7 @@ void ExprWith::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> &
|
||||||
prevWith = 0;
|
prevWith = 0;
|
||||||
for (curEnv = env.get(), level = 1; curEnv; curEnv = curEnv->up.get(), level++)
|
for (curEnv = env.get(), level = 1; curEnv; curEnv = curEnv->up.get(), level++)
|
||||||
if (curEnv->isWith) {
|
if (curEnv->isWith) {
|
||||||
|
assert(level <= std::numeric_limits<uint32_t>::max());
|
||||||
prevWith = level;
|
prevWith = level;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ Expr * parseExprFromBuf(
|
||||||
size_t length,
|
size_t length,
|
||||||
Pos::Origin origin,
|
Pos::Origin origin,
|
||||||
const SourcePath & basePath,
|
const SourcePath & basePath,
|
||||||
std::pmr::polymorphic_allocator<char> & alloc,
|
Exprs & exprs,
|
||||||
SymbolTable & symbols,
|
SymbolTable & symbols,
|
||||||
const EvalSettings & settings,
|
const EvalSettings & settings,
|
||||||
PosTable & positions,
|
PosTable & positions,
|
||||||
|
|
@ -113,12 +113,12 @@ static void setDocPosition(const LexerState & lexerState, ExprLambda * lambda, P
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Expr * makeCall(PosIdx pos, Expr * fn, Expr * arg) {
|
static Expr * makeCall(Exprs & exprs, PosIdx pos, Expr * fn, Expr * arg) {
|
||||||
if (auto e2 = dynamic_cast<ExprCall *>(fn)) {
|
if (auto e2 = dynamic_cast<ExprCall *>(fn)) {
|
||||||
e2->args.push_back(arg);
|
e2->args.push_back(arg);
|
||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
return new ExprCall(pos, fn, {arg});
|
return exprs.add<ExprCall>(pos, fn, {arg});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -179,14 +179,14 @@ expr: expr_function;
|
||||||
|
|
||||||
expr_function
|
expr_function
|
||||||
: ID ':' expr_function
|
: ID ':' expr_function
|
||||||
{ auto me = new ExprLambda(CUR_POS, state->symbols.create($1), $3);
|
{ auto me = state->exprs.add<ExprLambda>(CUR_POS, state->symbols.create($1), $3);
|
||||||
$$ = me;
|
$$ = me;
|
||||||
SET_DOC_POS(me, @1);
|
SET_DOC_POS(me, @1);
|
||||||
}
|
}
|
||||||
| formal_set ':' expr_function[body]
|
| formal_set ':' expr_function[body]
|
||||||
{
|
{
|
||||||
state->validateFormals($formal_set);
|
state->validateFormals($formal_set);
|
||||||
auto me = new ExprLambda(state->positions, state->alloc, CUR_POS, std::move($formal_set), $body);
|
auto me = state->exprs.add<ExprLambda>(state->positions, state->exprs.alloc, CUR_POS, std::move($formal_set), $body);
|
||||||
$$ = me;
|
$$ = me;
|
||||||
SET_DOC_POS(me, @1);
|
SET_DOC_POS(me, @1);
|
||||||
}
|
}
|
||||||
|
|
@ -194,7 +194,7 @@ expr_function
|
||||||
{
|
{
|
||||||
auto arg = state->symbols.create($ID);
|
auto arg = state->symbols.create($ID);
|
||||||
state->validateFormals($formal_set, CUR_POS, arg);
|
state->validateFormals($formal_set, CUR_POS, arg);
|
||||||
auto me = new ExprLambda(state->positions, state->alloc, CUR_POS, arg, std::move($formal_set), $body);
|
auto me = state->exprs.add<ExprLambda>(state->positions, state->exprs.alloc, CUR_POS, arg, std::move($formal_set), $body);
|
||||||
$$ = me;
|
$$ = me;
|
||||||
SET_DOC_POS(me, @1);
|
SET_DOC_POS(me, @1);
|
||||||
}
|
}
|
||||||
|
|
@ -202,67 +202,67 @@ expr_function
|
||||||
{
|
{
|
||||||
auto arg = state->symbols.create($ID);
|
auto arg = state->symbols.create($ID);
|
||||||
state->validateFormals($formal_set, CUR_POS, arg);
|
state->validateFormals($formal_set, CUR_POS, arg);
|
||||||
auto me = new ExprLambda(state->positions, state->alloc, CUR_POS, arg, std::move($formal_set), $body);
|
auto me = state->exprs.add<ExprLambda>(state->positions, state->exprs.alloc, CUR_POS, arg, std::move($formal_set), $body);
|
||||||
$$ = me;
|
$$ = me;
|
||||||
SET_DOC_POS(me, @1);
|
SET_DOC_POS(me, @1);
|
||||||
}
|
}
|
||||||
| ASSERT expr ';' expr_function
|
| ASSERT expr ';' expr_function
|
||||||
{ $$ = new ExprAssert(CUR_POS, $2, $4); }
|
{ $$ = state->exprs.add<ExprAssert>(CUR_POS, $2, $4); }
|
||||||
| WITH expr ';' expr_function
|
| WITH expr ';' expr_function
|
||||||
{ $$ = new ExprWith(CUR_POS, $2, $4); }
|
{ $$ = state->exprs.add<ExprWith>(CUR_POS, $2, $4); }
|
||||||
| LET binds IN_KW expr_function
|
| LET binds IN_KW expr_function
|
||||||
{ if (!$2->dynamicAttrs.empty())
|
{ if (!$2->dynamicAttrs.empty())
|
||||||
throw ParseError({
|
throw ParseError({
|
||||||
.msg = HintFmt("dynamic attributes not allowed in let"),
|
.msg = HintFmt("dynamic attributes not allowed in let"),
|
||||||
.pos = state->positions[CUR_POS]
|
.pos = state->positions[CUR_POS]
|
||||||
});
|
});
|
||||||
$$ = new ExprLet($2, $4);
|
$$ = state->exprs.add<ExprLet>($2, $4);
|
||||||
}
|
}
|
||||||
| expr_if
|
| expr_if
|
||||||
;
|
;
|
||||||
|
|
||||||
expr_if
|
expr_if
|
||||||
: IF expr THEN expr ELSE expr { $$ = new ExprIf(CUR_POS, $2, $4, $6); }
|
: IF expr THEN expr ELSE expr { $$ = state->exprs.add<ExprIf>(CUR_POS, $2, $4, $6); }
|
||||||
| expr_pipe_from
|
| expr_pipe_from
|
||||||
| expr_pipe_into
|
| expr_pipe_into
|
||||||
| expr_op
|
| expr_op
|
||||||
;
|
;
|
||||||
|
|
||||||
expr_pipe_from
|
expr_pipe_from
|
||||||
: expr_op PIPE_FROM expr_pipe_from { $$ = makeCall(state->at(@2), $1, $3); }
|
: expr_op PIPE_FROM expr_pipe_from { $$ = makeCall(state->exprs, state->at(@2), $1, $3); }
|
||||||
| expr_op PIPE_FROM expr_op { $$ = makeCall(state->at(@2), $1, $3); }
|
| expr_op PIPE_FROM expr_op { $$ = makeCall(state->exprs, state->at(@2), $1, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
expr_pipe_into
|
expr_pipe_into
|
||||||
: expr_pipe_into PIPE_INTO expr_op { $$ = makeCall(state->at(@2), $3, $1); }
|
: expr_pipe_into PIPE_INTO expr_op { $$ = makeCall(state->exprs, state->at(@2), $3, $1); }
|
||||||
| expr_op PIPE_INTO expr_op { $$ = makeCall(state->at(@2), $3, $1); }
|
| expr_op PIPE_INTO expr_op { $$ = makeCall(state->exprs, state->at(@2), $3, $1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
expr_op
|
expr_op
|
||||||
: '!' expr_op %prec NOT { $$ = new ExprOpNot($2); }
|
: '!' expr_op %prec NOT { $$ = state->exprs.add<ExprOpNot>($2); }
|
||||||
| '-' expr_op %prec NEGATE { $$ = new ExprCall(CUR_POS, new ExprVar(state->s.sub), {new ExprInt(0), $2}); }
|
| '-' expr_op %prec NEGATE { $$ = state->exprs.add<ExprCall>(CUR_POS, state->exprs.add<ExprVar>(state->s.sub), {state->exprs.add<ExprInt>(0), $2}); }
|
||||||
| expr_op EQ expr_op { $$ = new ExprOpEq($1, $3); }
|
| expr_op EQ expr_op { $$ = state->exprs.add<ExprOpEq>($1, $3); }
|
||||||
| expr_op NEQ expr_op { $$ = new ExprOpNEq($1, $3); }
|
| expr_op NEQ expr_op { $$ = state->exprs.add<ExprOpNEq>($1, $3); }
|
||||||
| expr_op '<' expr_op { $$ = new ExprCall(state->at(@2), new ExprVar(state->s.lessThan), {$1, $3}); }
|
| expr_op '<' expr_op { $$ = state->exprs.add<ExprCall>(state->at(@2), state->exprs.add<ExprVar>(state->s.lessThan), {$1, $3}); }
|
||||||
| expr_op LEQ expr_op { $$ = new ExprOpNot(new ExprCall(state->at(@2), new ExprVar(state->s.lessThan), {$3, $1})); }
|
| expr_op LEQ expr_op { $$ = state->exprs.add<ExprOpNot>(state->exprs.add<ExprCall>(state->at(@2), state->exprs.add<ExprVar>(state->s.lessThan), {$3, $1})); }
|
||||||
| expr_op '>' expr_op { $$ = new ExprCall(state->at(@2), new ExprVar(state->s.lessThan), {$3, $1}); }
|
| expr_op '>' expr_op { $$ = state->exprs.add<ExprCall>(state->at(@2), state->exprs.add<ExprVar>(state->s.lessThan), {$3, $1}); }
|
||||||
| expr_op GEQ expr_op { $$ = new ExprOpNot(new ExprCall(state->at(@2), new ExprVar(state->s.lessThan), {$1, $3})); }
|
| expr_op GEQ expr_op { $$ = state->exprs.add<ExprOpNot>(state->exprs.add<ExprCall>(state->at(@2), state->exprs.add<ExprVar>(state->s.lessThan), {$1, $3})); }
|
||||||
| expr_op AND expr_op { $$ = new ExprOpAnd(state->at(@2), $1, $3); }
|
| expr_op AND expr_op { $$ = state->exprs.add<ExprOpAnd>(state->at(@2), $1, $3); }
|
||||||
| expr_op OR expr_op { $$ = new ExprOpOr(state->at(@2), $1, $3); }
|
| expr_op OR expr_op { $$ = state->exprs.add<ExprOpOr>(state->at(@2), $1, $3); }
|
||||||
| expr_op IMPL expr_op { $$ = new ExprOpImpl(state->at(@2), $1, $3); }
|
| expr_op IMPL expr_op { $$ = state->exprs.add<ExprOpImpl>(state->at(@2), $1, $3); }
|
||||||
| expr_op UPDATE expr_op { $$ = new ExprOpUpdate(state->at(@2), $1, $3); }
|
| expr_op UPDATE expr_op { $$ = state->exprs.add<ExprOpUpdate>(state->at(@2), $1, $3); }
|
||||||
| expr_op '?' attrpath { $$ = new ExprOpHasAttr(state->alloc, $1, std::move($3)); }
|
| expr_op '?' attrpath { $$ = state->exprs.add<ExprOpHasAttr>(state->exprs.alloc, $1, std::move($3)); }
|
||||||
| expr_op '+' expr_op
|
| expr_op '+' expr_op
|
||||||
{ $$ = new ExprConcatStrings(state->at(@2), false, {{state->at(@1), $1}, {state->at(@3), $3}}); }
|
{ $$ = state->exprs.add<ExprConcatStrings>(state->exprs.alloc, state->at(@2), false, {{state->at(@1), $1}, {state->at(@3), $3}}); }
|
||||||
| expr_op '-' expr_op { $$ = new ExprCall(state->at(@2), new ExprVar(state->s.sub), {$1, $3}); }
|
| expr_op '-' expr_op { $$ = state->exprs.add<ExprCall>(state->at(@2), state->exprs.add<ExprVar>(state->s.sub), {$1, $3}); }
|
||||||
| expr_op '*' expr_op { $$ = new ExprCall(state->at(@2), new ExprVar(state->s.mul), {$1, $3}); }
|
| expr_op '*' expr_op { $$ = state->exprs.add<ExprCall>(state->at(@2), state->exprs.add<ExprVar>(state->s.mul), {$1, $3}); }
|
||||||
| expr_op '/' expr_op { $$ = new ExprCall(state->at(@2), new ExprVar(state->s.div), {$1, $3}); }
|
| expr_op '/' expr_op { $$ = state->exprs.add<ExprCall>(state->at(@2), state->exprs.add<ExprVar>(state->s.div), {$1, $3}); }
|
||||||
| expr_op CONCAT expr_op { $$ = new ExprOpConcatLists(state->at(@2), $1, $3); }
|
| expr_op CONCAT expr_op { $$ = state->exprs.add<ExprOpConcatLists>(state->at(@2), $1, $3); }
|
||||||
| expr_app
|
| expr_app
|
||||||
;
|
;
|
||||||
|
|
||||||
expr_app
|
expr_app
|
||||||
: expr_app expr_select { $$ = makeCall(CUR_POS, $1, $2); $2->warnIfCursedOr(state->symbols, state->positions); }
|
: expr_app expr_select { $$ = makeCall(state->exprs, CUR_POS, $1, $2); $2->warnIfCursedOr(state->symbols, state->positions); }
|
||||||
| /* Once a ‘cursed or’ reaches this nonterminal, it is no longer cursed,
|
| /* Once a ‘cursed or’ reaches this nonterminal, it is no longer cursed,
|
||||||
because the uncursed parse would also produce an expr_app. But we need
|
because the uncursed parse would also produce an expr_app. But we need
|
||||||
to remove the cursed status in order to prevent valid things like
|
to remove the cursed status in order to prevent valid things like
|
||||||
|
|
@ -272,9 +272,9 @@ expr_app
|
||||||
|
|
||||||
expr_select
|
expr_select
|
||||||
: expr_simple '.' attrpath
|
: expr_simple '.' attrpath
|
||||||
{ $$ = new ExprSelect(state->alloc, CUR_POS, $1, std::move($3), nullptr); }
|
{ $$ = state->exprs.add<ExprSelect>(state->exprs.alloc, CUR_POS, $1, std::move($3), nullptr); }
|
||||||
| expr_simple '.' attrpath OR_KW expr_select
|
| expr_simple '.' attrpath OR_KW expr_select
|
||||||
{ $$ = new ExprSelect(state->alloc, CUR_POS, $1, std::move($3), $5); $5->warnIfCursedOr(state->symbols, state->positions); }
|
{ $$ = state->exprs.add<ExprSelect>(state->exprs.alloc, CUR_POS, $1, std::move($3), $5); $5->warnIfCursedOr(state->symbols, state->positions); }
|
||||||
| /* Backwards compatibility: because Nixpkgs has a function named ‘or’,
|
| /* Backwards compatibility: because Nixpkgs has a function named ‘or’,
|
||||||
allow stuff like ‘map or [...]’. This production is problematic (see
|
allow stuff like ‘map or [...]’. This production is problematic (see
|
||||||
https://github.com/NixOS/nix/issues/11118) and will be refactored in the
|
https://github.com/NixOS/nix/issues/11118) and will be refactored in the
|
||||||
|
|
@ -283,7 +283,7 @@ expr_select
|
||||||
the ExprCall with data (establishing that it is a ‘cursed or’) that can
|
the ExprCall with data (establishing that it is a ‘cursed or’) that can
|
||||||
be used to emit a warning when an affected expression is parsed. */
|
be used to emit a warning when an affected expression is parsed. */
|
||||||
expr_simple OR_KW
|
expr_simple OR_KW
|
||||||
{ $$ = new ExprCall(CUR_POS, $1, {new ExprVar(CUR_POS, state->s.or_)}, state->positions.add(state->origin, @$.endOffset)); }
|
{ $$ = state->exprs.add<ExprCall>(CUR_POS, $1, {state->exprs.add<ExprVar>(CUR_POS, state->s.or_)}, state->positions.add(state->origin, @$.endOffset)); }
|
||||||
| expr_simple
|
| expr_simple
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -291,15 +291,15 @@ expr_simple
|
||||||
: ID {
|
: ID {
|
||||||
std::string_view s = "__curPos";
|
std::string_view s = "__curPos";
|
||||||
if ($1.l == s.size() && strncmp($1.p, s.data(), s.size()) == 0)
|
if ($1.l == s.size() && strncmp($1.p, s.data(), s.size()) == 0)
|
||||||
$$ = new ExprPos(CUR_POS);
|
$$ = state->exprs.add<ExprPos>(CUR_POS);
|
||||||
else
|
else
|
||||||
$$ = new ExprVar(CUR_POS, state->symbols.create($1));
|
$$ = state->exprs.add<ExprVar>(CUR_POS, state->symbols.create($1));
|
||||||
}
|
}
|
||||||
| INT_LIT { $$ = new ExprInt($1); }
|
| INT_LIT { $$ = state->exprs.add<ExprInt>($1); }
|
||||||
| FLOAT_LIT { $$ = new ExprFloat($1); }
|
| FLOAT_LIT { $$ = state->exprs.add<ExprFloat>($1); }
|
||||||
| '"' string_parts '"' {
|
| '"' string_parts '"' {
|
||||||
std::visit(overloaded{
|
std::visit(overloaded{
|
||||||
[&](std::string_view str) { $$ = new ExprString(state->alloc, str); },
|
[&](std::string_view str) { $$ = state->exprs.add<ExprString>(state->exprs.alloc, str); },
|
||||||
[&](Expr * expr) { $$ = expr; }},
|
[&](Expr * expr) { $$ = expr; }},
|
||||||
$2);
|
$2);
|
||||||
}
|
}
|
||||||
|
|
@ -309,14 +309,14 @@ expr_simple
|
||||||
| path_start PATH_END
|
| path_start PATH_END
|
||||||
| path_start string_parts_interpolated PATH_END {
|
| path_start string_parts_interpolated PATH_END {
|
||||||
$2.insert($2.begin(), {state->at(@1), $1});
|
$2.insert($2.begin(), {state->at(@1), $1});
|
||||||
$$ = new ExprConcatStrings(CUR_POS, false, std::move($2));
|
$$ = state->exprs.add<ExprConcatStrings>(state->exprs.alloc, CUR_POS, false, std::move($2));
|
||||||
}
|
}
|
||||||
| SPATH {
|
| SPATH {
|
||||||
std::string_view path($1.p + 1, $1.l - 2);
|
std::string_view path($1.p + 1, $1.l - 2);
|
||||||
$$ = new ExprCall(CUR_POS,
|
$$ = state->exprs.add<ExprCall>(CUR_POS,
|
||||||
new ExprVar(state->s.findFile),
|
state->exprs.add<ExprVar>(state->s.findFile),
|
||||||
{new ExprVar(state->s.nixPath),
|
{state->exprs.add<ExprVar>(state->s.nixPath),
|
||||||
new ExprString(state->alloc, path)});
|
state->exprs.add<ExprString>(state->exprs.alloc, path)});
|
||||||
}
|
}
|
||||||
| URI {
|
| URI {
|
||||||
static bool noURLLiterals = experimentalFeatureSettings.isEnabled(Xp::NoUrlLiterals);
|
static bool noURLLiterals = experimentalFeatureSettings.isEnabled(Xp::NoUrlLiterals);
|
||||||
|
|
@ -325,35 +325,35 @@ expr_simple
|
||||||
.msg = HintFmt("URL literals are disabled"),
|
.msg = HintFmt("URL literals are disabled"),
|
||||||
.pos = state->positions[CUR_POS]
|
.pos = state->positions[CUR_POS]
|
||||||
});
|
});
|
||||||
$$ = new ExprString(state->alloc, $1);
|
$$ = state->exprs.add<ExprString>(state->exprs.alloc, $1);
|
||||||
}
|
}
|
||||||
| '(' expr ')' { $$ = $2; }
|
| '(' expr ')' { $$ = $2; }
|
||||||
/* Let expressions `let {..., body = ...}' are just desugared
|
/* Let expressions `let {..., body = ...}' are just desugared
|
||||||
into `(rec {..., body = ...}).body'. */
|
into `(rec {..., body = ...}).body'. */
|
||||||
| LET '{' binds '}'
|
| LET '{' binds '}'
|
||||||
{ $3->recursive = true; $3->pos = CUR_POS; $$ = new ExprSelect(state->alloc, noPos, $3, state->s.body); }
|
{ $3->recursive = true; $3->pos = CUR_POS; $$ = state->exprs.add<ExprSelect>(state->exprs.alloc, noPos, $3, state->s.body); }
|
||||||
| REC '{' binds '}'
|
| REC '{' binds '}'
|
||||||
{ $3->recursive = true; $3->pos = CUR_POS; $$ = $3; }
|
{ $3->recursive = true; $3->pos = CUR_POS; $$ = $3; }
|
||||||
| '{' binds1 '}'
|
| '{' binds1 '}'
|
||||||
{ $2->pos = CUR_POS; $$ = $2; }
|
{ $2->pos = CUR_POS; $$ = $2; }
|
||||||
| '{' '}'
|
| '{' '}'
|
||||||
{ $$ = new ExprAttrs(CUR_POS); }
|
{ $$ = state->exprs.add<ExprAttrs>(CUR_POS); }
|
||||||
| '[' list ']' { $$ = new ExprList(state->alloc, std::move($2)); }
|
| '[' list ']' { $$ = state->exprs.add<ExprList>(state->exprs.alloc, std::move($2)); }
|
||||||
;
|
;
|
||||||
|
|
||||||
string_parts
|
string_parts
|
||||||
: STR { $$ = $1; }
|
: STR { $$ = $1; }
|
||||||
| string_parts_interpolated { $$ = new ExprConcatStrings(CUR_POS, true, std::move($1)); }
|
| string_parts_interpolated { $$ = state->exprs.add<ExprConcatStrings>(state->exprs.alloc, CUR_POS, true, std::move($1)); }
|
||||||
| { $$ = std::string_view(); }
|
| { $$ = std::string_view(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
string_parts_interpolated
|
string_parts_interpolated
|
||||||
: string_parts_interpolated STR
|
: string_parts_interpolated STR
|
||||||
{ $$ = std::move($1); $$.emplace_back(state->at(@2), new ExprString(state->alloc, $2)); }
|
{ $$ = std::move($1); $$.emplace_back(state->at(@2), state->exprs.add<ExprString>(state->exprs.alloc, $2)); }
|
||||||
| string_parts_interpolated DOLLAR_CURLY expr '}' { $$ = std::move($1); $$.emplace_back(state->at(@2), $3); }
|
| string_parts_interpolated DOLLAR_CURLY expr '}' { $$ = std::move($1); $$.emplace_back(state->at(@2), $3); }
|
||||||
| DOLLAR_CURLY expr '}' { $$.emplace_back(state->at(@1), $2); }
|
| DOLLAR_CURLY expr '}' { $$.emplace_back(state->at(@1), $2); }
|
||||||
| STR DOLLAR_CURLY expr '}' {
|
| STR DOLLAR_CURLY expr '}' {
|
||||||
$$.emplace_back(state->at(@1), new ExprString(state->alloc, $1));
|
$$.emplace_back(state->at(@1), state->exprs.add<ExprString>(state->exprs.alloc, $1));
|
||||||
$$.emplace_back(state->at(@2), $3);
|
$$.emplace_back(state->at(@2), $3);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -379,8 +379,8 @@ path_start
|
||||||
root filesystem accessor, rather than the accessor of the
|
root filesystem accessor, rather than the accessor of the
|
||||||
current Nix expression. */
|
current Nix expression. */
|
||||||
literal.front() == '/'
|
literal.front() == '/'
|
||||||
? new ExprPath(state->alloc, state->rootFS, path)
|
? state->exprs.add<ExprPath>(state->exprs.alloc, state->rootFS, path)
|
||||||
: new ExprPath(state->alloc, state->basePath.accessor, path);
|
: state->exprs.add<ExprPath>(state->exprs.alloc, state->basePath.accessor, path);
|
||||||
}
|
}
|
||||||
| HPATH {
|
| HPATH {
|
||||||
if (state->settings.pureEval) {
|
if (state->settings.pureEval) {
|
||||||
|
|
@ -390,7 +390,7 @@ path_start
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Path path(getHome() + std::string($1.p + 1, $1.l - 1));
|
Path path(getHome() + std::string($1.p + 1, $1.l - 1));
|
||||||
$$ = new ExprPath(state->alloc, ref<SourceAccessor>(state->rootFS), path);
|
$$ = state->exprs.add<ExprPath>(state->exprs.alloc, ref<SourceAccessor>(state->rootFS), path);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -402,7 +402,7 @@ ind_string_parts
|
||||||
|
|
||||||
binds
|
binds
|
||||||
: binds1
|
: binds1
|
||||||
| { $$ = new ExprAttrs; }
|
| { $$ = state->exprs.add<ExprAttrs>(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
binds1
|
binds1
|
||||||
|
|
@ -417,7 +417,7 @@ binds1
|
||||||
state->dupAttr(i.symbol, iPos, $accum->attrs[i.symbol].pos);
|
state->dupAttr(i.symbol, iPos, $accum->attrs[i.symbol].pos);
|
||||||
$accum->attrs.emplace(
|
$accum->attrs.emplace(
|
||||||
i.symbol,
|
i.symbol,
|
||||||
ExprAttrs::AttrDef(new ExprVar(iPos, i.symbol), iPos, ExprAttrs::AttrDef::Kind::Inherited));
|
ExprAttrs::AttrDef(state->exprs.add<ExprVar>(iPos, i.symbol), iPos, ExprAttrs::AttrDef::Kind::Inherited));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| binds[accum] INHERIT '(' expr ')' attrs ';'
|
| binds[accum] INHERIT '(' expr ')' attrs ';'
|
||||||
|
|
@ -432,13 +432,13 @@ binds1
|
||||||
$accum->attrs.emplace(
|
$accum->attrs.emplace(
|
||||||
i.symbol,
|
i.symbol,
|
||||||
ExprAttrs::AttrDef(
|
ExprAttrs::AttrDef(
|
||||||
new ExprSelect(state->alloc, iPos, from, i.symbol),
|
state->exprs.add<ExprSelect>(state->exprs.alloc, iPos, from, i.symbol),
|
||||||
iPos,
|
iPos,
|
||||||
ExprAttrs::AttrDef::Kind::InheritedFrom));
|
ExprAttrs::AttrDef::Kind::InheritedFrom));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| attrpath '=' expr ';'
|
| attrpath '=' expr ';'
|
||||||
{ $$ = new ExprAttrs;
|
{ $$ = state->exprs.add<ExprAttrs>();
|
||||||
state->addAttr($$, std::move($attrpath), @attrpath, $expr, @expr);
|
state->addAttr($$, std::move($attrpath), @attrpath, $expr, @expr);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -525,7 +525,7 @@ Expr * parseExprFromBuf(
|
||||||
size_t length,
|
size_t length,
|
||||||
Pos::Origin origin,
|
Pos::Origin origin,
|
||||||
const SourcePath & basePath,
|
const SourcePath & basePath,
|
||||||
std::pmr::polymorphic_allocator<char> & alloc,
|
Exprs & exprs,
|
||||||
SymbolTable & symbols,
|
SymbolTable & symbols,
|
||||||
const EvalSettings & settings,
|
const EvalSettings & settings,
|
||||||
PosTable & positions,
|
PosTable & positions,
|
||||||
|
|
@ -540,7 +540,7 @@ Expr * parseExprFromBuf(
|
||||||
};
|
};
|
||||||
ParserState state {
|
ParserState state {
|
||||||
.lexerState = lexerState,
|
.lexerState = lexerState,
|
||||||
.alloc = alloc,
|
.exprs = exprs,
|
||||||
.symbols = symbols,
|
.symbols = symbols,
|
||||||
.positions = positions,
|
.positions = positions,
|
||||||
.basePath = basePath,
|
.basePath = basePath,
|
||||||
|
|
|
||||||
|
|
@ -825,10 +825,10 @@ static RegisterPrimOp primop_genericClosure(
|
||||||
|
|
||||||
- [Int](@docroot@/language/types.md#type-int)
|
- [Int](@docroot@/language/types.md#type-int)
|
||||||
- [Float](@docroot@/language/types.md#type-float)
|
- [Float](@docroot@/language/types.md#type-float)
|
||||||
- [Boolean](@docroot@/language/types.md#type-boolean)
|
- [Boolean](@docroot@/language/types.md#type-bool)
|
||||||
- [String](@docroot@/language/types.md#type-string)
|
- [String](@docroot@/language/types.md#type-string)
|
||||||
- [Path](@docroot@/language/types.md#type-path)
|
- [Path](@docroot@/language/types.md#type-path)
|
||||||
- [List](@docroot@/language/types.md#list)
|
- [List](@docroot@/language/types.md#type-list)
|
||||||
|
|
||||||
The result is produced by calling the `operator` on each `item` that has not been called yet, including newly added items, until no new items are added.
|
The result is produced by calling the `operator` on each `item` that has not been called yet, including newly added items, until no new items are added.
|
||||||
Items are compared by their `key` attribute.
|
Items are compared by their `key` attribute.
|
||||||
|
|
@ -2103,7 +2103,7 @@ static RegisterPrimOp primop_findFile(
|
||||||
builtins.findFile builtins.nixPath "nixpkgs"
|
builtins.findFile builtins.nixPath "nixpkgs"
|
||||||
```
|
```
|
||||||
|
|
||||||
A search path is represented as a list of [attribute sets](./types.md#attribute-set) with two attributes:
|
A search path is represented as a list of [attribute sets](./types.md#type-attrs) with two attributes:
|
||||||
- `prefix` is a relative path.
|
- `prefix` is a relative path.
|
||||||
- `path` denotes a file system location
|
- `path` denotes a file system location
|
||||||
|
|
||||||
|
|
@ -2395,7 +2395,7 @@ static RegisterPrimOp primop_outputOf({
|
||||||
|
|
||||||
returns an input placeholder for the output of the output of `myDrv`.
|
returns an input placeholder for the output of the output of `myDrv`.
|
||||||
|
|
||||||
This primop corresponds to the `^` sigil for [deriving paths](@docroot@/glossary.md#gloss-deriving-paths), e.g. as part of installable syntax on the command line.
|
This primop corresponds to the `^` sigil for [deriving paths](@docroot@/glossary.md#gloss-deriving-path), e.g. as part of installable syntax on the command line.
|
||||||
)",
|
)",
|
||||||
.fun = prim_outputOf,
|
.fun = prim_outputOf,
|
||||||
.experimentalFeature = Xp::DynamicDerivations,
|
.experimentalFeature = Xp::DynamicDerivations,
|
||||||
|
|
@ -4966,7 +4966,7 @@ static RegisterPrimOp primop_compareVersions({
|
||||||
version *s1* is older than version *s2*, `0` if they are the same,
|
version *s1* is older than version *s2*, `0` if they are the same,
|
||||||
and `1` if *s1* is newer than *s2*. The version comparison
|
and `1` if *s1* is newer than *s2*. The version comparison
|
||||||
algorithm is the same as the one used by [`nix-env
|
algorithm is the same as the one used by [`nix-env
|
||||||
-u`](../command-ref/nix-env.md#operation---upgrade).
|
-u`](../command-ref/nix-env/upgrade.md).
|
||||||
)",
|
)",
|
||||||
.fun = prim_compareVersions,
|
.fun = prim_compareVersions,
|
||||||
});
|
});
|
||||||
|
|
@ -4995,7 +4995,7 @@ static RegisterPrimOp primop_splitVersion({
|
||||||
.doc = R"(
|
.doc = R"(
|
||||||
Split a string representing a version into its components, by the
|
Split a string representing a version into its components, by the
|
||||||
same version splitting logic underlying the version comparison in
|
same version splitting logic underlying the version comparison in
|
||||||
[`nix-env -u`](../command-ref/nix-env.md#operation---upgrade).
|
[`nix-env -u`](../command-ref/nix-env/upgrade.md).
|
||||||
)",
|
)",
|
||||||
.fun = prim_splitVersion,
|
.fun = prim_splitVersion,
|
||||||
});
|
});
|
||||||
|
|
@ -5045,9 +5045,9 @@ void EvalState::createBaseEnv(const EvalSettings & evalSettings)
|
||||||
Primitive value.
|
Primitive value.
|
||||||
|
|
||||||
It can be returned by
|
It can be returned by
|
||||||
[comparison operators](@docroot@/language/operators.md#Comparison)
|
[comparison operators](@docroot@/language/operators.md#comparison)
|
||||||
and used in
|
and used in
|
||||||
[conditional expressions](@docroot@/language/syntax.md#Conditionals).
|
[conditional expressions](@docroot@/language/syntax.md#conditionals).
|
||||||
|
|
||||||
The name `true` is not special, and can be shadowed:
|
The name `true` is not special, and can be shadowed:
|
||||||
|
|
||||||
|
|
@ -5068,9 +5068,9 @@ void EvalState::createBaseEnv(const EvalSettings & evalSettings)
|
||||||
Primitive value.
|
Primitive value.
|
||||||
|
|
||||||
It can be returned by
|
It can be returned by
|
||||||
[comparison operators](@docroot@/language/operators.md#Comparison)
|
[comparison operators](@docroot@/language/operators.md#comparison)
|
||||||
and used in
|
and used in
|
||||||
[conditional expressions](@docroot@/language/syntax.md#Conditionals).
|
[conditional expressions](@docroot@/language/syntax.md#conditionals).
|
||||||
|
|
||||||
The name `false` is not special, and can be shadowed:
|
The name `false` is not special, and can be shadowed:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ static RegisterPrimOp primop_unsafeDiscardOutputDependency(
|
||||||
Create a copy of the given string where every
|
Create a copy of the given string where every
|
||||||
[derivation deep](@docroot@/language/string-context.md#string-context-element-derivation-deep)
|
[derivation deep](@docroot@/language/string-context.md#string-context-element-derivation-deep)
|
||||||
string context element is turned into a
|
string context element is turned into a
|
||||||
[constant](@docroot@/language/string-context.md#string-context-element-constant)
|
[constant](@docroot@/language/string-context.md#string-context-constant)
|
||||||
string context element.
|
string context element.
|
||||||
|
|
||||||
This is the opposite of [`builtins.addDrvOutputDependencies`](#builtins-addDrvOutputDependencies).
|
This is the opposite of [`builtins.addDrvOutputDependencies`](#builtins-addDrvOutputDependencies).
|
||||||
|
|
@ -145,7 +145,7 @@ static RegisterPrimOp primop_addDrvOutputDependencies(
|
||||||
.args = {"s"},
|
.args = {"s"},
|
||||||
.doc = R"(
|
.doc = R"(
|
||||||
Create a copy of the given string where a single
|
Create a copy of the given string where a single
|
||||||
[constant](@docroot@/language/string-context.md#string-context-element-constant)
|
[constant](@docroot@/language/string-context.md#string-context-constant)
|
||||||
string context element is turned into a
|
string context element is turned into a
|
||||||
[derivation deep](@docroot@/language/string-context.md#string-context-element-derivation-deep)
|
[derivation deep](@docroot@/language/string-context.md#string-context-element-derivation-deep)
|
||||||
string context element.
|
string context element.
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@
|
||||||
#include "nix/util/fs-sink.hh"
|
#include "nix/util/fs-sink.hh"
|
||||||
#include "nix/util/sync.hh"
|
#include "nix/util/sync.hh"
|
||||||
#include "nix/util/util.hh"
|
#include "nix/util/util.hh"
|
||||||
|
#include "nix/util/thread-pool.hh"
|
||||||
|
#include "nix/util/pool.hh"
|
||||||
|
|
||||||
#include <git2/attr.h>
|
#include <git2/attr.h>
|
||||||
#include <git2/blob.h>
|
#include <git2/blob.h>
|
||||||
|
|
@ -33,12 +35,14 @@
|
||||||
#include <git2/tag.h>
|
#include <git2/tag.h>
|
||||||
#include <git2/tree.h>
|
#include <git2/tree.h>
|
||||||
|
|
||||||
|
#include <boost/unordered/concurrent_flat_set.hpp>
|
||||||
#include <boost/unordered/unordered_flat_map.hpp>
|
#include <boost/unordered/unordered_flat_map.hpp>
|
||||||
#include <boost/unordered/unordered_flat_set.hpp>
|
#include <boost/unordered/unordered_flat_set.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <span>
|
#include <span>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
|
||||||
|
|
@ -227,12 +231,16 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
||||||
{
|
{
|
||||||
/** Location of the repository on disk. */
|
/** Location of the repository on disk. */
|
||||||
std::filesystem::path path;
|
std::filesystem::path path;
|
||||||
|
|
||||||
|
bool bare;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* libgit2 repository. Note that new objects are not written to disk,
|
* libgit2 repository. Note that new objects are not written to disk,
|
||||||
* because we are using a mempack backend. For writing to disk, see
|
* because we are using a mempack backend. For writing to disk, see
|
||||||
* `flush()`, which is also called by `GitFileSystemObjectSink::sync()`.
|
* `flush()`, which is also called by `GitFileSystemObjectSink::sync()`.
|
||||||
*/
|
*/
|
||||||
Repository repo;
|
Repository repo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In-memory object store for efficient batched writing to packfiles.
|
* In-memory object store for efficient batched writing to packfiles.
|
||||||
* Owned by `repo`.
|
* Owned by `repo`.
|
||||||
|
|
@ -241,6 +249,7 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
||||||
|
|
||||||
GitRepoImpl(std::filesystem::path _path, bool create, bool bare)
|
GitRepoImpl(std::filesystem::path _path, bool create, bool bare)
|
||||||
: path(std::move(_path))
|
: path(std::move(_path))
|
||||||
|
, bare(bare)
|
||||||
{
|
{
|
||||||
initLibGit2();
|
initLibGit2();
|
||||||
|
|
||||||
|
|
@ -317,32 +326,56 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a connection pool for this repo. Useful for
|
||||||
|
* multithreaded access.
|
||||||
|
*/
|
||||||
|
Pool<GitRepoImpl> getPool()
|
||||||
|
{
|
||||||
|
// TODO: as an optimization, it would be nice to include `this` in the pool.
|
||||||
|
return Pool<GitRepoImpl>(std::numeric_limits<size_t>::max(), [this]() -> ref<GitRepoImpl> {
|
||||||
|
return make_ref<GitRepoImpl>(path, false, bare);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t getRevCount(const Hash & rev) override
|
uint64_t getRevCount(const Hash & rev) override
|
||||||
{
|
{
|
||||||
boost::unordered_flat_set<git_oid, std::hash<git_oid>> done;
|
boost::concurrent_flat_set<git_oid, std::hash<git_oid>> done;
|
||||||
std::queue<Commit> todo;
|
|
||||||
|
|
||||||
todo.push(peelObject<Commit>(lookupObject(*this, hashToOID(rev)).get(), GIT_OBJECT_COMMIT));
|
auto startCommit = peelObject<Commit>(lookupObject(*this, hashToOID(rev)).get(), GIT_OBJECT_COMMIT);
|
||||||
|
auto startOid = *git_commit_id(startCommit.get());
|
||||||
|
done.insert(startOid);
|
||||||
|
|
||||||
while (auto commit = pop(todo)) {
|
auto repoPool(getPool());
|
||||||
if (!done.insert(*git_commit_id(commit->get())).second)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (size_t n = 0; n < git_commit_parentcount(commit->get()); ++n) {
|
ThreadPool pool;
|
||||||
git_commit * parent;
|
|
||||||
if (git_commit_parent(&parent, commit->get(), n)) {
|
auto process = [&done, &pool, &repoPool](this const auto & process, const git_oid & oid) -> void {
|
||||||
|
auto repo(repoPool.get());
|
||||||
|
|
||||||
|
auto _commit = lookupObject(*repo, oid, GIT_OBJECT_COMMIT);
|
||||||
|
auto commit = (const git_commit *) &*_commit;
|
||||||
|
|
||||||
|
for (auto n : std::views::iota(0U, git_commit_parentcount(commit))) {
|
||||||
|
auto parentOid = git_commit_parent_id(commit, n);
|
||||||
|
if (!parentOid) {
|
||||||
throw Error(
|
throw Error(
|
||||||
"Failed to retrieve the parent of Git commit '%s': %s. "
|
"Failed to retrieve the parent of Git commit '%s': %s. "
|
||||||
"This may be due to an incomplete repository history. "
|
"This may be due to an incomplete repository history. "
|
||||||
"To resolve this, either enable the shallow parameter in your flake URL (?shallow=1) "
|
"To resolve this, either enable the shallow parameter in your flake URL (?shallow=1) "
|
||||||
"or add set the shallow parameter to true in builtins.fetchGit, "
|
"or add set the shallow parameter to true in builtins.fetchGit, "
|
||||||
"or fetch the complete history for this branch.",
|
"or fetch the complete history for this branch.",
|
||||||
*git_commit_id(commit->get()),
|
*git_commit_id(commit),
|
||||||
git_error_last()->message);
|
git_error_last()->message);
|
||||||
}
|
}
|
||||||
todo.push(Commit(parent));
|
if (done.insert(*parentOid))
|
||||||
|
pool.enqueue(std::bind(process, *parentOid));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
pool.enqueue(std::bind(process, startOid));
|
||||||
|
|
||||||
|
pool.process();
|
||||||
|
|
||||||
return done.size();
|
return done.size();
|
||||||
}
|
}
|
||||||
|
|
@ -549,25 +582,15 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
||||||
// then use code that was removed in this commit (see blame)
|
// then use code that was removed in this commit (see blame)
|
||||||
|
|
||||||
auto dir = this->path;
|
auto dir = this->path;
|
||||||
Strings gitArgs{"-C", dir.string(), "--git-dir", ".", "fetch", "--quiet", "--force"};
|
Strings gitArgs{"-C", dir.string(), "--git-dir", ".", "fetch", "--progress", "--force"};
|
||||||
if (shallow)
|
if (shallow)
|
||||||
append(gitArgs, {"--depth", "1"});
|
append(gitArgs, {"--depth", "1"});
|
||||||
append(gitArgs, {std::string("--"), url, refspec});
|
append(gitArgs, {std::string("--"), url, refspec});
|
||||||
|
|
||||||
auto [status, output] = runProgram(
|
auto status = runProgram(RunOptions{.program = "git", .args = gitArgs, .isInteractive = true}).first;
|
||||||
RunOptions{
|
|
||||||
.program = "git",
|
|
||||||
.lookupPath = true,
|
|
||||||
// FIXME: git stderr messes up our progress indicator, so
|
|
||||||
// we're using --quiet for now. Should process its stderr.
|
|
||||||
.args = gitArgs,
|
|
||||||
.input = {},
|
|
||||||
.mergeStderrToStdout = true,
|
|
||||||
.isInteractive = true});
|
|
||||||
|
|
||||||
if (status > 0) {
|
if (status > 0)
|
||||||
throw Error("Failed to fetch git repository %s : %s", url, output);
|
throw Error("Failed to fetch git repository '%s'", url);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void verifyCommit(const Hash & rev, const std::vector<fetchers::PublicKey> & publicKeys) override
|
void verifyCommit(const Hash & rev, const std::vector<fetchers::PublicKey> & publicKeys) override
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
///@file
|
///@file
|
||||||
|
|
||||||
#include "nix/util/types.hh"
|
#include "nix/util/types.hh"
|
||||||
|
#include "nix/util/source-path.hh"
|
||||||
#include "nix/fetchers/fetchers.hh"
|
#include "nix/fetchers/fetchers.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
@ -39,7 +40,7 @@ struct Registry
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<Registry> read(const Settings & settings, const Path & path, RegistryType type);
|
static std::shared_ptr<Registry> read(const Settings & settings, const SourcePath & path, RegistryType type);
|
||||||
|
|
||||||
void write(const Path & path);
|
void write(const Path & path);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,18 +10,18 @@
|
||||||
|
|
||||||
namespace nix::fetchers {
|
namespace nix::fetchers {
|
||||||
|
|
||||||
std::shared_ptr<Registry> Registry::read(const Settings & settings, const Path & path, RegistryType type)
|
std::shared_ptr<Registry> Registry::read(const Settings & settings, const SourcePath & path, RegistryType type)
|
||||||
{
|
{
|
||||||
debug("reading registry '%s'", path);
|
debug("reading registry '%s'", path);
|
||||||
|
|
||||||
auto registry = std::make_shared<Registry>(settings, type);
|
auto registry = std::make_shared<Registry>(settings, type);
|
||||||
|
|
||||||
if (!pathExists(path))
|
if (!path.pathExists())
|
||||||
return std::make_shared<Registry>(settings, type);
|
return std::make_shared<Registry>(settings, type);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
auto json = nlohmann::json::parse(readFile(path));
|
auto json = nlohmann::json::parse(path.readFile());
|
||||||
|
|
||||||
auto version = json.value("version", 0);
|
auto version = json.value("version", 0);
|
||||||
|
|
||||||
|
|
@ -97,7 +97,10 @@ static Path getSystemRegistryPath()
|
||||||
|
|
||||||
static std::shared_ptr<Registry> getSystemRegistry(const Settings & settings)
|
static std::shared_ptr<Registry> getSystemRegistry(const Settings & settings)
|
||||||
{
|
{
|
||||||
static auto systemRegistry = Registry::read(settings, getSystemRegistryPath(), Registry::System);
|
static auto systemRegistry = Registry::read(
|
||||||
|
settings,
|
||||||
|
SourcePath{getFSSourceAccessor(), CanonPath{getSystemRegistryPath()}}.resolveSymlinks(),
|
||||||
|
Registry::System);
|
||||||
return systemRegistry;
|
return systemRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,13 +111,17 @@ Path getUserRegistryPath()
|
||||||
|
|
||||||
std::shared_ptr<Registry> getUserRegistry(const Settings & settings)
|
std::shared_ptr<Registry> getUserRegistry(const Settings & settings)
|
||||||
{
|
{
|
||||||
static auto userRegistry = Registry::read(settings, getUserRegistryPath(), Registry::User);
|
static auto userRegistry = Registry::read(
|
||||||
|
settings,
|
||||||
|
SourcePath{getFSSourceAccessor(), CanonPath{getUserRegistryPath()}}.resolveSymlinks(),
|
||||||
|
Registry::User);
|
||||||
return userRegistry;
|
return userRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Registry> getCustomRegistry(const Settings & settings, const Path & p)
|
std::shared_ptr<Registry> getCustomRegistry(const Settings & settings, const Path & p)
|
||||||
{
|
{
|
||||||
static auto customRegistry = Registry::read(settings, p, Registry::Custom);
|
static auto customRegistry =
|
||||||
|
Registry::read(settings, SourcePath{getFSSourceAccessor(), CanonPath{p}}.resolveSymlinks(), Registry::Custom);
|
||||||
return customRegistry;
|
return customRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -137,14 +144,19 @@ static std::shared_ptr<Registry> getGlobalRegistry(const Settings & settings, re
|
||||||
return std::make_shared<Registry>(settings, Registry::Global); // empty registry
|
return std::make_shared<Registry>(settings, Registry::Global); // empty registry
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isAbsolute(path)) {
|
return Registry::read(
|
||||||
auto storePath = downloadFile(store, settings, path, "flake-registry.json").storePath;
|
settings,
|
||||||
if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>())
|
[&] -> SourcePath {
|
||||||
store2->addPermRoot(storePath, getCacheDir() + "/flake-registry.json");
|
if (!isAbsolute(path)) {
|
||||||
path = store->toRealPath(storePath);
|
auto storePath = downloadFile(store, settings, path, "flake-registry.json").storePath;
|
||||||
}
|
if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>())
|
||||||
|
store2->addPermRoot(storePath, getCacheDir() + "/flake-registry.json");
|
||||||
return Registry::read(settings, path, Registry::Global);
|
return {store->requireStoreObjectAccessor(storePath)};
|
||||||
|
} else {
|
||||||
|
return SourcePath{getFSSourceAccessor(), CanonPath{path}}.resolveSymlinks();
|
||||||
|
}
|
||||||
|
}(),
|
||||||
|
Registry::Global);
|
||||||
}();
|
}();
|
||||||
|
|
||||||
return reg;
|
return reg;
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,8 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
|
||||||
|
|
||||||
std::smatch match;
|
std::smatch match;
|
||||||
auto succeeds = std::regex_match(url, match, pathFlakeRegex);
|
auto succeeds = std::regex_match(url, match, pathFlakeRegex);
|
||||||
assert(succeeds);
|
if (!succeeds)
|
||||||
|
throw Error("invalid flakeref '%s'", url);
|
||||||
auto path = match[1].str();
|
auto path = match[1].str();
|
||||||
auto query = decodeQuery(match[3].str(), /*lenient=*/true);
|
auto query = decodeQuery(match[3].str(), /*lenient=*/true);
|
||||||
auto fragment = percentDecode(match[5].str());
|
auto fragment = percentDecode(match[5].str());
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include "nix/store/store-api.hh"
|
#include "nix/store/store-api.hh"
|
||||||
#include "nix/store/store-open.hh"
|
#include "nix/store/store-open.hh"
|
||||||
#include "nix/store/build-result.hh"
|
#include "nix/store/build-result.hh"
|
||||||
|
#include "nix/store/local-fs-store.hh"
|
||||||
|
|
||||||
#include "nix/store/globals.hh"
|
#include "nix/store/globals.hh"
|
||||||
|
|
||||||
|
|
@ -109,7 +110,8 @@ nix_err nix_store_real_path(
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
try {
|
try {
|
||||||
auto res = store->ptr->toRealPath(path->path);
|
auto store2 = store->ptr.dynamic_pointer_cast<nix::LocalFSStore>();
|
||||||
|
auto res = store2 ? store2->toRealPath(path->path) : store->ptr->printStorePath(path->path);
|
||||||
return call_nix_get_string_callback(res, callback, user_data);
|
return call_nix_get_string_callback(res, callback, user_data);
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
|
|
|
||||||
108
src/libstore-tests/build-result.cc
Normal file
108
src/libstore-tests/build-result.cc
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "nix/store/build-result.hh"
|
||||||
|
#include "nix/util/tests/json-characterization.hh"
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
class BuildResultTest : public virtual CharacterizationTest
|
||||||
|
{
|
||||||
|
std::filesystem::path unitTestData = getUnitTestData() / "build-result";
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::filesystem::path goldenMaster(std::string_view testStem) const override
|
||||||
|
{
|
||||||
|
return unitTestData / testStem;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using nlohmann::json;
|
||||||
|
|
||||||
|
struct BuildResultJsonTest : BuildResultTest,
|
||||||
|
JsonCharacterizationTest<BuildResult>,
|
||||||
|
::testing::WithParamInterface<std::pair<std::string_view, BuildResult>>
|
||||||
|
{};
|
||||||
|
|
||||||
|
TEST_P(BuildResultJsonTest, from_json)
|
||||||
|
{
|
||||||
|
auto & [name, expected] = GetParam();
|
||||||
|
readJsonTest(name, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(BuildResultJsonTest, to_json)
|
||||||
|
{
|
||||||
|
auto & [name, value] = GetParam();
|
||||||
|
writeJsonTest(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
BuildResultJSON,
|
||||||
|
BuildResultJsonTest,
|
||||||
|
::testing::Values(
|
||||||
|
std::pair{
|
||||||
|
"not-deterministic",
|
||||||
|
BuildResult{
|
||||||
|
.inner{BuildResult::Failure{
|
||||||
|
.status = BuildResult::Failure::NotDeterministic,
|
||||||
|
.errorMsg = "no idea why",
|
||||||
|
.isNonDeterministic = false, // Note: This field is separate from the status
|
||||||
|
}},
|
||||||
|
.timesBuilt = 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
std::pair{
|
||||||
|
"output-rejected",
|
||||||
|
BuildResult{
|
||||||
|
.inner{BuildResult::Failure{
|
||||||
|
.status = BuildResult::Failure::OutputRejected,
|
||||||
|
.errorMsg = "no idea why",
|
||||||
|
.isNonDeterministic = false,
|
||||||
|
}},
|
||||||
|
.timesBuilt = 3,
|
||||||
|
.startTime = 30,
|
||||||
|
.stopTime = 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
std::pair{
|
||||||
|
"success",
|
||||||
|
BuildResult{
|
||||||
|
.inner{BuildResult::Success{
|
||||||
|
.status = BuildResult::Success::Built,
|
||||||
|
.builtOutputs{
|
||||||
|
{
|
||||||
|
"foo",
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||||
|
},
|
||||||
|
DrvOutput{
|
||||||
|
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||||
|
.outputName = "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bar",
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar"},
|
||||||
|
},
|
||||||
|
DrvOutput{
|
||||||
|
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||||
|
.outputName = "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
.timesBuilt = 3,
|
||||||
|
.startTime = 30,
|
||||||
|
.stopTime = 50,
|
||||||
|
.cpuUser = std::chrono::microseconds(500s),
|
||||||
|
.cpuSystem = std::chrono::microseconds(604s),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
} // namespace nix
|
||||||
|
|
@ -114,13 +114,28 @@ CHARACTERIZATION_TEST(
|
||||||
Realisation{
|
Realisation{
|
||||||
{
|
{
|
||||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||||
.signatures = {"asdf", "qwer"},
|
|
||||||
},
|
},
|
||||||
DrvOutput{
|
{
|
||||||
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
||||||
.outputName = "baz",
|
.outputName = "baz",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Realisation{
|
||||||
|
{
|
||||||
|
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||||
|
.signatures = {"asdf", "qwer"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
||||||
|
.outputName = "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
|
||||||
|
CHARACTERIZATION_TEST(
|
||||||
|
realisation_with_deps,
|
||||||
|
"realisation-with-deps",
|
||||||
|
(std::tuple<Realisation>{
|
||||||
Realisation{
|
Realisation{
|
||||||
{
|
{
|
||||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"errorMsg": "no idea why",
|
||||||
|
"isNonDeterministic": false,
|
||||||
|
"startTime": 0,
|
||||||
|
"status": "NotDeterministic",
|
||||||
|
"stopTime": 0,
|
||||||
|
"success": false,
|
||||||
|
"timesBuilt": 1
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"errorMsg": "no idea why",
|
||||||
|
"isNonDeterministic": false,
|
||||||
|
"startTime": 30,
|
||||||
|
"status": "OutputRejected",
|
||||||
|
"stopTime": 50,
|
||||||
|
"success": false,
|
||||||
|
"timesBuilt": 3
|
||||||
|
}
|
||||||
23
src/libstore-tests/data/build-result/success.json
Normal file
23
src/libstore-tests/data/build-result/success.json
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"builtOutputs": {
|
||||||
|
"bar": {
|
||||||
|
"dependentRealisations": {},
|
||||||
|
"id": "sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!bar",
|
||||||
|
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
||||||
|
"signatures": []
|
||||||
|
},
|
||||||
|
"foo": {
|
||||||
|
"dependentRealisations": {},
|
||||||
|
"id": "sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!foo",
|
||||||
|
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||||
|
"signatures": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cpuSystem": 604000000,
|
||||||
|
"cpuUser": 500000000,
|
||||||
|
"startTime": 30,
|
||||||
|
"status": "Built",
|
||||||
|
"stopTime": 50,
|
||||||
|
"success": true,
|
||||||
|
"timesBuilt": 3
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -12,8 +12,10 @@
|
||||||
"outputHashMode": "recursive",
|
"outputHashMode": "recursive",
|
||||||
"system": "my-system"
|
"system": "my-system"
|
||||||
},
|
},
|
||||||
"inputDrvs": {},
|
"inputs": {
|
||||||
"inputSrcs": [],
|
"drvs": {},
|
||||||
|
"srcs": []
|
||||||
|
},
|
||||||
"name": "advanced-attributes-defaults",
|
"name": "advanced-attributes-defaults",
|
||||||
"outputs": {
|
"outputs": {
|
||||||
"out": {
|
"out": {
|
||||||
|
|
@ -22,5 +24,5 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"system": "my-system",
|
"system": "my-system",
|
||||||
"version": 3
|
"version": 4
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,10 @@
|
||||||
"dev": "/02qcpld1y6xhs5gz9bchpxaw0xdhmsp5dv88lh25r2ss44kh8dxz",
|
"dev": "/02qcpld1y6xhs5gz9bchpxaw0xdhmsp5dv88lh25r2ss44kh8dxz",
|
||||||
"out": "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9"
|
"out": "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9"
|
||||||
},
|
},
|
||||||
"inputDrvs": {},
|
"inputs": {
|
||||||
"inputSrcs": [],
|
"drvs": {},
|
||||||
|
"srcs": []
|
||||||
|
},
|
||||||
"name": "advanced-attributes-structured-attrs-defaults",
|
"name": "advanced-attributes-structured-attrs-defaults",
|
||||||
"outputs": {
|
"outputs": {
|
||||||
"dev": {
|
"dev": {
|
||||||
|
|
@ -33,5 +35,5 @@
|
||||||
"system": "my-system"
|
"system": "my-system"
|
||||||
},
|
},
|
||||||
"system": "my-system",
|
"system": "my-system",
|
||||||
"version": 3
|
"version": 4
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,25 +9,27 @@
|
||||||
"dev": "/02qcpld1y6xhs5gz9bchpxaw0xdhmsp5dv88lh25r2ss44kh8dxz",
|
"dev": "/02qcpld1y6xhs5gz9bchpxaw0xdhmsp5dv88lh25r2ss44kh8dxz",
|
||||||
"out": "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9"
|
"out": "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9"
|
||||||
},
|
},
|
||||||
"inputDrvs": {
|
"inputs": {
|
||||||
"j56sf12rxpcv5swr14vsjn5cwm6bj03h-foo.drv": {
|
"drvs": {
|
||||||
"dynamicOutputs": {},
|
"j56sf12rxpcv5swr14vsjn5cwm6bj03h-foo.drv": {
|
||||||
"outputs": [
|
"dynamicOutputs": {},
|
||||||
"dev",
|
"outputs": [
|
||||||
"out"
|
"dev",
|
||||||
]
|
"out"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv": {
|
||||||
|
"dynamicOutputs": {},
|
||||||
|
"outputs": [
|
||||||
|
"dev",
|
||||||
|
"out"
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv": {
|
"srcs": [
|
||||||
"dynamicOutputs": {},
|
"qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv"
|
||||||
"outputs": [
|
]
|
||||||
"dev",
|
|
||||||
"out"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"inputSrcs": [
|
|
||||||
"qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv"
|
|
||||||
],
|
|
||||||
"name": "advanced-attributes-structured-attrs",
|
"name": "advanced-attributes-structured-attrs",
|
||||||
"outputs": {
|
"outputs": {
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -101,5 +103,5 @@
|
||||||
"system": "my-system"
|
"system": "my-system"
|
||||||
},
|
},
|
||||||
"system": "my-system",
|
"system": "my-system",
|
||||||
"version": 3
|
"version": 4
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,25 +25,27 @@
|
||||||
"requiredSystemFeatures": "rainbow uid-range",
|
"requiredSystemFeatures": "rainbow uid-range",
|
||||||
"system": "my-system"
|
"system": "my-system"
|
||||||
},
|
},
|
||||||
"inputDrvs": {
|
"inputs": {
|
||||||
"j56sf12rxpcv5swr14vsjn5cwm6bj03h-foo.drv": {
|
"drvs": {
|
||||||
"dynamicOutputs": {},
|
"j56sf12rxpcv5swr14vsjn5cwm6bj03h-foo.drv": {
|
||||||
"outputs": [
|
"dynamicOutputs": {},
|
||||||
"dev",
|
"outputs": [
|
||||||
"out"
|
"dev",
|
||||||
]
|
"out"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv": {
|
||||||
|
"dynamicOutputs": {},
|
||||||
|
"outputs": [
|
||||||
|
"dev",
|
||||||
|
"out"
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv": {
|
"srcs": [
|
||||||
"dynamicOutputs": {},
|
"qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv"
|
||||||
"outputs": [
|
]
|
||||||
"dev",
|
|
||||||
"out"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"inputSrcs": [
|
|
||||||
"qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv"
|
|
||||||
],
|
|
||||||
"name": "advanced-attributes",
|
"name": "advanced-attributes",
|
||||||
"outputs": {
|
"outputs": {
|
||||||
"out": {
|
"out": {
|
||||||
|
|
@ -52,5 +54,5 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"system": "my-system",
|
"system": "my-system",
|
||||||
"version": 3
|
"version": 4
|
||||||
}
|
}
|
||||||
|
|
|
||||||
46
src/libstore-tests/data/derivation/ca/all_set.json
Normal file
46
src/libstore-tests/data/derivation/ca/all_set.json
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
{
|
||||||
|
"additionalSandboxProfile": "sandcastle",
|
||||||
|
"allowLocalNetworking": true,
|
||||||
|
"allowSubstitutes": false,
|
||||||
|
"exportReferencesGraph": {
|
||||||
|
"refs1": [
|
||||||
|
"/164j69y6zir9z0339n8pjigg3rckinlr77bxsavzizdaaljb7nh9"
|
||||||
|
],
|
||||||
|
"refs2": [
|
||||||
|
"/nix/store/qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"impureEnvVars": [
|
||||||
|
"UNICORN"
|
||||||
|
],
|
||||||
|
"impureHostDeps": [
|
||||||
|
"/usr/bin/ditto"
|
||||||
|
],
|
||||||
|
"noChroot": true,
|
||||||
|
"outputChecks": {
|
||||||
|
"forAllOutputs": {
|
||||||
|
"allowedReferences": [
|
||||||
|
"/164j69y6zir9z0339n8pjigg3rckinlr77bxsavzizdaaljb7nh9"
|
||||||
|
],
|
||||||
|
"allowedRequisites": [
|
||||||
|
"/0nr45p69vn6izw9446wsh9bng9nndhvn19kpsm4n96a5mycw0s4z"
|
||||||
|
],
|
||||||
|
"disallowedReferences": [
|
||||||
|
"/0nyw57wm2iicnm9rglvjmbci3ikmcp823czdqdzdcgsnnwqps71g"
|
||||||
|
],
|
||||||
|
"disallowedRequisites": [
|
||||||
|
"/07f301yqyz8c6wf6bbbavb2q39j4n8kmcly1s09xadyhgy6x2wr8"
|
||||||
|
],
|
||||||
|
"ignoreSelfRefs": true,
|
||||||
|
"maxClosureSize": null,
|
||||||
|
"maxSize": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"passAsFile": [],
|
||||||
|
"preferLocalBuild": true,
|
||||||
|
"requiredSystemFeatures": [
|
||||||
|
"rainbow",
|
||||||
|
"uid-range"
|
||||||
|
],
|
||||||
|
"unsafeDiscardReferences": {}
|
||||||
|
}
|
||||||
|
|
@ -10,8 +10,10 @@
|
||||||
"out": "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9",
|
"out": "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9",
|
||||||
"system": "x86_64-linux"
|
"system": "x86_64-linux"
|
||||||
},
|
},
|
||||||
"inputDrvs": {},
|
"inputs": {
|
||||||
"inputSrcs": [],
|
"drvs": {},
|
||||||
|
"srcs": []
|
||||||
|
},
|
||||||
"name": "myname",
|
"name": "myname",
|
||||||
"outputs": {
|
"outputs": {
|
||||||
"out": {
|
"out": {
|
||||||
|
|
@ -20,5 +22,5 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"system": "x86_64-linux",
|
"system": "x86_64-linux",
|
||||||
"version": 3
|
"version": 4
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
{
|
||||||
|
"additionalSandboxProfile": "sandcastle",
|
||||||
|
"allowLocalNetworking": true,
|
||||||
|
"allowSubstitutes": false,
|
||||||
|
"exportReferencesGraph": {
|
||||||
|
"refs1": [
|
||||||
|
"/164j69y6zir9z0339n8pjigg3rckinlr77bxsavzizdaaljb7nh9"
|
||||||
|
],
|
||||||
|
"refs2": [
|
||||||
|
"/nix/store/qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"impureEnvVars": [
|
||||||
|
"UNICORN"
|
||||||
|
],
|
||||||
|
"impureHostDeps": [
|
||||||
|
"/usr/bin/ditto"
|
||||||
|
],
|
||||||
|
"noChroot": true,
|
||||||
|
"outputChecks": {
|
||||||
|
"perOutput": {
|
||||||
|
"bin": {
|
||||||
|
"allowedReferences": null,
|
||||||
|
"allowedRequisites": null,
|
||||||
|
"disallowedReferences": [
|
||||||
|
"/0nyw57wm2iicnm9rglvjmbci3ikmcp823czdqdzdcgsnnwqps71g"
|
||||||
|
],
|
||||||
|
"disallowedRequisites": [
|
||||||
|
"/07f301yqyz8c6wf6bbbavb2q39j4n8kmcly1s09xadyhgy6x2wr8"
|
||||||
|
],
|
||||||
|
"ignoreSelfRefs": false,
|
||||||
|
"maxClosureSize": null,
|
||||||
|
"maxSize": null
|
||||||
|
},
|
||||||
|
"dev": {
|
||||||
|
"allowedReferences": null,
|
||||||
|
"allowedRequisites": null,
|
||||||
|
"disallowedReferences": [],
|
||||||
|
"disallowedRequisites": [],
|
||||||
|
"ignoreSelfRefs": false,
|
||||||
|
"maxClosureSize": 5909,
|
||||||
|
"maxSize": 789
|
||||||
|
},
|
||||||
|
"out": {
|
||||||
|
"allowedReferences": [
|
||||||
|
"/164j69y6zir9z0339n8pjigg3rckinlr77bxsavzizdaaljb7nh9"
|
||||||
|
],
|
||||||
|
"allowedRequisites": [
|
||||||
|
"/0nr45p69vn6izw9446wsh9bng9nndhvn19kpsm4n96a5mycw0s4z"
|
||||||
|
],
|
||||||
|
"disallowedReferences": [],
|
||||||
|
"disallowedRequisites": [],
|
||||||
|
"ignoreSelfRefs": false,
|
||||||
|
"maxClosureSize": null,
|
||||||
|
"maxSize": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"passAsFile": [],
|
||||||
|
"preferLocalBuild": true,
|
||||||
|
"requiredSystemFeatures": [
|
||||||
|
"rainbow",
|
||||||
|
"uid-range"
|
||||||
|
],
|
||||||
|
"unsafeDiscardReferences": {}
|
||||||
|
}
|
||||||
|
|
@ -7,33 +7,35 @@
|
||||||
"env": {
|
"env": {
|
||||||
"BIG_BAD": "WOLF"
|
"BIG_BAD": "WOLF"
|
||||||
},
|
},
|
||||||
"inputDrvs": {
|
"inputs": {
|
||||||
"c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv": {
|
"drvs": {
|
||||||
"dynamicOutputs": {
|
"c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv": {
|
||||||
"cat": {
|
"dynamicOutputs": {
|
||||||
"dynamicOutputs": {},
|
"cat": {
|
||||||
"outputs": [
|
"dynamicOutputs": {},
|
||||||
"kitten"
|
"outputs": [
|
||||||
]
|
"kitten"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"goose": {
|
||||||
|
"dynamicOutputs": {},
|
||||||
|
"outputs": [
|
||||||
|
"gosling"
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"goose": {
|
"outputs": [
|
||||||
"dynamicOutputs": {},
|
"cat",
|
||||||
"outputs": [
|
"dog"
|
||||||
"gosling"
|
]
|
||||||
]
|
}
|
||||||
}
|
},
|
||||||
},
|
"srcs": [
|
||||||
"outputs": [
|
"c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"
|
||||||
"cat",
|
]
|
||||||
"dog"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"inputSrcs": [
|
|
||||||
"c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"
|
|
||||||
],
|
|
||||||
"name": "dyn-dep-derivation",
|
"name": "dyn-dep-derivation",
|
||||||
"outputs": {},
|
"outputs": {},
|
||||||
"system": "wasm-sel4",
|
"system": "wasm-sel4",
|
||||||
"version": 3
|
"version": 4
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,10 @@
|
||||||
"out": "/nix/store/1qsc7svv43m4dw2prh6mvyf7cai5czji-advanced-attributes-defaults",
|
"out": "/nix/store/1qsc7svv43m4dw2prh6mvyf7cai5czji-advanced-attributes-defaults",
|
||||||
"system": "my-system"
|
"system": "my-system"
|
||||||
},
|
},
|
||||||
"inputDrvs": {},
|
"inputs": {
|
||||||
"inputSrcs": [],
|
"drvs": {},
|
||||||
|
"srcs": []
|
||||||
|
},
|
||||||
"name": "advanced-attributes-defaults",
|
"name": "advanced-attributes-defaults",
|
||||||
"outputs": {
|
"outputs": {
|
||||||
"out": {
|
"out": {
|
||||||
|
|
@ -19,5 +21,5 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"system": "my-system",
|
"system": "my-system",
|
||||||
"version": 3
|
"version": 4
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,10 @@
|
||||||
"dev": "/nix/store/8bazivnbipbyi569623skw5zm91z6kc2-advanced-attributes-structured-attrs-defaults-dev",
|
"dev": "/nix/store/8bazivnbipbyi569623skw5zm91z6kc2-advanced-attributes-structured-attrs-defaults-dev",
|
||||||
"out": "/nix/store/f8f8nvnx32bxvyxyx2ff7akbvwhwd9dw-advanced-attributes-structured-attrs-defaults"
|
"out": "/nix/store/f8f8nvnx32bxvyxyx2ff7akbvwhwd9dw-advanced-attributes-structured-attrs-defaults"
|
||||||
},
|
},
|
||||||
"inputDrvs": {},
|
"inputs": {
|
||||||
"inputSrcs": [],
|
"drvs": {},
|
||||||
|
"srcs": []
|
||||||
|
},
|
||||||
"name": "advanced-attributes-structured-attrs-defaults",
|
"name": "advanced-attributes-structured-attrs-defaults",
|
||||||
"outputs": {
|
"outputs": {
|
||||||
"dev": {
|
"dev": {
|
||||||
|
|
@ -29,5 +31,5 @@
|
||||||
"system": "my-system"
|
"system": "my-system"
|
||||||
},
|
},
|
||||||
"system": "my-system",
|
"system": "my-system",
|
||||||
"version": 3
|
"version": 4
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,25 +9,27 @@
|
||||||
"dev": "/nix/store/wyfgwsdi8rs851wmy1xfzdxy7y5vrg5l-advanced-attributes-structured-attrs-dev",
|
"dev": "/nix/store/wyfgwsdi8rs851wmy1xfzdxy7y5vrg5l-advanced-attributes-structured-attrs-dev",
|
||||||
"out": "/nix/store/7cxy4zx1vqc885r4jl2l64pymqbdmhii-advanced-attributes-structured-attrs"
|
"out": "/nix/store/7cxy4zx1vqc885r4jl2l64pymqbdmhii-advanced-attributes-structured-attrs"
|
||||||
},
|
},
|
||||||
"inputDrvs": {
|
"inputs": {
|
||||||
"afc3vbjbzql750v2lp8gxgaxsajphzih-foo.drv": {
|
"drvs": {
|
||||||
"dynamicOutputs": {},
|
"afc3vbjbzql750v2lp8gxgaxsajphzih-foo.drv": {
|
||||||
"outputs": [
|
"dynamicOutputs": {},
|
||||||
"dev",
|
"outputs": [
|
||||||
"out"
|
"dev",
|
||||||
]
|
"out"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv": {
|
||||||
|
"dynamicOutputs": {},
|
||||||
|
"outputs": [
|
||||||
|
"dev",
|
||||||
|
"out"
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv": {
|
"srcs": [
|
||||||
"dynamicOutputs": {},
|
"vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv"
|
||||||
"outputs": [
|
]
|
||||||
"dev",
|
|
||||||
"out"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"inputSrcs": [
|
|
||||||
"vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv"
|
|
||||||
],
|
|
||||||
"name": "advanced-attributes-structured-attrs",
|
"name": "advanced-attributes-structured-attrs",
|
||||||
"outputs": {
|
"outputs": {
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -96,5 +98,5 @@
|
||||||
"system": "my-system"
|
"system": "my-system"
|
||||||
},
|
},
|
||||||
"system": "my-system",
|
"system": "my-system",
|
||||||
"version": 3
|
"version": 4
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,25 +23,27 @@
|
||||||
"requiredSystemFeatures": "rainbow uid-range",
|
"requiredSystemFeatures": "rainbow uid-range",
|
||||||
"system": "my-system"
|
"system": "my-system"
|
||||||
},
|
},
|
||||||
"inputDrvs": {
|
"inputs": {
|
||||||
"afc3vbjbzql750v2lp8gxgaxsajphzih-foo.drv": {
|
"drvs": {
|
||||||
"dynamicOutputs": {},
|
"afc3vbjbzql750v2lp8gxgaxsajphzih-foo.drv": {
|
||||||
"outputs": [
|
"dynamicOutputs": {},
|
||||||
"dev",
|
"outputs": [
|
||||||
"out"
|
"dev",
|
||||||
]
|
"out"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv": {
|
||||||
|
"dynamicOutputs": {},
|
||||||
|
"outputs": [
|
||||||
|
"dev",
|
||||||
|
"out"
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv": {
|
"srcs": [
|
||||||
"dynamicOutputs": {},
|
"vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv"
|
||||||
"outputs": [
|
]
|
||||||
"dev",
|
|
||||||
"out"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"inputSrcs": [
|
|
||||||
"vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv"
|
|
||||||
],
|
|
||||||
"name": "advanced-attributes",
|
"name": "advanced-attributes",
|
||||||
"outputs": {
|
"outputs": {
|
||||||
"out": {
|
"out": {
|
||||||
|
|
@ -49,5 +51,5 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"system": "my-system",
|
"system": "my-system",
|
||||||
"version": 3
|
"version": 4
|
||||||
}
|
}
|
||||||
|
|
|
||||||
46
src/libstore-tests/data/derivation/ia/all_set.json
Normal file
46
src/libstore-tests/data/derivation/ia/all_set.json
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
{
|
||||||
|
"additionalSandboxProfile": "sandcastle",
|
||||||
|
"allowLocalNetworking": true,
|
||||||
|
"allowSubstitutes": false,
|
||||||
|
"exportReferencesGraph": {
|
||||||
|
"refs1": [
|
||||||
|
"/nix/store/p0hax2lzvjpfc2gwkk62xdglz0fcqfzn-foo"
|
||||||
|
],
|
||||||
|
"refs2": [
|
||||||
|
"/nix/store/vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"impureEnvVars": [
|
||||||
|
"UNICORN"
|
||||||
|
],
|
||||||
|
"impureHostDeps": [
|
||||||
|
"/usr/bin/ditto"
|
||||||
|
],
|
||||||
|
"noChroot": true,
|
||||||
|
"outputChecks": {
|
||||||
|
"forAllOutputs": {
|
||||||
|
"allowedReferences": [
|
||||||
|
"/nix/store/p0hax2lzvjpfc2gwkk62xdglz0fcqfzn-foo"
|
||||||
|
],
|
||||||
|
"allowedRequisites": [
|
||||||
|
"/nix/store/z0rjzy29v9k5qa4nqpykrbzirj7sd43v-foo-dev"
|
||||||
|
],
|
||||||
|
"disallowedReferences": [
|
||||||
|
"/nix/store/r5cff30838majxk5mp3ip2diffi8vpaj-bar"
|
||||||
|
],
|
||||||
|
"disallowedRequisites": [
|
||||||
|
"/nix/store/9b61w26b4avv870dw0ymb6rw4r1hzpws-bar-dev"
|
||||||
|
],
|
||||||
|
"ignoreSelfRefs": true,
|
||||||
|
"maxClosureSize": null,
|
||||||
|
"maxSize": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"passAsFile": [],
|
||||||
|
"preferLocalBuild": true,
|
||||||
|
"requiredSystemFeatures": [
|
||||||
|
"rainbow",
|
||||||
|
"uid-range"
|
||||||
|
],
|
||||||
|
"unsafeDiscardReferences": {}
|
||||||
|
}
|
||||||
24
src/libstore-tests/data/derivation/ia/defaults.json
Normal file
24
src/libstore-tests/data/derivation/ia/defaults.json
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"additionalSandboxProfile": "",
|
||||||
|
"allowLocalNetworking": false,
|
||||||
|
"allowSubstitutes": true,
|
||||||
|
"exportReferencesGraph": {},
|
||||||
|
"impureEnvVars": [],
|
||||||
|
"impureHostDeps": [],
|
||||||
|
"noChroot": false,
|
||||||
|
"outputChecks": {
|
||||||
|
"forAllOutputs": {
|
||||||
|
"allowedReferences": null,
|
||||||
|
"allowedRequisites": null,
|
||||||
|
"disallowedReferences": [],
|
||||||
|
"disallowedRequisites": [],
|
||||||
|
"ignoreSelfRefs": true,
|
||||||
|
"maxClosureSize": null,
|
||||||
|
"maxSize": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"passAsFile": [],
|
||||||
|
"preferLocalBuild": false,
|
||||||
|
"requiredSystemFeatures": [],
|
||||||
|
"unsafeDiscardReferences": {}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
{
|
||||||
|
"additionalSandboxProfile": "sandcastle",
|
||||||
|
"allowLocalNetworking": true,
|
||||||
|
"allowSubstitutes": false,
|
||||||
|
"exportReferencesGraph": {
|
||||||
|
"refs1": [
|
||||||
|
"/nix/store/p0hax2lzvjpfc2gwkk62xdglz0fcqfzn-foo"
|
||||||
|
],
|
||||||
|
"refs2": [
|
||||||
|
"/nix/store/vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"impureEnvVars": [
|
||||||
|
"UNICORN"
|
||||||
|
],
|
||||||
|
"impureHostDeps": [
|
||||||
|
"/usr/bin/ditto"
|
||||||
|
],
|
||||||
|
"noChroot": true,
|
||||||
|
"outputChecks": {
|
||||||
|
"perOutput": {
|
||||||
|
"bin": {
|
||||||
|
"allowedReferences": null,
|
||||||
|
"allowedRequisites": null,
|
||||||
|
"disallowedReferences": [
|
||||||
|
"/nix/store/r5cff30838majxk5mp3ip2diffi8vpaj-bar"
|
||||||
|
],
|
||||||
|
"disallowedRequisites": [
|
||||||
|
"/nix/store/9b61w26b4avv870dw0ymb6rw4r1hzpws-bar-dev"
|
||||||
|
],
|
||||||
|
"ignoreSelfRefs": false,
|
||||||
|
"maxClosureSize": null,
|
||||||
|
"maxSize": null
|
||||||
|
},
|
||||||
|
"dev": {
|
||||||
|
"allowedReferences": null,
|
||||||
|
"allowedRequisites": null,
|
||||||
|
"disallowedReferences": [],
|
||||||
|
"disallowedRequisites": [],
|
||||||
|
"ignoreSelfRefs": false,
|
||||||
|
"maxClosureSize": 5909,
|
||||||
|
"maxSize": 789
|
||||||
|
},
|
||||||
|
"out": {
|
||||||
|
"allowedReferences": [
|
||||||
|
"/nix/store/p0hax2lzvjpfc2gwkk62xdglz0fcqfzn-foo"
|
||||||
|
],
|
||||||
|
"allowedRequisites": [
|
||||||
|
"/nix/store/z0rjzy29v9k5qa4nqpykrbzirj7sd43v-foo-dev"
|
||||||
|
],
|
||||||
|
"disallowedReferences": [],
|
||||||
|
"disallowedRequisites": [],
|
||||||
|
"ignoreSelfRefs": false,
|
||||||
|
"maxClosureSize": null,
|
||||||
|
"maxSize": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"passAsFile": [],
|
||||||
|
"preferLocalBuild": true,
|
||||||
|
"requiredSystemFeatures": [
|
||||||
|
"rainbow",
|
||||||
|
"uid-range"
|
||||||
|
],
|
||||||
|
"unsafeDiscardReferences": {}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"additionalSandboxProfile": "",
|
||||||
|
"allowLocalNetworking": false,
|
||||||
|
"allowSubstitutes": true,
|
||||||
|
"exportReferencesGraph": {},
|
||||||
|
"impureEnvVars": [],
|
||||||
|
"impureHostDeps": [],
|
||||||
|
"noChroot": false,
|
||||||
|
"outputChecks": {
|
||||||
|
"perOutput": {}
|
||||||
|
},
|
||||||
|
"passAsFile": [],
|
||||||
|
"preferLocalBuild": false,
|
||||||
|
"requiredSystemFeatures": [],
|
||||||
|
"unsafeDiscardReferences": {}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
{
|
{
|
||||||
"hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f",
|
"hash": {
|
||||||
"hashAlgo": "sha256",
|
"algorithm": "sha256",
|
||||||
|
"format": "base64",
|
||||||
|
"hash": "iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="
|
||||||
|
},
|
||||||
"method": "flat"
|
"method": "flat"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
{
|
{
|
||||||
"hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f",
|
"hash": {
|
||||||
"hashAlgo": "sha256",
|
"algorithm": "sha256",
|
||||||
|
"format": "base64",
|
||||||
|
"hash": "iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="
|
||||||
|
},
|
||||||
"method": "nar"
|
"method": "nar"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
{
|
{
|
||||||
"hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f",
|
"hash": {
|
||||||
"hashAlgo": "sha256",
|
"algorithm": "sha256",
|
||||||
|
"format": "base64",
|
||||||
|
"hash": "iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="
|
||||||
|
},
|
||||||
"method": "text"
|
"method": "text"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,20 +7,22 @@
|
||||||
"env": {
|
"env": {
|
||||||
"BIG_BAD": "WOLF"
|
"BIG_BAD": "WOLF"
|
||||||
},
|
},
|
||||||
"inputDrvs": {
|
"inputs": {
|
||||||
"c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv": {
|
"drvs": {
|
||||||
"dynamicOutputs": {},
|
"c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv": {
|
||||||
"outputs": [
|
"dynamicOutputs": {},
|
||||||
"cat",
|
"outputs": [
|
||||||
"dog"
|
"cat",
|
||||||
]
|
"dog"
|
||||||
}
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"srcs": [
|
||||||
|
"c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"inputSrcs": [
|
|
||||||
"c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"
|
|
||||||
],
|
|
||||||
"name": "simple-derivation",
|
"name": "simple-derivation",
|
||||||
"outputs": {},
|
"outputs": {},
|
||||||
"system": "wasm-sel4",
|
"system": "wasm-sel4",
|
||||||
"version": 3
|
"version": 4
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,12 @@
|
||||||
{
|
{
|
||||||
"ca": "fixed:r:sha256:1lr187v6dck1rjh2j6svpikcfz53wyl3qrlcbb405zlh13x0khhh",
|
"ca": {
|
||||||
|
"hash": {
|
||||||
|
"algorithm": "sha256",
|
||||||
|
"format": "base64",
|
||||||
|
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM="
|
||||||
|
},
|
||||||
|
"method": "nar"
|
||||||
|
},
|
||||||
"compression": "xz",
|
"compression": "xz",
|
||||||
"deriver": "/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
"deriver": "/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
||||||
"downloadHash": "sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=",
|
"downloadHash": "sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=",
|
||||||
|
|
@ -16,5 +23,6 @@
|
||||||
"qwer"
|
"qwer"
|
||||||
],
|
],
|
||||||
"ultimate": true,
|
"ultimate": true,
|
||||||
"url": "nar/1w1fff338fvdw53sqgamddn1b2xgds473pv6y13gizdbqjv4i5p3.nar.xz"
|
"url": "nar/1w1fff338fvdw53sqgamddn1b2xgds473pv6y13gizdbqjv4i5p3.nar.xz",
|
||||||
|
"version": 2
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,17 @@
|
||||||
{
|
{
|
||||||
"ca": "fixed:r:sha256:1lr187v6dck1rjh2j6svpikcfz53wyl3qrlcbb405zlh13x0khhh",
|
"ca": {
|
||||||
|
"hash": {
|
||||||
|
"algorithm": "sha256",
|
||||||
|
"format": "base64",
|
||||||
|
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM="
|
||||||
|
},
|
||||||
|
"method": "nar"
|
||||||
|
},
|
||||||
"narHash": "sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=",
|
"narHash": "sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=",
|
||||||
"narSize": 34878,
|
"narSize": 34878,
|
||||||
"references": [
|
"references": [
|
||||||
"/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
"/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
||||||
"/nix/store/n5wkd9frr45pa74if5gpz9j7mifg27fh-foo"
|
"/nix/store/n5wkd9frr45pa74if5gpz9j7mifg27fh-foo"
|
||||||
]
|
],
|
||||||
|
"version": 2
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,5 +6,6 @@
|
||||||
"references": [],
|
"references": [],
|
||||||
"registrationTime": null,
|
"registrationTime": null,
|
||||||
"signatures": [],
|
"signatures": [],
|
||||||
"ultimate": false
|
"ultimate": false,
|
||||||
|
"version": 2
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,6 @@
|
||||||
"ca": null,
|
"ca": null,
|
||||||
"narHash": "sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=",
|
"narHash": "sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=",
|
||||||
"narSize": 0,
|
"narSize": 0,
|
||||||
"references": []
|
"references": [],
|
||||||
|
"version": 2
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,12 @@
|
||||||
{
|
{
|
||||||
"ca": "fixed:r:sha256:1lr187v6dck1rjh2j6svpikcfz53wyl3qrlcbb405zlh13x0khhh",
|
"ca": {
|
||||||
|
"hash": {
|
||||||
|
"algorithm": "sha256",
|
||||||
|
"format": "base64",
|
||||||
|
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM="
|
||||||
|
},
|
||||||
|
"method": "nar"
|
||||||
|
},
|
||||||
"deriver": "/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
"deriver": "/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
||||||
"narHash": "sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=",
|
"narHash": "sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=",
|
||||||
"narSize": 34878,
|
"narSize": 34878,
|
||||||
|
|
@ -12,5 +19,6 @@
|
||||||
"asdf",
|
"asdf",
|
||||||
"qwer"
|
"qwer"
|
||||||
],
|
],
|
||||||
"ultimate": true
|
"ultimate": true,
|
||||||
|
"version": 2
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,17 @@
|
||||||
{
|
{
|
||||||
"ca": "fixed:r:sha256:1lr187v6dck1rjh2j6svpikcfz53wyl3qrlcbb405zlh13x0khhh",
|
"ca": {
|
||||||
|
"hash": {
|
||||||
|
"algorithm": "sha256",
|
||||||
|
"format": "base64",
|
||||||
|
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM="
|
||||||
|
},
|
||||||
|
"method": "nar"
|
||||||
|
},
|
||||||
"narHash": "sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=",
|
"narHash": "sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=",
|
||||||
"narSize": 34878,
|
"narSize": 34878,
|
||||||
"references": [
|
"references": [
|
||||||
"/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
"/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
||||||
"/nix/store/n5wkd9frr45pa74if5gpz9j7mifg27fh-foo"
|
"/nix/store/n5wkd9frr45pa74if5gpz9j7mifg27fh-foo"
|
||||||
]
|
],
|
||||||
|
"version": 2
|
||||||
}
|
}
|
||||||
|
|
|
||||||
BIN
src/libstore-tests/data/serve-protocol/realisation-with-deps.bin
Normal file
BIN
src/libstore-tests/data/serve-protocol/realisation-with-deps.bin
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue