mirror of
https://github.com/NixOS/nix
synced 2025-06-27 00:11:17 +02:00
Move most of InputAccessor into libutil
This commit is contained in:
parent
06c57899e3
commit
fb6a3910c4
4 changed files with 206 additions and 185 deletions
108
src/libutil/source-accessor.cc
Normal file
108
src/libutil/source-accessor.cc
Normal file
|
@ -0,0 +1,108 @@
|
|||
#include "source-accessor.hh"
|
||||
#include "archive.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
static std::atomic<size_t> nextNumber{0};
|
||||
|
||||
SourceAccessor::SourceAccessor()
|
||||
: number(++nextNumber)
|
||||
{
|
||||
}
|
||||
|
||||
// FIXME: merge with archive.cc.
|
||||
void SourceAccessor::dumpPath(
|
||||
const CanonPath & path,
|
||||
Sink & sink,
|
||||
PathFilter & filter)
|
||||
{
|
||||
auto dumpContents = [&](const CanonPath & path)
|
||||
{
|
||||
// FIXME: pipe
|
||||
auto s = readFile(path);
|
||||
sink << "contents" << s.size();
|
||||
sink(s);
|
||||
writePadding(s.size(), sink);
|
||||
};
|
||||
|
||||
std::function<void(const CanonPath & path)> dump;
|
||||
|
||||
dump = [&](const CanonPath & path) {
|
||||
checkInterrupt();
|
||||
|
||||
auto st = lstat(path);
|
||||
|
||||
sink << "(";
|
||||
|
||||
if (st.type == tRegular) {
|
||||
sink << "type" << "regular";
|
||||
if (st.isExecutable)
|
||||
sink << "executable" << "";
|
||||
dumpContents(path);
|
||||
}
|
||||
|
||||
else if (st.type == tDirectory) {
|
||||
sink << "type" << "directory";
|
||||
|
||||
/* If we're on a case-insensitive system like macOS, undo
|
||||
the case hack applied by restorePath(). */
|
||||
std::map<std::string, std::string> unhacked;
|
||||
for (auto & i : readDirectory(path))
|
||||
if (/* archiveSettings.useCaseHack */ false) { // FIXME
|
||||
std::string name(i.first);
|
||||
size_t pos = i.first.find(caseHackSuffix);
|
||||
if (pos != std::string::npos) {
|
||||
debug("removing case hack suffix from '%s'", path + i.first);
|
||||
name.erase(pos);
|
||||
}
|
||||
if (!unhacked.emplace(name, i.first).second)
|
||||
throw Error("file name collision in between '%s' and '%s'",
|
||||
(path + unhacked[name]),
|
||||
(path + i.first));
|
||||
} else
|
||||
unhacked.emplace(i.first, i.first);
|
||||
|
||||
for (auto & i : unhacked)
|
||||
if (filter((path + i.first).abs())) {
|
||||
sink << "entry" << "(" << "name" << i.first << "node";
|
||||
dump(path + i.second);
|
||||
sink << ")";
|
||||
}
|
||||
}
|
||||
|
||||
else if (st.type == tSymlink)
|
||||
sink << "type" << "symlink" << "target" << readLink(path);
|
||||
|
||||
else throw Error("file '%s' has an unsupported type", path);
|
||||
|
||||
sink << ")";
|
||||
};
|
||||
|
||||
sink << narVersionMagic1;
|
||||
dump(path);
|
||||
}
|
||||
|
||||
Hash SourceAccessor::hashPath(
|
||||
const CanonPath & path,
|
||||
PathFilter & filter,
|
||||
HashType ht)
|
||||
{
|
||||
HashSink sink(ht);
|
||||
dumpPath(path, sink, filter);
|
||||
return sink.finish().first;
|
||||
}
|
||||
|
||||
std::optional<SourceAccessor::Stat> SourceAccessor::maybeLstat(const CanonPath & path)
|
||||
{
|
||||
// FIXME: merge these into one operation.
|
||||
if (!pathExists(path))
|
||||
return {};
|
||||
return lstat(path);
|
||||
}
|
||||
|
||||
std::string SourceAccessor::showPath(const CanonPath & path)
|
||||
{
|
||||
return path.abs();
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue