Add MemoryInputAccessor for corepkgs

This commit is contained in:
Eelco Dolstra 2022-02-07 13:14:52 +01:00
parent c56e17b718
commit ffe0dc9a8c
7 changed files with 86 additions and 38 deletions

View file

@ -451,6 +451,7 @@ EvalState::EvalState(
, repair(NoRepair) , repair(NoRepair)
, emptyBindings(0) , emptyBindings(0)
, rootFS(makeFSInputAccessor("")) , rootFS(makeFSInputAccessor(""))
, corepkgsFS(makeMemoryInputAccessor())
, store(store) , store(store)
, buildStore(buildStore ? buildStore : store) , buildStore(buildStore ? buildStore : store)
, regexCache(makeRegexCache()) , regexCache(makeRegexCache())
@ -500,6 +501,11 @@ EvalState::EvalState(
} }
createBaseEnv(); createBaseEnv();
corepkgsFS->addFile(
"/fetchurl.nix",
#include "fetchurl.nix.gen.hh"
);
} }

View file

@ -98,6 +98,7 @@ public:
Bindings emptyBindings; Bindings emptyBindings;
ref<InputAccessor> rootFS; ref<InputAccessor> rootFS;
ref<MemoryInputAccessor> corepkgsFS;
std::unordered_map<size_t, ref<InputAccessor>> inputAccessors; std::unordered_map<size_t, ref<InputAccessor>> inputAccessors;
@ -514,8 +515,6 @@ struct EvalSettings : Config
extern EvalSettings evalSettings; extern EvalSettings evalSettings;
static const std::string corepkgsPrefix{"/__corepkgs__/"};
} }
#include "eval-inline.hh" #include "eval-inline.hh"

View file

@ -788,7 +788,7 @@ Path EvalState::findFile(SearchPath & searchPath, const std::string_view path, c
} }
if (hasPrefix(path, "nix/")) if (hasPrefix(path, "nix/"))
return concatStrings(corepkgsPrefix, path.substr(4)); return packPath(SourcePath {corepkgsFS, (std::string) path.substr(3)});
throw ThrownError({ throw ThrownError({
.msg = hintfmt(evalSettings.pureEval .msg = hintfmt(evalSettings.pureEval

View file

@ -7,6 +7,7 @@ static constexpr std::string_view marker = "/__virtual/";
Path EvalState::packPath(const SourcePath & path) Path EvalState::packPath(const SourcePath & path)
{ {
// FIXME: canonPath(path) ?
printError("PACK %s", path.path); printError("PACK %s", path.path);
assert(hasPrefix(path.path, "/")); assert(hasPrefix(path.path, "/"));
inputAccessors.emplace(path.accessor->number, path.accessor); inputAccessors.emplace(path.accessor->number, path.accessor);

View file

@ -165,15 +165,6 @@ static void import(EvalState & state, const Pos & pos, Value & vPath, Value * vS
{ {
auto path = realisePath(state, pos, vPath); auto path = realisePath(state, pos, vPath);
#if 0
// FIXME: use InputAccessor
if (path == corepkgsPrefix + "fetchurl.nix") {
state.eval(state.parseExprFromString(
#include "fetchurl.nix.gen.hh"
, "/"), v);
}
#endif
state.evalFile(path, v); state.evalFile(path, v);
#if 0 #if 0
@ -216,13 +207,6 @@ static void import(EvalState & state, const Pos & pos, Value & vPath, Value * vS
state.forceAttrs(v, pos); state.forceAttrs(v, pos);
} }
// FIXME: use InputAccessor
else if (path == corepkgsPrefix + "fetchurl.nix") {
state.eval(state.parseExprFromString(
#include "fetchurl.nix.gen.hh"
, "/"), v);
}
else { else {
if (!vScope) if (!vScope)
state.evalFile(path, v); state.evalFile(path, v);
@ -1502,7 +1486,6 @@ static RegisterPrimOp primop_readFile({
which are desugared to 'findFile __nixPath "x"'. */ which are desugared to 'findFile __nixPath "x"'. */
static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Value & v) static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Value & v)
{ {
#if 0
state.forceList(*args[0], pos); state.forceList(*args[0], pos);
SearchPath searchPath; SearchPath searchPath;
@ -1523,7 +1506,18 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
pos pos
); );
auto path = realisePath(state, pos, *i->value, { .requireAbsolutePath = false }); PathSet context;
auto path = state.coerceToString(pos, *i->value, context, false, false).toOwned();
try {
auto rewrites = state.realiseContext(context);
path = rewriteStrings(path, rewrites);
} catch (InvalidPathError & e) {
throw EvalError({
.msg = hintfmt("cannot find '%1%', since path '%2%' is not valid", path, e.path),
.errPos = pos
});
}
searchPath.emplace_back(prefix, path); searchPath.emplace_back(prefix, path);
} }
@ -1532,9 +1526,6 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
// FIXME: checkSourcePath? // FIXME: checkSourcePath?
v.mkPath(state.findFile(searchPath, path, pos)); v.mkPath(state.findFile(searchPath, path, pos));
#endif
throw UnimplementedError("findFile");
} }
static RegisterPrimOp primop_findFile(RegisterPrimOp::Info { static RegisterPrimOp primop_findFile(RegisterPrimOp::Info {

View file

@ -23,7 +23,7 @@ void InputAccessor::dumpPath(
Sink & sink, Sink & sink,
PathFilter & filter) PathFilter & filter)
{ {
auto dumpContents = [&](std::string_view path) auto dumpContents = [&](PathView path)
{ {
// FIXME: pipe // FIXME: pipe
auto s = readFile(path); auto s = readFile(path);
@ -97,7 +97,7 @@ struct FSInputAccessor : InputAccessor
: root(root) : root(root)
{ } { }
std::string readFile(std::string_view path) override std::string readFile(PathView path) override
{ {
auto absPath = makeAbsPath(path); auto absPath = makeAbsPath(path);
printError("READ %s", absPath); printError("READ %s", absPath);
@ -105,14 +105,14 @@ struct FSInputAccessor : InputAccessor
return nix::readFile(absPath); return nix::readFile(absPath);
} }
bool pathExists(std::string_view path) override bool pathExists(PathView path) override
{ {
auto absPath = makeAbsPath(path); auto absPath = makeAbsPath(path);
printError("EXISTS %s", absPath); printError("EXISTS %s", absPath);
return isAllowed(absPath) && nix::pathExists(absPath); return isAllowed(absPath) && nix::pathExists(absPath);
} }
Stat lstat(std::string_view path) override Stat lstat(PathView path) override
{ {
auto absPath = makeAbsPath(path); auto absPath = makeAbsPath(path);
printError("LSTAT %s", absPath); printError("LSTAT %s", absPath);
@ -128,7 +128,7 @@ struct FSInputAccessor : InputAccessor
}; };
} }
DirEntries readDirectory(std::string_view path) override DirEntries readDirectory(PathView path) override
{ {
auto absPath = makeAbsPath(path); auto absPath = makeAbsPath(path);
printError("READDIR %s", absPath); printError("READDIR %s", absPath);
@ -136,7 +136,7 @@ struct FSInputAccessor : InputAccessor
abort(); abort();
} }
std::string readLink(std::string_view path) override std::string readLink(PathView path) override
{ {
auto absPath = makeAbsPath(path); auto absPath = makeAbsPath(path);
printError("READLINK %s", absPath); printError("READLINK %s", absPath);
@ -144,19 +144,19 @@ struct FSInputAccessor : InputAccessor
return nix::readLink(absPath); return nix::readLink(absPath);
} }
Path makeAbsPath(std::string_view path) Path makeAbsPath(PathView path)
{ {
assert(hasPrefix(path, "/")); assert(hasPrefix(path, "/"));
return canonPath(root + std::string(path)); return canonPath(root + std::string(path));
} }
void checkAllowed(std::string_view absPath) void checkAllowed(PathView absPath)
{ {
if (!isAllowed(absPath)) if (!isAllowed(absPath))
throw Error("access to path '%s' is not allowed", absPath); throw Error("access to path '%s' is not allowed", absPath);
} }
bool isAllowed(std::string_view absPath) bool isAllowed(PathView absPath)
{ {
if (!isDirOrInDir(absPath, root)) if (!isDirOrInDir(absPath, root))
return false; return false;
@ -175,4 +175,48 @@ std::ostream & operator << (std::ostream & str, const SourcePath & path)
return str; return str;
} }
struct MemoryInputAccessorImpl : MemoryInputAccessor
{
std::map<Path, std::string> files;
std::string readFile(PathView path) override
{
auto i = files.find((Path) path);
if (i == files.end())
throw Error("file '%s' does not exist", path);
return i->second;
}
bool pathExists(PathView path) override
{
auto i = files.find((Path) path);
return i != files.end();
}
Stat lstat(PathView path) override
{
throw UnimplementedError("MemoryInputAccessor::lstat");
}
DirEntries readDirectory(PathView path) override
{
return {};
}
std::string readLink(PathView path) override
{
throw UnimplementedError("MemoryInputAccessor::readLink");
}
void addFile(PathView path, std::string && contents) override
{
files.emplace(path, std::move(contents));
}
};
ref<MemoryInputAccessor> makeMemoryInputAccessor()
{
return make_ref<MemoryInputAccessorImpl>();
}
} }

View file

@ -15,9 +15,9 @@ struct InputAccessor
virtual ~InputAccessor() virtual ~InputAccessor()
{ } { }
virtual std::string readFile(std::string_view path) = 0; virtual std::string readFile(PathView path) = 0;
virtual bool pathExists(std::string_view path) = 0; virtual bool pathExists(PathView path) = 0;
enum Type { tRegular, tSymlink, tDirectory, tMisc }; enum Type { tRegular, tSymlink, tDirectory, tMisc };
@ -28,15 +28,15 @@ struct InputAccessor
bool isExecutable = false; // regular files only bool isExecutable = false; // regular files only
}; };
virtual Stat lstat(std::string_view path) = 0; virtual Stat lstat(PathView path) = 0;
typedef std::optional<Type> DirEntry; typedef std::optional<Type> DirEntry;
typedef std::map<std::string, DirEntry> DirEntries; typedef std::map<std::string, DirEntry> DirEntries;
virtual DirEntries readDirectory(std::string_view path) = 0; virtual DirEntries readDirectory(PathView path) = 0;
virtual std::string readLink(std::string_view path) = 0; virtual std::string readLink(PathView path) = 0;
virtual void dumpPath( virtual void dumpPath(
const Path & path, const Path & path,
@ -46,6 +46,13 @@ struct InputAccessor
ref<InputAccessor> makeFSInputAccessor(const Path & root); ref<InputAccessor> makeFSInputAccessor(const Path & root);
struct MemoryInputAccessor : InputAccessor
{
virtual void addFile(PathView path, std::string && contents) = 0;
};
ref<MemoryInputAccessor> makeMemoryInputAccessor();
struct SourcePath struct SourcePath
{ {
ref<InputAccessor> accessor; ref<InputAccessor> accessor;