diff options
Diffstat (limited to 'src/libexpr')
-rw-r--r-- | src/libexpr/eval.cc | 49 | ||||
-rw-r--r-- | src/libexpr/eval.hh | 5 | ||||
-rw-r--r-- | src/libexpr/flake/eval-cache.cc | 4 | ||||
-rw-r--r-- | src/libexpr/flake/eval-cache.hh | 5 | ||||
-rw-r--r-- | src/libexpr/flake/flake.cc | 10 | ||||
-rw-r--r-- | src/libexpr/flake/flakeref.cc | 2 | ||||
-rw-r--r-- | src/libexpr/flake/lockfile.cc | 2 | ||||
-rw-r--r-- | src/libexpr/get-drvs.cc | 18 | ||||
-rw-r--r-- | src/libexpr/local.mk | 2 | ||||
-rw-r--r-- | src/libexpr/names.cc | 8 | ||||
-rw-r--r-- | src/libexpr/names.hh | 2 | ||||
-rw-r--r-- | src/libexpr/primops.cc | 134 | ||||
-rw-r--r-- | src/libexpr/primops/context.cc | 2 | ||||
-rw-r--r-- | src/libexpr/primops/fetchGit.cc | 6 | ||||
-rw-r--r-- | src/libexpr/primops/fetchMercurial.cc | 6 | ||||
-rw-r--r-- | src/libexpr/symbol-table.hh | 7 |
16 files changed, 140 insertions, 122 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index ff7bce45e..cddbce20d 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -44,6 +44,19 @@ static char * dupString(const char * s) } +static char * dupStringWithLen(const char * s, size_t size) +{ + char * t; +#if HAVE_BOEHMGC + t = GC_STRNDUP(s, size); +#else + t = strndup(s, size); +#endif + if (!t) throw std::bad_alloc(); + return t; +} + + static void printValue(std::ostream & str, std::set<const Value *> & active, const Value & v) { checkInterrupt(); @@ -358,10 +371,10 @@ EvalState::EvalState(const Strings & _searchPath, ref<Store> store) auto path = r.second; if (store->isInStore(r.second)) { - PathSet closure; - store->computeFSClosure(store->toStorePath(r.second), closure); + StorePathSet closure; + store->computeFSClosure(store->parseStorePath(store->toStorePath(r.second)), closure); for (auto & path : closure) - allowedPaths->insert(path); + allowedPaths->insert(store->printStorePath(path)); } else allowedPaths->insert(r.second); } @@ -585,9 +598,11 @@ void mkString(Value & v, const char * s) } -Value & mkString(Value & v, const string & s, const PathSet & context) +Value & mkString(Value & v, std::string_view s, const PathSet & context) { - mkString(v, s.c_str()); + v.type = tString; + v.string.s = dupStringWithLen(s.data(), s.size()); + v.string.context = 0; if (!context.empty()) { size_t n = 0; v.string.context = (const char * *) @@ -1131,10 +1146,9 @@ void EvalState::callPrimOp(Value & fun, Value & arg, Value & v, const Pos & pos) void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & pos) { - std::optional<FunctionCallTrace> trace; - if (evalSettings.traceFunctionCalls) { - trace.emplace(pos); - } + std::unique_ptr<FunctionCallTrace> trace; + if (evalSettings.traceFunctionCalls) + trace = std::make_unique<FunctionCallTrace>(pos); forceValue(fun, pos); @@ -1680,15 +1694,16 @@ string EvalState::copyPathToStore(PathSet & context, const Path & path) throwEvalError("file names are not allowed to end in '%1%'", drvExtension); Path dstPath; - if (srcToStore[path] != "") - dstPath = srcToStore[path]; + auto i = srcToStore.find(path); + if (i != srcToStore.end()) + dstPath = store->printStorePath(i->second); else { - dstPath = settings.readOnlyMode - ? store->computeStorePathForPath(baseNameOf(path), checkSourcePath(path)).first - : store->addToStore(baseNameOf(path), checkSourcePath(path), true, htSHA256, defaultPathFilter, repair); - srcToStore[path] = dstPath; - printMsg(lvlChatty, format("copied source '%1%' -> '%2%'") - % path % dstPath); + auto p = settings.readOnlyMode + ? store->computeStorePathForPath(std::string(baseNameOf(path)), checkSourcePath(path)).first + : store->addToStore(std::string(baseNameOf(path)), checkSourcePath(path), true, htSHA256, defaultPathFilter, repair); + dstPath = store->printStorePath(p); + srcToStore.insert_or_assign(path, std::move(p)); + printMsg(lvlChatty, "copied source '%1%' -> '%2%'", path, dstPath); } context.insert(dstPath); diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index baca7f03f..526d8b198 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -17,6 +17,7 @@ namespace nix { class Store; class EvalState; +struct StorePath; enum RepairFlag : bool; namespace flake { @@ -46,14 +47,14 @@ struct Env }; -Value & mkString(Value & v, const string & s, const PathSet & context = PathSet()); +Value & mkString(Value & v, std::string_view s, const PathSet & context = PathSet()); void copyContext(const Value & v, PathSet & context); /* Cache for calls to addToStore(); maps source paths to the store paths. */ -typedef std::map<Path, Path> SrcToStore; +typedef std::map<Path, StorePath> SrcToStore; std::ostream & operator << (std::ostream & str, const Value & v); diff --git a/src/libexpr/flake/eval-cache.cc b/src/libexpr/flake/eval-cache.cc index b32d502f7..8d01ef0fc 100644 --- a/src/libexpr/flake/eval-cache.cc +++ b/src/libexpr/flake/eval-cache.cc @@ -77,7 +77,7 @@ void EvalCache::addDerivation( (fingerprint.hash, fingerprint.hashSize) (attrPath) (ValueType::Derivation) - (drv.drvPath + " " + drv.outPath + " " + drv.outputName).exec(); + (std::string(drv.drvPath.to_string()) + " " + std::string(drv.outPath.to_string()) + " " + drv.outputName).exec(); } std::optional<EvalCache::Derivation> EvalCache::getDerivation( @@ -104,7 +104,7 @@ std::optional<EvalCache::Derivation> EvalCache::getDerivation( debug("evaluation cache hit for '%s'", attrPath); - return Derivation { ss[0], ss[1], ss[2] }; + return Derivation { StorePath::fromBaseName(ss[0]), StorePath::fromBaseName(ss[1]), ss[2] }; } EvalCache & EvalCache::singleton() diff --git a/src/libexpr/flake/eval-cache.hh b/src/libexpr/flake/eval-cache.hh index 03aea142e..f81d48ba5 100644 --- a/src/libexpr/flake/eval-cache.hh +++ b/src/libexpr/flake/eval-cache.hh @@ -2,6 +2,7 @@ #include "sync.hh" #include "flake.hh" +#include "path.hh" namespace nix { struct SQLite; struct SQLiteStmt; } @@ -19,8 +20,8 @@ public: struct Derivation { - Path drvPath; - Path outPath; + StorePath drvPath; + StorePath outPath; std::string outputName; }; diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc index 80726a257..a644f6ad3 100644 --- a/src/libexpr/flake/flake.cc +++ b/src/libexpr/flake/flake.cc @@ -163,7 +163,7 @@ static SourceInfo fetchInput(EvalState & state, const FlakeRef & resolvedRef) SourceInfo info(ref); info.storePath = gitInfo.storePath; info.revCount = gitInfo.revCount; - info.narHash = state.store->queryPathInfo(info.storePath)->narHash; + info.narHash = state.store->queryPathInfo(state.store->parseStorePath(info.storePath))->narHash; info.lastModified = gitInfo.lastModified; return info; }; @@ -212,7 +212,7 @@ static Flake getFlake(EvalState & state, const FlakeRef & originalRef, refMap.push_back({originalRef, resolvedRef}); refMap.push_back({flakeRef, resolvedRef}); - state.store->assertStorePath(sourceInfo.storePath); + state.store->parseStorePath(sourceInfo.storePath); if (state.allowedPaths) state.allowedPaths->insert(state.store->toRealPath(sourceInfo.storePath)); @@ -334,7 +334,7 @@ static SourceInfo getNonFlake(EvalState & state, const FlakeRef & originalRef, refMap.push_back({originalRef, resolvedRef}); refMap.push_back({flakeRef, resolvedRef}); - state.store->assertStorePath(sourceInfo.storePath); + state.store->parseStorePath(sourceInfo.storePath); if (state.allowedPaths) state.allowedPaths->insert(sourceInfo.storePath); @@ -490,7 +490,7 @@ void updateLockFile(EvalState & state, const FlakeRef & flakeRef, bool recreateL static void emitSourceInfoAttrs(EvalState & state, const SourceInfo & sourceInfo, Value & vAttrs) { auto & path = sourceInfo.storePath; - assert(state.store->isValidPath(path)); + assert(state.store->isValidPath(state.store->parseStorePath(path))); mkString(*state.allocAttr(vAttrs, state.sOutPath), path, {path}); if (sourceInfo.resolvedRef.rev) { @@ -542,7 +542,7 @@ static void prim_callFlake(EvalState & state, const Pos & pos, Value * * args, V state.mkAttrs(v, 8); - assert(state.store->isValidPath(sourceInfo.storePath)); + assert(state.store->isValidPath(state.store->parseStorePath(sourceInfo.storePath))); mkString(*state.allocAttr(v, state.sOutPath), sourceInfo.storePath, {sourceInfo.storePath}); diff --git a/src/libexpr/flake/flakeref.cc b/src/libexpr/flake/flakeref.cc index 8e90e5989..ff7c725cb 100644 --- a/src/libexpr/flake/flakeref.cc +++ b/src/libexpr/flake/flakeref.cc @@ -161,7 +161,7 @@ FlakeRef::FlakeRef(const std::string & uri_, bool allowRelative) } while (true) { if (pathExists(d.path + "/.git")) break; - subdir = baseNameOf(d.path) + (subdir.empty() ? "" : "/" + subdir); + subdir = std::string(baseNameOf(d.path)) + (subdir.empty() ? "" : "/" + subdir); d.path = dirOf(d.path); if (d.path == "/") throw MissingFlake("path '%s' is not a flake (because it does not reference a Git repository)", uri); diff --git a/src/libexpr/flake/lockfile.cc b/src/libexpr/flake/lockfile.cc index 5693e57dc..93d4ae946 100644 --- a/src/libexpr/flake/lockfile.cc +++ b/src/libexpr/flake/lockfile.cc @@ -26,7 +26,7 @@ nlohmann::json LockedInput::toJson() const Path LockedInput::computeStorePath(Store & store) const { - return store.makeFixedOutputPath(true, narHash, "source"); + return store.printStorePath(store.makeFixedOutputPath(true, narHash, "source")); } LockedInputs::LockedInputs(const nlohmann::json & json) diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index 4e22a1d77..a3412eab9 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -19,27 +19,27 @@ DrvInfo::DrvInfo(EvalState & state, const string & attrPath, Bindings * attrs) DrvInfo::DrvInfo(EvalState & state, ref<Store> store, const std::string & drvPathWithOutputs) : state(&state), attrs(nullptr), attrPath("") { - auto spec = parseDrvPathWithOutputs(drvPathWithOutputs); + auto [drvPath, selectedOutputs] = store->parseDrvPathWithOutputs(drvPathWithOutputs); - drvPath = spec.first; + this->drvPath = store->printStorePath(drvPath); auto drv = store->derivationFromPath(drvPath); - name = storePathToName(drvPath); + name = drvPath.name(); - if (spec.second.size() > 1) + if (selectedOutputs.size() > 1) throw Error("building more than one derivation output is not supported, in '%s'", drvPathWithOutputs); outputName = - spec.second.empty() - ? get(drv.env, "outputName", "out") - : *spec.second.begin(); + selectedOutputs.empty() + ? get(drv.env, "outputName").value_or("out") + : *selectedOutputs.begin(); auto i = drv.outputs.find(outputName); if (i == drv.outputs.end()) - throw Error("derivation '%s' does not have output '%s'", drvPath, outputName); + throw Error("derivation '%s' does not have output '%s'", store->printStorePath(drvPath), outputName); - outPath = i->second.path; + outPath = store->printStorePath(i->second.path); } diff --git a/src/libexpr/local.mk b/src/libexpr/local.mk index a9cb6b7b6..c2225383f 100644 --- a/src/libexpr/local.mk +++ b/src/libexpr/local.mk @@ -11,7 +11,7 @@ libexpr_SOURCES := \ $(d)/lexer-tab.cc \ $(d)/parser-tab.cc -libexpr_LIBS = libutil libstore +libexpr_LIBS = libutil libstore libnixrust libexpr_LDFLAGS = ifneq ($(OS), FreeBSD) diff --git a/src/libexpr/names.cc b/src/libexpr/names.cc index 382088c78..d1c8a6101 100644 --- a/src/libexpr/names.cc +++ b/src/libexpr/names.cc @@ -16,14 +16,14 @@ DrvName::DrvName() a letter. The `version' part is the rest (excluding the separating dash). E.g., `apache-httpd-2.0.48' is parsed to (`apache-httpd', '2.0.48'). */ -DrvName::DrvName(const string & s) : hits(0) +DrvName::DrvName(std::string_view s) : hits(0) { - name = fullName = s; + name = fullName = std::string(s); for (unsigned int i = 0; i < s.size(); ++i) { /* !!! isalpha/isdigit are affected by the locale. */ if (s[i] == '-' && i + 1 < s.size() && !isalpha(s[i + 1])) { - name = string(s, 0, i); - version = string(s, i + 1); + name = s.substr(0, i); + version = s.substr(i + 1); break; } } diff --git a/src/libexpr/names.hh b/src/libexpr/names.hh index 13c3093e7..00e14b8c7 100644 --- a/src/libexpr/names.hh +++ b/src/libexpr/names.hh @@ -15,7 +15,7 @@ struct DrvName unsigned int hits; DrvName(); - DrvName(const string & s); + DrvName(std::string_view s); bool matches(DrvName & n); private: diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 021204f08..2df9277c9 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -44,19 +44,19 @@ std::pair<string, string> decodeContext(const string & s) InvalidPathError::InvalidPathError(const Path & path) : - EvalError(format("path '%1%' is not valid") % path), path(path) {} + EvalError("path '%s' is not valid", path), path(path) {} void EvalState::realiseContext(const PathSet & context) { - PathSet drvs; + std::vector<StorePathWithOutputs> drvs; for (auto & i : context) { - auto [ctx, outputName] = decodeContext(i); - assert(store->isStorePath(ctx)); + auto [ctxS, outputName] = decodeContext(i); + auto ctx = store->parseStorePath(ctxS); if (!store->isValidPath(ctx)) - throw InvalidPathError(ctx); - if (!outputName.empty() && nix::isDerivation(ctx)) { - drvs.insert(ctx + "!" + outputName); + throw InvalidPathError(store->printStorePath(ctx)); + if (!outputName.empty() && ctx.isDerivation()) { + drvs.push_back(StorePathWithOutputs{ctx.clone(), {outputName}}); /* Add the output of this derivation to the allowed paths. */ @@ -64,8 +64,8 @@ void EvalState::realiseContext(const PathSet & context) 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'", ctx, outputName); - allowedPaths->insert(i->second.path); + throw Error("derivation '%s' does not have an output named '%s'", ctxS, outputName); + allowedPaths->insert(store->printStorePath(i->second.path)); } } } @@ -73,10 +73,11 @@ void EvalState::realiseContext(const PathSet & context) if (drvs.empty()) return; if (!evalSettings.enableImportFromDerivation) - throw EvalError(format("attempted to realize '%1%' during evaluation but 'allow-import-from-derivation' is false") % *(drvs.begin())); + throw EvalError("attempted to realize '%1%' during evaluation but 'allow-import-from-derivation' is false", + store->printStorePath(drvs.begin()->path)); /* For performance, prefetch all substitute info. */ - PathSet willBuild, willSubstitute, unknown; + StorePathSet willBuild, willSubstitute, unknown; unsigned long long downloadSize, narSize; store->queryMissing(drvs, willBuild, willSubstitute, unknown, downloadSize, narSize); @@ -100,8 +101,9 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args Path realPath = state.checkSourcePath(state.toRealPath(path, context)); - if (state.store->isStorePath(path) && state.store->isValidPath(path) && isDerivation(path)) { - Derivation drv = readDerivation(realPath); + // FIXME + if (state.store->isStorePath(path) && state.store->isValidPath(state.store->parseStorePath(path)) && isDerivation(path)) { + Derivation drv = readDerivation(*state.store, realPath); Value & w = *state.allocValue(); state.mkAttrs(w, 3 + drv.outputs.size()); Value * v2 = state.allocAttr(w, state.sDrvPath); @@ -115,7 +117,7 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args for (const auto & o : drv.outputs) { v2 = state.allocAttr(w, state.symbols.create(o.first)); - mkString(*v2, o.second.path, {"!" + o.first + "!" + path}); + mkString(*v2, state.store->printStorePath(o.second.path), {"!" + o.first + "!" + path}); outputsVal->listElems()[outputs_index] = state.allocValue(); mkString(*(outputsVal->listElems()[outputs_index++]), o.first); } @@ -676,24 +678,24 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * runs. */ if (path.at(0) == '=') { /* !!! This doesn't work if readOnlyMode is set. */ - PathSet refs; - state.store->computeFSClosure(string(path, 1), refs); + StorePathSet refs; + state.store->computeFSClosure(state.store->parseStorePath(std::string_view(path).substr(1)), refs); for (auto & j : refs) { - drv.inputSrcs.insert(j); - if (isDerivation(j)) - drv.inputDrvs[j] = state.store->queryDerivationOutputNames(j); + drv.inputSrcs.insert(j.clone()); + if (j.isDerivation()) + drv.inputDrvs[j.clone()] = state.store->queryDerivationOutputNames(j); } } /* Handle derivation outputs of the form ‘!<name>!<path>’. */ else if (path.at(0) == '!') { std::pair<string, string> ctx = decodeContext(path); - drv.inputDrvs[ctx.first].insert(ctx.second); + drv.inputDrvs[state.store->parseStorePath(ctx.first)].insert(ctx.second); } /* Otherwise it's a source file. */ else - drv.inputSrcs.insert(path); + drv.inputSrcs.insert(state.store->parseStorePath(path)); } /* Do we have all required attributes? */ @@ -703,10 +705,8 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * throw EvalError(format("required attribute 'system' missing, at %1%") % posDrvName); /* Check whether the derivation name is valid. */ - checkStoreName(drvName); if (isDerivation(drvName)) - throw EvalError(format("derivation names are not allowed to end in '%1%', at %2%") - % drvExtension % posDrvName); + throw EvalError("derivation names are not allowed to end in '%s', at %s", drvExtension, posDrvName); if (outputHash) { /* Handle fixed-output derivations. */ @@ -716,52 +716,51 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * HashType ht = outputHashAlgo.empty() ? htUnknown : parseHashType(outputHashAlgo); Hash h(*outputHash, ht); - Path outPath = state.store->makeFixedOutputPath(outputHashRecursive, h, drvName); - if (!jsonObject) drv.env["out"] = outPath; - drv.outputs["out"] = DerivationOutput(outPath, - (outputHashRecursive ? "r:" : "") + printHashType(h.type), - h.to_string(Base16, false)); + auto outPath = state.store->makeFixedOutputPath(outputHashRecursive, h, drvName); + if (!jsonObject) drv.env["out"] = state.store->printStorePath(outPath); + drv.outputs.insert_or_assign("out", DerivationOutput(std::move(outPath), + (outputHashRecursive ? "r:" : "") + printHashType(h.type), + h.to_string(Base16, false))); } else { - /* Construct the "masked" store derivation, which is the final - one except that in the list of outputs, the output paths - are empty, and the corresponding environment variables have - an empty value. This ensures that changes in the set of - output names do get reflected in the hash. */ + /* Compute a hash over the "masked" store derivation, which is + the final one except that in the list of outputs, the + output paths are empty strings, and the corresponding + environment variables have an empty value. This ensures + that changes in the set of output names do get reflected in + the hash. */ for (auto & i : outputs) { if (!jsonObject) drv.env[i] = ""; - drv.outputs[i] = DerivationOutput("", "", ""); } - /* Use the masked derivation expression to compute the output - path. */ - Hash h = hashDerivationModulo(*state.store, drv); + Hash h = hashDerivationModulo(*state.store, Derivation(drv), true); - for (auto & i : drv.outputs) - if (i.second.path == "") { - Path outPath = state.store->makeOutputPath(i.first, h, drvName); - if (!jsonObject) drv.env[i.first] = outPath; - i.second.path = outPath; - } + for (auto & i : outputs) { + auto outPath = state.store->makeOutputPath(i, h, drvName); + if (!jsonObject) drv.env[i] = state.store->printStorePath(outPath); + drv.outputs.insert_or_assign(i, + DerivationOutput(std::move(outPath), "", "")); + } } /* Write the resulting term into the Nix store directory. */ - Path drvPath = writeDerivation(state.store, drv, drvName, state.repair); + auto drvPath = writeDerivation(state.store, drv, drvName, state.repair); + auto drvPathS = state.store->printStorePath(drvPath); - printMsg(lvlChatty, format("instantiated '%1%' -> '%2%'") - % drvName % drvPath); + printMsg(lvlChatty, "instantiated '%1%' -> '%2%'", drvName, drvPathS); /* 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[drvPath] = hashDerivationModulo(*state.store, drv); + drvHashes.insert_or_assign(drvPath.clone(), + hashDerivationModulo(*state.store, Derivation(drv), false)); state.mkAttrs(v, 1 + drv.outputs.size()); - mkString(*state.allocAttr(v, state.sDrvPath), drvPath, {"=" + drvPath}); + mkString(*state.allocAttr(v, state.sDrvPath), drvPathS, {"=" + drvPathS}); for (auto & i : drv.outputs) { mkString(*state.allocAttr(v, state.symbols.create(i.first)), - i.second.path, {"!" + i.first + "!" + drvPath}); + state.store->printStorePath(i.second.path), {"!" + i.first + "!" + drvPathS}); } v.attrs->sort(); } @@ -814,7 +813,7 @@ static void prim_storePath(EvalState & state, const Pos & pos, Value * * args, V throw EvalError(format("path '%1%' is not in the Nix store, at %2%") % path % pos); Path path2 = state.store->toStorePath(path); if (!settings.readOnlyMode) - state.store->ensurePath(path2); + state.store->ensurePath(state.store->parseStorePath(path2)); context.insert(path2); mkString(v, path, context); } @@ -1010,17 +1009,17 @@ static void prim_toFile(EvalState & state, const Pos & pos, Value * * args, Valu string name = state.forceStringNoCtx(*args[0], pos); string contents = state.forceString(*args[1], context, pos); - PathSet refs; + StorePathSet refs; for (auto path : context) { if (path.at(0) != '/') throw EvalError(format("in 'toFile': the file '%1%' cannot refer to derivation outputs, at %2%") % name % pos); - refs.insert(path); + refs.insert(state.store->parseStorePath(path)); } - Path storePath = settings.readOnlyMode + auto storePath = state.store->printStorePath(settings.readOnlyMode ? state.store->computeStorePathForText(name, contents, refs) - : state.store->addTextToStore(name, contents, refs, state.repair); + : state.store->addTextToStore(name, contents, refs, state.repair)); /* Note: we don't need to add `context' to the context of the result, since `storePath' itself has references to the paths @@ -1060,21 +1059,18 @@ static void addPath(EvalState & state, const Pos & pos, const string & name, con return state.forceBool(res, pos); }) : defaultPathFilter; - Path expectedStorePath; - if (expectedHash) { - expectedStorePath = - state.store->makeFixedOutputPath(recursive, expectedHash, name); - } + std::optional<StorePath> expectedStorePath; + if (expectedHash) + expectedStorePath = state.store->makeFixedOutputPath(recursive, expectedHash, name); Path dstPath; - if (!expectedHash || !state.store->isValidPath(expectedStorePath)) { - dstPath = settings.readOnlyMode + if (!expectedHash || !state.store->isValidPath(*expectedStorePath)) { + dstPath = state.store->printStorePath(settings.readOnlyMode ? state.store->computeStorePathForPath(name, path, recursive, htSHA256, filter).first - : state.store->addToStore(name, path, recursive, htSHA256, filter, state.repair); - if (expectedHash && expectedStorePath != dstPath) { - throw Error(format("store path mismatch in (possibly filtered) path added from '%1%'") % path); - } + : state.store->addToStore(name, path, recursive, htSHA256, filter, state.repair)); + if (expectedHash && expectedStorePath != state.store->parseStorePath(dstPath)) + throw Error("store path mismatch in (possibly filtered) path added from '%s'", path); } else - dstPath = expectedStorePath; + dstPath = state.store->printStorePath(*expectedStorePath); mkString(v, dstPath, {dstPath}); } @@ -1091,7 +1087,7 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args if (args[0]->type != tLambda) throw TypeError(format("first argument in call to 'filterSource' is not a function but %1%, at %2%") % showType(*args[0]) % pos); - addPath(state, pos, baseNameOf(path), path, args[0], true, Hash(), v); + addPath(state, pos, std::string(baseNameOf(path)), path, args[0], true, Hash(), v); } static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value & v) @@ -2151,7 +2147,7 @@ void EvalState::createBaseEnv() } if (!evalSettings.pureEval) { - mkString(v, settings.thisSystem); + mkString(v, settings.thisSystem.get()); addConstant("__currentSystem", v); } diff --git a/src/libexpr/primops/context.cc b/src/libexpr/primops/context.cc index 2d79739ea..94fa0158c 100644 --- a/src/libexpr/primops/context.cc +++ b/src/libexpr/primops/context.cc @@ -148,7 +148,7 @@ static void prim_appendContext(EvalState & state, const Pos & pos, Value * * arg if (!state.store->isStorePath(i.name)) throw EvalError("Context key '%s' is not a store path, at %s", i.name, i.pos); if (!settings.readOnlyMode) - state.store->ensurePath(i.name); + state.store->ensurePath(state.store->parseStorePath(i.name)); state.forceAttrs(*i.value, *i.pos); auto iter = i.value->attrs->find(sPath); if (iter != i.value->attrs->end()) { diff --git a/src/libexpr/primops/fetchGit.cc b/src/libexpr/primops/fetchGit.cc index a4c4b0943..80588f54f 100644 --- a/src/libexpr/primops/fetchGit.cc +++ b/src/libexpr/primops/fetchGit.cc @@ -56,7 +56,7 @@ static std::optional<GitInfo> lookupGitInfo( Path storePath = json["storePath"]; - if (store->isValidPath(storePath)) { + if (store->isValidPath(store->parseStorePath(storePath))) { GitInfo gitInfo; gitInfo.storePath = storePath; gitInfo.rev = rev; @@ -145,7 +145,7 @@ GitInfo exportGit(ref<Store> store, std::string uri, return files.count(file); }; - gitInfo.storePath = store->addToStore("source", uri, true, htSHA256, filter); + gitInfo.storePath = store->printStorePath(store->addToStore("source", uri, true, htSHA256, filter)); gitInfo.revCount = haveCommits ? std::stoull(runProgram("git", true, { "-C", uri, "rev-list", "--count", "HEAD" })) : 0; // FIXME: maybe we should use the timestamp of the last // modified dirty file? @@ -265,7 +265,7 @@ GitInfo exportGit(ref<Store> store, std::string uri, unpackTarfile(*source, tmpDir); - gitInfo.storePath = store->addToStore(name, tmpDir); + gitInfo.storePath = store->printStorePath(store->addToStore(name, tmpDir)); gitInfo.revCount = std::stoull(runProgram("git", true, { "-C", repoDir, "rev-list", "--count", gitInfo.rev.gitRev() })); gitInfo.lastModified = std::stoull(runProgram("git", true, { "-C", repoDir, "log", "-1", "--format=%ct", gitInfo.rev.gitRev() })); diff --git a/src/libexpr/primops/fetchMercurial.cc b/src/libexpr/primops/fetchMercurial.cc index 40082894f..290cdb0b2 100644 --- a/src/libexpr/primops/fetchMercurial.cc +++ b/src/libexpr/primops/fetchMercurial.cc @@ -64,7 +64,7 @@ HgInfo exportMercurial(ref<Store> store, const std::string & uri, return files.count(file); }; - hgInfo.storePath = store->addToStore("source", uri, true, htSHA256, filter); + hgInfo.storePath = store->printStorePath(store->addToStore("source", uri, true, htSHA256, filter)); return hgInfo; } @@ -135,7 +135,7 @@ HgInfo exportMercurial(ref<Store> store, const std::string & uri, hgInfo.storePath = json["storePath"]; - if (store->isValidPath(hgInfo.storePath)) { + if (store->isValidPath(store->parseStorePath(hgInfo.storePath))) { printTalkative("using cached Mercurial store path '%s'", hgInfo.storePath); return hgInfo; } @@ -151,7 +151,7 @@ HgInfo exportMercurial(ref<Store> store, const std::string & uri, deletePath(tmpDir + "/.hg_archival.txt"); - hgInfo.storePath = store->addToStore(name, tmpDir); + hgInfo.storePath = store->printStorePath(store->addToStore(name, tmpDir)); nlohmann::json json; json["storePath"] = hgInfo.storePath; diff --git a/src/libexpr/symbol-table.hh b/src/libexpr/symbol-table.hh index 91faea122..7ba5e1c14 100644 --- a/src/libexpr/symbol-table.hh +++ b/src/libexpr/symbol-table.hh @@ -38,7 +38,12 @@ public: return s < s2.s; } - operator const string & () const + operator const std::string & () const + { + return *s; + } + + operator const std::string_view () const { return *s; } |