mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-23 22:46:16 +02:00
Checkpoint
This commit is contained in:
parent
00b0fb27c1
commit
06c1edf889
18 changed files with 134 additions and 120 deletions
|
@ -396,8 +396,11 @@ Value & AttrCursor::forceValue()
|
||||||
if (v.type() == nString)
|
if (v.type() == nString)
|
||||||
cachedValue = {root->db->setString(getKey(), v.string.s, v.string.context),
|
cachedValue = {root->db->setString(getKey(), v.string.s, v.string.context),
|
||||||
string_t{v.string.s, {}}};
|
string_t{v.string.s, {}}};
|
||||||
else if (v.type() == nPath)
|
else if (v.type() == nPath) {
|
||||||
cachedValue = {root->db->setString(getKey(), v.path), string_t{v.path, {}}};
|
// FIXME: take accessor into account?
|
||||||
|
auto path = v.path().path;
|
||||||
|
cachedValue = {root->db->setString(getKey(), path), string_t{path, {}}};
|
||||||
|
}
|
||||||
else if (v.type() == nBool)
|
else if (v.type() == nBool)
|
||||||
cachedValue = {root->db->setBool(getKey(), v.boolean), v.boolean};
|
cachedValue = {root->db->setBool(getKey(), v.boolean), v.boolean};
|
||||||
else if (v.type() == nAttrs)
|
else if (v.type() == nAttrs)
|
||||||
|
@ -537,7 +540,7 @@ std::string AttrCursor::getString()
|
||||||
if (v.type() != nString && v.type() != nPath)
|
if (v.type() != nString && v.type() != nPath)
|
||||||
throw TypeError("'%s' is not a string but %s", getAttrPathStr(), showType(v.type()));
|
throw TypeError("'%s' is not a string but %s", getAttrPathStr(), showType(v.type()));
|
||||||
|
|
||||||
return v.type() == nString ? v.string.s : v.path;
|
return v.type() == nString ? v.string.s : v.path().to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
string_t AttrCursor::getStringWithContext()
|
string_t AttrCursor::getStringWithContext()
|
||||||
|
@ -568,7 +571,7 @@ string_t AttrCursor::getStringWithContext()
|
||||||
if (v.type() == nString)
|
if (v.type() == nString)
|
||||||
return {v.string.s, v.getContext(*root->state.store)};
|
return {v.string.s, v.getContext(*root->state.store)};
|
||||||
else if (v.type() == nPath)
|
else if (v.type() == nPath)
|
||||||
return {v.path, {}};
|
return {v.path().to_string(), {}};
|
||||||
else
|
else
|
||||||
throw TypeError("'%s' is not a string but %s", getAttrPathStr(), showType(v.type()));
|
throw TypeError("'%s' is not a string but %s", getAttrPathStr(), showType(v.type()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,7 @@ void Value::print(std::ostream & str, std::set<const void *> * seen) const
|
||||||
str << "\"";
|
str << "\"";
|
||||||
break;
|
break;
|
||||||
case tPath:
|
case tPath:
|
||||||
str << path; // !!! escaping?
|
str << path().to_string(); // !!! escaping?
|
||||||
break;
|
break;
|
||||||
case tNull:
|
case tNull:
|
||||||
str << "null";
|
str << "null";
|
||||||
|
@ -721,11 +721,6 @@ std::optional<EvalState::Doc> EvalState::getDoc(Value & v)
|
||||||
evaluator. So here are some helper functions for throwing
|
evaluator. So here are some helper functions for throwing
|
||||||
exceptions. */
|
exceptions. */
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwEvalError(const char * s, const std::string & s2))
|
|
||||||
{
|
|
||||||
throw EvalError(s, s2);
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const Suggestions & suggestions, const char * s, const std::string & s2))
|
LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const Suggestions & suggestions, const char * s, const std::string & s2))
|
||||||
{
|
{
|
||||||
throw EvalError(ErrorInfo {
|
throw EvalError(ErrorInfo {
|
||||||
|
@ -862,9 +857,12 @@ void Value::mkStringMove(const char * s, const PathSet & context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Value::mkPath(std::string_view s)
|
void Value::mkPath(const SourcePath & path)
|
||||||
{
|
{
|
||||||
mkPath(makeImmutableString(s));
|
clearValue();
|
||||||
|
internalType = tPath;
|
||||||
|
_path.accessor = &path.accessor;
|
||||||
|
_path.path = makeImmutableString(path.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -978,24 +976,19 @@ Value * ExprPath::maybeThunk(EvalState & state, Env & env)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EvalState::evalFile(const SourcePath & path_, Value & v, bool mustBeTrivial)
|
void EvalState::evalFile(const SourcePath & path, Value & v, bool mustBeTrivial)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
auto path = checkSourcePath(path_);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto path = packPath(path_);
|
|
||||||
|
|
||||||
// FIXME: use SourcePath as cache key
|
// FIXME: use SourcePath as cache key
|
||||||
|
auto pathKey = path.to_string();
|
||||||
FileEvalCache::iterator i;
|
FileEvalCache::iterator i;
|
||||||
if ((i = fileEvalCache.find(path)) != fileEvalCache.end()) {
|
if ((i = fileEvalCache.find(pathKey)) != fileEvalCache.end()) {
|
||||||
v = i->second;
|
v = i->second;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resolvedPath_ = resolveExprPath(path_);
|
auto resolvedPath = resolveExprPath(path);
|
||||||
auto resolvedPath = packPath(resolvedPath_);
|
auto resolvedPathKey = resolvedPath.to_string();
|
||||||
if ((i = fileEvalCache.find(resolvedPath)) != fileEvalCache.end()) {
|
if ((i = fileEvalCache.find(resolvedPathKey)) != fileEvalCache.end()) {
|
||||||
v = i->second;
|
v = i->second;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1003,17 +996,17 @@ void EvalState::evalFile(const SourcePath & path_, Value & v, bool mustBeTrivial
|
||||||
printTalkative("evaluating file '%1%'", resolvedPath);
|
printTalkative("evaluating file '%1%'", resolvedPath);
|
||||||
Expr * e = nullptr;
|
Expr * e = nullptr;
|
||||||
|
|
||||||
auto j = fileParseCache.find(resolvedPath);
|
auto j = fileParseCache.find(resolvedPathKey);
|
||||||
if (j != fileParseCache.end())
|
if (j != fileParseCache.end())
|
||||||
e = j->second;
|
e = j->second;
|
||||||
|
|
||||||
if (!e)
|
if (!e)
|
||||||
e = parseExprFromFile(resolvedPath_);
|
e = parseExprFromFile(resolvedPath);
|
||||||
#if 0
|
#if 0
|
||||||
e = parseExprFromFile(checkSourcePath(resolvedPath));
|
e = parseExprFromFile(checkSourcePath(resolvedPath));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cacheFile(path, resolvedPath, e, v, mustBeTrivial);
|
cacheFile(pathKey, resolvedPathKey, e, v, mustBeTrivial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1790,9 +1783,9 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
||||||
throwEvalError(i_pos, "cannot add %1% to a float", showType(vTmp));
|
throwEvalError(i_pos, "cannot add %1% to a float", showType(vTmp));
|
||||||
} else {
|
} else {
|
||||||
if (s.empty()) s.reserve(es->size());
|
if (s.empty()) s.reserve(es->size());
|
||||||
/* skip canonization of first path, which would only be not
|
/* Skip canonization of first path, which would only be
|
||||||
canonized in the first place if it's coming from a ./${foo} type
|
non-canonical in the first place if it's coming from a
|
||||||
path */
|
./${foo} type path. */
|
||||||
auto part = state.coerceToString(i_pos, vTmp, context, false, firstType == nString, !first);
|
auto part = state.coerceToString(i_pos, vTmp, context, false, firstType == nString, !first);
|
||||||
sSize += part->size();
|
sSize += part->size();
|
||||||
s.emplace_back(std::move(part));
|
s.emplace_back(std::move(part));
|
||||||
|
@ -1808,7 +1801,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
||||||
else if (firstType == nPath) {
|
else if (firstType == nPath) {
|
||||||
if (!context.empty())
|
if (!context.empty())
|
||||||
throwEvalError(pos, "a string that refers to a store path cannot be appended to a path");
|
throwEvalError(pos, "a string that refers to a store path cannot be appended to a path");
|
||||||
v.mkPath(canonPath(str()));
|
v.mkPath({.accessor = *values[0]._path.accessor, .path = canonPath(str())});
|
||||||
} else
|
} else
|
||||||
v.mkStringMove(c_str(), context);
|
v.mkStringMove(c_str(), context);
|
||||||
}
|
}
|
||||||
|
@ -2005,11 +1998,12 @@ BackedStringView EvalState::coerceToString(const Pos & pos, Value & v, PathSet &
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v.type() == nPath) {
|
if (v.type() == nPath) {
|
||||||
BackedStringView path(PathView(v.path));
|
auto path = v.path().to_string();
|
||||||
if (canonicalizePath)
|
if (canonicalizePath)
|
||||||
path = canonPath(*path);
|
// FIXME: unnecessary?
|
||||||
|
path = canonPath(path);
|
||||||
if (copyToStore)
|
if (copyToStore)
|
||||||
path = copyPathToStore(context, std::move(path).toOwned());
|
path = copyPathToStore(context, path);
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2054,6 +2048,7 @@ BackedStringView EvalState::coerceToString(const Pos & pos, Value & v, PathSet &
|
||||||
|
|
||||||
std::string EvalState::copyPathToStore(PathSet & context, const Path & path)
|
std::string EvalState::copyPathToStore(PathSet & context, const Path & path)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
if (nix::isDerivation(path))
|
if (nix::isDerivation(path))
|
||||||
throwEvalError("file names are not allowed to end in '%1%'", drvExtension);
|
throwEvalError("file names are not allowed to end in '%1%'", drvExtension);
|
||||||
|
|
||||||
|
@ -2070,7 +2065,7 @@ std::string EvalState::copyPathToStore(PathSet & context, const Path & path)
|
||||||
: store->addToStore(path2.baseName(), canonPath(path), FileIngestionMethod::Recursive, htSHA256, defaultPathFilter, repair);
|
: store->addToStore(path2.baseName(), canonPath(path), FileIngestionMethod::Recursive, htSHA256, defaultPathFilter, repair);
|
||||||
#endif
|
#endif
|
||||||
auto source = sinkToSource([&](Sink & sink) {
|
auto source = sinkToSource([&](Sink & sink) {
|
||||||
path2.accessor->dumpPath(path2.path, sink);
|
path2.dumpPath(sink);
|
||||||
});
|
});
|
||||||
// FIXME: readOnlyMode
|
// FIXME: readOnlyMode
|
||||||
auto p = store->addToStoreFromDump(*source, path2.baseName(), FileIngestionMethod::Recursive, htSHA256, repair);
|
auto p = store->addToStoreFromDump(*source, path2.baseName(), FileIngestionMethod::Recursive, htSHA256, repair);
|
||||||
|
@ -2082,15 +2077,18 @@ std::string EvalState::copyPathToStore(PathSet & context, const Path & path)
|
||||||
|
|
||||||
context.insert(dstPath);
|
context.insert(dstPath);
|
||||||
return dstPath;
|
return dstPath;
|
||||||
|
#endif
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Path EvalState::coerceToPath(const Pos & pos, Value & v, PathSet & context)
|
SourcePath EvalState::coerceToPath(const Pos & pos, Value & v, PathSet & context)
|
||||||
{
|
{
|
||||||
auto path = coerceToString(pos, v, context, false, false).toOwned();
|
auto path = coerceToString(pos, v, context, false, false).toOwned();
|
||||||
if (path == "" || path[0] != '/')
|
if (path == "" || path[0] != '/')
|
||||||
throwEvalError(pos, "string '%1%' doesn't represent an absolute path", path);
|
throwEvalError(pos, "string '%1%' doesn't represent an absolute path", path);
|
||||||
return path;
|
// FIXME
|
||||||
|
return rootPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2137,7 +2135,9 @@ bool EvalState::eqValues(Value & v1, Value & v2)
|
||||||
return strcmp(v1.string.s, v2.string.s) == 0;
|
return strcmp(v1.string.s, v2.string.s) == 0;
|
||||||
|
|
||||||
case nPath:
|
case nPath:
|
||||||
return strcmp(v1.path, v2.path) == 0;
|
return
|
||||||
|
v1._path.accessor == v2._path.accessor
|
||||||
|
&& strcmp(v1._path.path, v2._path.path) == 0;
|
||||||
|
|
||||||
case nNull:
|
case nNull:
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -96,7 +96,7 @@ public:
|
||||||
ref<FSInputAccessor> rootFS;
|
ref<FSInputAccessor> rootFS;
|
||||||
ref<MemoryInputAccessor> corepkgsFS;
|
ref<MemoryInputAccessor> corepkgsFS;
|
||||||
|
|
||||||
std::unordered_map<size_t, ref<InputAccessor>> inputAccessors;
|
std::unordered_map<InputAccessor *, ref<InputAccessor>> inputAccessors;
|
||||||
|
|
||||||
/* Store used to materialise .drv files. */
|
/* Store used to materialise .drv files. */
|
||||||
const ref<Store> store;
|
const ref<Store> store;
|
||||||
|
@ -156,11 +156,9 @@ public:
|
||||||
|
|
||||||
SearchPath getSearchPath() { return searchPath; }
|
SearchPath getSearchPath() { return searchPath; }
|
||||||
|
|
||||||
Path packPath(const SourcePath & path);
|
SourcePath rootPath(Path path);
|
||||||
|
|
||||||
SourcePath unpackPath(const Path & path);
|
InputAccessor & registerAccessor(ref<InputAccessor> accessor);
|
||||||
|
|
||||||
SourcePath rootPath(const Path & path);
|
|
||||||
|
|
||||||
/* Allow access to a path. */
|
/* Allow access to a path. */
|
||||||
void allowPath(const Path & path);
|
void allowPath(const Path & path);
|
||||||
|
@ -274,8 +272,7 @@ public:
|
||||||
/* Path coercion. Converts strings, paths and derivations to a
|
/* Path coercion. Converts strings, paths and derivations to a
|
||||||
path. The result is guaranteed to be a canonicalised, absolute
|
path. The result is guaranteed to be a canonicalised, absolute
|
||||||
path. Nothing is copied to the store. */
|
path. Nothing is copied to the store. */
|
||||||
// FIXME: return SourcePath
|
SourcePath coerceToPath(const Pos & pos, Value & v, PathSet & context);
|
||||||
Path coerceToPath(const Pos & pos, Value & v, PathSet & context);
|
|
||||||
|
|
||||||
/* Like coerceToPath, but the result must be a store path. */
|
/* Like coerceToPath, but the result must be a store path. */
|
||||||
StorePath coerceToStorePath(const Pos & pos, Value & v, PathSet & context);
|
StorePath coerceToStorePath(const Pos & pos, Value & v, PathSet & context);
|
||||||
|
|
|
@ -201,7 +201,7 @@ static std::map<FlakeId, FlakeInput> parseFlakeInputs(
|
||||||
static Flake readFlake(
|
static Flake readFlake(
|
||||||
EvalState & state,
|
EvalState & state,
|
||||||
const FlakeRef & lockedRef,
|
const FlakeRef & lockedRef,
|
||||||
nix::ref<InputAccessor> accessor,
|
InputAccessor & accessor,
|
||||||
const InputPath & lockRootPath)
|
const InputPath & lockRootPath)
|
||||||
{
|
{
|
||||||
auto flakeDir = canonPath("/" + lockedRef.subdir);
|
auto flakeDir = canonPath("/" + lockedRef.subdir);
|
||||||
|
@ -213,14 +213,14 @@ static Flake readFlake(
|
||||||
Value vInfo;
|
Value vInfo;
|
||||||
state.evalFile(flakePath, vInfo, true);
|
state.evalFile(flakePath, vInfo, true);
|
||||||
|
|
||||||
expectType(state, nAttrs, vInfo, Pos(foFile, state.symbols.create(state.packPath(flakePath)), 0, 0));
|
expectType(state, nAttrs, vInfo, Pos(foFile, state.symbols.create(flakePath.to_string()), 0, 0));
|
||||||
|
|
||||||
Flake flake {
|
Flake flake {
|
||||||
// FIXME
|
// FIXME
|
||||||
.originalRef = lockedRef,
|
.originalRef = lockedRef,
|
||||||
.resolvedRef = lockedRef,
|
.resolvedRef = lockedRef,
|
||||||
.lockedRef = lockedRef,
|
.lockedRef = lockedRef,
|
||||||
.accessor = accessor,
|
.accessor = ptr(&accessor),
|
||||||
.flakePath = dirOf(flakePath.path),
|
.flakePath = dirOf(flakePath.path),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -308,7 +308,7 @@ static Flake getFlake(
|
||||||
// FIXME: resolve
|
// FIXME: resolve
|
||||||
auto [accessor, input] = originalRef.input.lazyFetch(state.store);
|
auto [accessor, input] = originalRef.input.lazyFetch(state.store);
|
||||||
|
|
||||||
return readFlake(state, originalRef, accessor, lockRootPath);
|
return readFlake(state, originalRef, state.registerAccessor(accessor), lockRootPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
Flake getFlake(EvalState & state, const FlakeRef & originalRef, bool allowLookup, FlakeCache & flakeCache)
|
Flake getFlake(EvalState & state, const FlakeRef & originalRef, bool allowLookup, FlakeCache & flakeCache)
|
||||||
|
@ -324,7 +324,7 @@ Flake getFlake(EvalState & state, const FlakeRef & originalRef, bool allowLookup
|
||||||
|
|
||||||
static LockFile readLockFile(const Flake & flake)
|
static LockFile readLockFile(const Flake & flake)
|
||||||
{
|
{
|
||||||
SourcePath lockFilePath{flake.accessor, canonPath(flake.flakePath + "/flake.lock")};
|
SourcePath lockFilePath{*flake.accessor, canonPath(flake.flakePath + "/flake.lock")};
|
||||||
return lockFilePath.pathExists()
|
return lockFilePath.pathExists()
|
||||||
? LockFile(lockFilePath.readFile(), fmt("%s", lockFilePath))
|
? LockFile(lockFilePath.readFile(), fmt("%s", lockFilePath))
|
||||||
: LockFile();
|
: LockFile();
|
||||||
|
@ -703,7 +703,7 @@ void callFlake(EvalState & state,
|
||||||
|
|
||||||
emitTreeAttrs(
|
emitTreeAttrs(
|
||||||
state,
|
state,
|
||||||
{lockedFlake.flake.accessor, lockedFlake.flake.flakePath},
|
{*lockedFlake.flake.accessor, lockedFlake.flake.flakePath},
|
||||||
lockedFlake.flake.lockedRef.input,
|
lockedFlake.flake.lockedRef.input,
|
||||||
*vRootSrc,
|
*vRootSrc,
|
||||||
false,
|
false,
|
||||||
|
|
|
@ -61,7 +61,7 @@ struct Flake
|
||||||
FlakeRef originalRef; // the original flake specification (by the user)
|
FlakeRef originalRef; // the original flake specification (by the user)
|
||||||
FlakeRef resolvedRef; // registry references and caching resolved to the specific underlying flake
|
FlakeRef resolvedRef; // registry references and caching resolved to the specific underlying flake
|
||||||
FlakeRef lockedRef; // the specific local store result of invoking the fetcher
|
FlakeRef lockedRef; // the specific local store result of invoking the fetcher
|
||||||
ref<InputAccessor> accessor;
|
ptr<InputAccessor> accessor;
|
||||||
Path flakePath;
|
Path flakePath;
|
||||||
bool forceDirty = false; // pretend that 'lockedRef' is dirty
|
bool forceDirty = false; // pretend that 'lockedRef' is dirty
|
||||||
std::optional<std::string> description;
|
std::optional<std::string> description;
|
||||||
|
|
|
@ -121,9 +121,13 @@ struct ExprString : Expr
|
||||||
|
|
||||||
struct ExprPath : Expr
|
struct ExprPath : Expr
|
||||||
{
|
{
|
||||||
std::string s;
|
std::string s; // FIXME: remove
|
||||||
Value v;
|
Value v;
|
||||||
ExprPath(std::string s) : s(std::move(s)) { v.mkPath(this->s.c_str()); };
|
ExprPath(InputAccessor & accessor, std::string s)
|
||||||
|
: s(std::move(s))
|
||||||
|
{
|
||||||
|
v.mkPath({accessor, this->s});
|
||||||
|
}
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
Value * maybeThunk(EvalState & state, Env & env);
|
Value * maybeThunk(EvalState & state, Env & env);
|
||||||
};
|
};
|
||||||
|
|
|
@ -517,11 +517,11 @@ path_start
|
||||||
/* add back in the trailing '/' to the first segment */
|
/* add back in the trailing '/' to the first segment */
|
||||||
if ($1.p[$1.l-1] == '/' && $1.l > 1)
|
if ($1.p[$1.l-1] == '/' && $1.l > 1)
|
||||||
path += "/";
|
path += "/";
|
||||||
$$ = new ExprPath(path);
|
$$ = new ExprPath(*data->state.rootFS, path);
|
||||||
}
|
}
|
||||||
| HPATH {
|
| HPATH {
|
||||||
Path path(getHome() + std::string($1.p + 1, $1.l - 1));
|
Path path(getHome() + std::string($1.p + 1, $1.l - 1));
|
||||||
$$ = new ExprPath(path);
|
$$ = new ExprPath(*data->state.rootFS, path);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -700,7 +700,7 @@ SourcePath resolveExprPath(const SourcePath & path)
|
||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
auto path2 = path.path + "/default.nix";
|
auto path2 = path.path + "/default.nix";
|
||||||
if (path.accessor->pathExists(path2))
|
if (path.pathExists())
|
||||||
return {path.accessor, path2};
|
return {path.accessor, path2};
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
|
@ -715,11 +715,11 @@ Expr * EvalState::parseExprFromFile(const SourcePath & path)
|
||||||
|
|
||||||
Expr * EvalState::parseExprFromFile(const SourcePath & path, StaticEnv & staticEnv)
|
Expr * EvalState::parseExprFromFile(const SourcePath & path, StaticEnv & staticEnv)
|
||||||
{
|
{
|
||||||
auto packed = packPath(path);
|
|
||||||
auto buffer = path.readFile();
|
auto buffer = path.readFile();
|
||||||
// readFile hopefully have left some extra space for terminators
|
// readFile hopefully have left some extra space for terminators
|
||||||
buffer.append("\0\0", 2);
|
buffer.append("\0\0", 2);
|
||||||
return parse(buffer.data(), buffer.size(), foFile, packed, dirOf(packed), staticEnv);
|
// FIXME: pass SourcePaths
|
||||||
|
return parse(buffer.data(), buffer.size(), foFile, path.path, dirOf(path.path), staticEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -788,7 +788,8 @@ Path EvalState::findFile(SearchPath & searchPath, const std::string_view path, c
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasPrefix(path, "nix/"))
|
if (hasPrefix(path, "nix/"))
|
||||||
return packPath(SourcePath {corepkgsFS, (std::string) path.substr(3)});
|
abort();
|
||||||
|
//return packPath(SourcePath {corepkgsFS, (std::string) path.substr(3)});
|
||||||
|
|
||||||
throw ThrownError({
|
throw ThrownError({
|
||||||
.msg = hintfmt(evalSettings.pureEval
|
.msg = hintfmt(evalSettings.pureEval
|
||||||
|
|
|
@ -3,34 +3,15 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
static constexpr std::string_view marker = "/__virtual/";
|
SourcePath EvalState::rootPath(Path path)
|
||||||
|
|
||||||
Path EvalState::packPath(const SourcePath & path)
|
|
||||||
{
|
{
|
||||||
// FIXME: canonPath(path) ?
|
return {*rootFS, std::move(path)};
|
||||||
assert(hasPrefix(path.path, "/"));
|
|
||||||
inputAccessors.emplace(path.accessor->number, path.accessor);
|
|
||||||
return std::string(marker) + std::to_string(path.accessor->number) + path.path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SourcePath EvalState::unpackPath(const Path & path)
|
InputAccessor & EvalState::registerAccessor(ref<InputAccessor> accessor)
|
||||||
{
|
{
|
||||||
if (hasPrefix(path, marker)) {
|
inputAccessors.emplace(&*accessor, accessor);
|
||||||
auto s = path.substr(marker.size());
|
return *accessor;
|
||||||
auto slash = s.find('/');
|
|
||||||
auto n = std::stoi(s.substr(0, slash));
|
|
||||||
auto i = inputAccessors.find(n);
|
|
||||||
assert(i != inputAccessors.end());
|
|
||||||
return {i->second, slash != std::string::npos ? s.substr(slash) : "/"};
|
|
||||||
} else {
|
|
||||||
printError("FIXME: %s", path);
|
|
||||||
return rootPath(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SourcePath EvalState::rootPath(const Path & path)
|
|
||||||
{
|
|
||||||
return {rootFS, path};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ static SourcePath realisePath(EvalState & state, const Pos & pos, Value & v, con
|
||||||
auto path = [&]()
|
auto path = [&]()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return state.unpackPath(state.coerceToPath(pos, v, context));
|
return state.coerceToPath(pos, v, context);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(pos, "while realising the context of a path");
|
e.addTrace(pos, "while realising the context of a path");
|
||||||
throw;
|
throw;
|
||||||
|
@ -557,7 +557,8 @@ struct CompareValues
|
||||||
case nString:
|
case nString:
|
||||||
return strcmp(v1->string.s, v2->string.s) < 0;
|
return strcmp(v1->string.s, v2->string.s) < 0;
|
||||||
case nPath:
|
case nPath:
|
||||||
return strcmp(v1->path, v2->path) < 0;
|
// FIXME: handle accessor?
|
||||||
|
return strcmp(v1->_path.path, v2->_path.path) < 0;
|
||||||
case nList:
|
case nList:
|
||||||
// Lexicographic comparison
|
// Lexicographic comparison
|
||||||
for (size_t i = 0;; i++) {
|
for (size_t i = 0;; i++) {
|
||||||
|
@ -1315,8 +1316,8 @@ static RegisterPrimOp primop_placeholder({
|
||||||
static void prim_toPath(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_toPath(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
Path path = state.coerceToPath(pos, *args[0], context);
|
auto path = state.coerceToPath(pos, *args[0], context);
|
||||||
v.mkString(canonPath(path), context);
|
v.mkString(canonPath(path.path), context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_toPath({
|
static RegisterPrimOp primop_toPath({
|
||||||
|
@ -1347,7 +1348,7 @@ static void prim_storePath(EvalState & state, const Pos & pos, Value * * args, V
|
||||||
|
|
||||||
PathSet context;
|
PathSet context;
|
||||||
// FIXME: check rootPath
|
// FIXME: check rootPath
|
||||||
Path path = state.coerceToPath(pos, *args[0], context);
|
auto path = state.coerceToPath(pos, *args[0], context).path;
|
||||||
/* Resolve symlinks in ‘path’, unless ‘path’ itself is a symlink
|
/* Resolve symlinks in ‘path’, unless ‘path’ itself is a symlink
|
||||||
directly in the store. The latter condition is necessary so
|
directly in the store. The latter condition is necessary so
|
||||||
e.g. nix-push does the right thing. */
|
e.g. nix-push does the right thing. */
|
||||||
|
@ -1439,7 +1440,10 @@ static void prim_dirOf(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
PathSet context;
|
PathSet context;
|
||||||
auto path = state.coerceToString(pos, *args[0], context, false, false);
|
auto path = state.coerceToString(pos, *args[0], context, false, false);
|
||||||
auto dir = dirOf(*path);
|
auto dir = dirOf(*path);
|
||||||
|
abort();
|
||||||
|
#if 0
|
||||||
if (args[0]->type() == nPath) v.mkPath(dir); else v.mkString(dir, context);
|
if (args[0]->type() == nPath) v.mkPath(dir); else v.mkString(dir, context);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_dirOf({
|
static RegisterPrimOp primop_dirOf({
|
||||||
|
@ -1520,8 +1524,11 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
|
|
||||||
auto path = state.forceStringNoCtx(*args[1], pos);
|
auto path = state.forceStringNoCtx(*args[1], pos);
|
||||||
|
|
||||||
|
#if 0
|
||||||
// FIXME: checkSourcePath?
|
// FIXME: checkSourcePath?
|
||||||
v.mkPath(state.findFile(searchPath, path, pos));
|
v.mkPath(state.findFile(searchPath, path, pos));
|
||||||
|
#endif
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_findFile(RegisterPrimOp::Info {
|
static RegisterPrimOp primop_findFile(RegisterPrimOp::Info {
|
||||||
|
@ -1563,7 +1570,7 @@ static void prim_readDir(EvalState & state, const Pos & pos, Value * * args, Val
|
||||||
{
|
{
|
||||||
auto path = realisePath(state, pos, *args[0]);
|
auto path = realisePath(state, pos, *args[0]);
|
||||||
|
|
||||||
auto entries = path.accessor->readDirectory(path.path);
|
auto entries = path.readDirectory();
|
||||||
auto attrs = state.buildBindings(entries.size());
|
auto attrs = state.buildBindings(entries.size());
|
||||||
|
|
||||||
for (auto & [name, type] : entries) {
|
for (auto & [name, type] : entries) {
|
||||||
|
@ -1881,7 +1888,7 @@ static RegisterPrimOp primop_toFile({
|
||||||
static void addPath(
|
static void addPath(
|
||||||
EvalState & state,
|
EvalState & state,
|
||||||
const Pos & pos,
|
const Pos & pos,
|
||||||
const std::string & name,
|
std::string_view name,
|
||||||
Path path,
|
Path path,
|
||||||
Value * filterFun,
|
Value * filterFun,
|
||||||
FileIngestionMethod method,
|
FileIngestionMethod method,
|
||||||
|
@ -1959,7 +1966,7 @@ static void addPath(
|
||||||
static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
Path path = state.coerceToPath(pos, *args[1], context);
|
auto path = state.coerceToPath(pos, *args[1], context);
|
||||||
|
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
if (args[0]->type() != nFunction)
|
if (args[0]->type() != nFunction)
|
||||||
|
@ -1970,7 +1977,8 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args
|
||||||
.errPos = pos
|
.errPos = pos
|
||||||
});
|
});
|
||||||
|
|
||||||
addPath(state, pos, std::string(baseNameOf(path)), path, args[0], FileIngestionMethod::Recursive, std::nullopt, v, context);
|
// FIXME: use SourcePath
|
||||||
|
addPath(state, pos, path.baseName(), path.path, args[0], FileIngestionMethod::Recursive, std::nullopt, v, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_filterSource({
|
static RegisterPrimOp primop_filterSource({
|
||||||
|
@ -2031,7 +2039,7 @@ static RegisterPrimOp primop_filterSource({
|
||||||
static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceAttrs(*args[0], pos);
|
state.forceAttrs(*args[0], pos);
|
||||||
Path path;
|
std::optional<SourcePath> path;
|
||||||
std::string name;
|
std::string name;
|
||||||
Value * filterFun = nullptr;
|
Value * filterFun = nullptr;
|
||||||
auto method = FileIngestionMethod::Recursive;
|
auto method = FileIngestionMethod::Recursive;
|
||||||
|
@ -2041,7 +2049,7 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
for (auto & attr : *args[0]->attrs) {
|
for (auto & attr : *args[0]->attrs) {
|
||||||
auto & n(attr.name);
|
auto & n(attr.name);
|
||||||
if (n == "path")
|
if (n == "path")
|
||||||
path = state.coerceToPath(*attr.pos, *attr.value, context);
|
path.emplace(state.coerceToPath(*attr.pos, *attr.value, context));
|
||||||
else if (attr.name == state.sName)
|
else if (attr.name == state.sName)
|
||||||
name = state.forceStringNoCtx(*attr.value, *attr.pos);
|
name = state.forceStringNoCtx(*attr.value, *attr.pos);
|
||||||
else if (n == "filter") {
|
else if (n == "filter") {
|
||||||
|
@ -2057,15 +2065,16 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
.errPos = *attr.pos
|
.errPos = *attr.pos
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (path.empty())
|
if (!path)
|
||||||
throw EvalError({
|
throw EvalError({
|
||||||
.msg = hintfmt("'path' required"),
|
.msg = hintfmt("'path' required"),
|
||||||
.errPos = pos
|
.errPos = pos
|
||||||
});
|
});
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
name = baseNameOf(path);
|
name = path->baseName();
|
||||||
|
|
||||||
addPath(state, pos, name, path, filterFun, method, expectedHash, v, context);
|
// FIXME: use SourcePath
|
||||||
|
addPath(state, pos, name, path->path, filterFun, method, expectedHash, v, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_path({
|
static RegisterPrimOp primop_path({
|
||||||
|
|
|
@ -30,7 +30,7 @@ void emitTreeAttrs(
|
||||||
attrs.alloc(state.sOutPath).mkString(storePath, {storePath});
|
attrs.alloc(state.sOutPath).mkString(storePath, {storePath});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
attrs.alloc(state.sOutPath).mkPath(state.packPath(path));
|
attrs.alloc(state.sOutPath).mkPath(path);
|
||||||
|
|
||||||
// FIXME: support arbitrary input attributes.
|
// FIXME: support arbitrary input attributes.
|
||||||
|
|
||||||
|
@ -138,8 +138,8 @@ static void fetchTree(
|
||||||
for (auto elem : attr.value->listItems()) {
|
for (auto elem : attr.value->listItems()) {
|
||||||
// FIXME: use realisePath
|
// FIXME: use realisePath
|
||||||
PathSet context;
|
PathSet context;
|
||||||
auto patchFile = state.unpackPath(state.coerceToPath(pos, *elem, context));
|
auto patchFile = state.coerceToPath(pos, *elem, context);
|
||||||
patches.push_back(patchFile.accessor->readFile(patchFile.path));
|
patches.push_back(patchFile.readFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
@ -201,7 +201,7 @@ static void fetchTree(
|
||||||
|
|
||||||
emitTreeAttrs(
|
emitTreeAttrs(
|
||||||
state,
|
state,
|
||||||
{accessor, "/"},
|
{state.registerAccessor(accessor), "/"},
|
||||||
input2,
|
input2,
|
||||||
v,
|
v,
|
||||||
params.emptyRevFallback,
|
params.emptyRevFallback,
|
||||||
|
|
|
@ -32,7 +32,8 @@ void printValueAsJSON(EvalState & state, bool strict,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nPath:
|
case nPath:
|
||||||
out.write(state.copyPathToStore(context, v.path));
|
// FIXME: handle accessors
|
||||||
|
out.write(state.copyPathToStore(context, v.path().path));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nNull:
|
case nNull:
|
||||||
|
|
|
@ -77,7 +77,7 @@ static void printValueAsXML(EvalState & state, bool strict, bool location,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nPath:
|
case nPath:
|
||||||
doc.writeEmptyElement("path", singletonAttrs("value", v.path));
|
doc.writeEmptyElement("path", singletonAttrs("value", v.path().to_string()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nNull:
|
case nNull:
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include "symbol-table.hh"
|
#include "symbol-table.hh"
|
||||||
|
#include "input-accessor.hh"
|
||||||
|
|
||||||
#if HAVE_BOEHMGC
|
#if HAVE_BOEHMGC
|
||||||
#include <gc/gc_allocator.h>
|
#include <gc/gc_allocator.h>
|
||||||
|
@ -170,7 +171,11 @@ public:
|
||||||
const char * * context; // must be in sorted order
|
const char * * context; // must be in sorted order
|
||||||
} string;
|
} string;
|
||||||
|
|
||||||
const char * path;
|
struct {
|
||||||
|
InputAccessor * accessor;
|
||||||
|
const char * path;
|
||||||
|
} _path;
|
||||||
|
|
||||||
Bindings * attrs;
|
Bindings * attrs;
|
||||||
struct {
|
struct {
|
||||||
size_t size;
|
size_t size;
|
||||||
|
@ -255,14 +260,7 @@ public:
|
||||||
mkString(((const std::string &) s).c_str());
|
mkString(((const std::string &) s).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void mkPath(const char * s)
|
void mkPath(const SourcePath & path);
|
||||||
{
|
|
||||||
clearValue();
|
|
||||||
internalType = tPath;
|
|
||||||
path = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mkPath(std::string_view s);
|
|
||||||
|
|
||||||
inline void mkNull()
|
inline void mkNull()
|
||||||
{
|
{
|
||||||
|
@ -404,6 +402,12 @@ public:
|
||||||
auto begin = listElems();
|
auto begin = listElems();
|
||||||
return ConstListIterable { begin, begin + listSize() };
|
return ConstListIterable { begin, begin + listSize() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SourcePath path() const
|
||||||
|
{
|
||||||
|
assert(internalType == tPath);
|
||||||
|
return SourcePath { .accessor = *_path.accessor, .path = _path.path };
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -216,9 +216,14 @@ ref<FSInputAccessor> makeFSInputAccessor(
|
||||||
return make_ref<FSInputAccessorImpl>(root, std::move(allowedPaths));
|
return make_ref<FSInputAccessorImpl>(root, std::move(allowedPaths));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string SourcePath::to_string() const
|
||||||
|
{
|
||||||
|
return path; // FIXME
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream & operator << (std::ostream & str, const SourcePath & path)
|
std::ostream & operator << (std::ostream & str, const SourcePath & path)
|
||||||
{
|
{
|
||||||
str << path.path; // FIXME
|
str << path.to_string();
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,16 +72,26 @@ ref<InputAccessor> makePatchingInputAccessor(
|
||||||
|
|
||||||
struct SourcePath
|
struct SourcePath
|
||||||
{
|
{
|
||||||
ref<InputAccessor> accessor;
|
InputAccessor & accessor;
|
||||||
Path path;
|
Path path;
|
||||||
|
|
||||||
std::string_view baseName() const;
|
std::string_view baseName() const;
|
||||||
|
|
||||||
std::string readFile() const
|
std::string readFile() const
|
||||||
{ return accessor->readFile(path); }
|
{ return accessor.readFile(path); }
|
||||||
|
|
||||||
bool pathExists() const
|
bool pathExists() const
|
||||||
{ return accessor->pathExists(path); }
|
{ return accessor.pathExists(path); }
|
||||||
|
|
||||||
|
InputAccessor::DirEntries readDirectory() const
|
||||||
|
{ return accessor.readDirectory(path); }
|
||||||
|
|
||||||
|
void dumpPath(
|
||||||
|
Sink & sink,
|
||||||
|
PathFilter & filter = defaultPathFilter) const
|
||||||
|
{ return accessor.dumpPath(path, sink, filter); }
|
||||||
|
|
||||||
|
std::string to_string() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream & operator << (std::ostream & str, const SourcePath & path);
|
std::ostream & operator << (std::ostream & str, const SourcePath & path);
|
||||||
|
|
|
@ -452,9 +452,7 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
if (auto attr = v.attrs->get(state->symbols.create("path"))) {
|
if (auto attr = v.attrs->get(state->symbols.create("path"))) {
|
||||||
if (attr->name == state->symbols.create("path")) {
|
if (attr->name == state->symbols.create("path")) {
|
||||||
PathSet context;
|
PathSet context;
|
||||||
auto path = state->coerceToPath(*attr->pos, *attr->value, context);
|
state->coerceToStorePath(*attr->pos, *attr->value, context);
|
||||||
if (!store->isInStore(path))
|
|
||||||
throw Error("template '%s' has a bad 'path' attribute");
|
|
||||||
// TODO: recursively check the flake in 'path'.
|
// TODO: recursively check the flake in 'path'.
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -178,6 +178,7 @@ static void showHelp(std::vector<std::string> subcommand, MultiCommand & topleve
|
||||||
#include "generate-manpage.nix.gen.hh"
|
#include "generate-manpage.nix.gen.hh"
|
||||||
, "/"), *vGenerateManpage);
|
, "/"), *vGenerateManpage);
|
||||||
|
|
||||||
|
// FIXME: use MemoryAccessor
|
||||||
auto vUtils = state.allocValue();
|
auto vUtils = state.allocValue();
|
||||||
state.cacheFile(
|
state.cacheFile(
|
||||||
"/utils.nix", "/utils.nix",
|
"/utils.nix", "/utils.nix",
|
||||||
|
|
|
@ -772,7 +772,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nPath:
|
case nPath:
|
||||||
str << ANSI_GREEN << v.path << ANSI_NORMAL; // !!! escaping?
|
str << ANSI_GREEN << v.path().path << ANSI_NORMAL; // !!! escaping?
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nNull:
|
case nNull:
|
||||||
|
|
Loading…
Reference in a new issue