From e7f8aa8bddf0b29a78231b95958dad91cb77b6c6 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 9 May 2022 15:29:42 +0200 Subject: [PATCH] Fix copyPathToStore() --- src/libexpr/eval.cc | 62 ++++++++++++++----------------- src/libexpr/eval.hh | 12 +++--- src/libexpr/primops.cc | 3 +- src/libexpr/value-to-json.cc | 5 ++- src/libfetchers/input-accessor.hh | 20 ++++++++++ 5 files changed, 58 insertions(+), 44 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index fb851ac23..33ae0aa60 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -2027,13 +2027,10 @@ BackedStringView EvalState::coerceToString(const PosIdx pos, Value & v, PathSet } if (v.type() == nPath) { - auto path = v.path().to_string(); - if (canonicalizePath) - // FIXME: unnecessary? - path = canonPath(path); - if (copyToStore) - path = copyPathToStore(context, path); - return path; + auto path = v.path(); + return copyToStore + ? store->printStorePath(copyPathToStore(context, path)) + : path.path; } if (v.type() == nAttrs) { @@ -2075,39 +2072,34 @@ BackedStringView EvalState::coerceToString(const PosIdx pos, Value & v, PathSet } -std::string EvalState::copyPathToStore(PathSet & context, const Path & path) +StorePath EvalState::copyPathToStore(PathSet & context, const SourcePath & path) { - #if 0 - if (nix::isDerivation(path)) - throwEvalError("file names are not allowed to end in '%1%'", drvExtension); + if (nix::isDerivation(path.path)) + throw EvalError("file names are not allowed to end in '%s'", drvExtension); - Path dstPath; auto i = srcToStore.find(path); - if (i != srcToStore.end()) - dstPath = store->printStorePath(i->second); - else { - // FIXME: use SourcePath - auto path2 = unpackPath(path); - #if 0 - auto p = settings.readOnlyMode - ? store->computeStorePathForPath(path2.baseName(), canonPath(path)).first - : store->addToStore(path2.baseName(), canonPath(path), FileIngestionMethod::Recursive, htSHA256, defaultPathFilter, repair); - #endif - auto source = sinkToSource([&](Sink & sink) { - path2.dumpPath(sink); - }); - // FIXME: readOnlyMode - auto p = store->addToStoreFromDump(*source, path2.baseName(), FileIngestionMethod::Recursive, htSHA256, repair); - dstPath = store->printStorePath(p); - allowPath(p); - srcToStore.insert_or_assign(path, std::move(p)); - printMsg(lvlChatty, "copied source '%1%' -> '%2%'", path, dstPath); - } - context.insert(dstPath); + auto dstPath = i != srcToStore.end() + ? i->second + : [&]() { + #if 0 + auto p = settings.readOnlyMode + ? store->computeStorePathForPath(path2.baseName(), canonPath(path)).first + : store->addToStore(path2.baseName(), canonPath(path), FileIngestionMethod::Recursive, htSHA256, defaultPathFilter, repair); + #endif + auto source = sinkToSource([&](Sink & sink) { + path.dumpPath(sink); + }); + // FIXME: readOnlyMode + auto dstPath = store->addToStoreFromDump(*source, path.baseName(), FileIngestionMethod::Recursive, htSHA256, repair); + allowPath(dstPath); + srcToStore.insert_or_assign(path, dstPath); + printMsg(lvlChatty, "copied source '%1%' -> '%2%'", path, store->printStorePath(dstPath)); + return dstPath; + }(); + + context.insert(store->printStorePath(dstPath)); return dstPath; - #endif - abort(); } diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index ecd72dab0..c007a235b 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -50,11 +50,6 @@ struct Env void copyContext(const Value & v, PathSet & context); -/* Cache for calls to addToStore(); maps source paths to the store - paths. */ -typedef std::map SrcToStore; - - std::ostream & printValue(const EvalState & state, std::ostream & str, const Value & v); std::string printValue(const EvalState & state, const Value & v); @@ -112,7 +107,10 @@ public: RootValue vImportedDrvToDerivation = nullptr; private: - SrcToStore srcToStore; + + /* Cache for calls to addToStore(); maps source paths to the store + paths. */ + std::map srcToStore; /* A cache from path names to parse trees. */ #if HAVE_BOEHMGC @@ -308,7 +306,7 @@ public: bool coerceMore = false, bool copyToStore = true, bool canonicalizePath = true); - std::string copyPathToStore(PathSet & context, const Path & path); + StorePath copyPathToStore(PathSet & context, const SourcePath & path); /* Path coercion. Converts strings, paths and derivations to a path. The result is guaranteed to be a canonicalised, absolute diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 7858733aa..2f47c54d3 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -1549,7 +1549,8 @@ static void prim_findFile(EvalState & state, const PosIdx pos, Value * * args, V // FIXME: checkSourcePath? v.mkPath(state.findFile(searchPath, path, pos)); #endif - abort(); + + throw ThrownError("findFile('%s'): not implemented", path); } static RegisterPrimOp primop_findFile(RegisterPrimOp::Info { diff --git a/src/libexpr/value-to-json.cc b/src/libexpr/value-to-json.cc index 7b26e8125..547540de7 100644 --- a/src/libexpr/value-to-json.cc +++ b/src/libexpr/value-to-json.cc @@ -2,6 +2,7 @@ #include "json.hh" #include "eval-inline.hh" #include "util.hh" +#include "store-api.hh" #include #include @@ -33,7 +34,9 @@ void printValueAsJSON(EvalState & state, bool strict, case nPath: // FIXME: handle accessors - out.write(state.copyPathToStore(context, v.path().path)); + out.write( + state.store->printStorePath( + state.copyPathToStore(context, v.path()))); break; case nNull: diff --git a/src/libfetchers/input-accessor.hh b/src/libfetchers/input-accessor.hh index 93e891ac2..90e8abbf7 100644 --- a/src/libfetchers/input-accessor.hh +++ b/src/libfetchers/input-accessor.hh @@ -42,6 +42,16 @@ struct InputAccessor const Path & path, Sink & sink, PathFilter & filter = defaultPathFilter); + + bool operator == (const InputAccessor & x) const + { + return number == x.number; + } + + bool operator < (const InputAccessor & x) const + { + return number < x.number; + } }; struct FSInputAccessor : InputAccessor @@ -94,6 +104,16 @@ struct SourcePath std::string to_string() const; SourcePath append(std::string_view s) const; + + bool operator == (const SourcePath & x) const + { + return std::tie(accessor, path) == std::tie(x.accessor, x.path); + } + + bool operator < (const SourcePath & x) const + { + return std::tie(accessor, path) < std::tie(x.accessor, x.path); + } }; std::ostream & operator << (std::ostream & str, const SourcePath & path);