Commit 3000!

* Make the `derivation' primitive much more lazy.  The expression
  `derivation attrs' now evaluates to (essentially)

    attrs // {
      type = "derivation";
      outPath = derivation! attrs;
      drvPath = derivation! attrs;
    }

  where `derivation!' is a primop that does the actual derivation
  instantiation (i.e., it does what `derivation' used to do).  The
  advantage is that it allows commands such as `nix-env -qa' and
  `nix-env -i' to be much faster since they no longer need to
  instantiate all derivations, just the `name' attribute.  (However,
  `nix-env' doesn't yet take advantage of this since it still always
  evaluates the `outPath' and `drvPath' attributes).

  Also, this allows derivations to cyclically reference each other,
  for example,

    webServer = derivation {
      ...
      hostName = "svn.cs.uu.nl";
      services = [svnService];
    };

    svnService = derivation {
      ...
      hostName = webServer.hostName;
    };

  Previously, this would yield a black hole (infinite recursion).
This commit is contained in:
Eelco Dolstra 2005-05-07 21:48:49 +00:00
parent 6057b51835
commit 77557a6f06

View file

@ -213,14 +213,12 @@ static string concatStrings(const Strings & ss)
derivation; `drvPath' containing the path of the Nix expression;
and `type' set to `derivation' to indicate that this is a
derivation. */
static Expr primDerivation(EvalState & state, const ATermVector & _args)
static Expr primDerivationStrict(EvalState & state, const ATermVector & args)
{
startNest(nest, lvlVomit, "evaluating derivation");
ATermMap attrs;
Expr args = _args[0];
args = evalExpr(state, args);
queryAllAttrs(args, attrs, true);
queryAllAttrs(evalExpr(state, args[0]), attrs, true);
/* Build the derivation expression by processing the attributes. */
Derivation drv;
@ -341,10 +339,27 @@ static Expr primDerivation(EvalState & state, const ATermVector & _args)
state.drvHashes[drvPath] = hashDerivationModulo(state, drv);
/* !!! assumes a single output */
attrs.set("outPath", makeAttrRHS(makePath(toATerm(outPath)), makeNoPos()));
attrs.set("drvPath", makeAttrRHS(makePath(toATerm(drvPath)), makeNoPos()));
ATermMap outAttrs;
outAttrs.set("outPath", makeAttrRHS(makePath(toATerm(outPath)), makeNoPos()));
outAttrs.set("drvPath", makeAttrRHS(makePath(toATerm(drvPath)), makeNoPos()));
return makeAttrs(outAttrs);
}
static Expr primDerivationLazy(EvalState & state, const ATermVector & args)
{
Expr eAttrs = evalExpr(state, args[0]);
ATermMap attrs;
queryAllAttrs(eAttrs, attrs, true);
attrs.set("type", makeAttrRHS(makeStr(toATerm("derivation")), makeNoPos()));
Expr drvStrict = makeCall(makeVar(toATerm("derivation!")), eAttrs);
attrs.set("outPath", makeAttrRHS(makeSelect(drvStrict, toATerm("outPath")), makeNoPos()));
attrs.set("drvPath", makeAttrRHS(makeSelect(drvStrict, toATerm("drvPath")), makeNoPos()));
return makeAttrs(attrs);
}
@ -438,7 +453,8 @@ void EvalState::addPrimOps()
addPrimOp("__currentTime", 0, primCurrentTime);
addPrimOp("import", 1, primImport);
addPrimOp("derivation", 1, primDerivation);
addPrimOp("derivation!", 1, primDerivationStrict);
addPrimOp("derivation", 1, primDerivationLazy);
addPrimOp("baseNameOf", 1, primBaseNameOf);
addPrimOp("toString", 1, primToString);
addPrimOp("isNull", 1, primIsNull);