mirror of
https://github.com/NixOS/nix
synced 2025-07-02 09:21:47 +02:00
Finish separating concerns with tarball cache
There is no longer an `importTarball` method. Instead, there is a `unpackTarfileToSink` function (back in libutil). The caller can use thisw with the `getParseSink` method we added in the last commit easily enough. In addition, tarball cache functionality is separated from `git-utils` and moved into `tarball-cache`. This ensures we are separating mechanism and policy.
This commit is contained in:
parent
ba6a5f06ee
commit
ed24baaec4
7 changed files with 107 additions and 99 deletions
|
@ -132,4 +132,66 @@ void unpackTarfile(const Path & tarFile, const Path & destDir)
|
|||
extract_archive(archive, destDir);
|
||||
}
|
||||
|
||||
time_t unpackTarfileToSink(TarArchive & archive, FileSystemObjectSink & parseSink)
|
||||
{
|
||||
time_t lastModified = 0;
|
||||
|
||||
for (;;) {
|
||||
// FIXME: merge with extract_archive
|
||||
struct archive_entry * entry;
|
||||
int r = archive_read_next_header(archive.archive, &entry);
|
||||
if (r == ARCHIVE_EOF) break;
|
||||
auto path = archive_entry_pathname(entry);
|
||||
if (!path)
|
||||
throw Error("cannot get archive member name: %s", archive_error_string(archive.archive));
|
||||
if (r == ARCHIVE_WARN)
|
||||
warn(archive_error_string(archive.archive));
|
||||
else
|
||||
archive.check(r);
|
||||
|
||||
lastModified = std::max(lastModified, archive_entry_mtime(entry));
|
||||
|
||||
switch (archive_entry_filetype(entry)) {
|
||||
|
||||
case AE_IFDIR:
|
||||
parseSink.createDirectory(path);
|
||||
break;
|
||||
|
||||
case AE_IFREG: {
|
||||
parseSink.createRegularFile(path, [&](auto & crf) {
|
||||
if (archive_entry_mode(entry) & S_IXUSR)
|
||||
crf.isExecutable();
|
||||
|
||||
while (true) {
|
||||
std::vector<unsigned char> buf(128 * 1024);
|
||||
auto n = archive_read_data(archive.archive, buf.data(), buf.size());
|
||||
if (n < 0)
|
||||
throw Error("cannot read file '%s' from tarball", path);
|
||||
if (n == 0) break;
|
||||
crf(std::string_view {
|
||||
(const char *) buf.data(),
|
||||
(size_t) n,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case AE_IFLNK: {
|
||||
auto target = archive_entry_symlink(entry);
|
||||
|
||||
parseSink.createSymlink(path, target);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw Error("file '%s' in tarball has unsupported file type", path);
|
||||
}
|
||||
}
|
||||
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue