aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/eval.cc49
-rw-r--r--src/libexpr/eval.hh5
-rw-r--r--src/libexpr/flake/eval-cache.cc4
-rw-r--r--src/libexpr/flake/eval-cache.hh5
-rw-r--r--src/libexpr/flake/flake.cc10
-rw-r--r--src/libexpr/flake/flakeref.cc2
-rw-r--r--src/libexpr/flake/lockfile.cc2
-rw-r--r--src/libexpr/get-drvs.cc18
-rw-r--r--src/libexpr/local.mk2
-rw-r--r--src/libexpr/names.cc8
-rw-r--r--src/libexpr/names.hh2
-rw-r--r--src/libexpr/primops.cc134
-rw-r--r--src/libexpr/primops/context.cc2
-rw-r--r--src/libexpr/primops/fetchGit.cc6
-rw-r--r--src/libexpr/primops/fetchMercurial.cc6
-rw-r--r--src/libexpr/symbol-table.hh7
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;
}