aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/tarfile.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2019-09-11 15:25:43 +0200
committerEelco Dolstra <edolstra@gmail.com>2019-11-26 22:07:28 +0100
commit8918bae09828133259acb36d6aef60ffbfad252c (patch)
tree67cb5628c4fc537a4c42ba38a79dbf342215e36c /src/libutil/tarfile.cc
parentf2bd8470926686361602e545d63a69d4bfc22f90 (diff)
Drop remaining uses of external "tar"
Also, fetchGit now runs in O(1) memory since we pipe the output of 'git archive' directly into unpackTarball() (rather than first reading it all into memory).
Diffstat (limited to 'src/libutil/tarfile.cc')
-rw-r--r--src/libutil/tarfile.cc22
1 files changed, 21 insertions, 1 deletions
diff --git a/src/libutil/tarfile.cc b/src/libutil/tarfile.cc
index ae6d512bd..f7d3ad417 100644
--- a/src/libutil/tarfile.cc
+++ b/src/libutil/tarfile.cc
@@ -1,4 +1,5 @@
#include "rust-ffi.hh"
+#include "compression.hh"
extern "C" {
rust::CBox2<rust::Result<std::tuple<>>> unpack_tarfile(rust::Source source, rust::StringSlice dest_dir);
@@ -6,9 +7,28 @@ extern "C" {
namespace nix {
-void unpackTarfile(Source & source, Path destDir)
+void unpackTarfile(Source & source, const Path & destDir)
{
unpack_tarfile(source, destDir).use()->unwrap();
}
+void unpackTarfile(const Path & tarFile, const Path & destDir,
+ std::optional<std::string> baseName)
+{
+ if (!baseName) baseName = baseNameOf(tarFile);
+
+ auto source = sinkToSource([&](Sink & sink) {
+ // FIXME: look at first few bytes to determine compression type.
+ auto decompressor =
+ // FIXME: add .gz support
+ hasSuffix(*baseName, ".bz2") ? makeDecompressionSink("bzip2", sink) :
+ hasSuffix(*baseName, ".xz") ? makeDecompressionSink("xz", sink) :
+ makeDecompressionSink("none", sink);
+ readFile(tarFile, *decompressor);
+ decompressor->finish();
+ });
+
+ unpackTarfile(*source, destDir);
+}
+
}