Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into lazy-trees
Browse files Browse the repository at this point in the history
  • Loading branch information
edolstra committed May 6, 2024
2 parents 4133514 + feb1d10 commit 2cb003c
Show file tree
Hide file tree
Showing 50 changed files with 244 additions and 321 deletions.
1 change: 0 additions & 1 deletion src/libcmd/common-eval-args.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include "flake/flakeref.hh"
#include "store-api.hh"
#include "command.hh"
#include "fs-input-accessor.hh"
#include "tarball.hh"
#include "fetch-to-store.hh"

Expand Down
3 changes: 1 addition & 2 deletions src/libcmd/installables.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#include "url.hh"
#include "registry.hh"
#include "build-result.hh"
#include "fs-input-accessor.hh"

#include <regex>
#include <queue>
Expand Down Expand Up @@ -147,7 +146,7 @@ MixFlakeOptions::MixFlakeOptions()
.category = category,
.labels = {"flake-lock-path"},
.handler = {[&](std::string lockFilePath) {
lockFlags.referenceLockFilePath = getUnfilteredRootPath(CanonPath(absPath(lockFilePath)));
lockFlags.referenceLockFilePath = {makeFSSourceAccessor(), CanonPath(absPath(lockFilePath))};
}},
.completer = completePath
});
Expand Down
21 changes: 10 additions & 11 deletions src/libexpr/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@
#include "function-trace.hh"
#include "profiles.hh"
#include "print.hh"
#include "fs-input-accessor.hh"
#include "filtering-input-accessor.hh"
#include "memory-input-accessor.hh"
#include "memory-source-accessor.hh"
#include "signals.hh"
#include "gc-small-vector.hh"
#include "url.hh"
Expand Down Expand Up @@ -405,16 +404,16 @@ EvalState::EvalState(
, emptyBindings(0)
, rootFS(
evalSettings.restrictEval || evalSettings.pureEval
? ref<InputAccessor>(AllowListInputAccessor::create(makeFSInputAccessor(), {},
? ref<SourceAccessor>(AllowListInputAccessor::create(makeFSSourceAccessor(), {},
[](const CanonPath & path) -> RestrictedPathError {
auto modeInformation = evalSettings.pureEval
? "in pure evaluation mode (use '--impure' to override)"
: "in restricted mode";
throw RestrictedPathError("access to absolute path '%1%' is forbidden %2%", path, modeInformation);
}))
: makeFSInputAccessor())
, corepkgsFS(makeMemoryInputAccessor())
, internalFS(makeMemoryInputAccessor())
: makeFSSourceAccessor())
, corepkgsFS(make_ref<MemorySourceAccessor>())
, internalFS(make_ref<MemorySourceAccessor>())
, derivationInternal{corepkgsFS->addFile(
CanonPath("derivation-internal.nix"),
#include "primops/derivation.nix.gen.hh"
Expand Down Expand Up @@ -2039,7 +2038,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
// List of returned strings. References to these Values must NOT be persisted.
SmallTemporaryValueVector<conservativeStackReservation> values(es->size());
Value * vTmpP = values.data();
std::shared_ptr<InputAccessor> accessor;
std::shared_ptr<SourceAccessor> accessor;

for (auto & [i_pos, i] : *es) {
Value * vTmp = vTmpP++;
Expand Down Expand Up @@ -2534,8 +2533,8 @@ std::pair<SingleDerivedPath, std::string_view> EvalState::coerceToSingleDerivedP
return std::move(b);
},
[&](NixStringContextElem::InputAccessor && a) -> SingleDerivedPath {
auto accessor = inputAccessors.find(a.accessor);
assert(accessor != inputAccessors.end());
auto accessor = sourceAccessors.find(a.accessor);
assert(accessor != sourceAccessors.end());
return SingleDerivedPath::Opaque(fetchToStore(
*store,
{accessor->second},
Expand Down Expand Up @@ -2821,12 +2820,12 @@ SourcePath resolveExprPath(SourcePath path)
if (++followCount >= maxFollow)
throw Error("too many symbolic links encountered while traversing the path '%s'", path);
auto p = path.parent().resolveSymlinks() / path.baseName();
if (p.lstat().type != InputAccessor::tSymlink) break;
if (p.lstat().type != SourceAccessor::tSymlink) break;
path = {path.accessor, CanonPath(p.readLink(), path.path.parent().value_or(CanonPath::root))};
}

/* If `path' refers to a directory, append `/default.nix'. */
if (path.resolveSymlinks().lstat().type == InputAccessor::tDirectory)
if (path.resolveSymlinks().lstat().type == SourceAccessor::tDirectory)
return path / "default.nix";

return path;
Expand Down
16 changes: 8 additions & 8 deletions src/libexpr/eval.hh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "symbol-table.hh"
#include "config.hh"
#include "experimental-features.hh"
#include "input-accessor.hh"
#include "source-accessor.hh"
#include "search-path.hh"
#include "repl-exit-status.hh"

Expand All @@ -35,7 +35,7 @@ struct DerivedPath;
struct SourcePath;
struct SingleDerivedPath;
enum RepairFlag : bool;
struct MemoryInputAccessor;
struct MemorySourceAccessor;
namespace eval_cache {
class EvalCache;
}
Expand Down Expand Up @@ -231,26 +231,26 @@ public:
/**
* The accessor for the root filesystem.
*/
const ref<InputAccessor> rootFS;
const ref<SourceAccessor> rootFS;

/**
* The in-memory filesystem for <nix/...> paths.
*/
const ref<MemoryInputAccessor> corepkgsFS;
const ref<MemorySourceAccessor> corepkgsFS;

/**
* In-memory filesystem for internal, non-user-callable Nix
* expressions like call-flake.nix.
*/
const ref<MemoryInputAccessor> internalFS;
const ref<MemorySourceAccessor> internalFS;

const SourcePath derivationInternal;

const SourcePath callFlakeInternal;

/* A map keyed by InputAccessor::number that keeps input accessors
/* A map keyed by SourceAccessor::number that keeps input accessors
alive. */
std::unordered_map<size_t, ref<InputAccessor>> inputAccessors;
std::unordered_map<size_t, ref<SourceAccessor>> sourceAccessors;

/**
* Store used to materialise .drv files.
Expand Down Expand Up @@ -359,7 +359,7 @@ public:
*/
SourcePath rootPath(CanonPath path);

void registerAccessor(ref<InputAccessor> accessor);
void registerAccessor(ref<SourceAccessor> accessor);

/* Convert a path to a string representation of the format
`/nix/store/virtual000...<accessor-number>/<path>`. */
Expand Down
2 changes: 1 addition & 1 deletion src/libexpr/flake/flake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ static Flake getFlake(
auto [accessor, lockedRef] = resolvedRef.lazyFetch(state.store);

if (!patches.empty())
accessor = makePatchingInputAccessor(accessor, patches);
accessor = makePatchingSourceAccessor(accessor, patches);

state.registerAccessor(accessor);

Expand Down
2 changes: 1 addition & 1 deletion src/libexpr/flake/flakeref.cc
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ FlakeRef FlakeRef::fromAttrs(const fetchers::Attrs & attrs)
fetchers::maybeGetStrAttr(attrs, "dir").value_or(""));
}

std::pair<ref<InputAccessor>, FlakeRef> FlakeRef::lazyFetch(ref<Store> store) const
std::pair<ref<SourceAccessor>, FlakeRef> FlakeRef::lazyFetch(ref<Store> store) const
{
auto [accessor, lockedInput] = input.getAccessor(store);
return {accessor, FlakeRef(std::move(lockedInput), subdir)};
Expand Down
2 changes: 1 addition & 1 deletion src/libexpr/flake/flakeref.hh
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ struct FlakeRef

static FlakeRef fromAttrs(const fetchers::Attrs & attrs);

std::pair<ref<InputAccessor>, FlakeRef> lazyFetch(ref<Store> store) const;
std::pair<ref<SourceAccessor>, FlakeRef> lazyFetch(ref<Store> store) const;
};

std::ostream & operator << (std::ostream & str, const FlakeRef & flakeRef);
Expand Down
2 changes: 1 addition & 1 deletion src/libexpr/parser-state.hh
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ struct ParserState
Expr * result;
SourcePath basePath;
PosTable::Origin origin;
const ref<InputAccessor> rootFS;
const ref<SourceAccessor> rootFS;
const Expr::AstSymbols & s;

void dupAttr(const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos);
Expand Down
4 changes: 2 additions & 2 deletions src/libexpr/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Expr * parseExprFromBuf(
const SourcePath & basePath,
SymbolTable & symbols,
PosTable & positions,
const ref<InputAccessor> rootFS,
const ref<SourceAccessor> rootFS,
const Expr::AstSymbols & astSymbols);

}
Expand Down Expand Up @@ -443,7 +443,7 @@ Expr * parseExprFromBuf(
const SourcePath & basePath,
SymbolTable & symbols,
PosTable & positions,
const ref<InputAccessor> rootFS,
const ref<SourceAccessor> rootFS,
const Expr::AstSymbols & astSymbols)
{
yyscan_t scanner;
Expand Down
14 changes: 7 additions & 7 deletions src/libexpr/paths.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ SourcePath EvalState::rootPath(PathView path)
return {rootFS, CanonPath(absPath(path))};
}

void EvalState::registerAccessor(ref<InputAccessor> accessor)
void EvalState::registerAccessor(ref<SourceAccessor> accessor)
{
inputAccessors.emplace(accessor->number, accessor);
sourceAccessors.emplace(accessor->number, accessor);
}

std::string EvalState::encodePath(const SourcePath & path)
Expand All @@ -26,7 +26,7 @@ std::string EvalState::encodePath(const SourcePath & path)
to /nix/store/virtual000...<N>) and we should deprecate it
eventually. So print a warning about use of an encoded path in
decodePath(). */
return path.accessor == ref<InputAccessor>(rootFS)
return path.accessor == ref<SourceAccessor>(rootFS)
? path.path.abs()
: fmt("%s%08d-source%s", virtualPathMarker, path.accessor->number, path.path.absOrEmpty());
}
Expand All @@ -46,8 +46,8 @@ SourcePath EvalState::decodePath(std::string_view s, PosIdx pos)
size_t number = std::stoi(std::string(s.substr(0, slash)), nullptr, 10);
s = slash == s.npos ? "" : s.substr(slash);

auto accessor = inputAccessors.find(number);
if (accessor == inputAccessors.end())
auto accessor = sourceAccessors.find(number);
if (accessor == sourceAccessors.end())
fail();

SourcePath path{accessor->second, CanonPath(s)};
Expand Down Expand Up @@ -116,8 +116,8 @@ std::string EvalState::rewriteVirtualPaths(std::string_view s, PosIdx pos)
try {
size_t number = std::stoi(std::string(s.substr(m + 24, 8)), nullptr, 10); // FIXME

auto accessor = inputAccessors.find(number);
assert(accessor != inputAccessors.end()); // FIXME
auto accessor = sourceAccessors.find(number);
assert(accessor != sourceAccessors.end()); // FIXME

warn(
"derivation at %s has an attribute that refers to source tree '%s' without context; this does not work correctly",
Expand Down
13 changes: 6 additions & 7 deletions src/libexpr/primops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include "value-to-json.hh"
#include "value-to-xml.hh"
#include "primops.hh"
#include "fs-input-accessor.hh"
#include "fetch-to-store.hh"

#include <boost/container/small_vector.hpp>
Expand Down Expand Up @@ -1330,8 +1329,8 @@ static void derivationStrictInternal(
[&](const NixStringContextElem::InputAccessor & a) {
/* Copy a virtual path (from encodePath()) to the
store. */
auto accessor = state.inputAccessors.find(a.accessor);
assert(accessor != state.inputAccessors.end());
auto accessor = state.sourceAccessors.find(a.accessor);
assert(accessor != state.sourceAccessors.end());
SourcePath path{accessor->second};
auto storePath = fetchToStore(
*state.store,
Expand Down Expand Up @@ -1873,12 +1872,12 @@ static RegisterPrimOp primop_hashFile({
.fun = prim_hashFile,
});

static Value * fileTypeToString(EvalState & state, InputAccessor::Type type)
static Value * fileTypeToString(EvalState & state, SourceAccessor::Type type)
{
return
type == InputAccessor::Type::tRegular ? &state.vStringRegular :
type == InputAccessor::Type::tDirectory ? &state.vStringDirectory :
type == InputAccessor::Type::tSymlink ? &state.vStringSymlink :
type == SourceAccessor::Type::tRegular ? &state.vStringRegular :
type == SourceAccessor::Type::tDirectory ? &state.vStringDirectory :
type == SourceAccessor::Type::tSymlink ? &state.vStringSymlink :
&state.vStringUnknown;
}

Expand Down
38 changes: 17 additions & 21 deletions src/libexpr/primops/patch.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,38 @@

namespace nix {

static void prim_patch(EvalState & state, const PosIdx pos, Value * * args, Value & v)
static void prim_patch(EvalState & state, const PosIdx pos, Value ** args, Value & v)
{
std::vector<std::string> patches;
std::optional<SourcePath> src;

state.forceAttrs(*args[0], pos,
"while evaluating the first argument to 'builtins.patch'");
state.forceAttrs(*args[0], pos, "while evaluating the first argument to 'builtins.patch'");

for (auto & attr : *args[0]->attrs()) {
std::string_view n(state.symbols[attr.name]);

auto check = [&]()
{
auto check = [&]() {
if (!patches.empty())
state.error<EvalError>(
"'builtins.patch' does not support both 'patches' and 'patchFiles'")
.atPos(attr.pos).debugThrow();
state.error<EvalError>("'builtins.patch' does not support both 'patches' and 'patchFiles'")
.atPos(attr.pos)
.debugThrow();
};

if (n == "src") {
NixStringContext context;
src.emplace(state.coerceToPath(pos, *attr.value, context,
"while evaluating the 'src' attribute passed to 'builtins.patch'"));
src.emplace(state.coerceToPath(
pos, *attr.value, context, "while evaluating the 'src' attribute passed to 'builtins.patch'"));
}

else if (n == "patchFiles") {
check();
state.forceList(*attr.value, attr.pos,
"while evaluating the 'patchFiles' attribute passed to 'builtins.patch'");
state.forceList(
*attr.value, attr.pos, "while evaluating the 'patchFiles' attribute passed to 'builtins.patch'");
for (auto elem : attr.value->listItems()) {
// FIXME: use realisePath
NixStringContext context;
auto patchFile = state.coerceToPath(attr.pos, *elem, context,
"while evaluating the 'patchFiles' attribute passed to 'builtins.patch'");
auto patchFile = state.coerceToPath(
attr.pos, *elem, context, "while evaluating the 'patchFiles' attribute passed to 'builtins.patch'");
patches.push_back(patchFile.readFile());
}
}
Expand All @@ -50,20 +48,18 @@ static void prim_patch(EvalState & state, const PosIdx pos, Value * * args, Valu
}

else
state.error<EvalError>(
"attribute '%s' isn't supported in call to 'builtins.patch'", n)
.atPos(pos).debugThrow();
state.error<EvalError>("attribute '%s' isn't supported in call to 'builtins.patch'", n)
.atPos(pos)
.debugThrow();
}

if (!src)
state.error<EvalError>(
"attribute 'src' is missing in call to 'builtins.patch'")
.atPos(pos).debugThrow();
state.error<EvalError>("attribute 'src' is missing in call to 'builtins.patch'").atPos(pos).debugThrow();

if (!src->path.isRoot())
throw UnimplementedError("applying patches to a non-root path ('%s') is not yet supported", src->path);

auto accessor = makePatchingInputAccessor(src->accessor, patches);
auto accessor = makePatchingSourceAccessor(src->accessor, patches);

state.registerAccessor(accessor);

Expand Down
5 changes: 2 additions & 3 deletions src/libexpr/value.hh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

#include "symbol-table.hh"
#include "value/context.hh"
#include "input-accessor.hh"
#include "source-path.hh"
#include "print-options.hh"

Expand Down Expand Up @@ -217,7 +216,7 @@ public:
};

struct Path {
InputAccessor * accessor;
SourceAccessor * accessor;
const char * path;
};

Expand Down Expand Up @@ -335,7 +334,7 @@ public:
void mkPath(const SourcePath & path);
void mkPath(std::string_view path);

inline void mkPath(InputAccessor * accessor, const char * path)
inline void mkPath(SourceAccessor * accessor, const char * path)
{
finishValue(tPath, { .path = { .accessor = accessor, .path = path } });
}
Expand Down
2 changes: 1 addition & 1 deletion src/libfetchers/fetch-to-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ StorePath fetchToStore(
RepairFlag repair)
{
// FIXME: add an optimisation for the case where the accessor is
// an FSInputAccessor pointing to a store path.
// a `PosixSourceAccessor` pointing to a store path.

std::optional<fetchers::Attrs> cacheKey;

Expand Down
Loading

0 comments on commit 2cb003c

Please sign in to comment.