import, builtins.readFile: Handle diverted stores

Fixes #1791
This commit is contained in:
Eelco Dolstra 2018-01-12 17:31:08 +01:00
parent 435ccc7980
commit 74f75c8558
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
4 changed files with 33 additions and 8 deletions

View file

@ -375,6 +375,16 @@ void EvalState::checkURI(const std::string & uri)
} }
Path EvalState::toRealPath(const Path & path, const PathSet & context)
{
// FIXME: check whether 'path' is in 'context'.
return
!context.empty() && store->isInStore(path)
? store->toRealPath(path)
: path;
};
void EvalState::addConstant(const string & name, Value & v) void EvalState::addConstant(const string & name, Value & v)
{ {
Value * v2 = allocValue(); Value * v2 = allocValue();

View file

@ -112,6 +112,15 @@ public:
void checkURI(const std::string & uri); void checkURI(const std::string & uri);
/* When using a diverted store and 'path' is in the Nix store, map
'path' to the diverted location (e.g. /nix/store/foo is mapped
to /home/alice/my-nix/nix/store/foo). However, this is only
done if the context is not empty, since otherwise we're
probably trying to read from the actual /nix/store. This is
intended to distinguish between import-from-derivation and
sources stored in the actual /nix/store. */
Path toRealPath(const Path & path, const PathSet & context);
/* Parse a Nix expression from the specified file. */ /* Parse a Nix expression from the specified file. */
Expr * parseExprFromFile(const Path & path); Expr * parseExprFromFile(const Path & path);
Expr * parseExprFromFile(const Path & path, StaticEnv & staticEnv); Expr * parseExprFromFile(const Path & path, StaticEnv & staticEnv);

View file

@ -84,10 +84,10 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args
% path % e.path % pos); % path % e.path % pos);
} }
path = state.checkSourcePath(path); Path realPath = state.checkSourcePath(state.toRealPath(path, context));
if (state.store->isStorePath(path) && state.store->isValidPath(path) && isDerivation(path)) { if (state.store->isStorePath(path) && state.store->isValidPath(path) && isDerivation(path)) {
Derivation drv = readDerivation(path); Derivation drv = readDerivation(realPath);
Value & w = *state.allocValue(); Value & w = *state.allocValue();
state.mkAttrs(w, 3 + drv.outputs.size()); state.mkAttrs(w, 3 + drv.outputs.size());
Value * v2 = state.allocAttr(w, state.sDrvPath); Value * v2 = state.allocAttr(w, state.sDrvPath);
@ -114,7 +114,7 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args
} else { } else {
state.forceAttrs(*args[0]); state.forceAttrs(*args[0]);
if (args[0]->attrs->empty()) if (args[0]->attrs->empty())
state.evalFile(path, v); state.evalFile(realPath, v);
else { else {
Env * env = &state.allocEnv(args[0]->attrs->size()); Env * env = &state.allocEnv(args[0]->attrs->size());
env->up = &state.baseEnv; env->up = &state.baseEnv;
@ -127,8 +127,8 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args
env->values[displ++] = attr.value; env->values[displ++] = attr.value;
} }
printTalkative("evaluating file '%1%'", path); printTalkative("evaluating file '%1%'", realPath);
Expr * e = state.parseExprFromFile(resolveExprPath(path), staticEnv); Expr * e = state.parseExprFromFile(resolveExprPath(realPath), staticEnv);
e->eval(state, *env, v); e->eval(state, *env, v);
} }
@ -863,7 +863,7 @@ static void prim_readFile(EvalState & state, const Pos & pos, Value * * args, Va
throw EvalError(format("cannot read '%1%', since path '%2%' is not valid, at %3%") throw EvalError(format("cannot read '%1%', since path '%2%' is not valid, at %3%")
% path % e.path % pos); % path % e.path % pos);
} }
string s = readFile(state.checkSourcePath(path)); string s = readFile(state.checkSourcePath(state.toRealPath(path, context)));
if (s.find((char) 0) != string::npos) if (s.find((char) 0) != string::npos)
throw Error(format("the contents of the file '%1%' cannot be represented as a Nix string") % path); throw Error(format("the contents of the file '%1%' cannot be represented as a Nix string") % path);
mkString(v, s.c_str()); mkString(v, s.c_str());

View file

@ -597,6 +597,11 @@ public:
"nix-cache-info" file. Lower value means higher priority. */ "nix-cache-info" file. Lower value means higher priority. */
virtual int getPriority() { return 0; } virtual int getPriority() { return 0; }
virtual Path toRealPath(const Path & storePath)
{
return storePath;
}
protected: protected:
Stats stats; Stats stats;
@ -639,9 +644,10 @@ public:
virtual Path getRealStoreDir() { return storeDir; } virtual Path getRealStoreDir() { return storeDir; }
Path toRealPath(const Path & storePath) Path toRealPath(const Path & storePath) override
{ {
return getRealStoreDir() + "/" + baseNameOf(storePath); assert(isInStore(storePath));
return getRealStoreDir() + "/" + std::string(storePath, storeDir.size() + 1);
} }
std::shared_ptr<std::string> getBuildLog(const Path & path) override; std::shared_ptr<std::string> getBuildLog(const Path & path) override;