mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-11 00:36:20 +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)
|
||||
cachedValue = {root->db->setString(getKey(), v.string.s, v.string.context),
|
||||
string_t{v.string.s, {}}};
|
||||
else if (v.type() == nPath)
|
||||
cachedValue = {root->db->setString(getKey(), v.path), string_t{v.path, {}}};
|
||||
else if (v.type() == nPath) {
|
||||
// FIXME: take accessor into account?
|
||||
auto path = v.path().path;
|
||||
cachedValue = {root->db->setString(getKey(), path), string_t{path, {}}};
|
||||
}
|
||||
else if (v.type() == nBool)
|
||||
cachedValue = {root->db->setBool(getKey(), v.boolean), v.boolean};
|
||||
else if (v.type() == nAttrs)
|
||||
|
@ -537,7 +540,7 @@ std::string AttrCursor::getString()
|
|||
if (v.type() != nString && v.type() != nPath)
|
||||
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()
|
||||
|
@ -568,7 +571,7 @@ string_t AttrCursor::getStringWithContext()
|
|||
if (v.type() == nString)
|
||||
return {v.string.s, v.getContext(*root->state.store)};
|
||||
else if (v.type() == nPath)
|
||||
return {v.path, {}};
|
||||
return {v.path().to_string(), {}};
|
||||
else
|
||||
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 << "\"";
|
||||
break;
|
||||
case tPath:
|
||||
str << path; // !!! escaping?
|
||||
str << path().to_string(); // !!! escaping?
|
||||
break;
|
||||
case tNull:
|
||||
str << "null";
|
||||
|
@ -721,11 +721,6 @@ std::optional<EvalState::Doc> EvalState::getDoc(Value & v)
|
|||
evaluator. So here are some helper functions for throwing
|
||||
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))
|
||||
{
|
||||
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
|
||||
auto pathKey = path.to_string();
|
||||
FileEvalCache::iterator i;
|
||||
if ((i = fileEvalCache.find(path)) != fileEvalCache.end()) {
|
||||
if ((i = fileEvalCache.find(pathKey)) != fileEvalCache.end()) {
|
||||
v = i->second;
|
||||
return;
|
||||
}
|
||||
|
||||
auto resolvedPath_ = resolveExprPath(path_);
|
||||
auto resolvedPath = packPath(resolvedPath_);
|
||||
if ((i = fileEvalCache.find(resolvedPath)) != fileEvalCache.end()) {
|
||||
auto resolvedPath = resolveExprPath(path);
|
||||
auto resolvedPathKey = resolvedPath.to_string();
|
||||
if ((i = fileEvalCache.find(resolvedPathKey)) != fileEvalCache.end()) {
|
||||
v = i->second;
|
||||
return;
|
||||
}
|
||||
|
@ -1003,17 +996,17 @@ void EvalState::evalFile(const SourcePath & path_, Value & v, bool mustBeTrivial
|
|||
printTalkative("evaluating file '%1%'", resolvedPath);
|
||||
Expr * e = nullptr;
|
||||
|
||||
auto j = fileParseCache.find(resolvedPath);
|
||||
auto j = fileParseCache.find(resolvedPathKey);
|
||||
if (j != fileParseCache.end())
|
||||
e = j->second;
|
||||
|
||||
if (!e)
|
||||
e = parseExprFromFile(resolvedPath_);
|
||||
e = parseExprFromFile(resolvedPath);
|
||||
#if 0
|
||||
e = parseExprFromFile(checkSourcePath(resolvedPath));
|
||||
#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));
|
||||
} else {
|
||||
if (s.empty()) s.reserve(es->size());
|
||||
/* skip canonization of first path, which would only be not
|
||||
canonized in the first place if it's coming from a ./${foo} type
|
||||
path */
|
||||
/* Skip canonization of first path, which would only be
|
||||
non-canonical in the first place if it's coming from a
|
||||
./${foo} type path. */
|
||||
auto part = state.coerceToString(i_pos, vTmp, context, false, firstType == nString, !first);
|
||||
sSize += part->size();
|
||||
s.emplace_back(std::move(part));
|
||||
|
@ -1808,7 +1801,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
|||
else if (firstType == nPath) {
|
||||
if (!context.empty())
|
||||
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
|
||||
v.mkStringMove(c_str(), context);
|
||||
}
|
||||
|
@ -2005,11 +1998,12 @@ BackedStringView EvalState::coerceToString(const Pos & pos, Value & v, PathSet &
|
|||
}
|
||||
|
||||
if (v.type() == nPath) {
|
||||
BackedStringView path(PathView(v.path));
|
||||
auto path = v.path().to_string();
|
||||
if (canonicalizePath)
|
||||
path = canonPath(*path);
|
||||
// FIXME: unnecessary?
|
||||
path = canonPath(path);
|
||||
if (copyToStore)
|
||||
path = copyPathToStore(context, std::move(path).toOwned());
|
||||
path = copyPathToStore(context, 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)
|
||||
{
|
||||
#if 0
|
||||
if (nix::isDerivation(path))
|
||||
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);
|
||||
#endif
|
||||
auto source = sinkToSource([&](Sink & sink) {
|
||||
path2.accessor->dumpPath(path2.path, sink);
|
||||
path2.dumpPath(sink);
|
||||
});
|
||||
// FIXME: readOnlyMode
|
||||
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);
|
||||
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();
|
||||
if (path == "" || path[0] != '/')
|
||||
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;
|
||||
|
||||
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:
|
||||
return true;
|
||||
|
|
|
@ -96,7 +96,7 @@ public:
|
|||
ref<FSInputAccessor> rootFS;
|
||||
ref<MemoryInputAccessor> corepkgsFS;
|
||||
|
||||
std::unordered_map<size_t, ref<InputAccessor>> inputAccessors;
|
||||
std::unordered_map<InputAccessor *, ref<InputAccessor>> inputAccessors;
|
||||
|
||||
/* Store used to materialise .drv files. */
|
||||
const ref<Store> store;
|
||||
|
@ -156,11 +156,9 @@ public:
|
|||
|
||||
SearchPath getSearchPath() { return searchPath; }
|
||||
|
||||
Path packPath(const SourcePath & path);
|
||||
SourcePath rootPath(Path path);
|
||||
|
||||
SourcePath unpackPath(const Path & path);
|
||||
|
||||
SourcePath rootPath(const Path & path);
|
||||
InputAccessor & registerAccessor(ref<InputAccessor> accessor);
|
||||
|
||||
/* Allow access to a path. */
|
||||
void allowPath(const Path & path);
|
||||
|
@ -274,8 +272,7 @@ public:
|
|||
/* Path coercion. Converts strings, paths and derivations to a
|
||||
path. The result is guaranteed to be a canonicalised, absolute
|
||||
path. Nothing is copied to the store. */
|
||||
// FIXME: return SourcePath
|
||||
Path coerceToPath(const Pos & pos, Value & v, PathSet & context);
|
||||
SourcePath coerceToPath(const Pos & pos, Value & v, PathSet & context);
|
||||
|
||||
/* Like coerceToPath, but the result must be a store path. */
|
||||
StorePath coerceToStorePath(const Pos & pos, Value & v, PathSet & context);
|
||||
|
|
|
@ -201,7 +201,7 @@ static std::map<FlakeId, FlakeInput> parseFlakeInputs(
|
|||
static Flake readFlake(
|
||||
EvalState & state,
|
||||
const FlakeRef & lockedRef,
|
||||
nix::ref<InputAccessor> accessor,
|
||||
InputAccessor & accessor,
|
||||
const InputPath & lockRootPath)
|
||||
{
|
||||
auto flakeDir = canonPath("/" + lockedRef.subdir);
|
||||
|
@ -213,14 +213,14 @@ static Flake readFlake(
|
|||
Value vInfo;
|
||||
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 {
|
||||
// FIXME
|
||||
.originalRef = lockedRef,
|
||||
.resolvedRef = lockedRef,
|
||||
.lockedRef = lockedRef,
|
||||
.accessor = accessor,
|
||||
.accessor = ptr(&accessor),
|
||||
.flakePath = dirOf(flakePath.path),
|
||||
};
|
||||
|
||||
|
@ -308,7 +308,7 @@ static Flake getFlake(
|
|||
// FIXME: resolve
|
||||
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)
|
||||
|
@ -324,7 +324,7 @@ Flake getFlake(EvalState & state, const FlakeRef & originalRef, bool allowLookup
|
|||
|
||||
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()
|
||||
? LockFile(lockFilePath.readFile(), fmt("%s", lockFilePath))
|
||||
: LockFile();
|
||||
|
@ -703,7 +703,7 @@ void callFlake(EvalState & state,
|
|||
|
||||
emitTreeAttrs(
|
||||
state,
|
||||
{lockedFlake.flake.accessor, lockedFlake.flake.flakePath},
|
||||
{*lockedFlake.flake.accessor, lockedFlake.flake.flakePath},
|
||||
lockedFlake.flake.lockedRef.input,
|
||||
*vRootSrc,
|
||||
false,
|
||||
|
|
|
@ -61,7 +61,7 @@ struct Flake
|
|||
FlakeRef originalRef; // the original flake specification (by the user)
|
||||
FlakeRef resolvedRef; // registry references and caching resolved to the specific underlying flake
|
||||
FlakeRef lockedRef; // the specific local store result of invoking the fetcher
|
||||
ref<InputAccessor> accessor;
|
||||
ptr<InputAccessor> accessor;
|
||||
Path flakePath;
|
||||
bool forceDirty = false; // pretend that 'lockedRef' is dirty
|
||||
std::optional<std::string> description;
|
||||
|
|
|
@ -121,9 +121,13 @@ struct ExprString : Expr
|
|||
|
||||
struct ExprPath : Expr
|
||||
{
|
||||
std::string s;
|
||||
std::string s; // FIXME: remove
|
||||
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
|
||||
Value * maybeThunk(EvalState & state, Env & env);
|
||||
};
|
||||
|
|
|
@ -517,11 +517,11 @@ path_start
|
|||
/* add back in the trailing '/' to the first segment */
|
||||
if ($1.p[$1.l-1] == '/' && $1.l > 1)
|
||||
path += "/";
|
||||
$$ = new ExprPath(path);
|
||||
$$ = new ExprPath(*data->state.rootFS, path);
|
||||
}
|
||||
| HPATH {
|
||||
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
|
||||
auto path2 = path.path + "/default.nix";
|
||||
if (path.accessor->pathExists(path2))
|
||||
if (path.pathExists())
|
||||
return {path.accessor, path2};
|
||||
|
||||
return path;
|
||||
|
@ -715,11 +715,11 @@ Expr * EvalState::parseExprFromFile(const SourcePath & path)
|
|||
|
||||
Expr * EvalState::parseExprFromFile(const SourcePath & path, StaticEnv & staticEnv)
|
||||
{
|
||||
auto packed = packPath(path);
|
||||
auto buffer = path.readFile();
|
||||
// readFile hopefully have left some extra space for terminators
|
||||
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/"))
|
||||
return packPath(SourcePath {corepkgsFS, (std::string) path.substr(3)});
|
||||
abort();
|
||||
//return packPath(SourcePath {corepkgsFS, (std::string) path.substr(3)});
|
||||
|
||||
throw ThrownError({
|
||||
.msg = hintfmt(evalSettings.pureEval
|
||||
|
|
|
@ -3,34 +3,15 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
static constexpr std::string_view marker = "/__virtual/";
|
||||
|
||||
Path EvalState::packPath(const SourcePath & path)
|
||||
SourcePath EvalState::rootPath(Path path)
|
||||
{
|
||||
// FIXME: canonPath(path) ?
|
||||
assert(hasPrefix(path.path, "/"));
|
||||
inputAccessors.emplace(path.accessor->number, path.accessor);
|
||||
return std::string(marker) + std::to_string(path.accessor->number) + path.path;
|
||||
return {*rootFS, std::move(path)};
|
||||
}
|
||||
|
||||
SourcePath EvalState::unpackPath(const Path & path)
|
||||
InputAccessor & EvalState::registerAccessor(ref<InputAccessor> accessor)
|
||||
{
|
||||
if (hasPrefix(path, marker)) {
|
||||
auto s = path.substr(marker.size());
|
||||
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};
|
||||
inputAccessors.emplace(&*accessor, accessor);
|
||||
return *accessor;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ static SourcePath realisePath(EvalState & state, const Pos & pos, Value & v, con
|
|||
auto path = [&]()
|
||||
{
|
||||
try {
|
||||
return state.unpackPath(state.coerceToPath(pos, v, context));
|
||||
return state.coerceToPath(pos, v, context);
|
||||
} catch (Error & e) {
|
||||
e.addTrace(pos, "while realising the context of a path");
|
||||
throw;
|
||||
|
@ -557,7 +557,8 @@ struct CompareValues
|
|||
case nString:
|
||||
return strcmp(v1->string.s, v2->string.s) < 0;
|
||||
case nPath:
|
||||
return strcmp(v1->path, v2->path) < 0;
|
||||
// FIXME: handle accessor?
|
||||
return strcmp(v1->_path.path, v2->_path.path) < 0;
|
||||
case nList:
|
||||
// Lexicographic comparison
|
||||
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)
|
||||
{
|
||||
PathSet context;
|
||||
Path path = state.coerceToPath(pos, *args[0], context);
|
||||
v.mkString(canonPath(path), context);
|
||||
auto path = state.coerceToPath(pos, *args[0], context);
|
||||
v.mkString(canonPath(path.path), context);
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_toPath({
|
||||
|
@ -1347,7 +1348,7 @@ static void prim_storePath(EvalState & state, const Pos & pos, Value * * args, V
|
|||
|
||||
PathSet context;
|
||||
// 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
|
||||
directly in the store. The latter condition is necessary so
|
||||
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;
|
||||
auto path = state.coerceToString(pos, *args[0], context, false, false);
|
||||
auto dir = dirOf(*path);
|
||||
abort();
|
||||
#if 0
|
||||
if (args[0]->type() == nPath) v.mkPath(dir); else v.mkString(dir, context);
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
#if 0
|
||||
// FIXME: checkSourcePath?
|
||||
v.mkPath(state.findFile(searchPath, path, pos));
|
||||
#endif
|
||||
abort();
|
||||
}
|
||||
|
||||
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 entries = path.accessor->readDirectory(path.path);
|
||||
auto entries = path.readDirectory();
|
||||
auto attrs = state.buildBindings(entries.size());
|
||||
|
||||
for (auto & [name, type] : entries) {
|
||||
|
@ -1881,7 +1888,7 @@ static RegisterPrimOp primop_toFile({
|
|||
static void addPath(
|
||||
EvalState & state,
|
||||
const Pos & pos,
|
||||
const std::string & name,
|
||||
std::string_view name,
|
||||
Path path,
|
||||
Value * filterFun,
|
||||
FileIngestionMethod method,
|
||||
|
@ -1959,7 +1966,7 @@ static void addPath(
|
|||
static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||
{
|
||||
PathSet context;
|
||||
Path path = state.coerceToPath(pos, *args[1], context);
|
||||
auto path = state.coerceToPath(pos, *args[1], context);
|
||||
|
||||
state.forceValue(*args[0], pos);
|
||||
if (args[0]->type() != nFunction)
|
||||
|
@ -1970,7 +1977,8 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args
|
|||
.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({
|
||||
|
@ -2031,7 +2039,7 @@ static RegisterPrimOp primop_filterSource({
|
|||
static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||
{
|
||||
state.forceAttrs(*args[0], pos);
|
||||
Path path;
|
||||
std::optional<SourcePath> path;
|
||||
std::string name;
|
||||
Value * filterFun = nullptr;
|
||||
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) {
|
||||
auto & n(attr.name);
|
||||
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)
|
||||
name = state.forceStringNoCtx(*attr.value, *attr.pos);
|
||||
else if (n == "filter") {
|
||||
|
@ -2057,15 +2065,16 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value
|
|||
.errPos = *attr.pos
|
||||
});
|
||||
}
|
||||
if (path.empty())
|
||||
if (!path)
|
||||
throw EvalError({
|
||||
.msg = hintfmt("'path' required"),
|
||||
.errPos = pos
|
||||
});
|
||||
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({
|
||||
|
|
|
@ -30,7 +30,7 @@ void emitTreeAttrs(
|
|||
attrs.alloc(state.sOutPath).mkString(storePath, {storePath});
|
||||
#endif
|
||||
|
||||
attrs.alloc(state.sOutPath).mkPath(state.packPath(path));
|
||||
attrs.alloc(state.sOutPath).mkPath(path);
|
||||
|
||||
// FIXME: support arbitrary input attributes.
|
||||
|
||||
|
@ -138,8 +138,8 @@ static void fetchTree(
|
|||
for (auto elem : attr.value->listItems()) {
|
||||
// FIXME: use realisePath
|
||||
PathSet context;
|
||||
auto patchFile = state.unpackPath(state.coerceToPath(pos, *elem, context));
|
||||
patches.push_back(patchFile.accessor->readFile(patchFile.path));
|
||||
auto patchFile = state.coerceToPath(pos, *elem, context);
|
||||
patches.push_back(patchFile.readFile());
|
||||
}
|
||||
|
||||
continue;
|
||||
|
@ -201,7 +201,7 @@ static void fetchTree(
|
|||
|
||||
emitTreeAttrs(
|
||||
state,
|
||||
{accessor, "/"},
|
||||
{state.registerAccessor(accessor), "/"},
|
||||
input2,
|
||||
v,
|
||||
params.emptyRevFallback,
|
||||
|
|
|
@ -32,7 +32,8 @@ void printValueAsJSON(EvalState & state, bool strict,
|
|||
break;
|
||||
|
||||
case nPath:
|
||||
out.write(state.copyPathToStore(context, v.path));
|
||||
// FIXME: handle accessors
|
||||
out.write(state.copyPathToStore(context, v.path().path));
|
||||
break;
|
||||
|
||||
case nNull:
|
||||
|
|
|
@ -77,7 +77,7 @@ static void printValueAsXML(EvalState & state, bool strict, bool location,
|
|||
break;
|
||||
|
||||
case nPath:
|
||||
doc.writeEmptyElement("path", singletonAttrs("value", v.path));
|
||||
doc.writeEmptyElement("path", singletonAttrs("value", v.path().to_string()));
|
||||
break;
|
||||
|
||||
case nNull:
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <cassert>
|
||||
|
||||
#include "symbol-table.hh"
|
||||
#include "input-accessor.hh"
|
||||
|
||||
#if HAVE_BOEHMGC
|
||||
#include <gc/gc_allocator.h>
|
||||
|
@ -170,7 +171,11 @@ public:
|
|||
const char * * context; // must be in sorted order
|
||||
} string;
|
||||
|
||||
const char * path;
|
||||
struct {
|
||||
InputAccessor * accessor;
|
||||
const char * path;
|
||||
} _path;
|
||||
|
||||
Bindings * attrs;
|
||||
struct {
|
||||
size_t size;
|
||||
|
@ -255,14 +260,7 @@ public:
|
|||
mkString(((const std::string &) s).c_str());
|
||||
}
|
||||
|
||||
inline void mkPath(const char * s)
|
||||
{
|
||||
clearValue();
|
||||
internalType = tPath;
|
||||
path = s;
|
||||
}
|
||||
|
||||
void mkPath(std::string_view s);
|
||||
void mkPath(const SourcePath & path);
|
||||
|
||||
inline void mkNull()
|
||||
{
|
||||
|
@ -404,6 +402,12 @@ public:
|
|||
auto begin = listElems();
|
||||
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));
|
||||
}
|
||||
|
||||
std::string SourcePath::to_string() const
|
||||
{
|
||||
return path; // FIXME
|
||||
}
|
||||
|
||||
std::ostream & operator << (std::ostream & str, const SourcePath & path)
|
||||
{
|
||||
str << path.path; // FIXME
|
||||
str << path.to_string();
|
||||
return str;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,16 +72,26 @@ ref<InputAccessor> makePatchingInputAccessor(
|
|||
|
||||
struct SourcePath
|
||||
{
|
||||
ref<InputAccessor> accessor;
|
||||
InputAccessor & accessor;
|
||||
Path path;
|
||||
|
||||
std::string_view baseName() const;
|
||||
|
||||
std::string readFile() const
|
||||
{ return accessor->readFile(path); }
|
||||
{ return accessor.readFile(path); }
|
||||
|
||||
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);
|
||||
|
|
|
@ -452,9 +452,7 @@ struct CmdFlakeCheck : FlakeCommand
|
|||
if (auto attr = v.attrs->get(state->symbols.create("path"))) {
|
||||
if (attr->name == state->symbols.create("path")) {
|
||||
PathSet context;
|
||||
auto path = state->coerceToPath(*attr->pos, *attr->value, context);
|
||||
if (!store->isInStore(path))
|
||||
throw Error("template '%s' has a bad 'path' attribute");
|
||||
state->coerceToStorePath(*attr->pos, *attr->value, context);
|
||||
// TODO: recursively check the flake in 'path'.
|
||||
}
|
||||
} else
|
||||
|
|
|
@ -178,6 +178,7 @@ static void showHelp(std::vector<std::string> subcommand, MultiCommand & topleve
|
|||
#include "generate-manpage.nix.gen.hh"
|
||||
, "/"), *vGenerateManpage);
|
||||
|
||||
// FIXME: use MemoryAccessor
|
||||
auto vUtils = state.allocValue();
|
||||
state.cacheFile(
|
||||
"/utils.nix", "/utils.nix",
|
||||
|
|
|
@ -772,7 +772,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m
|
|||
break;
|
||||
|
||||
case nPath:
|
||||
str << ANSI_GREEN << v.path << ANSI_NORMAL; // !!! escaping?
|
||||
str << ANSI_GREEN << v.path().path << ANSI_NORMAL; // !!! escaping?
|
||||
break;
|
||||
|
||||
case nNull:
|
||||
|
|
Loading…
Reference in a new issue