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

Change JSON derivation format in two ways

- Use canonical content address JSON format for floating content
  addressed derivation outputs

  This keeps it more consistent.

- Reorganize inputs into nested structure (`inputs.srcs` and
  `inputs.drvs`)

  This will allow for an easier to use, but less compact, alternative
  where `srcs` is just a list of derived paths.

  It also allows for other experiments for derivations with a different
  input structure, as I suspect will be needed for secure build traces.
This commit is contained in:
John Ericson 2025-10-13 00:24:12 -04:00
parent 147e183c68
commit 0c37a62207
21 changed files with 298 additions and 251 deletions

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

@ -13,7 +13,7 @@ schemas = [
'content-address-v1', 'content-address-v1',
'store-path-v1', 'store-path-v1',
'store-object-info-v1', 'store-object-info-v1',
'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

@ -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',
], ],

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

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

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