mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-10 00:08:07 +02:00
Merge pull request #9948 from obsidiansystems/no-canon-path-from-cwd
Get rid of `CanonPath::fromCwd`
This commit is contained in:
commit
ec6ca6e42c
30 changed files with 152 additions and 135 deletions
|
@ -256,9 +256,9 @@ SV *
|
|||
hashPath(char * algo, int base32, char * path)
|
||||
PPCODE:
|
||||
try {
|
||||
PosixSourceAccessor accessor;
|
||||
auto [accessor, canonPath] = PosixSourceAccessor::createAtRoot(path);
|
||||
Hash h = hashPath(
|
||||
accessor, CanonPath::fromCwd(path),
|
||||
accessor, canonPath,
|
||||
FileIngestionMethod::Recursive, parseHashAlgo(algo)).first;
|
||||
auto s = h.to_string(base32 ? HashFormat::Nix32 : HashFormat::Base16, false);
|
||||
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
|
||||
|
@ -336,10 +336,10 @@ StoreWrapper::addToStore(char * srcPath, int recursive, char * algo)
|
|||
PPCODE:
|
||||
try {
|
||||
auto method = recursive ? FileIngestionMethod::Recursive : FileIngestionMethod::Flat;
|
||||
PosixSourceAccessor accessor;
|
||||
auto [accessor, canonPath] = PosixSourceAccessor::createAtRoot(srcPath);
|
||||
auto path = THIS->store->addToStore(
|
||||
std::string(baseNameOf(srcPath)),
|
||||
accessor, CanonPath::fromCwd(srcPath),
|
||||
accessor, canonPath,
|
||||
method, parseHashAlgo(algo));
|
||||
XPUSHs(sv_2mortal(newSVpv(THIS->store->printStorePath(path).c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
|
|
|
@ -156,7 +156,7 @@ Bindings * MixEvalArgs::getAutoArgs(EvalState & state)
|
|||
for (auto & i : autoArgs) {
|
||||
auto v = state.allocValue();
|
||||
if (i.second[0] == 'E')
|
||||
state.mkThunk_(*v, state.parseExprFromString(i.second.substr(1), state.rootPath(CanonPath::fromCwd())));
|
||||
state.mkThunk_(*v, state.parseExprFromString(i.second.substr(1), state.rootPath(".")));
|
||||
else
|
||||
v->mkString(((std::string_view) i.second).substr(1));
|
||||
res.insert(state.symbols.create(i.first), v);
|
||||
|
@ -164,7 +164,7 @@ Bindings * MixEvalArgs::getAutoArgs(EvalState & state)
|
|||
return res.finish();
|
||||
}
|
||||
|
||||
SourcePath lookupFileArg(EvalState & state, std::string_view s, CanonPath baseDir)
|
||||
SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * baseDir)
|
||||
{
|
||||
if (EvalSettings::isPseudoUrl(s)) {
|
||||
auto storePath = fetchers::downloadTarball(
|
||||
|
@ -185,7 +185,7 @@ SourcePath lookupFileArg(EvalState & state, std::string_view s, CanonPath baseDi
|
|||
}
|
||||
|
||||
else
|
||||
return state.rootPath(CanonPath(s, baseDir));
|
||||
return state.rootPath(baseDir ? absPath(s, *baseDir) : absPath(s));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,6 @@ private:
|
|||
std::map<std::string, std::string> autoArgs;
|
||||
};
|
||||
|
||||
SourcePath lookupFileArg(EvalState & state, std::string_view s, CanonPath baseDir = CanonPath::fromCwd());
|
||||
SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * baseDir = nullptr);
|
||||
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ Strings editorFor(const SourcePath & file, uint32_t line)
|
|||
editor.find("vim") != std::string::npos ||
|
||||
editor.find("kak") != std::string::npos))
|
||||
args.push_back(fmt("+%d", line));
|
||||
args.push_back(path->abs());
|
||||
args.push_back(path->string());
|
||||
return args;
|
||||
}
|
||||
|
||||
|
|
|
@ -487,10 +487,11 @@ Installables SourceExprCommand::parseInstallables(
|
|||
state->eval(e, *vFile);
|
||||
}
|
||||
else if (file) {
|
||||
state->evalFile(lookupFileArg(*state, *file, CanonPath::fromCwd(getCommandBaseDir())), *vFile);
|
||||
auto dir = absPath(getCommandBaseDir());
|
||||
state->evalFile(lookupFileArg(*state, *file, &dir), *vFile);
|
||||
}
|
||||
else {
|
||||
CanonPath dir(CanonPath::fromCwd(getCommandBaseDir()));
|
||||
Path dir = absPath(getCommandBaseDir());
|
||||
auto e = state->parseExprFromString(*expr, state->rootPath(dir));
|
||||
state->eval(e, *vFile);
|
||||
}
|
||||
|
|
|
@ -897,7 +897,7 @@ void NixRepl::addVarToScope(const Symbol name, Value & v)
|
|||
|
||||
Expr * NixRepl::parseString(std::string s)
|
||||
{
|
||||
return state->parseExprFromString(std::move(s), state->rootPath(CanonPath::fromCwd()), staticEnv);
|
||||
return state->parseExprFromString(std::move(s), state->rootPath("."), staticEnv);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -394,14 +394,14 @@ EvalState::EvalState(
|
|||
, emptyBindings(0)
|
||||
, rootFS(
|
||||
evalSettings.restrictEval || evalSettings.pureEval
|
||||
? ref<InputAccessor>(AllowListInputAccessor::create(makeFSInputAccessor(CanonPath::root), {},
|
||||
? ref<InputAccessor>(AllowListInputAccessor::create(makeFSInputAccessor(), {},
|
||||
[](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(CanonPath::root))
|
||||
: makeFSInputAccessor())
|
||||
, corepkgsFS(makeMemoryInputAccessor())
|
||||
, internalFS(makeMemoryInputAccessor())
|
||||
, derivationInternal{corepkgsFS->addFile(
|
||||
|
@ -2739,7 +2739,7 @@ Expr * EvalState::parseStdin()
|
|||
// drainFD should have left some extra space for terminators
|
||||
buffer.append("\0\0", 2);
|
||||
auto s = make_ref<std::string>(std::move(buffer));
|
||||
return parse(s->data(), s->size(), Pos::Stdin{.source = s}, rootPath(CanonPath::fromCwd()), staticBaseEnv);
|
||||
return parse(s->data(), s->size(), Pos::Stdin{.source = s}, rootPath("."), staticBaseEnv);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -306,6 +306,11 @@ public:
|
|||
*/
|
||||
SourcePath rootPath(CanonPath path);
|
||||
|
||||
/**
|
||||
* Variant which accepts relative paths too.
|
||||
*/
|
||||
SourcePath rootPath(PathView path);
|
||||
|
||||
/**
|
||||
* Allow access to a path.
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "eval.hh"
|
||||
#include "fs-input-accessor.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
@ -8,4 +7,9 @@ SourcePath EvalState::rootPath(CanonPath path)
|
|||
return {rootFS, std::move(path)};
|
||||
}
|
||||
|
||||
SourcePath EvalState::rootPath(PathView path)
|
||||
{
|
||||
return {rootFS, CanonPath(absPath(path))};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,72 +6,30 @@ namespace nix {
|
|||
|
||||
struct FSInputAccessor : InputAccessor, PosixSourceAccessor
|
||||
{
|
||||
CanonPath root;
|
||||
|
||||
FSInputAccessor(const CanonPath & root)
|
||||
: root(root)
|
||||
{
|
||||
displayPrefix = root.isRoot() ? "" : root.abs();
|
||||
}
|
||||
|
||||
void readFile(
|
||||
const CanonPath & path,
|
||||
Sink & sink,
|
||||
std::function<void(uint64_t)> sizeCallback) override
|
||||
{
|
||||
auto absPath = makeAbsPath(path);
|
||||
PosixSourceAccessor::readFile(absPath, sink, sizeCallback);
|
||||
}
|
||||
|
||||
bool pathExists(const CanonPath & path) override
|
||||
{
|
||||
return PosixSourceAccessor::pathExists(makeAbsPath(path));
|
||||
}
|
||||
|
||||
std::optional<Stat> maybeLstat(const CanonPath & path) override
|
||||
{
|
||||
return PosixSourceAccessor::maybeLstat(makeAbsPath(path));
|
||||
}
|
||||
|
||||
DirEntries readDirectory(const CanonPath & path) override
|
||||
{
|
||||
DirEntries res;
|
||||
for (auto & entry : PosixSourceAccessor::readDirectory(makeAbsPath(path)))
|
||||
res.emplace(entry);
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string readLink(const CanonPath & path) override
|
||||
{
|
||||
return PosixSourceAccessor::readLink(makeAbsPath(path));
|
||||
}
|
||||
|
||||
CanonPath makeAbsPath(const CanonPath & path)
|
||||
{
|
||||
return root / path;
|
||||
}
|
||||
|
||||
std::optional<CanonPath> getPhysicalPath(const CanonPath & path) override
|
||||
{
|
||||
return makeAbsPath(path);
|
||||
}
|
||||
using PosixSourceAccessor::PosixSourceAccessor;
|
||||
};
|
||||
|
||||
ref<InputAccessor> makeFSInputAccessor(const CanonPath & root)
|
||||
ref<InputAccessor> makeFSInputAccessor()
|
||||
{
|
||||
return make_ref<FSInputAccessor>(root);
|
||||
return make_ref<FSInputAccessor>();
|
||||
}
|
||||
|
||||
ref<InputAccessor> makeFSInputAccessor(std::filesystem::path root)
|
||||
{
|
||||
return make_ref<FSInputAccessor>(std::move(root));
|
||||
}
|
||||
|
||||
ref<InputAccessor> makeStorePathAccessor(
|
||||
ref<Store> store,
|
||||
const StorePath & storePath)
|
||||
{
|
||||
return makeFSInputAccessor(CanonPath(store->toRealPath(storePath)));
|
||||
// FIXME: should use `store->getFSAccessor()`
|
||||
return makeFSInputAccessor(std::filesystem::path { store->toRealPath(storePath) });
|
||||
}
|
||||
|
||||
SourcePath getUnfilteredRootPath(CanonPath path)
|
||||
{
|
||||
static auto rootFS = makeFSInputAccessor(CanonPath::root);
|
||||
static auto rootFS = makeFSInputAccessor();
|
||||
return {rootFS, path};
|
||||
}
|
||||
|
||||
|
|
|
@ -8,8 +8,9 @@ namespace nix {
|
|||
class StorePath;
|
||||
class Store;
|
||||
|
||||
ref<InputAccessor> makeFSInputAccessor(
|
||||
const CanonPath & root);
|
||||
ref<InputAccessor> makeFSInputAccessor();
|
||||
|
||||
ref<InputAccessor> makeFSInputAccessor(std::filesystem::path root);
|
||||
|
||||
ref<InputAccessor> makeStorePathAccessor(
|
||||
ref<Store> store,
|
||||
|
|
|
@ -140,15 +140,15 @@ T peelObject(git_repository * repo, git_object * obj, git_object_t type)
|
|||
struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
||||
{
|
||||
/** Location of the repository on disk. */
|
||||
CanonPath path;
|
||||
std::filesystem::path path;
|
||||
Repository repo;
|
||||
|
||||
GitRepoImpl(CanonPath _path, bool create, bool bare)
|
||||
GitRepoImpl(std::filesystem::path _path, bool create, bool bare)
|
||||
: path(std::move(_path))
|
||||
{
|
||||
initLibGit2();
|
||||
|
||||
if (pathExists(path.abs())) {
|
||||
if (pathExists(path.native())) {
|
||||
if (git_repository_open(Setter(repo), path.c_str()))
|
||||
throw Error("opening Git repository '%s': %s", path, git_error_last()->message);
|
||||
} else {
|
||||
|
@ -221,10 +221,10 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
|||
return toHash(*oid);
|
||||
}
|
||||
|
||||
std::vector<Submodule> parseSubmodules(const CanonPath & configFile)
|
||||
std::vector<Submodule> parseSubmodules(const std::filesystem::path & configFile)
|
||||
{
|
||||
GitConfig config;
|
||||
if (git_config_open_ondisk(Setter(config), configFile.abs().c_str()))
|
||||
if (git_config_open_ondisk(Setter(config), configFile.c_str()))
|
||||
throw Error("parsing .gitmodules file: %s", git_error_last()->message);
|
||||
|
||||
ConfigIterator it;
|
||||
|
@ -296,7 +296,7 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
|||
|
||||
/* Get submodule info. */
|
||||
auto modulesFile = path / ".gitmodules";
|
||||
if (pathExists(modulesFile.abs()))
|
||||
if (pathExists(modulesFile))
|
||||
info.submodules = parseSubmodules(modulesFile);
|
||||
|
||||
return info;
|
||||
|
@ -389,10 +389,10 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
|||
auto dir = this->path;
|
||||
Strings gitArgs;
|
||||
if (shallow) {
|
||||
gitArgs = { "-C", dir.abs(), "fetch", "--quiet", "--force", "--depth", "1", "--", url, refspec };
|
||||
gitArgs = { "-C", dir, "fetch", "--quiet", "--force", "--depth", "1", "--", url, refspec };
|
||||
}
|
||||
else {
|
||||
gitArgs = { "-C", dir.abs(), "fetch", "--quiet", "--force", "--", url, refspec };
|
||||
gitArgs = { "-C", dir, "fetch", "--quiet", "--force", "--", url, refspec };
|
||||
}
|
||||
|
||||
runProgram(RunOptions {
|
||||
|
@ -438,7 +438,7 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
|||
.args = {
|
||||
"-c",
|
||||
"gpg.ssh.allowedSignersFile=" + allowedSignersFile,
|
||||
"-C", path.abs(),
|
||||
"-C", path,
|
||||
"verify-commit",
|
||||
rev.gitRev()
|
||||
},
|
||||
|
@ -465,7 +465,7 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
|||
}
|
||||
};
|
||||
|
||||
ref<GitRepo> GitRepo::openRepo(const CanonPath & path, bool create, bool bare)
|
||||
ref<GitRepo> GitRepo::openRepo(const std::filesystem::path & path, bool create, bool bare)
|
||||
{
|
||||
return make_ref<GitRepoImpl>(path, create, bare);
|
||||
}
|
||||
|
@ -781,7 +781,7 @@ std::vector<std::tuple<GitRepoImpl::Submodule, Hash>> GitRepoImpl::getSubmodules
|
|||
|
||||
auto rawAccessor = getRawAccessor(rev);
|
||||
|
||||
for (auto & submodule : parseSubmodules(CanonPath(pathTemp))) {
|
||||
for (auto & submodule : parseSubmodules(pathTemp)) {
|
||||
auto rev = rawAccessor->getSubmoduleRev(submodule.path);
|
||||
result.push_back({std::move(submodule), rev});
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ struct GitRepo
|
|||
virtual ~GitRepo()
|
||||
{ }
|
||||
|
||||
static ref<GitRepo> openRepo(const CanonPath & path, bool create = false, bool bare = false);
|
||||
static ref<GitRepo> openRepo(const std::filesystem::path & path, bool create = false, bool bare = false);
|
||||
|
||||
virtual uint64_t getRevCount(const Hash & rev) = 0;
|
||||
|
||||
|
|
|
@ -415,7 +415,7 @@ struct GitInputScheme : InputScheme
|
|||
// If this is a local directory and no ref or revision is
|
||||
// given, then allow the use of an unclean working tree.
|
||||
if (!input.getRef() && !input.getRev() && repoInfo.isLocal)
|
||||
repoInfo.workdirInfo = GitRepo::openRepo(CanonPath(repoInfo.url))->getWorkdirInfo();
|
||||
repoInfo.workdirInfo = GitRepo::openRepo(repoInfo.url)->getWorkdirInfo();
|
||||
|
||||
return repoInfo;
|
||||
}
|
||||
|
@ -429,7 +429,7 @@ struct GitInputScheme : InputScheme
|
|||
if (auto res = cache->lookup(key))
|
||||
return getIntAttr(*res, "lastModified");
|
||||
|
||||
auto lastModified = GitRepo::openRepo(CanonPath(repoDir))->getLastModified(rev);
|
||||
auto lastModified = GitRepo::openRepo(repoDir)->getLastModified(rev);
|
||||
|
||||
cache->upsert(key, Attrs{{"lastModified", lastModified}});
|
||||
|
||||
|
@ -447,7 +447,7 @@ struct GitInputScheme : InputScheme
|
|||
|
||||
Activity act(*logger, lvlChatty, actUnknown, fmt("getting Git revision count of '%s'", repoInfo.url));
|
||||
|
||||
auto revCount = GitRepo::openRepo(CanonPath(repoDir))->getRevCount(rev);
|
||||
auto revCount = GitRepo::openRepo(repoDir)->getRevCount(rev);
|
||||
|
||||
cache->upsert(key, Attrs{{"revCount", revCount}});
|
||||
|
||||
|
@ -457,7 +457,7 @@ struct GitInputScheme : InputScheme
|
|||
std::string getDefaultRef(const RepoInfo & repoInfo) const
|
||||
{
|
||||
auto head = repoInfo.isLocal
|
||||
? GitRepo::openRepo(CanonPath(repoInfo.url))->getWorkdirRef()
|
||||
? GitRepo::openRepo(repoInfo.url)->getWorkdirRef()
|
||||
: readHeadCached(repoInfo.url);
|
||||
if (!head) {
|
||||
warn("could not read HEAD ref from repo at '%s', using 'master'", repoInfo.url);
|
||||
|
@ -510,7 +510,7 @@ struct GitInputScheme : InputScheme
|
|||
if (repoInfo.isLocal) {
|
||||
repoDir = repoInfo.url;
|
||||
if (!input.getRev())
|
||||
input.attrs.insert_or_assign("rev", GitRepo::openRepo(CanonPath(repoDir))->resolveRef(ref).gitRev());
|
||||
input.attrs.insert_or_assign("rev", GitRepo::openRepo(repoDir)->resolveRef(ref).gitRev());
|
||||
} else {
|
||||
Path cacheDir = getCachePath(repoInfo.url, getShallowAttr(input));
|
||||
repoDir = cacheDir;
|
||||
|
@ -519,7 +519,7 @@ struct GitInputScheme : InputScheme
|
|||
createDirs(dirOf(cacheDir));
|
||||
PathLocks cacheDirLock({cacheDir});
|
||||
|
||||
auto repo = GitRepo::openRepo(CanonPath(cacheDir), true, true);
|
||||
auto repo = GitRepo::openRepo(cacheDir, true, true);
|
||||
|
||||
Path localRefFile =
|
||||
ref.compare(0, 5, "refs/") == 0
|
||||
|
@ -588,7 +588,7 @@ struct GitInputScheme : InputScheme
|
|||
// cache dir lock is removed at scope end; we will only use read-only operations on specific revisions in the remainder
|
||||
}
|
||||
|
||||
auto repo = GitRepo::openRepo(CanonPath(repoDir));
|
||||
auto repo = GitRepo::openRepo(repoDir);
|
||||
|
||||
auto isShallow = repo->isShallow();
|
||||
|
||||
|
@ -664,7 +664,7 @@ struct GitInputScheme : InputScheme
|
|||
for (auto & submodule : repoInfo.workdirInfo.submodules)
|
||||
repoInfo.workdirInfo.files.insert(submodule.path);
|
||||
|
||||
auto repo = GitRepo::openRepo(CanonPath(repoInfo.url), false, false);
|
||||
auto repo = GitRepo::openRepo(repoInfo.url, false, false);
|
||||
|
||||
auto exportIgnore = getExportIgnoreAttr(input);
|
||||
|
||||
|
@ -703,7 +703,7 @@ struct GitInputScheme : InputScheme
|
|||
}
|
||||
|
||||
if (!repoInfo.workdirInfo.isDirty) {
|
||||
auto repo = GitRepo::openRepo(CanonPath(repoInfo.url));
|
||||
auto repo = GitRepo::openRepo(repoInfo.url);
|
||||
|
||||
if (auto ref = repo->getWorkdirRef())
|
||||
input.attrs.insert_or_assign("ref", *ref);
|
||||
|
|
|
@ -110,8 +110,8 @@ void SourceAccessor::dumpPath(
|
|||
|
||||
time_t dumpPathAndGetMtime(const Path & path, Sink & sink, PathFilter & filter)
|
||||
{
|
||||
PosixSourceAccessor accessor;
|
||||
accessor.dumpPath(CanonPath::fromCwd(path), sink, filter);
|
||||
auto [accessor, canonPath] = PosixSourceAccessor::createAtRoot(path);
|
||||
accessor.dumpPath(canonPath, sink, filter);
|
||||
return accessor.mtime;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,11 +20,6 @@ CanonPath::CanonPath(const std::vector<std::string> & elems)
|
|||
push(s);
|
||||
}
|
||||
|
||||
CanonPath CanonPath::fromCwd(std::string_view path)
|
||||
{
|
||||
return CanonPath(unchecked_t(), absPath(path));
|
||||
}
|
||||
|
||||
std::optional<CanonPath> CanonPath::parent() const
|
||||
{
|
||||
if (isRoot()) return std::nullopt;
|
||||
|
|
|
@ -52,8 +52,6 @@ public:
|
|||
*/
|
||||
CanonPath(const std::vector<std::string> & elems);
|
||||
|
||||
static CanonPath fromCwd(std::string_view path = ".");
|
||||
|
||||
static CanonPath root;
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,6 +6,33 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
PosixSourceAccessor::PosixSourceAccessor(std::filesystem::path && root)
|
||||
: root(std::move(root))
|
||||
{
|
||||
assert(root.empty() || root.is_absolute());
|
||||
displayPrefix = root;
|
||||
}
|
||||
|
||||
PosixSourceAccessor::PosixSourceAccessor()
|
||||
: PosixSourceAccessor(std::filesystem::path {})
|
||||
{ }
|
||||
|
||||
std::pair<PosixSourceAccessor, CanonPath> PosixSourceAccessor::createAtRoot(const std::filesystem::path & path)
|
||||
{
|
||||
std::filesystem::path path2 = absPath(path.native());
|
||||
return {
|
||||
PosixSourceAccessor { path2.root_path() },
|
||||
CanonPath { static_cast<std::string>(path2.relative_path()) },
|
||||
};
|
||||
}
|
||||
|
||||
std::filesystem::path PosixSourceAccessor::makeAbsPath(const CanonPath & path)
|
||||
{
|
||||
return root.empty()
|
||||
? (std::filesystem::path { path.abs() })
|
||||
: root / path.rel();
|
||||
}
|
||||
|
||||
void PosixSourceAccessor::readFile(
|
||||
const CanonPath & path,
|
||||
Sink & sink,
|
||||
|
@ -13,9 +40,11 @@ void PosixSourceAccessor::readFile(
|
|||
{
|
||||
assertNoSymlinks(path);
|
||||
|
||||
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
|
||||
auto ap = makeAbsPath(path);
|
||||
|
||||
AutoCloseFD fd = open(ap.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
|
||||
if (!fd)
|
||||
throw SysError("opening file '%1%'", path);
|
||||
throw SysError("opening file '%1%'", ap.native());
|
||||
|
||||
struct stat st;
|
||||
if (fstat(fd.get(), &st) == -1)
|
||||
|
@ -46,7 +75,7 @@ void PosixSourceAccessor::readFile(
|
|||
bool PosixSourceAccessor::pathExists(const CanonPath & path)
|
||||
{
|
||||
if (auto parent = path.parent()) assertNoSymlinks(*parent);
|
||||
return nix::pathExists(path.abs());
|
||||
return nix::pathExists(makeAbsPath(path));
|
||||
}
|
||||
|
||||
std::optional<struct stat> PosixSourceAccessor::cachedLstat(const CanonPath & path)
|
||||
|
@ -60,7 +89,7 @@ std::optional<struct stat> PosixSourceAccessor::cachedLstat(const CanonPath & pa
|
|||
}
|
||||
|
||||
std::optional<struct stat> st{std::in_place};
|
||||
if (::lstat(path.c_str(), &*st)) {
|
||||
if (::lstat(makeAbsPath(path).c_str(), &*st)) {
|
||||
if (errno == ENOENT || errno == ENOTDIR)
|
||||
st.reset();
|
||||
else
|
||||
|
@ -95,7 +124,7 @@ SourceAccessor::DirEntries PosixSourceAccessor::readDirectory(const CanonPath &
|
|||
{
|
||||
assertNoSymlinks(path);
|
||||
DirEntries res;
|
||||
for (auto & entry : nix::readDirectory(path.abs())) {
|
||||
for (auto & entry : nix::readDirectory(makeAbsPath(path))) {
|
||||
std::optional<Type> type;
|
||||
switch (entry.type) {
|
||||
case DT_REG: type = Type::tRegular; break;
|
||||
|
@ -110,12 +139,12 @@ SourceAccessor::DirEntries PosixSourceAccessor::readDirectory(const CanonPath &
|
|||
std::string PosixSourceAccessor::readLink(const CanonPath & path)
|
||||
{
|
||||
if (auto parent = path.parent()) assertNoSymlinks(*parent);
|
||||
return nix::readLink(path.abs());
|
||||
return nix::readLink(makeAbsPath(path));
|
||||
}
|
||||
|
||||
std::optional<CanonPath> PosixSourceAccessor::getPhysicalPath(const CanonPath & path)
|
||||
std::optional<std::filesystem::path> PosixSourceAccessor::getPhysicalPath(const CanonPath & path)
|
||||
{
|
||||
return path;
|
||||
return makeAbsPath(path);
|
||||
}
|
||||
|
||||
void PosixSourceAccessor::assertNoSymlinks(CanonPath path)
|
||||
|
|
|
@ -9,6 +9,16 @@ namespace nix {
|
|||
*/
|
||||
struct PosixSourceAccessor : virtual SourceAccessor
|
||||
{
|
||||
/**
|
||||
* Optional root path to prefix all operations into the native file
|
||||
* system. This allows prepending funny things like `C:\` that
|
||||
* `CanonPath` intentionally doesn't support.
|
||||
*/
|
||||
const std::filesystem::path root;
|
||||
|
||||
PosixSourceAccessor();
|
||||
PosixSourceAccessor(std::filesystem::path && root);
|
||||
|
||||
/**
|
||||
* The most recent mtime seen by lstat(). This is a hack to
|
||||
* support dumpPathAndGetMtime(). Should remove this eventually.
|
||||
|
@ -28,7 +38,22 @@ struct PosixSourceAccessor : virtual SourceAccessor
|
|||
|
||||
std::string readLink(const CanonPath & path) override;
|
||||
|
||||
std::optional<CanonPath> getPhysicalPath(const CanonPath & path) override;
|
||||
std::optional<std::filesystem::path> getPhysicalPath(const CanonPath & path) override;
|
||||
|
||||
/**
|
||||
* Create a `PosixSourceAccessor` and `CanonPath` corresponding to
|
||||
* some native path.
|
||||
*
|
||||
* The `PosixSourceAccessor` is rooted as far up the tree as
|
||||
* possible, (e.g. on Windows it could scoped to a drive like
|
||||
* `C:\`). This allows more `..` parent accessing to work.
|
||||
*
|
||||
* See
|
||||
* [`std::filesystem::path::root_path`](https://en.cppreference.com/w/cpp/filesystem/path/root_path)
|
||||
* and
|
||||
* [`std::filesystem::path::relative_path`](https://en.cppreference.com/w/cpp/filesystem/path/relative_path).
|
||||
*/
|
||||
static std::pair<PosixSourceAccessor, CanonPath> createAtRoot(const std::filesystem::path & path);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -38,6 +63,8 @@ private:
|
|||
void assertNoSymlinks(CanonPath path);
|
||||
|
||||
std::optional<struct stat> cachedLstat(const CanonPath & path);
|
||||
|
||||
std::filesystem::path makeAbsPath(const CanonPath & path);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include "canon-path.hh"
|
||||
#include "hash.hh"
|
||||
|
||||
|
@ -119,7 +121,7 @@ struct SourceAccessor
|
|||
* possible. This is only possible for filesystems that are
|
||||
* materialized in the root filesystem.
|
||||
*/
|
||||
virtual std::optional<CanonPath> getPhysicalPath(const CanonPath & path)
|
||||
virtual std::optional<std::filesystem::path> getPhysicalPath(const CanonPath & path)
|
||||
{ return std::nullopt; }
|
||||
|
||||
bool operator == (const SourceAccessor & x) const
|
||||
|
|
|
@ -35,7 +35,7 @@ void SourcePath::dumpPath(
|
|||
PathFilter & filter) const
|
||||
{ return accessor->dumpPath(path, sink, filter); }
|
||||
|
||||
std::optional<CanonPath> SourcePath::getPhysicalPath() const
|
||||
std::optional<std::filesystem::path> SourcePath::getPhysicalPath() const
|
||||
{ return accessor->getPhysicalPath(path); }
|
||||
|
||||
std::string SourcePath::to_string() const
|
||||
|
|
|
@ -82,7 +82,7 @@ struct SourcePath
|
|||
* Return the location of this path in the "real" filesystem, if
|
||||
* it has a physical location.
|
||||
*/
|
||||
std::optional<CanonPath> getPhysicalPath() const;
|
||||
std::optional<std::filesystem::path> getPhysicalPath() const;
|
||||
|
||||
std::string to_string() const;
|
||||
|
||||
|
|
|
@ -299,7 +299,7 @@ static void main_nix_build(int argc, char * * argv)
|
|||
else
|
||||
for (auto i : left) {
|
||||
if (fromArgs)
|
||||
exprs.push_back(state->parseExprFromString(std::move(i), state->rootPath(CanonPath::fromCwd())));
|
||||
exprs.push_back(state->parseExprFromString(std::move(i), state->rootPath(".")));
|
||||
else {
|
||||
auto absolute = i;
|
||||
try {
|
||||
|
@ -400,7 +400,7 @@ static void main_nix_build(int argc, char * * argv)
|
|||
try {
|
||||
auto expr = state->parseExprFromString(
|
||||
"(import <nixpkgs> {}).bashInteractive",
|
||||
state->rootPath(CanonPath::fromCwd()));
|
||||
state->rootPath("."));
|
||||
|
||||
Value v;
|
||||
state->eval(expr, v);
|
||||
|
|
|
@ -413,7 +413,7 @@ static void queryInstSources(EvalState & state,
|
|||
loadSourceExpr(state, *instSource.nixExprPath, vArg);
|
||||
|
||||
for (auto & i : args) {
|
||||
Expr * eFun = state.parseExprFromString(i, state.rootPath(CanonPath::fromCwd()));
|
||||
Expr * eFun = state.parseExprFromString(i, state.rootPath("."));
|
||||
Value vFun, vTmp;
|
||||
state.eval(eFun, vFun);
|
||||
vTmp.mkApp(&vFun, &vArg);
|
||||
|
|
|
@ -168,7 +168,7 @@ static int main_nix_instantiate(int argc, char * * argv)
|
|||
for (auto & i : files) {
|
||||
auto p = state->findFile(i);
|
||||
if (auto fn = p.getPhysicalPath())
|
||||
std::cout << fn->abs() << std::endl;
|
||||
std::cout << fn->native() << std::endl;
|
||||
else
|
||||
throw Error("'%s' has no physical path", p);
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ static int main_nix_instantiate(int argc, char * * argv)
|
|||
|
||||
for (auto & i : files) {
|
||||
Expr * e = fromArgs
|
||||
? state->parseExprFromString(i, state->rootPath(CanonPath::fromCwd()))
|
||||
? state->parseExprFromString(i, state->rootPath("."))
|
||||
: state->parseExprFromFile(resolveExprPath(lookupFileArg(*state, i)));
|
||||
processExpr(*state, attrPaths, parseOnly, strict, autoArgs,
|
||||
evalOnly, outputKind, xmlOutputSourceLocation, e);
|
||||
|
|
|
@ -176,12 +176,11 @@ static void opAdd(Strings opFlags, Strings opArgs)
|
|||
{
|
||||
if (!opFlags.empty()) throw UsageError("unknown flag");
|
||||
|
||||
PosixSourceAccessor accessor;
|
||||
for (auto & i : opArgs)
|
||||
for (auto & i : opArgs) {
|
||||
auto [accessor, canonPath] = PosixSourceAccessor::createAtRoot(i);
|
||||
cout << fmt("%s\n", store->printStorePath(store->addToStore(
|
||||
std::string(baseNameOf(i)),
|
||||
accessor,
|
||||
CanonPath::fromCwd(i))));
|
||||
std::string(baseNameOf(i)), accessor, canonPath)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -201,14 +200,15 @@ static void opAddFixed(Strings opFlags, Strings opArgs)
|
|||
HashAlgorithm hashAlgo = parseHashAlgo(opArgs.front());
|
||||
opArgs.pop_front();
|
||||
|
||||
PosixSourceAccessor accessor;
|
||||
for (auto & i : opArgs)
|
||||
for (auto & i : opArgs) {
|
||||
auto [accessor, canonPath] = PosixSourceAccessor::createAtRoot(i);
|
||||
std::cout << fmt("%s\n", store->printStorePath(store->addToStoreSlow(
|
||||
baseNameOf(i),
|
||||
accessor,
|
||||
CanonPath::fromCwd(i),
|
||||
canonPath,
|
||||
method,
|
||||
hashAlgo).path));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -60,9 +60,7 @@ struct CmdAddToStore : MixDryRun, StoreCommand
|
|||
{
|
||||
if (!namePart) namePart = baseNameOf(path);
|
||||
|
||||
PosixSourceAccessor accessor;
|
||||
|
||||
auto path2 = CanonPath::fromCwd(path);
|
||||
auto [accessor, path2] = PosixSourceAccessor::createAtRoot(path);
|
||||
|
||||
auto storePath = dryRun
|
||||
? store->computeStorePath(
|
||||
|
|
|
@ -66,7 +66,7 @@ struct CmdEval : MixJSON, InstallableValueCommand, MixReadOnlyOption
|
|||
|
||||
if (apply) {
|
||||
auto vApply = state->allocValue();
|
||||
state->eval(state->parseExprFromString(*apply, state->rootPath(CanonPath::fromCwd())), *vApply);
|
||||
state->eval(state->parseExprFromString(*apply, state->rootPath(".")), *vApply);
|
||||
auto vRes = state->allocValue();
|
||||
state->callFunction(*vApply, *v, *vRes, noPos);
|
||||
v = vRes;
|
||||
|
|
|
@ -89,8 +89,8 @@ struct CmdHashBase : Command
|
|||
else
|
||||
hashSink = std::make_unique<HashSink>(ha);
|
||||
|
||||
PosixSourceAccessor accessor;
|
||||
dumpPath(accessor, CanonPath::fromCwd(path), *hashSink, mode);
|
||||
auto [accessor, canonPath] = PosixSourceAccessor::createAtRoot(path);
|
||||
dumpPath(accessor, canonPath, *hashSink, mode);
|
||||
|
||||
Hash h = hashSink->finish().first;
|
||||
if (truncate && h.hashSize > 20) h = compressHash(h, 20);
|
||||
|
|
|
@ -123,10 +123,9 @@ std::tuple<StorePath, Hash> prefetchFile(
|
|||
Activity act(*logger, lvlChatty, actUnknown,
|
||||
fmt("adding '%s' to the store", url));
|
||||
|
||||
PosixSourceAccessor accessor;
|
||||
auto [accessor, canonPath] = PosixSourceAccessor::createAtRoot(tmpFile);
|
||||
auto info = store->addToStoreSlow(
|
||||
*name,
|
||||
accessor, CanonPath::fromCwd(tmpFile),
|
||||
*name, accessor, canonPath,
|
||||
ingestionMethod, hashAlgo, {}, expectedHash);
|
||||
storePath = info.path;
|
||||
assert(info.ca);
|
||||
|
|
Loading…
Reference in a new issue