mirror of
https://github.com/NixOS/nix.git
synced 2025-11-08 11:36:03 +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 |
136 changed files with 2254 additions and 855 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, Value::StringWithContext::Context 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 (Value::StringWithContext::Context 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 Value::StringWithContext::Context 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 = (Value::StringWithContext::Context) 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 Value::StringWithContext::Context encodeContext(const NixStringContext &
|
||||||
|
|
||||||
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 (Value::StringWithContext::Context 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,18 +220,55 @@ struct ValueBase
|
||||||
struct StringWithContext
|
struct StringWithContext
|
||||||
{
|
{
|
||||||
const char * c_str;
|
const char * c_str;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the context itself.
|
* The type of the context itself.
|
||||||
*
|
*
|
||||||
* Currently, it is pointer to an array of pointers to strings.
|
* Currently, it is length-prefixed array of pointers to
|
||||||
* The strings are specially formatted to represent a flattening
|
* null-terminated strings. The strings are specially formatted
|
||||||
* of the recursive sum type that is s context element.
|
* to represent a flattening of the recursive sum type that is a
|
||||||
|
* context element.
|
||||||
*
|
*
|
||||||
* @See NixStringContext for an more easily understood type,
|
* @See NixStringContext for an more easily understood type,
|
||||||
* that of the "builder" for this data structure.
|
* that of the "builder" for this data structure.
|
||||||
*/
|
*/
|
||||||
using Context = const char **;
|
struct Context
|
||||||
Context context; // must be in sorted order
|
{
|
||||||
|
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
|
||||||
|
|
@ -1002,7 +1039,7 @@ public:
|
||||||
setStorage(b);
|
setStorage(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mkStringNoCopy(const char * s, Value::StringWithContext::Context 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});
|
||||||
}
|
}
|
||||||
|
|
@ -1128,7 +1165,7 @@ public:
|
||||||
return getStorage<StringWithContext>().c_str;
|
return getStorage<StringWithContext>().c_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value::StringWithContext::Context context() const noexcept
|
const Value::StringWithContext::Context * context() const noexcept
|
||||||
{
|
{
|
||||||
return getStorage<StringWithContext>().context;
|
return getStorage<StringWithContext>().context;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.
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