aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/get-drvs.cc13
-rw-r--r--src/libexpr/get-drvs.hh2
-rw-r--r--src/libexpr/primops.cc59
3 files changed, 50 insertions, 24 deletions
diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc
index 5d6e39aa0..d41cac132 100644
--- a/src/libexpr/get-drvs.cc
+++ b/src/libexpr/get-drvs.cc
@@ -39,7 +39,9 @@ DrvInfo::DrvInfo(EvalState & state, ref<Store> store, const std::string & drvPat
if (i == drv.outputs.end())
throw Error("derivation '%s' does not have output '%s'", store->printStorePath(drvPath), outputName);
- outPath = store->printStorePath(i->second.path(*store, drv.name));
+ auto optStorePath = i->second.pathOpt(*store, drv.name);
+ if (optStorePath)
+ outPath = store->printStorePath(*optStorePath);
}
@@ -77,12 +79,15 @@ string DrvInfo::queryDrvPath() const
string DrvInfo::queryOutPath() const
{
- if (outPath == "" && attrs) {
+ if (!outPath && attrs) {
Bindings::iterator i = attrs->find(state->sOutPath);
PathSet context;
- outPath = i != attrs->end() ? state->coerceToPath(*i->pos, *i->value, context) : "";
+ if (i != attrs->end())
+ outPath = state->coerceToPath(*i->pos, *i->value, context);
}
- return outPath;
+ if (!outPath)
+ throw UnimplementedError("CA derivations are not yet supported");
+ return *outPath;
}
diff --git a/src/libexpr/get-drvs.hh b/src/libexpr/get-drvs.hh
index d7860fc6a..29bb6a660 100644
--- a/src/libexpr/get-drvs.hh
+++ b/src/libexpr/get-drvs.hh
@@ -20,7 +20,7 @@ private:
mutable string name;
mutable string system;
mutable string drvPath;
- mutable string outPath;
+ mutable std::optional<string> outPath;
mutable string outputName;
Outputs outputs;
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 65d36ca0e..11f44fb97 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -44,16 +44,6 @@ void EvalState::realiseContext(const PathSet & context)
throw InvalidPathError(store->printStorePath(ctx));
if (!outputName.empty() && ctx.isDerivation()) {
drvs.push_back(StorePathWithOutputs{ctx, {outputName}});
-
- /* Add the output of this derivation to the allowed
- paths. */
- if (allowedPaths) {
- auto drv = store->derivationFromPath(ctx);
- DerivationOutputs::iterator i = drv.outputs.find(outputName);
- if (i == drv.outputs.end())
- throw Error("derivation '%s' does not have an output named '%s'", ctxS, outputName);
- allowedPaths->insert(store->printStorePath(i->second.path(*store, drv.name)));
- }
}
}
@@ -69,8 +59,38 @@ void EvalState::realiseContext(const PathSet & context)
store->queryMissing(drvs, willBuild, willSubstitute, unknown, downloadSize, narSize);
store->buildPaths(drvs);
+
+ /* Add the output of this derivations to the allowed
+ paths. */
+ if (allowedPaths) {
+ for (auto & [drvPath, outputs] : drvs) {
+ auto outputPaths = store->queryDerivationOutputMapAssumeTotal(drvPath);
+ for (auto & outputName : outputs) {
+ if (outputPaths.count(outputName) == 0)
+ throw Error("derivation '%s' does not have an output named '%s'",
+ store->printStorePath(drvPath), outputName);
+ allowedPaths->insert(store->printStorePath(outputPaths.at(outputName)));
+ }
+ }
+ }
}
+static void mkOutputString(EvalState & state, Value & v,
+ const StorePath & drvPath, const BasicDerivation & drv,
+ std::pair<string, DerivationOutput> o)
+{
+ auto optOutputPath = o.second.pathOpt(*state.store, drv.name);
+ mkString(
+ *state.allocAttr(v, state.symbols.create(o.first)),
+ state.store->printStorePath(optOutputPath
+ ? *optOutputPath
+ /* Downstream we would substitute this for an actual path once
+ we build the floating CA derivation */
+ /* FIXME: we need to depend on the basic derivation, not
+ derivation */
+ : downstreamPlaceholder(*state.store, drvPath, o.first)),
+ {"!" + o.first + "!" + state.store->printStorePath(drvPath)});
+}
/* Load and evaluate an expression from path specified by the
argument. */
@@ -114,8 +134,7 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args
unsigned int outputs_index = 0;
for (const auto & o : drv.outputs) {
- v2 = state.allocAttr(w, state.symbols.create(o.first));
- mkString(*v2, state.store->printStorePath(o.second.path(*state.store, drv.name)), {"!" + o.first + "!" + path});
+ mkOutputString(state, w, storePath, drv, o);
outputsVal->listElems()[outputs_index] = state.allocValue();
mkString(*(outputsVal->listElems()[outputs_index++]), o.first);
}
@@ -846,16 +865,18 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
/* Optimisation, but required in read-only mode! because in that
case we don't actually write store derivations, so we can't
- read them later. */
- drvHashes.insert_or_assign(drvPath,
- hashDerivationModulo(*state.store, Derivation(drv), false));
+ read them later.
+
+ However, we don't bother doing this for floating CA derivations because
+ their "hash modulo" is indeterminate until built. */
+ if (drv.type() != DerivationType::CAFloating)
+ drvHashes.insert_or_assign(drvPath,
+ hashDerivationModulo(*state.store, Derivation(drv), false));
state.mkAttrs(v, 1 + drv.outputs.size());
mkString(*state.allocAttr(v, state.sDrvPath), drvPathS, {"=" + drvPathS});
- for (auto & i : drv.outputs) {
- mkString(*state.allocAttr(v, state.symbols.create(i.first)),
- state.store->printStorePath(i.second.path(*state.store, drv.name)), {"!" + i.first + "!" + drvPathS});
- }
+ for (auto & i : drv.outputs)
+ mkOutputString(state, v, drvPath, drv, i);
v.attrs->sort();
}