tvix: implement __structuredAttrs
Similar to how tvix-glue's derivation_to_build_request now takes care of passAsFile, structured attrs modifies the build environment.
If __structuredAttrs is set to true, a .attrs.sh and .attrs.json file is created in the /build directory (and NIX_ATTRS_JSON_FILE and NIX_ATTRS_SH_FILE point to the paths).
See https://nixos.org/manual/nix/stable/language/advanced-attributes#adv-attr-structuredAttrs for docs.
https://github.com/NixOS/nixpkgs/pull/234883 also suggests Nix 2.3 did set ATTRS_JSON_FILE and ATTRS_SH_FILE(only) at some point.
My opinion is we should use the new env var in Tvix, backport the Nix fix to 2.3 too, so we can drop the workaround in nixpkgs/pkgs/stdenv/generic/setup.sh.
In terms of nixpkgs cleanups, we should also figure out why there's a ton of references to the .attrs.sh path itself, rather than reading NIX_ATTRS_SH_FILE. Maybe all this code can be dropped in Nixpkgs.
It's not entirely clear yet if and how __structuredAttrs affects the ATerm serialization / the contents of the Derivation struct. Maybe some of the JSON serialization code needs to live in builtins.derivationStrict instead - to be investigated.
There's also two fields getting new meanings in case __structuredAttrs is used - outputChecks and unsafeDiscardReferences
- flokli updated the body of this issue at 2024-01-03T16·43+00
nixpkgs/pkgs/test/stdenv/default.nixhas some tests, we should peek at them to see if the behaviour is correct.flokli at 2024-01-03T17·12+00
cl/10604 implements the __structuredAttrs feature, at least as far as "populating the Derivation struct" is concerned.
flokli at 2024-01-11T20·11+00
There's still some open questions around string contexts inside the structured attributes themselves, a TODO for that is left in the code.
flokli at 2024-01-12T22·10+00
Apparently,
builtins.toJsonnormally does propagate context, and we currently don't do that either - so we can't add it yet.So far we kept string contexts a somewhat private field of
NixString, but we don't return aNixStringforValue::into_json, but aserde_json::Value(which isn't necessarily a string at all).Adding contexts to all
tvix_eval::Valuewould be annoying memory-wise.Manually dealing with context, forcing once, then traversing to collect all contexts on all
NixStringkinds, then another time to serialize to JSON would also suck.Probably a way out would be to have some opaque "SerdeValueWithContext", that can be easily "downcasted" to a context-free version.
flokli at 2024-01-12T22·47+00