Skip to content

Commit 20226c8

Browse files
authored
Merge pull request #13273 from NixOS/deprecate-structured-attrs-hack
Deprecate hacky way of making structured attrs
2 parents 5e9744c + 7577d2d commit 20226c8

File tree

5 files changed

+26
-1
lines changed

5 files changed

+26
-1
lines changed

doc/manual/rl-next/deprecate__json.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
synopsis: Deprecate manually making structured attrs with `__json = ...;`
3+
prs: [13220]
4+
---
5+
6+
The proper way to create a derivation using [structured attrs] in the Nix language is by using `__structuredAttrs = true` with [`builtins.derivation`].
7+
However, by exploiting how structured attrs are implementated, it has also been possible to create them by setting the `__json` environment variable to a serialized JSON string.
8+
This sneaky alternative method is now deprecated, and may be disallowed in future versions of Nix.
9+
10+
[structured attrs]: @docroot@/language/advanced-attributes.md#adv-attr-structuredAttrs
11+
[`builtins.derivation`]: @docroot@/language/builtins.html#builtins-derivation

src/libexpr/eval.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ EvalState::EvalState(
212212
, sRight(symbols.create("right"))
213213
, sWrong(symbols.create("wrong"))
214214
, sStructuredAttrs(symbols.create("__structuredAttrs"))
215+
, sJson(symbols.create("__json"))
215216
, sAllowedReferences(symbols.create("allowedReferences"))
216217
, sAllowedRequisites(symbols.create("allowedRequisites"))
217218
, sDisallowedReferences(symbols.create("disallowedReferences"))

src/libexpr/include/nix/expr/eval.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ public:
213213
const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, sValue,
214214
sSystem, sOverrides, sOutputs, sOutputName, sIgnoreNulls,
215215
sFile, sLine, sColumn, sFunctor, sToString,
216-
sRight, sWrong, sStructuredAttrs,
216+
sRight, sWrong, sStructuredAttrs, sJson,
217217
sAllowedReferences, sAllowedRequisites, sDisallowedReferences, sDisallowedRequisites,
218218
sMaxSize, sMaxClosureSize,
219219
sBuilder, sArgs,

src/libexpr/primops.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,6 +1427,8 @@ static void derivationStrictInternal(
14271427
else if (i->name == state.sOutputHashMode) handleHashMode(s);
14281428
else if (i->name == state.sOutputs)
14291429
handleOutputs(tokenizeString<Strings>(s));
1430+
else if (i->name == state.sJson)
1431+
warn("In derivation '%s': setting structured attributes via '__json' is deprecated, and may be disallowed in future versions of Nix. Set '__structuredAttrs = true' instead.", drvName);
14301432
}
14311433

14321434
}

tests/functional/structured-attrs.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,14 @@ jsonOut="$(nix print-dev-env -f structured-attrs-shell.nix --json)"
4040
test "$(<<<"$jsonOut" jq '.structuredAttrs|keys|.[]' -r)" = "$(printf ".attrs.json\n.attrs.sh")"
4141

4242
test "$(<<<"$jsonOut" jq '.variables.outputs.value.out' -r)" = "$(<<<"$jsonOut" jq '.structuredAttrs.".attrs.json"' -r | jq -r '.outputs.out')"
43+
44+
# Hacky way of making structured attrs. We should preserve for now for back compat, but also deprecate.
45+
46+
hackyExpr='derivation { name = "a"; system = "foo"; builder = "/bin/sh"; __json = builtins.toJSON { a = 1; }; }'
47+
48+
# Check for deprecation message
49+
expectStderr 0 nix-instantiate --expr "$hackyExpr" --eval --strict | grepQuiet "In derivation 'a': setting structured attributes via '__json' is deprecated, and may be disallowed in future versions of Nix. Set '__structuredAttrs = true' instead."
50+
51+
# Check it works with the expected structured attrs
52+
hacky=$(nix-instantiate --expr "$hackyExpr")
53+
nix derivation show "$hacky" | jq --exit-status '."'"$hacky"'".env.__json | fromjson | . == {"a": 1}'

0 commit comments

Comments
 (0)