From 408a7bfac1f4282ff6647696dfbc7988eed3a2ca Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 26 Nov 2012 17:39:09 +0100 Subject: [PATCH] nix-instantiate: Fix read-only evaluation --- src/libexpr/eval.cc | 1 + src/libexpr/eval.hh | 2 +- src/libexpr/get-drvs.cc | 11 +++++++++++ src/libexpr/get-drvs.hh | 2 ++ src/nix-instantiate/nix-instantiate.cc | 11 ++--------- 5 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index b176bbc82..31aaad548 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -138,6 +138,7 @@ EvalState::EvalState() , sName(symbols.create("name")) , sSystem(symbols.create("system")) , sOverrides(symbols.create("__overrides")) + , sOutputName(symbols.create("outputName")) , baseEnv(allocEnv(128)) , baseEnvDispl(0) , staticBaseEnv(false, 0) diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index a3c55a388..432a0bad1 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -93,7 +93,7 @@ public: SymbolTable symbols; const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, - sSystem, sOverrides; + sSystem, sOverrides, sOutputName; /* If set, force copying files to the Nix store even if they already exist there. */ diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index f9e7dc6db..2ee55bdca 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -28,6 +28,17 @@ string DrvInfo::queryOutPath(EvalState & state) const } +string DrvInfo::queryOutputName(EvalState & state) const +{ + if (outputName == "" && attrs) { + Bindings::iterator i = attrs->find(state.sOutputName); + PathSet context; + (string &) outputName = i != attrs->end() ? state.coerceToString(*i->value, context) : ""; + } + return outputName; +} + + MetaInfo DrvInfo::queryMetaInfo(EvalState & state) const { if (metaInfoRead) return meta; diff --git a/src/libexpr/get-drvs.hh b/src/libexpr/get-drvs.hh index 8159417a0..f84636a1a 100644 --- a/src/libexpr/get-drvs.hh +++ b/src/libexpr/get-drvs.hh @@ -28,6 +28,7 @@ struct DrvInfo private: string drvPath; string outPath; + string outputName; bool metaInfoRead; MetaInfo meta; @@ -46,6 +47,7 @@ public: string queryDrvPath(EvalState & state) const; string queryOutPath(EvalState & state) const; + string queryOutputName(EvalState & state) const; MetaInfo queryMetaInfo(EvalState & state) const; MetaValue queryMetaInfo(EvalState & state, const string & name) const; diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc index a5053c323..53cd71189 100644 --- a/src/nix-instantiate/nix-instantiate.cc +++ b/src/nix-instantiate/nix-instantiate.cc @@ -62,16 +62,9 @@ void processExpr(EvalState & state, const Strings & attrPaths, Path drvPath = i->queryDrvPath(state); /* What output do we want? */ - Path outPath = i->queryOutPath(state); - Derivation drv = derivationFromPath(*store, drvPath); - string outputName; - foreach (DerivationOutputs::iterator, i, drv.outputs) - if (i->second.path == outPath) { - outputName = i->first; - break; - } + string outputName = i->queryOutputName(state); if (outputName == "") - throw Error(format("derivation `%1%' does not have an output `%2%'") % drvPath % outPath); + throw Error(format("derivation `%1%' lacks an `outputName' attribute ") % drvPath); if (gcRoot == "") printGCWarning();