1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-08 19:46:02 +01:00

Merge pull request #14493 from obsidiansystems/drv-and-path-info-new-fmts

Modifications to the JSON formats for `Derivation` and `ValidPathInfo`
This commit is contained in:
John Ericson 2025-11-06 21:09:27 +00:00 committed by GitHub
commit 5b15544bdd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 475 additions and 287 deletions

View 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.

View file

@ -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)
--> -->

View file

@ -12,8 +12,8 @@ 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-trace-entry-v1',
'build-result-v1', 'build-result-v1',

View file

@ -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 derivations outputs. Used when calculating store paths for the derivations 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:

View file

@ -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" }

View file

@ -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)
--> -->

View file

@ -70,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',
@ -78,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',
@ -92,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',
@ -108,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',
], ],
@ -134,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',
@ -144,7 +144,7 @@ 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',
@ -162,7 +162,7 @@ schemas += [
# 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',
@ -170,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',
@ -178,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',
], ],

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -1,5 +1,8 @@
{ {
"hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f", "hash": {
"hashAlgo": "sha256", "algorithm": "sha256",
"format": "base64",
"hash": "iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="
},
"method": "flat" "method": "flat"
} }

View file

@ -1,5 +1,8 @@
{ {
"hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f", "hash": {
"hashAlgo": "sha256", "algorithm": "sha256",
"format": "base64",
"hash": "iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="
},
"method": "nar" "method": "nar"
} }

View file

@ -1,5 +1,8 @@
{ {
"hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f", "hash": {
"hashAlgo": "sha256", "algorithm": "sha256",
"format": "base64",
"hash": "iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="
},
"method": "text" "method": "text"
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -6,5 +6,6 @@
"references": [], "references": [],
"registrationTime": null, "registrationTime": null,
"signatures": [], "signatures": [],
"ultimate": false "ultimate": false,
"version": 2
} }

View file

@ -2,5 +2,6 @@
"ca": null, "ca": null,
"narHash": "sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=", "narHash": "sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=",
"narSize": 0, "narSize": 0,
"references": [] "references": [],
"version": 2
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -636,7 +636,7 @@ TEST_F(NixApiStoreTestWithRealisedPath, nix_store_realise_output_ordering)
auto outj_ph = nix::hashPlaceholder("outj"); auto outj_ph = nix::hashPlaceholder("outj");
std::string drvJson = R"({ std::string drvJson = R"({
"version": 3, "version": 4,
"name": "multi-output-test", "name": "multi-output-test",
"system": ")" + nix::settings.thisSystem.get() "system": ")" + nix::settings.thisSystem.get()
+ R"(", + R"(",
@ -668,8 +668,10 @@ TEST_F(NixApiStoreTestWithRealisedPath, nix_store_realise_output_ordering)
"outa": ")" + outa_ph "outa": ")" + outa_ph
+ R"(" + R"("
}, },
"inputDrvs": {}, "inputs": {
"inputSrcs": [], "drvs": {},
"srcs": []
},
"outputs": { "outputs": {
"outd": { "hashAlgo": "sha256", "method": "nar" }, "outd": { "hashAlgo": "sha256", "method": "nar" },
"outf": { "hashAlgo": "sha256", "method": "nar" }, "outf": { "hashAlgo": "sha256", "method": "nar" },

View file

@ -1293,15 +1293,13 @@ void adl_serializer<DerivationOutput>::to_json(json & res, const DerivationOutpu
overloaded{ overloaded{
[&](const DerivationOutput::InputAddressed & doi) { res["path"] = doi.path; }, [&](const DerivationOutput::InputAddressed & doi) { res["path"] = doi.path; },
[&](const DerivationOutput::CAFixed & dof) { [&](const DerivationOutput::CAFixed & dof) {
/* it would be nice to output the path for user convenience, but res = dof.ca;
this would require us to know the store dir. */ // FIXME print refs?
/* it would be nice to output the path for user convenience, but
this would require us to know the store dir. */
#if 0 #if 0
res["path"] = dof.path(store, drvName, outputName); res["path"] = dof.path(store, drvName, outputName);
#endif #endif
res["method"] = std::string{dof.ca.method.render()};
res["hashAlgo"] = printHashAlgo(dof.ca.hash.algo);
res["hash"] = dof.ca.hash.to_string(HashFormat::Base16, false);
// FIXME print refs?
}, },
[&](const DerivationOutput::CAFloating & dof) { [&](const DerivationOutput::CAFloating & dof) {
res["method"] = std::string{dof.method.render()}; res["method"] = std::string{dof.method.render()};
@ -1341,15 +1339,12 @@ adl_serializer<DerivationOutput>::from_json(const json & _json, const Experiment
}; };
} }
else if (keys == (std::set<std::string_view>{"method", "hashAlgo", "hash"})) { else if (keys == (std::set<std::string_view>{"method", "hash"})) {
auto [method, hashAlgo] = methodAlgo();
auto dof = DerivationOutput::CAFixed{ auto dof = DerivationOutput::CAFixed{
.ca = .ca = static_cast<ContentAddress>(_json),
ContentAddress{
.method = std::move(method),
.hash = Hash::parseNonSRIUnprefixed(getString(valueAt(json, "hash")), hashAlgo),
},
}; };
if (dof.ca.method == ContentAddressMethod::Raw::Text)
xpSettings.require(Xp::DynamicDerivations, "text-hashed derivation output in JSON");
/* We no longer produce this (denormalized) field (for the /* We no longer produce this (denormalized) field (for the
reasons described above), so we don't need to check it. */ reasons described above), so we don't need to check it. */
#if 0 #if 0
@ -1392,7 +1387,7 @@ void adl_serializer<Derivation>::to_json(json & res, const Derivation & d)
res["name"] = d.name; res["name"] = d.name;
res["version"] = 3; res["version"] = 4;
{ {
nlohmann::json & outputsObj = res["outputs"]; nlohmann::json & outputsObj = res["outputs"];
@ -1403,13 +1398,16 @@ void adl_serializer<Derivation>::to_json(json & res, const Derivation & d)
} }
{ {
auto & inputsList = res["inputSrcs"]; auto & inputsObj = res["inputs"];
inputsList = nlohmann::json::array(); inputsObj = nlohmann::json::object();
for (auto & input : d.inputSrcs)
inputsList.emplace_back(input); {
} auto & inputsList = inputsObj["srcs"];
inputsList = nlohmann::json::array();
for (auto & input : d.inputSrcs)
inputsList.emplace_back(input);
}
{
auto doInput = [&](this const auto & doInput, const auto & inputNode) -> nlohmann::json { auto doInput = [&](this const auto & doInput, const auto & inputNode) -> nlohmann::json {
auto value = nlohmann::json::object(); auto value = nlohmann::json::object();
value["outputs"] = inputNode.value; value["outputs"] = inputNode.value;
@ -1421,12 +1419,11 @@ void adl_serializer<Derivation>::to_json(json & res, const Derivation & d)
} }
return value; return value;
}; };
{
auto & inputDrvsObj = res["inputDrvs"]; auto & inputDrvsObj = inputsObj["drvs"];
inputDrvsObj = nlohmann::json::object(); inputDrvsObj = nlohmann::json::object();
for (auto & [inputDrv, inputNode] : d.inputDrvs.map) { for (auto & [inputDrv, inputNode] : d.inputDrvs.map) {
inputDrvsObj[inputDrv.to_string()] = doInput(inputNode); inputDrvsObj[inputDrv.to_string()] = doInput(inputNode);
}
} }
} }
@ -1449,8 +1446,8 @@ Derivation adl_serializer<Derivation>::from_json(const json & _json, const Exper
res.name = getString(valueAt(json, "name")); res.name = getString(valueAt(json, "name"));
if (valueAt(json, "version") != 3) if (valueAt(json, "version") != 4)
throw Error("Only derivation format version 3 is currently supported."); throw Error("Only derivation format version 4 is currently supported.");
try { try {
auto outputs = getObject(valueAt(json, "outputs")); auto outputs = getObject(valueAt(json, "outputs"));
@ -1463,32 +1460,39 @@ Derivation adl_serializer<Derivation>::from_json(const json & _json, const Exper
} }
try { try {
auto inputSrcs = getArray(valueAt(json, "inputSrcs")); auto inputsObj = getObject(valueAt(json, "inputs"));
for (auto & input : inputSrcs)
res.inputSrcs.insert(input);
} catch (Error & e) {
e.addTrace({}, "while reading key 'inputSrcs'");
throw;
}
try { try {
auto doInput = [&](this const auto & doInput, const auto & _json) -> DerivedPathMap<StringSet>::ChildNode { auto inputSrcs = getArray(valueAt(inputsObj, "srcs"));
auto & json = getObject(_json); for (auto & input : inputSrcs)
DerivedPathMap<StringSet>::ChildNode node; res.inputSrcs.insert(input);
node.value = getStringSet(valueAt(json, "outputs")); } catch (Error & e) {
auto drvs = getObject(valueAt(json, "dynamicOutputs")); e.addTrace({}, "while reading key 'srcs'");
for (auto & [outputId, childNode] : drvs) { throw;
xpSettings.require( }
Xp::DynamicDerivations, [&] { return fmt("dynamic output '%s' in JSON", outputId); });
node.childMap[outputId] = doInput(childNode); try {
} auto doInput = [&](this const auto & doInput, const auto & _json) -> DerivedPathMap<StringSet>::ChildNode {
return node; auto & json = getObject(_json);
}; DerivedPathMap<StringSet>::ChildNode node;
auto drvs = getObject(valueAt(json, "inputDrvs")); node.value = getStringSet(valueAt(json, "outputs"));
for (auto & [inputDrvPath, inputOutputs] : drvs) auto drvs = getObject(valueAt(json, "dynamicOutputs"));
res.inputDrvs.map[StorePath{inputDrvPath}] = doInput(inputOutputs); for (auto & [outputId, childNode] : drvs) {
xpSettings.require(
Xp::DynamicDerivations, [&] { return fmt("dynamic output '%s' in JSON", outputId); });
node.childMap[outputId] = doInput(childNode);
}
return node;
};
auto drvs = getObject(valueAt(inputsObj, "drvs"));
for (auto & [inputDrvPath, inputOutputs] : drvs)
res.inputDrvs.map[StorePath{inputDrvPath}] = doInput(inputOutputs);
} catch (Error & e) {
e.addTrace({}, "while reading key 'drvs'");
throw;
}
} catch (Error & e) { } catch (Error & e) {
e.addTrace({}, "while reading key 'inputDrvs'"); e.addTrace({}, "while reading key 'inputs'");
throw; throw;
} }

View file

@ -156,6 +156,8 @@ UnkeyedValidPathInfo::toJSON(const StoreDirConfig & store, bool includeImpureInf
auto jsonObject = json::object(); auto jsonObject = json::object();
jsonObject["version"] = 2;
jsonObject["narHash"] = narHash.to_string(hashFormat, true); jsonObject["narHash"] = narHash.to_string(hashFormat, true);
jsonObject["narSize"] = narSize; jsonObject["narSize"] = narSize;
@ -165,7 +167,7 @@ UnkeyedValidPathInfo::toJSON(const StoreDirConfig & store, bool includeImpureInf
jsonRefs.emplace_back(store.printStorePath(ref)); jsonRefs.emplace_back(store.printStorePath(ref));
} }
jsonObject["ca"] = ca ? (std::optional{renderContentAddress(*ca)}) : std::nullopt; jsonObject["ca"] = ca;
if (includeImpureInfo) { if (includeImpureInfo) {
jsonObject["deriver"] = deriver ? (std::optional{store.printStorePath(*deriver)}) : std::nullopt; jsonObject["deriver"] = deriver ? (std::optional{store.printStorePath(*deriver)}) : std::nullopt;
@ -189,6 +191,16 @@ UnkeyedValidPathInfo UnkeyedValidPathInfo::fromJSON(const StoreDirConfig & store
}; };
auto & json = getObject(_json); auto & json = getObject(_json);
// Check version (optional for backward compatibility)
nlohmann::json::number_unsigned_t version = 1;
if (json.contains("version")) {
version = getUnsigned(valueAt(json, "version"));
if (version != 1 && version != 2) {
throw Error("Unsupported path info JSON format version %d, expected 1 through 2", version);
}
}
res.narHash = Hash::parseAny(getString(valueAt(json, "narHash")), std::nullopt); res.narHash = Hash::parseAny(getString(valueAt(json, "narHash")), std::nullopt);
res.narSize = getUnsigned(valueAt(json, "narSize")); res.narSize = getUnsigned(valueAt(json, "narSize"));
@ -205,7 +217,15 @@ UnkeyedValidPathInfo UnkeyedValidPathInfo::fromJSON(const StoreDirConfig & store
// missing is for back-compat. // missing is for back-compat.
if (auto * rawCa0 = optionalValueAt(json, "ca")) if (auto * rawCa0 = optionalValueAt(json, "ca"))
if (auto * rawCa = getNullable(*rawCa0)) if (auto * rawCa = getNullable(*rawCa0))
res.ca = ContentAddress::parse(getString(*rawCa)); switch (version) {
case 1:
// old string format also used in SQLite DB and .narinfo
res.ca = ContentAddress::parse(getString(*rawCa));
break;
case 2 ... std::numeric_limits<decltype(version)>::max():
res.ca = *rawCa;
break;
}
if (auto * rawDeriver0 = optionalValueAt(json, "deriver")) if (auto * rawDeriver0 = optionalValueAt(json, "deriver"))
if (auto * rawDeriver = getNullable(*rawDeriver0)) if (auto * rawDeriver = getNullable(*rawDeriver0))

View file

@ -51,10 +51,12 @@ builtins.outputOf
"$word": "hello, from $word!", "$word": "hello, from $word!",
"PATH": ${builtins.toJSON path} "PATH": ${builtins.toJSON path}
}, },
"inputDrvs": { "inputs": {
$inputDrvs "drvs": {
$inputDrvs
},
"srcs": []
}, },
"inputSrcs": [],
"name": "build-$word", "name": "build-$word",
"outputs": { "outputs": {
"out": { "out": {
@ -63,7 +65,7 @@ builtins.outputOf
} }
}, },
"system": "${system}", "system": "${system}",
"version": 3 "version": 4
} }
EOF EOF
drvPath=$(echo "$json" | nix derivation add) drvPath=$(echo "$json" | nix derivation add)

View file

@ -14,7 +14,16 @@ nix-build fixed.nix -A bad --no-out-link && fail "should fail"
# Building with the bad hash should produce the "good" output path as # Building with the bad hash should produce the "good" output path as
# a side-effect. # a side-effect.
[[ -e $path ]] [[ -e $path ]]
nix path-info --json "$path" | grep fixed:md5:2qk15sxzzjlnpjk9brn7j8ppcd nix path-info --json "$path" | jq -e \
--arg hash "$(nix hash convert --to base64 "md5:8ddd8be4b179a529afa5f2ffae4b9858")" \
'.[].ca == {
method: "flat",
hash: {
algorithm: "md5",
format: "base64",
hash: $hash
},
}'
echo 'testing good...' echo 'testing good...'
nix-build fixed.nix -A good --no-out-link nix-build fixed.nix -A good --no-out-link

View file

@ -47,9 +47,17 @@ try2 () {
hashFromGit=$(git -C "$repo" rev-parse "HEAD:$hashPath") hashFromGit=$(git -C "$repo" rev-parse "HEAD:$hashPath")
[[ "$hashFromGit" == "$expected" ]] [[ "$hashFromGit" == "$expected" ]]
local caFromNix nix path-info --json "$path" | jq -e \
caFromNix=$(nix path-info --json "$path" | jq -r ".[] | .ca") --arg algo "$hashAlgo" \
[[ "fixed:git:$hashAlgo:$(nix hash convert --to nix32 "$hashAlgo:$hashFromGit")" = "$caFromNix" ]] --arg hash "$(nix hash convert --to base64 "$hashAlgo:$hashFromGit")" \
'.[].ca == {
method: "git",
hash: {
algorithm: $algo,
format: "base64",
hash: $hash
},
}'
} }
test0 () { test0 () {

View file

@ -30,7 +30,7 @@ path1_stuff=$(echo "$json" | jq -r .[].outputs.stuff)
[[ $(< "$path1"/n) = 0 ]] [[ $(< "$path1"/n) = 0 ]]
[[ $(< "$path1_stuff"/bla) = 0 ]] [[ $(< "$path1_stuff"/bla) = 0 ]]
[[ $(nix path-info --json "$path1" | jq .[].ca) =~ fixed:r:sha256: ]] nix path-info --json "$path1" | jq -e '.[].ca | .method == "nar" and .hash.algorithm == "sha256"'
path2=$(nix build -L --no-link --json --file ./impure-derivations.nix impure | jq -r .[].outputs.out) path2=$(nix build -L --no-link --json --file ./impure-derivations.nix impure | jq -r .[].outputs.out)
[[ $(< "$path2"/n) = 1 ]] [[ $(< "$path2"/n) = 1 ]]

View file

@ -166,7 +166,7 @@ printf 4.0 > "$flake1Dir"/version
printf Utrecht > "$flake1Dir"/who printf Utrecht > "$flake1Dir"/who
nix profile add "$flake1Dir" nix profile add "$flake1Dir"
[[ $("$TEST_HOME"/.nix-profile/bin/hello) = "Hello Utrecht" ]] [[ $("$TEST_HOME"/.nix-profile/bin/hello) = "Hello Utrecht" ]]
[[ $(nix path-info --json "$(realpath "$TEST_HOME"/.nix-profile/bin/hello)" | jq -r .[].ca) =~ fixed:r:sha256: ]] nix path-info --json "$(realpath "$TEST_HOME"/.nix-profile/bin/hello)" | jq -e '.[].ca | .method == "nar" and .hash.algorithm == "sha256"'
# Override the outputs. # Override the outputs.
nix profile remove simple flake1 nix profile remove simple flake1

View file

@ -58,7 +58,7 @@ nix store verify -r "$outPath2" --sigs-needed 1 --trusted-public-keys "$pk1"
# Build something content-addressed. # Build something content-addressed.
outPathCA=$(IMPURE_VAR1=foo IMPURE_VAR2=bar nix-build ./fixed.nix -A good.0 --no-out-link) outPathCA=$(IMPURE_VAR1=foo IMPURE_VAR2=bar nix-build ./fixed.nix -A good.0 --no-out-link)
nix path-info --json "$outPathCA" | jq -e '.[] | .ca | startswith("fixed:md5:")' nix path-info --json "$outPathCA" | jq -e '.[].ca | .method == "flat" and .hash.algorithm == "md5"'
# Content-addressed paths don't need signatures, so they verify # Content-addressed paths don't need signatures, so they verify
# regardless of --sigs-needed. # regardless of --sigs-needed.