From ba5929c7becfb8e3668cdabddc4e1ea0b0330189 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 3 May 2024 12:14:01 +0200 Subject: [PATCH] Merge InputAccessor into SourceAccessor After the removal of the InputAccessor::fetchToStore() method, the only remaining functionality in InputAccessor was `fingerprint` and `getLastModified()`, and there is no reason to keep those in a separate class. --- src/libexpr/eval.cc | 12 ++++----- src/libexpr/eval.hh | 10 +++---- src/libexpr/nixexpr.hh | 4 +-- src/libexpr/parser-state.hh | 2 +- src/libexpr/parser.y | 8 +++--- src/libexpr/primops.cc | 8 +++--- src/libexpr/value.hh | 5 ++-- src/libfetchers/fetchers.cc | 5 ++-- src/libfetchers/fetchers.hh | 10 +++---- src/libfetchers/filtering-input-accessor.cc | 8 +++--- src/libfetchers/filtering-input-accessor.hh | 7 +++-- src/libfetchers/fs-input-accessor.cc | 15 ++++------- src/libfetchers/fs-input-accessor.hh | 7 +++-- src/libfetchers/git-utils.cc | 21 +++++++-------- src/libfetchers/git-utils.hh | 5 ++-- src/libfetchers/github.cc | 2 +- src/libfetchers/indirect.cc | 2 +- src/libfetchers/memory-input-accessor.cc | 29 --------------------- src/libfetchers/memory-input-accessor.hh | 18 ------------- src/libfetchers/mounted-input-accessor.cc | 10 +++---- src/libfetchers/mounted-input-accessor.hh | 4 +-- src/libfetchers/path.cc | 2 +- src/libfetchers/tarball.cc | 4 +-- src/libfetchers/tarball.hh | 4 +-- src/libfetchers/unix/git.cc | 12 ++++----- src/libfetchers/unix/mercurial.cc | 2 +- src/libutil/input-accessor.hh | 27 ------------------- src/libutil/memory-source-accessor.cc | 10 +++++-- src/libutil/memory-source-accessor.hh | 4 +-- src/libutil/source-accessor.hh | 26 +++++++++++++++++- src/libutil/source-path.cc | 6 ++--- src/libutil/source-path.hh | 12 ++++----- src/nix-env/nix-env.cc | 14 +++++----- src/nix/main.cc | 2 +- tests/unit/libexpr/primops.cc | 1 - 35 files changed, 130 insertions(+), 188 deletions(-) delete mode 100644 src/libfetchers/memory-input-accessor.cc delete mode 100644 src/libfetchers/memory-input-accessor.hh delete mode 100644 src/libutil/input-accessor.hh diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index aa058b04f..fbd846d14 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -17,7 +17,7 @@ #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" @@ -400,7 +400,7 @@ EvalState::EvalState( , emptyBindings(0) , rootFS( evalSettings.restrictEval || evalSettings.pureEval - ? ref(AllowListInputAccessor::create(makeFSInputAccessor(), {}, + ? ref(AllowListInputAccessor::create(makeFSInputAccessor(), {}, [](const CanonPath & path) -> RestrictedPathError { auto modeInformation = evalSettings.pureEval ? "in pure evaluation mode (use '--impure' to override)" @@ -408,8 +408,8 @@ EvalState::EvalState( throw RestrictedPathError("access to absolute path '%1%' is forbidden %2%", path, modeInformation); })) : makeFSInputAccessor()) - , corepkgsFS(makeMemoryInputAccessor()) - , internalFS(makeMemoryInputAccessor()) + , corepkgsFS(make_ref()) + , internalFS(make_ref()) , derivationInternal{corepkgsFS->addFile( CanonPath("derivation-internal.nix"), #include "primops/derivation.nix.gen.hh" @@ -2766,12 +2766,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; diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index ae8b9dd04..7ca2d6227 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -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" @@ -33,7 +33,7 @@ class EvalState; class StorePath; struct SingleDerivedPath; enum RepairFlag : bool; -struct MemoryInputAccessor; +struct MemorySourceAccessor; namespace eval_cache { class EvalCache; } @@ -229,18 +229,18 @@ public: /** * The accessor for the root filesystem. */ - const ref rootFS; + const ref rootFS; /** * The in-memory filesystem for paths. */ - const ref corepkgsFS; + const ref corepkgsFS; /** * In-memory filesystem for internal, non-user-callable Nix * expressions like call-flake.nix. */ - const ref internalFS; + const ref internalFS; const SourcePath derivationInternal; diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index e3cae8385..e37e3bdd1 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -92,10 +92,10 @@ struct ExprString : Expr struct ExprPath : Expr { - ref accessor; + ref accessor; std::string s; Value v; - ExprPath(ref accessor, std::string s) : accessor(accessor), s(std::move(s)) + ExprPath(ref accessor, std::string s) : accessor(accessor), s(std::move(s)) { v.mkPath(&*accessor, this->s.c_str()); } diff --git a/src/libexpr/parser-state.hh b/src/libexpr/parser-state.hh index 024e79c43..5a928e9aa 100644 --- a/src/libexpr/parser-state.hh +++ b/src/libexpr/parser-state.hh @@ -44,7 +44,7 @@ struct ParserState Expr * result; SourcePath basePath; PosTable::Origin origin; - const ref rootFS; + const ref rootFS; const Expr::AstSymbols & s; void dupAttr(const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos); diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index bff066170..00300449f 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -41,7 +41,7 @@ Expr * parseExprFromBuf( const SourcePath & basePath, SymbolTable & symbols, PosTable & positions, - const ref rootFS, + const ref rootFS, const Expr::AstSymbols & astSymbols); } @@ -291,7 +291,7 @@ path_start /* add back in the trailing '/' to the first segment */ if ($1.p[$1.l-1] == '/' && $1.l > 1) path += "/"; - $$ = new ExprPath(ref(state->rootFS), std::move(path)); + $$ = new ExprPath(ref(state->rootFS), std::move(path)); } | HPATH { if (evalSettings.pureEval) { @@ -301,7 +301,7 @@ path_start ); } Path path(getHome() + std::string($1.p + 1, $1.l - 1)); - $$ = new ExprPath(ref(state->rootFS), std::move(path)); + $$ = new ExprPath(ref(state->rootFS), std::move(path)); } ; @@ -430,7 +430,7 @@ Expr * parseExprFromBuf( const SourcePath & basePath, SymbolTable & symbols, PosTable & positions, - const ref rootFS, + const ref rootFS, const Expr::AstSymbols & astSymbols) { yyscan_t scanner; diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index df274caed..a3ccc9771 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -1828,12 +1828,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; } diff --git a/src/libexpr/value.hh b/src/libexpr/value.hh index 5795f04cf..61cf2d310 100644 --- a/src/libexpr/value.hh +++ b/src/libexpr/value.hh @@ -7,7 +7,6 @@ #include "symbol-table.hh" #include "value/context.hh" -#include "input-accessor.hh" #include "source-path.hh" #include "print-options.hh" @@ -217,7 +216,7 @@ public: }; struct Path { - InputAccessor * accessor; + SourceAccessor * accessor; const char * path; }; @@ -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 } }); } diff --git a/src/libfetchers/fetchers.cc b/src/libfetchers/fetchers.cc index 0577b8d9d..73923907c 100644 --- a/src/libfetchers/fetchers.cc +++ b/src/libfetchers/fetchers.cc @@ -1,6 +1,5 @@ #include "fetchers.hh" #include "store-api.hh" -#include "input-accessor.hh" #include "source-path.hh" #include "fetch-to-store.hh" #include "json-utils.hh" @@ -238,7 +237,7 @@ void InputScheme::checkLocks(const Input & specified, const Input & final) const } } -std::pair, Input> Input::getAccessor(ref store) const +std::pair, Input> Input::getAccessor(ref store) const { try { auto [accessor, final] = getAccessorUnchecked(store); @@ -252,7 +251,7 @@ std::pair, Input> Input::getAccessor(ref store) const } } -std::pair, Input> Input::getAccessorUnchecked(ref store) const +std::pair, Input> Input::getAccessorUnchecked(ref store) const { // FIXME: cache the accessor diff --git a/src/libfetchers/fetchers.hh b/src/libfetchers/fetchers.hh index bb21c68cc..42b184393 100644 --- a/src/libfetchers/fetchers.hh +++ b/src/libfetchers/fetchers.hh @@ -11,7 +11,7 @@ #include #include -namespace nix { class Store; class StorePath; struct InputAccessor; } +namespace nix { class Store; class StorePath; struct SourceAccessor; } namespace nix::fetchers { @@ -84,15 +84,15 @@ public: std::pair fetchToStore(ref store) const; /** - * Return an InputAccessor that allows access to files in the + * Return a `SourceAccessor` that allows access to files in the * input without copying it to the store. Also return a possibly * unlocked input. */ - std::pair, Input> getAccessor(ref store) const; + std::pair, Input> getAccessor(ref store) const; private: - std::pair, Input> getAccessorUnchecked(ref store) const; + std::pair, Input> getAccessorUnchecked(ref store) const; public: @@ -185,7 +185,7 @@ struct InputScheme std::string_view contents, std::optional commitMsg) const; - virtual std::pair, Input> getAccessor(ref store, const Input & input) const = 0; + virtual std::pair, Input> getAccessor(ref store, const Input & input) const = 0; /** * Is this `InputScheme` part of an experimental feature? diff --git a/src/libfetchers/filtering-input-accessor.cc b/src/libfetchers/filtering-input-accessor.cc index e0cbfd905..d2b47b5e5 100644 --- a/src/libfetchers/filtering-input-accessor.cc +++ b/src/libfetchers/filtering-input-accessor.cc @@ -13,13 +13,13 @@ bool FilteringInputAccessor::pathExists(const CanonPath & path) return isAllowed(path) && next->pathExists(prefix / path); } -std::optional FilteringInputAccessor::maybeLstat(const CanonPath & path) +std::optional FilteringInputAccessor::maybeLstat(const CanonPath & path) { checkAccess(path); return next->maybeLstat(prefix / path); } -InputAccessor::DirEntries FilteringInputAccessor::readDirectory(const CanonPath & path) +SourceAccessor::DirEntries FilteringInputAccessor::readDirectory(const CanonPath & path) { checkAccess(path); DirEntries entries; @@ -54,7 +54,7 @@ struct AllowListInputAccessorImpl : AllowListInputAccessor std::set allowedPrefixes; AllowListInputAccessorImpl( - ref next, + ref next, std::set && allowedPrefixes, MakeNotAllowedError && makeNotAllowedError) : AllowListInputAccessor(SourcePath(next), std::move(makeNotAllowedError)) @@ -73,7 +73,7 @@ struct AllowListInputAccessorImpl : AllowListInputAccessor }; ref AllowListInputAccessor::create( - ref next, + ref next, std::set && allowedPrefixes, MakeNotAllowedError && makeNotAllowedError) { diff --git a/src/libfetchers/filtering-input-accessor.hh b/src/libfetchers/filtering-input-accessor.hh index 133a6cee3..ddf18eea4 100644 --- a/src/libfetchers/filtering-input-accessor.hh +++ b/src/libfetchers/filtering-input-accessor.hh @@ -1,6 +1,5 @@ #pragma once -#include "input-accessor.hh" #include "source-path.hh" namespace nix { @@ -17,9 +16,9 @@ typedef std::function MakeNotAllowe * control. Subclasses should override `isAllowed()` to implement an * access control policy. The error message is customized at construction. */ -struct FilteringInputAccessor : InputAccessor +struct FilteringInputAccessor : SourceAccessor { - ref next; + ref next; CanonPath prefix; MakeNotAllowedError makeNotAllowedError; @@ -67,7 +66,7 @@ struct AllowListInputAccessor : public FilteringInputAccessor virtual void allowPrefix(CanonPath prefix) = 0; static ref create( - ref next, + ref next, std::set && allowedPrefixes, MakeNotAllowedError && makeNotAllowedError); diff --git a/src/libfetchers/fs-input-accessor.cc b/src/libfetchers/fs-input-accessor.cc index 2bbe53e11..bd4e4e2cd 100644 --- a/src/libfetchers/fs-input-accessor.cc +++ b/src/libfetchers/fs-input-accessor.cc @@ -4,22 +4,17 @@ namespace nix { -struct FSInputAccessor : InputAccessor, PosixSourceAccessor +ref makeFSInputAccessor() { - using PosixSourceAccessor::PosixSourceAccessor; -}; - -ref makeFSInputAccessor() -{ - return make_ref(); + return make_ref(); } -ref makeFSInputAccessor(std::filesystem::path root) +ref makeFSInputAccessor(std::filesystem::path root) { - return make_ref(std::move(root)); + return make_ref(std::move(root)); } -ref makeStorePathAccessor( +ref makeStorePathAccessor( ref store, const StorePath & storePath) { diff --git a/src/libfetchers/fs-input-accessor.hh b/src/libfetchers/fs-input-accessor.hh index e60906bd8..80dc74725 100644 --- a/src/libfetchers/fs-input-accessor.hh +++ b/src/libfetchers/fs-input-accessor.hh @@ -1,6 +1,5 @@ #pragma once -#include "input-accessor.hh" #include "source-path.hh" namespace nix { @@ -8,11 +7,11 @@ namespace nix { class StorePath; class Store; -ref makeFSInputAccessor(); +ref makeFSInputAccessor(); -ref makeFSInputAccessor(std::filesystem::path root); +ref makeFSInputAccessor(std::filesystem::path root); -ref makeStorePathAccessor( +ref makeStorePathAccessor( ref store, const StorePath & storePath); diff --git a/src/libfetchers/git-utils.cc b/src/libfetchers/git-utils.cc index e310af063..5657a6b4f 100644 --- a/src/libfetchers/git-utils.cc +++ b/src/libfetchers/git-utils.cc @@ -1,8 +1,5 @@ #include "git-utils.hh" #include "fs-input-accessor.hh" -#include "input-accessor.hh" -#include "filtering-input-accessor.hh" -#include "memory-input-accessor.hh" #include "cache.hh" #include "finally.hh" #include "processes.hh" @@ -338,9 +335,9 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this */ ref getRawAccessor(const Hash & rev); - ref getAccessor(const Hash & rev, bool exportIgnore) override; + ref getAccessor(const Hash & rev, bool exportIgnore) override; - ref getAccessor(const WorkdirInfo & wd, bool exportIgnore, MakeNotAllowedError e) override; + ref getAccessor(const WorkdirInfo & wd, bool exportIgnore, MakeNotAllowedError e) override; ref getFileSystemObjectSink() override; @@ -477,7 +474,7 @@ ref GitRepo::openRepo(const std::filesystem::path & path, bool create, /** * Raw git tree input accessor. */ -struct GitInputAccessor : InputAccessor +struct GitInputAccessor : SourceAccessor { ref repo; Tree root; @@ -710,7 +707,7 @@ struct GitExportIgnoreInputAccessor : CachingFilteringInputAccessor { ref repo; std::optional rev; - GitExportIgnoreInputAccessor(ref repo, ref next, std::optional rev) + GitExportIgnoreInputAccessor(ref repo, ref next, std::optional rev) : CachingFilteringInputAccessor(next, [&](const CanonPath & path) { return RestrictedPathError(fmt("'%s' does not exist because it was fetched with exportIgnore enabled", path)); }) @@ -928,7 +925,7 @@ ref GitRepoImpl::getRawAccessor(const Hash & rev) return make_ref(self, rev); } -ref GitRepoImpl::getAccessor(const Hash & rev, bool exportIgnore) +ref GitRepoImpl::getAccessor(const Hash & rev, bool exportIgnore) { auto self = ref(shared_from_this()); ref rawGitAccessor = getRawAccessor(rev); @@ -940,20 +937,20 @@ ref GitRepoImpl::getAccessor(const Hash & rev, bool exportIgnore) } } -ref GitRepoImpl::getAccessor(const WorkdirInfo & wd, bool exportIgnore, MakeNotAllowedError makeNotAllowedError) +ref GitRepoImpl::getAccessor(const WorkdirInfo & wd, bool exportIgnore, MakeNotAllowedError makeNotAllowedError) { auto self = ref(shared_from_this()); /* In case of an empty workdir, return an empty in-memory tree. We cannot use AllowListInputAccessor because it would return an error for the root (and we can't add the root to the allow-list since that would allow access to all its children). */ - ref fileAccessor = + ref fileAccessor = wd.files.empty() - ? makeEmptyInputAccessor() + ? makeEmptySourceAccessor() : AllowListInputAccessor::create( makeFSInputAccessor(path), std::set { wd.files }, - std::move(makeNotAllowedError)).cast(); + std::move(makeNotAllowedError)).cast(); if (exportIgnore) return make_ref(self, fileAccessor, std::nullopt); else diff --git a/src/libfetchers/git-utils.hh b/src/libfetchers/git-utils.hh index 600a42da0..e264b2f63 100644 --- a/src/libfetchers/git-utils.hh +++ b/src/libfetchers/git-utils.hh @@ -1,7 +1,6 @@ #pragma once #include "filtering-input-accessor.hh" -#include "input-accessor.hh" #include "fs-sink.hh" namespace nix { @@ -75,9 +74,9 @@ struct GitRepo virtual bool hasObject(const Hash & oid) = 0; - virtual ref getAccessor(const Hash & rev, bool exportIgnore) = 0; + virtual ref getAccessor(const Hash & rev, bool exportIgnore) = 0; - virtual ref getAccessor(const WorkdirInfo & wd, bool exportIgnore, MakeNotAllowedError makeNotAllowedError) = 0; + virtual ref getAccessor(const WorkdirInfo & wd, bool exportIgnore, MakeNotAllowedError makeNotAllowedError) = 0; virtual ref getFileSystemObjectSink() = 0; diff --git a/src/libfetchers/github.cc b/src/libfetchers/github.cc index 985f2e479..b9a3d5c0d 100644 --- a/src/libfetchers/github.cc +++ b/src/libfetchers/github.cc @@ -272,7 +272,7 @@ struct GitArchiveInputScheme : InputScheme return {std::move(input), tarballInfo}; } - std::pair, Input> getAccessor(ref store, const Input & _input) const override + std::pair, Input> getAccessor(ref store, const Input & _input) const override { auto [input, tarballInfo] = downloadArchive(store, _input); diff --git a/src/libfetchers/indirect.cc b/src/libfetchers/indirect.cc index 3f21445e1..ba5078631 100644 --- a/src/libfetchers/indirect.cc +++ b/src/libfetchers/indirect.cc @@ -97,7 +97,7 @@ struct IndirectInputScheme : InputScheme return input; } - std::pair, Input> getAccessor(ref store, const Input & input) const override + std::pair, Input> getAccessor(ref store, const Input & input) const override { throw Error("indirect input '%s' cannot be fetched directly", input.to_string()); } diff --git a/src/libfetchers/memory-input-accessor.cc b/src/libfetchers/memory-input-accessor.cc deleted file mode 100644 index 34a801f67..000000000 --- a/src/libfetchers/memory-input-accessor.cc +++ /dev/null @@ -1,29 +0,0 @@ -#include "memory-input-accessor.hh" -#include "memory-source-accessor.hh" -#include "source-path.hh" - -namespace nix { - -struct MemoryInputAccessorImpl : MemoryInputAccessor, MemorySourceAccessor -{ - SourcePath addFile(CanonPath path, std::string && contents) override - { - return { - ref(shared_from_this()), - MemorySourceAccessor::addFile(path, std::move(contents)) - }; - } -}; - -ref makeMemoryInputAccessor() -{ - return make_ref(); -} - -ref makeEmptyInputAccessor() -{ - static auto empty = makeMemoryInputAccessor().cast(); - return empty; -} - -} diff --git a/src/libfetchers/memory-input-accessor.hh b/src/libfetchers/memory-input-accessor.hh deleted file mode 100644 index 63afadd2a..000000000 --- a/src/libfetchers/memory-input-accessor.hh +++ /dev/null @@ -1,18 +0,0 @@ -#include "input-accessor.hh" -#include "source-path.hh" - -namespace nix { - -/** - * An input accessor for an in-memory file system. - */ -struct MemoryInputAccessor : InputAccessor -{ - virtual SourcePath addFile(CanonPath path, std::string && contents) = 0; -}; - -ref makeMemoryInputAccessor(); - -ref makeEmptyInputAccessor(); - -} diff --git a/src/libfetchers/mounted-input-accessor.cc b/src/libfetchers/mounted-input-accessor.cc index b1eeaa97d..4d086c7ad 100644 --- a/src/libfetchers/mounted-input-accessor.cc +++ b/src/libfetchers/mounted-input-accessor.cc @@ -2,11 +2,11 @@ namespace nix { -struct MountedInputAccessor : InputAccessor +struct MountedInputAccessor : SourceAccessor { - std::map> mounts; + std::map> mounts; - MountedInputAccessor(std::map> _mounts) + MountedInputAccessor(std::map> _mounts) : mounts(std::move(_mounts)) { displayPrefix.clear(); @@ -53,7 +53,7 @@ struct MountedInputAccessor : InputAccessor return displayPrefix + accessor->showPath(subpath) + displaySuffix; } - std::pair, CanonPath> resolve(CanonPath path) + std::pair, CanonPath> resolve(CanonPath path) { // Find the nearest parent of `path` that is a mount point. std::vector subpath; @@ -71,7 +71,7 @@ struct MountedInputAccessor : InputAccessor } }; -ref makeMountedInputAccessor(std::map> mounts) +ref makeMountedInputAccessor(std::map> mounts) { return make_ref(std::move(mounts)); } diff --git a/src/libfetchers/mounted-input-accessor.hh b/src/libfetchers/mounted-input-accessor.hh index b557c5dad..74e040f44 100644 --- a/src/libfetchers/mounted-input-accessor.hh +++ b/src/libfetchers/mounted-input-accessor.hh @@ -1,9 +1,9 @@ #pragma once -#include "input-accessor.hh" +#include "source-accessor.hh" namespace nix { -ref makeMountedInputAccessor(std::map> mounts); +ref makeMountedInputAccessor(std::map> mounts); } diff --git a/src/libfetchers/path.cc b/src/libfetchers/path.cc index 67a9fc2f2..1e9683ae1 100644 --- a/src/libfetchers/path.cc +++ b/src/libfetchers/path.cc @@ -114,7 +114,7 @@ struct PathInputScheme : InputScheme throw Error("cannot fetch input '%s' because it uses a relative path", input.to_string()); } - std::pair, Input> getAccessor(ref store, const Input & _input) const override + std::pair, Input> getAccessor(ref store, const Input & _input) const override { Input input(_input); std::string absPath; diff --git a/src/libfetchers/tarball.cc b/src/libfetchers/tarball.cc index a1f934c35..8ebc2c296 100644 --- a/src/libfetchers/tarball.cc +++ b/src/libfetchers/tarball.cc @@ -297,7 +297,7 @@ struct FileInputScheme : CurlInputScheme : (!requireTree && !hasTarballExtension(url.path))); } - std::pair, Input> getAccessor(ref store, const Input & _input) const override + std::pair, Input> getAccessor(ref store, const Input & _input) const override { auto input(_input); @@ -332,7 +332,7 @@ struct TarballInputScheme : CurlInputScheme : (requireTree || hasTarballExtension(url.path))); } - std::pair, Input> getAccessor(ref store, const Input & _input) const override + std::pair, Input> getAccessor(ref store, const Input & _input) const override { auto input(_input); diff --git a/src/libfetchers/tarball.hh b/src/libfetchers/tarball.hh index bcb5dcc5e..ba0dfd623 100644 --- a/src/libfetchers/tarball.hh +++ b/src/libfetchers/tarball.hh @@ -8,7 +8,7 @@ namespace nix { class Store; -struct InputAccessor; +struct SourceAccessor; } namespace nix::fetchers { @@ -32,7 +32,7 @@ struct DownloadTarballResult Hash treeHash; time_t lastModified; std::optional immutableUrl; - ref accessor; + ref accessor; }; /** diff --git a/src/libfetchers/unix/git.cc b/src/libfetchers/unix/git.cc index 0c54c5504..be44b2eda 100644 --- a/src/libfetchers/unix/git.cc +++ b/src/libfetchers/unix/git.cc @@ -495,7 +495,7 @@ struct GitInputScheme : InputScheme } } - std::pair, Input> getAccessorFromCommit( + std::pair, Input> getAccessorFromCommit( ref store, RepoInfo & repoInfo, Input && input) const @@ -629,7 +629,7 @@ struct GitInputScheme : InputScheme input accessor consisting of the accessor for the top-level repo and the accessors for the submodules. */ if (getSubmodulesAttr(input)) { - std::map> mounts; + std::map> mounts; for (auto & [submodule, submoduleRev] : repo->getSubmodules(rev, exportIgnore)) { auto resolved = repo->resolveSubmoduleUrl(submodule.url); @@ -665,7 +665,7 @@ struct GitInputScheme : InputScheme return {accessor, std::move(input)}; } - std::pair, Input> getAccessorFromWorkdir( + std::pair, Input> getAccessorFromWorkdir( ref store, RepoInfo & repoInfo, Input && input) const @@ -679,7 +679,7 @@ struct GitInputScheme : InputScheme auto exportIgnore = getExportIgnoreAttr(input); - ref accessor = + ref accessor = repo->getAccessor(repoInfo.workdirInfo, exportIgnore, makeNotAllowedError(repoInfo.url)); @@ -690,7 +690,7 @@ struct GitInputScheme : InputScheme consisting of the accessor for the top-level repo and the accessors for the submodule workdirs. */ if (getSubmodulesAttr(input) && !repoInfo.workdirInfo.submodules.empty()) { - std::map> mounts; + std::map> mounts; for (auto & submodule : repoInfo.workdirInfo.submodules) { auto submodulePath = CanonPath(repoInfo.url) / submodule.path; @@ -755,7 +755,7 @@ struct GitInputScheme : InputScheme return {accessor, std::move(input)}; } - std::pair, Input> getAccessor(ref store, const Input & _input) const override + std::pair, Input> getAccessor(ref store, const Input & _input) const override { Input input(_input); diff --git a/src/libfetchers/unix/mercurial.cc b/src/libfetchers/unix/mercurial.cc index df6bc5335..e85f7e854 100644 --- a/src/libfetchers/unix/mercurial.cc +++ b/src/libfetchers/unix/mercurial.cc @@ -346,7 +346,7 @@ struct MercurialInputScheme : InputScheme return makeResult(infoAttrs, std::move(storePath)); } - std::pair, Input> getAccessor(ref store, const Input & _input) const override + std::pair, Input> getAccessor(ref store, const Input & _input) const override { Input input(_input); diff --git a/src/libutil/input-accessor.hh b/src/libutil/input-accessor.hh deleted file mode 100644 index 55b7c2f2f..000000000 --- a/src/libutil/input-accessor.hh +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -///@file - -#include "source-accessor.hh" -#include "ref.hh" -#include "repair-flag.hh" - -namespace nix { - -MakeError(RestrictedPathError, Error); - -struct InputAccessor : virtual SourceAccessor, std::enable_shared_from_this -{ - std::optional fingerprint; - - /** - * Return the maximum last-modified time of the files in this - * tree, if available. - */ - virtual std::optional getLastModified() - { - return std::nullopt; - } - -}; - -} diff --git a/src/libutil/memory-source-accessor.cc b/src/libutil/memory-source-accessor.cc index 880fa61b7..b7207cffb 100644 --- a/src/libutil/memory-source-accessor.cc +++ b/src/libutil/memory-source-accessor.cc @@ -108,7 +108,7 @@ std::string MemorySourceAccessor::readLink(const CanonPath & path) throw Error("file '%s' is not a symbolic link", path); } -CanonPath MemorySourceAccessor::addFile(CanonPath path, std::string && contents) +SourcePath MemorySourceAccessor::addFile(CanonPath path, std::string && contents) { auto * f = open(path, File { File::Regular {} }); if (!f) @@ -118,7 +118,7 @@ CanonPath MemorySourceAccessor::addFile(CanonPath path, std::string && contents) else throw Error("file '%s' is not a regular file", path); - return path; + return SourcePath{ref(shared_from_this()), path}; } @@ -184,4 +184,10 @@ void MemorySink::createSymlink(const Path & path, const std::string & target) throw Error("file '%s' is not a symbolic link", path); } +ref makeEmptySourceAccessor() +{ + static auto empty = make_ref().cast(); + return empty; +} + } diff --git a/src/libutil/memory-source-accessor.hh b/src/libutil/memory-source-accessor.hh index 7a1990d2f..c8f793922 100644 --- a/src/libutil/memory-source-accessor.hh +++ b/src/libutil/memory-source-accessor.hh @@ -1,4 +1,4 @@ -#include "source-accessor.hh" +#include "source-path.hh" #include "fs-sink.hh" #include "variant-wrapper.hh" @@ -69,7 +69,7 @@ struct MemorySourceAccessor : virtual SourceAccessor */ File * open(const CanonPath & path, std::optional create); - CanonPath addFile(CanonPath path, std::string && contents); + SourcePath addFile(CanonPath path, std::string && contents); }; /** diff --git a/src/libutil/source-accessor.hh b/src/libutil/source-accessor.hh index 1f272327f..5f1afb946 100644 --- a/src/libutil/source-accessor.hh +++ b/src/libutil/source-accessor.hh @@ -35,7 +35,7 @@ enum class SymlinkResolution { * filesystem-like entities (such as the real filesystem, tarballs or * Git repositories). */ -struct SourceAccessor +struct SourceAccessor : std::enable_shared_from_this { const size_t number; @@ -168,6 +168,30 @@ struct SourceAccessor CanonPath resolveSymlinks( const CanonPath & path, SymlinkResolution mode = SymlinkResolution::Full); + + /** + * A string that uniquely represents the contents of this + * accessor. This is used for caching lookups (see `fetchToStore()`). + */ + std::optional fingerprint; + + /** + * Return the maximum last-modified time of the files in this + * tree, if available. + */ + virtual std::optional getLastModified() + { return std::nullopt; } }; +/** + * Return a source accessor that contains only an empty root directory. + */ +ref makeEmptySourceAccessor(); + +/** + * Exception thrown when accessing a filtered path (see + * `FilteringInputAccessor`). + */ +MakeError(RestrictedPathError, Error); + } diff --git a/src/libutil/source-path.cc b/src/libutil/source-path.cc index 2a5b20858..023b5ed4b 100644 --- a/src/libutil/source-path.cc +++ b/src/libutil/source-path.cc @@ -18,13 +18,13 @@ std::string SourcePath::readFile() const bool SourcePath::pathExists() const { return accessor->pathExists(path); } -InputAccessor::Stat SourcePath::lstat() const +SourceAccessor::Stat SourcePath::lstat() const { return accessor->lstat(path); } -std::optional SourcePath::maybeLstat() const +std::optional SourcePath::maybeLstat() const { return accessor->maybeLstat(path); } -InputAccessor::DirEntries SourcePath::readDirectory() const +SourceAccessor::DirEntries SourcePath::readDirectory() const { return accessor->readDirectory(path); } std::string SourcePath::readLink() const diff --git a/src/libutil/source-path.hh b/src/libutil/source-path.hh index b8f69af12..7e4c3c65d 100644 --- a/src/libutil/source-path.hh +++ b/src/libutil/source-path.hh @@ -7,7 +7,7 @@ #include "ref.hh" #include "canon-path.hh" -#include "input-accessor.hh" +#include "source-accessor.hh" namespace nix { @@ -19,10 +19,10 @@ namespace nix { */ struct SourcePath { - ref accessor; + ref accessor; CanonPath path; - SourcePath(ref accessor, CanonPath path = CanonPath::root) + SourcePath(ref accessor, CanonPath path = CanonPath::root) : accessor(std::move(accessor)) , path(std::move(path)) { } @@ -51,19 +51,19 @@ struct SourcePath * Return stats about this `SourcePath`, or throw an exception if * it doesn't exist. */ - InputAccessor::Stat lstat() const; + SourceAccessor::Stat lstat() const; /** * Return stats about this `SourcePath`, or std::nullopt if it * doesn't exist. */ - std::optional maybeLstat() const; + std::optional maybeLstat() const; /** * If this `SourcePath` denotes a directory (not a symlink), * return its directory entries; otherwise throw an error. */ - InputAccessor::DirEntries readDirectory() const; + SourceAccessor::DirEntries readDirectory() const; /** * If this `SourcePath` denotes a symlink, return its target; diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 25c8f43c2..b5e13cc23 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -94,11 +94,11 @@ static bool parseInstallSourceOptions(Globals & globals, } -static bool isNixExpr(const SourcePath & path, struct InputAccessor::Stat & st) +static bool isNixExpr(const SourcePath & path, struct SourceAccessor::Stat & st) { return - st.type == InputAccessor::tRegular - || (st.type == InputAccessor::tDirectory && (path / "default.nix").resolveSymlinks().pathExists()); + st.type == SourceAccessor::tRegular + || (st.type == SourceAccessor::tDirectory && (path / "default.nix").resolveSymlinks().pathExists()); } @@ -119,14 +119,14 @@ static void getAllExprs(EvalState & state, auto path2 = (path / i).resolveSymlinks(); - InputAccessor::Stat st; + SourceAccessor::Stat st; try { st = path2.lstat(); } catch (Error &) { continue; // ignore dangling symlinks in ~/.nix-defexpr } - if (isNixExpr(path2, st) && (st.type != InputAccessor::tRegular || hasSuffix(path2.baseName(), ".nix"))) { + if (isNixExpr(path2, st) && (st.type != SourceAccessor::tRegular || hasSuffix(path2.baseName(), ".nix"))) { /* Strip off the `.nix' filename suffix (if applicable), otherwise the attribute cannot be selected with the `-A' option. Useful if you want to stick a Nix @@ -149,7 +149,7 @@ static void getAllExprs(EvalState & state, throw Error("too many Nix expressions in directory '%1%'", path); attrs.alloc(attrName).mkApp(&state.getBuiltin("import"), vArg); } - else if (st.type == InputAccessor::tDirectory) + else if (st.type == SourceAccessor::tDirectory) /* `path2' is a directory (with no default.nix in it); recurse into it. */ getAllExprs(state, path2, seen, attrs); @@ -171,7 +171,7 @@ static void loadSourceExpr(EvalState & state, const SourcePath & path, Value & v set flat, not nested, to make it easier for a user to have a ~/.nix-defexpr directory that includes some system-wide directory). */ - else if (st.type == InputAccessor::tDirectory) { + else if (st.type == SourceAccessor::tDirectory) { auto attrs = state.buildBindings(maxAttrs); attrs.insert(state.symbols.create("_combineChannels"), &state.vEmptyList); StringSet seen; diff --git a/src/nix/main.cc b/src/nix/main.cc index 7b0478a9f..8ea2f7748 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -14,7 +14,7 @@ #include "finally.hh" #include "loggers.hh" #include "markdown.hh" -#include "memory-input-accessor.hh" +#include "memory-source-accessor.hh" #include "terminal.hh" #include "users.hh" diff --git a/tests/unit/libexpr/primops.cc b/tests/unit/libexpr/primops.cc index 5ddc031f7..10c250d74 100644 --- a/tests/unit/libexpr/primops.cc +++ b/tests/unit/libexpr/primops.cc @@ -2,7 +2,6 @@ #include #include "eval-settings.hh" -#include "memory-input-accessor.hh" #include "tests/libexpr.hh"