#pragma once #include "ref.hh" #include "types.hh" #include "archive.hh" #include "canon-path.hh" #include "repair-flag.hh" #include "hash.hh" namespace nix { MakeError(RestrictedPathError, Error); struct SourcePath; class StorePath; class Store; struct InputAccessor : public std::enable_shared_from_this { const size_t number; std::string displayPrefix, displaySuffix; std::optional fingerprint; InputAccessor(); virtual ~InputAccessor() { } virtual std::string readFile(const CanonPath & path) = 0; virtual bool pathExists(const CanonPath & path) = 0; enum Type { tRegular, tSymlink, tDirectory, tMisc }; struct Stat { Type type = tMisc; //uint64_t fileSize = 0; // regular files only bool isExecutable = false; // regular files only }; virtual Stat lstat(const CanonPath & path) = 0; std::optional maybeLstat(const CanonPath & path); typedef std::optional DirEntry; typedef std::map DirEntries; virtual DirEntries readDirectory(const CanonPath & path) = 0; virtual std::string readLink(const CanonPath & path) = 0; virtual void dumpPath( const CanonPath & path, Sink & sink, PathFilter & filter = defaultPathFilter); Hash hashPath( const CanonPath & path, PathFilter & filter = defaultPathFilter, HashType ht = htSHA256); StorePath fetchToStore( ref store, const CanonPath & path, std::string_view name = "source", PathFilter * filter = nullptr, RepairFlag repair = NoRepair); /* Return a corresponding path in the root filesystem, if possible. This is only possible for inputs that are materialized in the root filesystem. */ virtual std::optional getPhysicalPath(const CanonPath & path) { return std::nullopt; } bool operator == (const InputAccessor & x) const { return number == x.number; } bool operator < (const InputAccessor & x) const { return number < x.number; } void setPathDisplay(std::string displayPrefix, std::string displaySuffix = ""); virtual std::string showPath(const CanonPath & path); SourcePath root(); /* Return the maximum last-modified time of the files in this tree, if available. */ virtual std::optional getLastModified() { return std::nullopt; } }; typedef std::function MakeNotAllowedError; struct SourcePath; struct MemoryInputAccessor : InputAccessor { virtual SourcePath addFile(CanonPath path, std::string && contents) = 0; }; ref makeMemoryInputAccessor(); ref makeZipInputAccessor(const CanonPath & path); ref makePatchingInputAccessor( ref next, const std::vector & patches); ref makeGitInputAccessor(const CanonPath & path, const Hash & rev); Hash importTarball(Source & source); ref makeTarballCacheAccessor(const Hash & rev); struct SourcePath { ref accessor; CanonPath path; std::string_view baseName() const; SourcePath parent() const; std::string readFile() const { return accessor->readFile(path); } bool pathExists() const { return accessor->pathExists(path); } InputAccessor::Stat lstat() const { return accessor->lstat(path); } std::optional maybeLstat() const { return accessor->maybeLstat(path); } InputAccessor::DirEntries readDirectory() const { return accessor->readDirectory(path); } std::string readLink() const { return accessor->readLink(path); } void dumpPath( Sink & sink, PathFilter & filter = defaultPathFilter) const { return accessor->dumpPath(path, sink, filter); } StorePath fetchToStore( ref store, std::string_view name = "source", PathFilter * filter = nullptr, RepairFlag repair = NoRepair) const; std::optional getPhysicalPath() const { return accessor->getPhysicalPath(path); } std::string to_string() const { return accessor->showPath(path); } SourcePath operator + (const CanonPath & x) const { return {accessor, path + x}; } SourcePath operator + (std::string_view c) const { return {accessor, path + c}; } bool operator == (const SourcePath & x) const { return std::tie(accessor, path) == std::tie(x.accessor, x.path); } bool operator != (const SourcePath & x) const { return std::tie(accessor, path) != std::tie(x.accessor, x.path); } bool operator < (const SourcePath & x) const { return std::tie(accessor, path) < std::tie(x.accessor, x.path); } SourcePath resolveSymlinks() const; }; std::ostream & operator << (std::ostream & str, const SourcePath & path); }