aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2020-07-27 16:17:50 +0000
committerJohn Ericson <John.Ericson@Obsidian.Systems>2020-07-27 16:17:50 +0000
commit1d7d94ceea0dbed564a5c3812f00be7fdaf1aa52 (patch)
tree6d197c708e6006965f16cd219b2012d403eaf584 /src/libstore
parent66a2067288a86dae19aecfa9e6a5b2d37952669f (diff)
parent43f2bd8dc5950c38a817242884870f344a84a291 (diff)
Merge branch 'hash-always-has-type' of github.com:obsidiansystems/nix into better-ca-parse-errors
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/build.cc76
-rw-r--r--src/libstore/builtins/fetchurl.cc21
-rw-r--r--src/libstore/daemon.cc2
-rw-r--r--src/libstore/derivations.cc121
-rw-r--r--src/libstore/derivations.hh27
-rw-r--r--src/libstore/local-store.cc11
-rw-r--r--src/libstore/misc.cc4
7 files changed, 151 insertions, 111 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 7d82ef09b..d26f96b74 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -1047,7 +1047,7 @@ DerivationGoal::DerivationGoal(const StorePath & drvPath, const BasicDerivation
{
this->drv = std::make_unique<BasicDerivation>(BasicDerivation(drv));
state = &DerivationGoal::haveDerivation;
- name = fmt("building of %s", worker.store.showPaths(drv.outputPaths()));
+ name = fmt("building of %s", worker.store.showPaths(drv.outputPaths(worker.store)));
trace("created");
mcExpectedBuilds = std::make_unique<MaintainCount<uint64_t>>(worker.expectedBuilds);
@@ -1182,7 +1182,7 @@ void DerivationGoal::haveDerivation()
retrySubstitution = false;
for (auto & i : drv->outputs)
- worker.store.addTempRoot(i.second.path);
+ worker.store.addTempRoot(i.second.path(worker.store, drv->name));
/* Check what outputs paths are not already valid. */
auto invalidOutputs = checkPathValidity(false, buildMode == bmRepair);
@@ -1290,12 +1290,12 @@ void DerivationGoal::repairClosure()
StorePathSet outputClosure;
for (auto & i : drv->outputs) {
if (!wantOutput(i.first, wantedOutputs)) continue;
- worker.store.computeFSClosure(i.second.path, outputClosure);
+ worker.store.computeFSClosure(i.second.path(worker.store, drv->name), outputClosure);
}
/* Filter out our own outputs (which we have already checked). */
for (auto & i : drv->outputs)
- outputClosure.erase(i.second.path);
+ outputClosure.erase(i.second.path(worker.store, drv->name));
/* Get all dependencies of this derivation so that we know which
derivation is responsible for which path in the output
@@ -1307,7 +1307,7 @@ void DerivationGoal::repairClosure()
if (i.isDerivation()) {
Derivation drv = worker.store.derivationFromPath(i);
for (auto & j : drv.outputs)
- outputsToDrv.insert_or_assign(j.second.path, i);
+ outputsToDrv.insert_or_assign(j.second.path(worker.store, drv.name), i);
}
/* Check each path (slow!). */
@@ -1379,7 +1379,7 @@ void DerivationGoal::inputsRealised()
for (auto & j : i.second) {
auto k = inDrv.outputs.find(j);
if (k != inDrv.outputs.end())
- worker.store.computeFSClosure(k->second.path, inputPaths);
+ worker.store.computeFSClosure(k->second.path(worker.store, inDrv.name), inputPaths);
else
throw Error(
"derivation '%s' requires non-existent output '%s' from input derivation '%s'",
@@ -1432,7 +1432,7 @@ void DerivationGoal::tryToBuild()
goal can start a build, and if not, the main loop will sleep a
few seconds and then retry this goal. */
PathSet lockFiles;
- for (auto & outPath : drv->outputPaths())
+ for (auto & outPath : drv->outputPaths(worker.store))
lockFiles.insert(worker.store.Store::toRealPath(outPath));
if (!outputLocks.lockPaths(lockFiles, "", false)) {
@@ -1460,16 +1460,16 @@ void DerivationGoal::tryToBuild()
return;
}
- missingPaths = drv->outputPaths();
+ missingPaths = drv->outputPaths(worker.store);
if (buildMode != bmCheck)
for (auto & i : validPaths) missingPaths.erase(i);
/* If any of the outputs already exist but are not valid, delete
them. */
for (auto & i : drv->outputs) {
- if (worker.store.isValidPath(i.second.path)) continue;
- debug("removing invalid path '%s'", worker.store.printStorePath(i.second.path));
- deletePath(worker.store.Store::toRealPath(i.second.path));
+ if (worker.store.isValidPath(i.second.path(worker.store, drv->name))) continue;
+ debug("removing invalid path '%s'", worker.store.printStorePath(i.second.path(worker.store, drv->name)));
+ deletePath(worker.store.Store::toRealPath(i.second.path(worker.store, drv->name)));
}
/* Don't do a remote build if the derivation has the attribute
@@ -1692,7 +1692,7 @@ void DerivationGoal::buildDone()
fmt("running post-build-hook '%s'", settings.postBuildHook),
Logger::Fields{worker.store.printStorePath(drvPath)});
PushActivity pact(act.id);
- auto outputPaths = drv->outputPaths();
+ auto outputPaths = drv->outputPaths(worker.store);
std::map<std::string, std::string> hookEnvironment = getEnv();
hookEnvironment.emplace("DRV_PATH", worker.store.printStorePath(drvPath));
@@ -1920,7 +1920,7 @@ StorePathSet DerivationGoal::exportReferences(const StorePathSet & storePaths)
if (j.isDerivation()) {
Derivation drv = worker.store.derivationFromPath(j);
for (auto & k : drv.outputs)
- worker.store.computeFSClosure(k.second.path, paths);
+ worker.store.computeFSClosure(k.second.path(worker.store, drv.name), paths);
}
}
@@ -2015,7 +2015,7 @@ void DerivationGoal::startBuilder()
/* Substitute output placeholders with the actual output paths. */
for (auto & output : drv->outputs)
- inputRewrites[hashPlaceholder(output.first)] = worker.store.printStorePath(output.second.path);
+ inputRewrites[hashPlaceholder(output.first)] = worker.store.printStorePath(output.second.path(worker.store, drv->name));
/* Construct the environment passed to the builder. */
initEnv();
@@ -2200,7 +2200,7 @@ void DerivationGoal::startBuilder()
(typically the dependencies of /bin/sh). Throw them
out. */
for (auto & i : drv->outputs)
- dirsInChroot.erase(worker.store.printStorePath(i.second.path));
+ dirsInChroot.erase(worker.store.printStorePath(i.second.path(worker.store, drv->name)));
#elif __APPLE__
/* We don't really have any parent prep work to do (yet?)
@@ -2613,7 +2613,7 @@ void DerivationGoal::writeStructuredAttrs()
/* Add an "outputs" object containing the output paths. */
nlohmann::json outputs;
for (auto & i : drv->outputs)
- outputs[i.first] = rewriteStrings(worker.store.printStorePath(i.second.path), inputRewrites);
+ outputs[i.first] = rewriteStrings(worker.store.printStorePath(i.second.path(worker.store, drv->name)), inputRewrites);
json["outputs"] = outputs;
/* Handle exportReferencesGraph. */
@@ -2817,7 +2817,7 @@ struct RestrictedStore : public LocalFSStore
auto drv = derivationFromPath(path.path);
for (auto & output : drv.outputs)
if (wantOutput(output.first, path.outputs))
- newPaths.insert(output.second.path);
+ newPaths.insert(output.second.path(*this, drv.name));
} else if (!goal.isAllowed(path.path))
throw InvalidPath("cannot build unknown path '%s' in recursive Nix", printStorePath(path.path));
}
@@ -3579,7 +3579,7 @@ StorePathSet parseReferenceSpecifiers(Store & store, const BasicDerivation & drv
if (store.isStorePath(i))
result.insert(store.parseStorePath(i));
else if (drv.outputs.count(i))
- result.insert(drv.outputs.find(i)->second.path);
+ result.insert(drv.outputs.find(i)->second.path(store, drv.name));
else throw BuildError("derivation contains an illegal reference specifier '%s'", i);
}
return result;
@@ -3617,7 +3617,7 @@ void DerivationGoal::registerOutputs()
if (hook) {
bool allValid = true;
for (auto & i : drv->outputs)
- if (!worker.store.isValidPath(i.second.path)) allValid = false;
+ if (!worker.store.isValidPath(i.second.path(worker.store, drv->name))) allValid = false;
if (allValid) return;
}
@@ -3638,23 +3638,23 @@ void DerivationGoal::registerOutputs()
Nix calls. */
StorePathSet referenceablePaths;
for (auto & p : inputPaths) referenceablePaths.insert(p);
- for (auto & i : drv->outputs) referenceablePaths.insert(i.second.path);
+ for (auto & i : drv->outputs) referenceablePaths.insert(i.second.path(worker.store, drv->name));
for (auto & p : addedPaths) referenceablePaths.insert(p);
/* Check whether the output paths were created, and grep each
output path to determine what other paths it references. Also make all
output paths read-only. */
for (auto & i : drv->outputs) {
- auto path = worker.store.printStorePath(i.second.path);
- if (!missingPaths.count(i.second.path)) continue;
+ auto path = worker.store.printStorePath(i.second.path(worker.store, drv->name));
+ if (!missingPaths.count(i.second.path(worker.store, drv->name))) continue;
Path actualPath = path;
if (needsHashRewrite()) {
- auto r = redirectedOutputs.find(i.second.path);
+ auto r = redirectedOutputs.find(i.second.path(worker.store, drv->name));
if (r != redirectedOutputs.end()) {
auto redirected = worker.store.Store::toRealPath(r->second);
if (buildMode == bmRepair
- && redirectedBadOutputs.count(i.second.path)
+ && redirectedBadOutputs.count(i.second.path(worker.store, drv->name))
&& pathExists(redirected))
replaceValidPath(path, redirected);
if (buildMode == bmCheck)
@@ -3723,7 +3723,9 @@ void DerivationGoal::registerOutputs()
if (fixedOutput) {
- if (i.second.hash->method == FileIngestionMethod::Flat) {
+ FixedOutputHash outputHash = std::get<DerivationOutputFixed>(i.second.output).hash;
+
+ if (outputHash.method == FileIngestionMethod::Flat) {
/* The output path should be a regular file without execute permission. */
if (!S_ISREG(st.st_mode) || (st.st_mode & S_IXUSR) != 0)
throw BuildError(
@@ -3734,13 +3736,13 @@ void DerivationGoal::registerOutputs()
/* Check the hash. In hash mode, move the path produced by
the derivation to its content-addressed location. */
- Hash h2 = i.second.hash->method == FileIngestionMethod::Recursive
- ? hashPath(i.second.hash->hash.type, actualPath).first
- : hashFile(i.second.hash->hash.type, actualPath);
+ Hash h2 = outputHash.method == FileIngestionMethod::Recursive
+ ? hashPath(outputHash.hash.type, actualPath).first
+ : hashFile(outputHash.hash.type, actualPath);
- auto dest = worker.store.makeFixedOutputPath(i.second.hash->method, h2, i.second.path.name());
+ auto dest = worker.store.makeFixedOutputPath(outputHash.method, h2, i.second.path(worker.store, drv->name).name());
- if (i.second.hash->hash != h2) {
+ if (outputHash.hash != h2) {
/* Throw an error after registering the path as
valid. */
@@ -3748,7 +3750,7 @@ void DerivationGoal::registerOutputs()
delayedException = std::make_exception_ptr(
BuildError("hash mismatch in fixed-output derivation '%s':\n wanted: %s\n got: %s",
worker.store.printStorePath(dest),
- i.second.hash->hash.to_string(SRI, true),
+ outputHash.hash.to_string(SRI, true),
h2.to_string(SRI, true)));
Path actualDest = worker.store.Store::toRealPath(dest);
@@ -3770,7 +3772,7 @@ void DerivationGoal::registerOutputs()
assert(worker.store.parseStorePath(path) == dest);
ca = FixedOutputHash {
- .method = i.second.hash->method,
+ .method = outputHash.method,
.hash = h2,
};
}
@@ -3896,7 +3898,7 @@ void DerivationGoal::registerOutputs()
/* If this is the first round of several, then move the output out of the way. */
if (nrRounds > 1 && curRound == 1 && curRound < nrRounds && keepPreviousRound) {
for (auto & i : drv->outputs) {
- auto path = worker.store.printStorePath(i.second.path);
+ auto path = worker.store.printStorePath(i.second.path(worker.store, drv->name));
Path prev = path + checkSuffix;
deletePath(prev);
Path dst = path + checkSuffix;
@@ -3914,7 +3916,7 @@ void DerivationGoal::registerOutputs()
if the result was not determistic? */
if (curRound == nrRounds) {
for (auto & i : drv->outputs) {
- Path prev = worker.store.printStorePath(i.second.path) + checkSuffix;
+ Path prev = worker.store.printStorePath(i.second.path(worker.store, drv->name)) + checkSuffix;
deletePath(prev);
}
}
@@ -4215,9 +4217,9 @@ StorePathSet DerivationGoal::checkPathValidity(bool returnValid, bool checkHash)
for (auto & i : drv->outputs) {
if (!wantOutput(i.first, wantedOutputs)) continue;
bool good =
- worker.store.isValidPath(i.second.path) &&
- (!checkHash || worker.pathContentsGood(i.second.path));
- if (good == returnValid) result.insert(i.second.path);
+ worker.store.isValidPath(i.second.path(worker.store, drv->name)) &&
+ (!checkHash || worker.pathContentsGood(i.second.path(worker.store, drv->name)));
+ if (good == returnValid) result.insert(i.second.path(worker.store, drv->name));
}
return result;
}
diff --git a/src/libstore/builtins/fetchurl.cc b/src/libstore/builtins/fetchurl.cc
index 84c7d2082..03bb77488 100644
--- a/src/libstore/builtins/fetchurl.cc
+++ b/src/libstore/builtins/fetchurl.cc
@@ -63,16 +63,19 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData)
auto & output = drv.outputs.begin()->second;
/* Try the hashed mirrors first. */
- if (output.hash && output.hash->method == FileIngestionMethod::Flat)
- for (auto hashedMirror : settings.hashedMirrors.get())
- try {
- if (!hasSuffix(hashedMirror, "/")) hashedMirror += '/';
- auto & h = output.hash->hash;
- fetch(hashedMirror + printHashType(h.type) + "/" + h.to_string(Base16, false));
- return;
- } catch (Error & e) {
- debug(e.what());
+ if (auto hash = std::get_if<DerivationOutputFixed>(&output.output)) {
+ if (hash->hash.method == FileIngestionMethod::Flat) {
+ for (auto hashedMirror : settings.hashedMirrors.get()) {
+ try {
+ if (!hasSuffix(hashedMirror, "/")) hashedMirror += '/';
+ fetch(hashedMirror + printHashType(hash->hash.hash.type) + "/" + hash->hash.hash.to_string(Base16, false));
+ return;
+ } catch (Error & e) {
+ debug(e.what());
+ }
}
+ }
+ }
/* Otherwise try the specified URL. */
fetch(mainUrl);
diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc
index 9e138e8d9..b760d74fa 100644
--- a/src/libstore/daemon.cc
+++ b/src/libstore/daemon.cc
@@ -451,7 +451,7 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
case wopBuildDerivation: {
auto drvPath = store->parseStorePath(readString(from));
BasicDerivation drv;
- readDerivation(from, *store, drv);
+ readDerivation(from, *store, drv, Derivation::nameFromPath(drvPath));
BuildMode buildMode = (BuildMode) readInt(from);
logger->startWork();
if (!trusted)
diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc
index 08e95dd41..d552d0bfd 100644
--- a/src/libstore/derivations.cc
+++ b/src/libstore/derivations.cc
@@ -7,12 +7,20 @@
namespace nix {
-const StorePath & BasicDerivation::findOutput(const string & id) const
+// FIXME Put this somewhere?
+template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
+template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
+
+StorePath DerivationOutput::path(const Store & store, std::string_view drvName) const
{
- auto i = outputs.find(id);
- if (i == outputs.end())
- throw Error("derivation has no output '%s'", id);
- return i->second.path;
+ return std::visit(overloaded {
+ [](DerivationOutputInputAddressed doi) {
+ return doi.path;
+ },
+ [&](DerivationOutputFixed dof) {
+ return store.makeFixedOutputPath(dof.hash.method, dof.hash.hash, drvName);
+ }
+ }, output);
}
@@ -107,7 +115,6 @@ static DerivationOutput parseDerivationOutput(const Store & store, std::istrings
expect(str, ","); const auto hash = parseString(str);
expect(str, ")");
- std::optional<FixedOutputHash> fsh;
if (hashAlgo != "") {
auto method = FileIngestionMethod::Flat;
if (string(hashAlgo, 0, 2) == "r:") {
@@ -115,22 +122,29 @@ static DerivationOutput parseDerivationOutput(const Store & store, std::istrings
hashAlgo = string(hashAlgo, 2);
}
const HashType hashType = parseHashType(hashAlgo);
- fsh = FixedOutputHash {
- .method = std::move(method),
- .hash = Hash::parseNonSRIUnprefixed(hash, hashType),
- };
- }
- return DerivationOutput {
- .path = std::move(path),
- .hash = std::move(fsh),
- };
+ return DerivationOutput {
+ .output = DerivationOutputFixed {
+ .hash = FixedOutputHash {
+ .method = std::move(method),
+ .hash = Hash::parseNonSRIUnprefixed(hash, hashType),
+ },
+ }
+ };
+ } else
+ return DerivationOutput {
+ .output = DerivationOutputInputAddressed {
+ .path = std::move(path),
+ }
+ };
}
-static Derivation parseDerivation(const Store & store, std::string && s)
+static Derivation parseDerivation(const Store & store, std::string && s, std::string_view name)
{
Derivation drv;
+ drv.name = name;
+
std::istringstream str(std::move(s));
expect(str, "Derive([");
@@ -174,10 +188,10 @@ static Derivation parseDerivation(const Store & store, std::string && s)
}
-Derivation readDerivation(const Store & store, const Path & drvPath)
+Derivation readDerivation(const Store & store, const Path & drvPath, std::string_view name)
{
try {
- return parseDerivation(store, readFile(drvPath));
+ return parseDerivation(store, readFile(drvPath), name);
} catch (FormatError & e) {
throw Error("error parsing derivation '%1%': %2%", drvPath, e.msg());
}
@@ -195,7 +209,7 @@ Derivation Store::readDerivation(const StorePath & drvPath)
{
auto accessor = getFSAccessor();
try {
- return parseDerivation(*this, accessor->readFile(printStorePath(drvPath)));
+ return parseDerivation(*this, accessor->readFile(printStorePath(drvPath)), Derivation::nameFromPath(drvPath));
} catch (FormatError & e) {
throw Error("error parsing derivation '%s': %s", printStorePath(drvPath), e.msg());
}
@@ -263,10 +277,14 @@ string Derivation::unparse(const Store & store, bool maskOutputs,
for (auto & i : outputs) {
if (first) first = false; else s += ',';
s += '('; printUnquotedString(s, i.first);
- s += ','; printUnquotedString(s, maskOutputs ? "" : store.printStorePath(i.second.path));
- s += ','; printUnquotedString(s, i.second.hash ? i.second.hash->printMethodAlgo() : "");
- s += ','; printUnquotedString(s,
- i.second.hash ? i.second.hash->hash.to_string(Base16, false) : "");
+ s += ','; printUnquotedString(s, maskOutputs ? "" : store.printStorePath(i.second.path(store, name)));
+ if (auto hash = std::get_if<DerivationOutputFixed>(&i.second.output)) {
+ s += ','; printUnquotedString(s, hash->hash.printMethodAlgo());
+ s += ','; printUnquotedString(s, hash->hash.hash.to_string(Base16, false));
+ } else {
+ s += ','; printUnquotedString(s, "");
+ s += ','; printUnquotedString(s, "");
+ }
s += ')';
}
@@ -322,7 +340,7 @@ bool BasicDerivation::isFixedOutput() const
{
return outputs.size() == 1 &&
outputs.begin()->first == "out" &&
- outputs.begin()->second.hash;
+ std::holds_alternative<DerivationOutputFixed>(outputs.begin()->second.output);
}
@@ -354,10 +372,11 @@ Hash hashDerivationModulo(Store & store, const Derivation & drv, bool maskOutput
/* Return a fixed hash for fixed-output derivations. */
if (drv.isFixedOutput()) {
DerivationOutputs::const_iterator i = drv.outputs.begin();
+ auto hash = std::get<DerivationOutputFixed>(i->second.output);
return hashString(htSHA256, "fixed:out:"
- + i->second.hash->printMethodAlgo() + ":"
- + i->second.hash->hash.to_string(Base16, false) + ":"
- + store.printStorePath(i->second.path));
+ + hash.hash.printMethodAlgo() + ":"
+ + hash.hash.hash.to_string(Base16, false) + ":"
+ + store.printStorePath(i->second.path(store, drv.name)));
}
/* For other derivations, replace the inputs paths with recursive
@@ -391,11 +410,11 @@ bool wantOutput(const string & output, const std::set<string> & wanted)
}
-StorePathSet BasicDerivation::outputPaths() const
+StorePathSet BasicDerivation::outputPaths(const Store & store) const
{
StorePathSet paths;
for (auto & i : outputs)
- paths.insert(i.second.path);
+ paths.insert(i.second.path(store, name));
return paths;
}
@@ -405,7 +424,6 @@ static DerivationOutput readDerivationOutput(Source & in, const Store & store)
auto hashAlgo = readString(in);
auto hash = readString(in);
- std::optional<FixedOutputHash> fsh;
if (hashAlgo != "") {
auto method = FileIngestionMethod::Flat;
if (string(hashAlgo, 0, 2) == "r:") {
@@ -413,16 +431,20 @@ static DerivationOutput readDerivationOutput(Source & in, const Store & store)
hashAlgo = string(hashAlgo, 2);
}
auto hashType = parseHashType(hashAlgo);
- fsh = FixedOutputHash {
- .method = std::move(method),
- .hash = Hash::parseNonSRIUnprefixed(hash, hashType),
+ return DerivationOutput {
+ .output = DerivationOutputFixed {
+ .hash = FixedOutputHash {
+ .method = std::move(method),
+ .hash = Hash::parseNonSRIUnprefixed(hash, hashType),
+ },
+ }
+ };
+ } else
+ return DerivationOutput {
+ .output = DerivationOutputInputAddressed {
+ .path = std::move(path),
+ }
};
- }
-
- return DerivationOutput {
- .path = std::move(path),
- .hash = std::move(fsh),
- };
}
StringSet BasicDerivation::outputNames() const
@@ -434,8 +456,19 @@ StringSet BasicDerivation::outputNames() const
}
-Source & readDerivation(Source & in, const Store & store, BasicDerivation & drv)
+std::string_view BasicDerivation::nameFromPath(const StorePath & drvPath) {
+ auto nameWithSuffix = drvPath.name();
+ constexpr std::string_view extension = ".drv";
+ assert(hasSuffix(nameWithSuffix, extension));
+ nameWithSuffix.remove_suffix(extension.size());
+ return nameWithSuffix;
+}
+
+
+Source & readDerivation(Source & in, const Store & store, BasicDerivation & drv, std::string_view name)
{
+ drv.name = name;
+
drv.outputs.clear();
auto nr = readNum<size_t>(in);
for (size_t n = 0; n < nr; n++) {
@@ -464,10 +497,10 @@ void writeDerivation(Sink & out, const Store & store, const BasicDerivation & dr
out << drv.outputs.size();
for (auto & i : drv.outputs) {
out << i.first
- << store.printStorePath(i.second.path);
- if (i.second.hash) {
- out << i.second.hash->printMethodAlgo()
- << i.second.hash->hash.to_string(Base16, false);
+ << store.printStorePath(i.second.path(store, drv.name));
+ if (auto hash = std::get_if<DerivationOutputFixed>(&i.second.output)) {
+ out << hash->hash.printMethodAlgo()
+ << hash->hash.hash.to_string(Base16, false);
} else {
out << "" << "";
}
diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh
index 68c53c1ff..133ffe50e 100644
--- a/src/libstore/derivations.hh
+++ b/src/libstore/derivations.hh
@@ -13,10 +13,20 @@ namespace nix {
/* Abstract syntax of derivations. */
-struct DerivationOutput
+struct DerivationOutputInputAddressed
{
StorePath path;
- std::optional<FixedOutputHash> hash; /* hash used for expected hash computation */
+};
+
+struct DerivationOutputFixed
+{
+ FixedOutputHash hash; /* hash used for expected hash computation */
+};
+
+struct DerivationOutput
+{
+ std::variant<DerivationOutputInputAddressed, DerivationOutputFixed> output;
+ StorePath path(const Store & store, std::string_view drvName) const;
};
typedef std::map<string, DerivationOutput> DerivationOutputs;
@@ -35,24 +45,23 @@ struct BasicDerivation
Path builder;
Strings args;
StringPairs env;
+ std::string name;
BasicDerivation() { }
virtual ~BasicDerivation() { };
- /* Return the path corresponding to the output identifier `id' in
- the given derivation. */
- const StorePath & findOutput(const std::string & id) const;
-
bool isBuiltin() const;
/* Return true iff this is a fixed-output derivation. */
bool isFixedOutput() const;
/* Return the output paths of a derivation. */
- StorePathSet outputPaths() const;
+ StorePathSet outputPaths(const Store & store) const;
/* Return the output names of a derivation. */
StringSet outputNames() const;
+
+ static std::string_view nameFromPath(const StorePath & storePath);
};
struct Derivation : BasicDerivation
@@ -76,7 +85,7 @@ StorePath writeDerivation(ref<Store> store,
const Derivation & drv, std::string_view name, RepairFlag repair = NoRepair);
/* Read a derivation from a file. */
-Derivation readDerivation(const Store & store, const Path & drvPath);
+Derivation readDerivation(const Store & store, const Path & drvPath, std::string_view name);
// FIXME: remove
bool isDerivation(const string & fileName);
@@ -93,7 +102,7 @@ bool wantOutput(const string & output, const std::set<string> & wanted);
struct Source;
struct Sink;
-Source & readDerivation(Source & in, const Store & store, BasicDerivation & drv);
+Source & readDerivation(Source & in, const Store & store, BasicDerivation & drv, std::string_view name);
void writeDerivation(Sink & out, const Store & store, const BasicDerivation & drv);
std::string hashPlaceholder(const std::string & outputName);
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 2911d8b33..91613747b 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -560,19 +560,12 @@ void LocalStore::checkDerivationOutputs(const StorePath & drvPath, const Derivat
DerivationOutputs::const_iterator out = drv.outputs.find("out");
if (out == drv.outputs.end())
throw Error("derivation '%s' does not have an output named 'out'", printStorePath(drvPath));
-
- check(
- makeFixedOutputPath(
- out->second.hash->method,
- out->second.hash->hash,
- drvName),
- out->second.path, "out");
}
else {
Hash h = hashDerivationModulo(*this, drv, true);
for (auto & i : drv.outputs)
- check(makeOutputPath(i.first, h, drvName), i.second.path, i.first);
+ check(makeOutputPath(i.first, h, drvName), i.second.path(*this, drv.name), i.first);
}
}
@@ -614,7 +607,7 @@ uint64_t LocalStore::addValidPath(State & state,
state.stmtAddDerivationOutput.use()
(id)
(i.first)
- (printStorePath(i.second.path))
+ (printStorePath(i.second.path(*this, drv.name)))
.exec();
}
}
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index e68edb38c..c4d22a634 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -198,8 +198,8 @@ void Store::queryMissing(const std::vector<StorePathWithOutputs> & targets,
PathSet invalid;
for (auto & j : drv->outputs)
if (wantOutput(j.first, path.outputs)
- && !isValidPath(j.second.path))
- invalid.insert(printStorePath(j.second.path));
+ && !isValidPath(j.second.path(*this, drv->name)))
+ invalid.insert(printStorePath(j.second.path(*this, drv->name)));
if (invalid.empty()) return;
if (settings.useSubstitutes && parsedDrv.substitutesAllowed()) {