about summary refs log tree commit diff
path: root/src/libexpr/eval.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-01-25T15·42+0100
committerEelco Dolstra <edolstra@gmail.com>2017-01-26T19·40+0100
commit6de33a9c675b187437a2e1abbcb290981a89ecb1 (patch)
tree4626fd3ba81f16f27229abc4eaf61a8374a30f89 /src/libexpr/eval.cc
parent54801ed6ad4e0ea8faa67b0b4ba10debeb824d3b (diff)
Add support for passing structured data to builders
Previously, all derivation attributes had to be coerced into strings
so that they could be passed via the environment. This is lossy
(e.g. lists get flattened, necessitating configureFlags
vs. configureFlagsArray, of which the latter cannot be specified as an
attribute), doesn't support attribute sets at all, and has size
limitations (necessitating hacks like passAsFile).

This patch adds a new mode for passing attributes to builders, namely
encoded as a JSON file ".attrs.json" in the current directory of the
builder. This mode is activated via the special attribute

  __structuredAttrs = true;

(The idea is that one day we can set this in stdenv.mkDerivation.)

For example,

  stdenv.mkDerivation {
    __structuredAttrs = true;
    name = "foo";
    buildInputs = [ pkgs.hello pkgs.cowsay ];
    doCheck = true;
    hardening.format = false;
  }

results in a ".attrs.json" file containing (sans the indentation):

  {
    "buildInputs": [],
    "builder": "/nix/store/ygl61ycpr2vjqrx775l1r2mw1g2rb754-bash-4.3-p48/bin/bash",
    "configureFlags": [
      "--with-foo",
      "--with-bar=1 2"
    ],
    "doCheck": true,
    "hardening": {
      "format": false
    },
    "name": "foo",
    "nativeBuildInputs": [
      "/nix/store/10h6li26i7g6z3mdpvra09yyf10mmzdr-hello-2.10",
      "/nix/store/4jnvjin0r6wp6cv1hdm5jbkx3vinlcvk-cowsay-3.03"
    ],
    "propagatedBuildInputs": [],
    "propagatedNativeBuildInputs": [],
    "stdenv": "/nix/store/f3hw3p8armnzy6xhd4h8s7anfjrs15n2-stdenv",
    "system": "x86_64-linux"
  }

"passAsFile" is ignored in this mode because it's not needed - large
strings are included directly in the JSON representation.

It is up to the builder to do something with the JSON
representation. For example, in bash-based builders, lists/attrsets of
string values could be mapped to bash (associative) arrays.
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r--src/libexpr/eval.cc2
1 files changed, 2 insertions, 0 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 5f9f5bac1e..d418ab4e43 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -291,6 +291,8 @@ EvalState::EvalState(const Strings & _searchPath, ref<Store> store)
     , sToString(symbols.create("__toString"))
     , sRight(symbols.create("right"))
     , sWrong(symbols.create("wrong"))
+    , sStructuredAttrs(symbols.create("__structuredAttrs"))
+    , sBuilder(symbols.create("builder"))
     , store(store)
     , baseEnv(allocEnv(128))
     , staticBaseEnv(false, 0)