mirror of
https://github.com/NixOS/nix.git
synced 2025-12-08 18:11:02 +01:00
Make nix nar cat work on pipes too
This was lost after 2.32 while making the accessor lazy. We can restore the support for it pretty easily. Also this is significant optimization for nix nar cat. E.g. with a NAR of a linux repo this speeds up by ~3x: Benchmark 1: nix nar cat /tmp/linux.nar README Time (mean ± σ): 737.2 ms ± 5.6 ms [User: 298.1 ms, System: 435.7 ms] Range (min … max): 728.6 ms … 746.9 ms 10 runs Benchmark 2: build/src/nix/nix nar cat /tmp/linux.nar README Time (mean ± σ): 253.5 ms ± 2.9 ms [User: 56.4 ms, System: 196.3 ms] Range (min … max): 248.1 ms … 258.7 ms 12 runs
This commit is contained in:
parent
b9b6defca6
commit
c5c05e44b3
3 changed files with 38 additions and 2 deletions
|
|
@ -12,7 +12,7 @@ namespace nix {
|
|||
*
|
||||
* See `FileSystemObjectSink::createRegularFile`.
|
||||
*/
|
||||
struct CreateRegularFileSink : Sink
|
||||
struct CreateRegularFileSink : virtual Sink
|
||||
{
|
||||
/**
|
||||
* If set to true, the sink will not be called with the contents
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "nix/cmd/command.hh"
|
||||
#include "nix/store/store-api.hh"
|
||||
#include "nix/util/archive.hh"
|
||||
#include "nix/util/nar-accessor.hh"
|
||||
#include "nix/util/serialise.hh"
|
||||
#include "nix/util/source-accessor.hh"
|
||||
|
|
@ -79,7 +80,40 @@ struct CmdCatNar : StoreCommand, MixCat
|
|||
if (!fd)
|
||||
throw SysError("opening NAR file '%s'", narPath);
|
||||
auto source = FdSource{fd.get()};
|
||||
cat(makeLazyNarAccessor(source, seekableGetNarBytes(fd.get())), CanonPath{path});
|
||||
|
||||
struct CatRegularFileSink : NullFileSystemObjectSink
|
||||
{
|
||||
CanonPath neededPath = CanonPath::root;
|
||||
bool found = false;
|
||||
|
||||
void createRegularFile(const CanonPath & path, std::function<void(CreateRegularFileSink &)> crf) override
|
||||
{
|
||||
struct : CreateRegularFileSink, FdSink
|
||||
{
|
||||
void isExecutable() override {}
|
||||
} crfSink;
|
||||
|
||||
crfSink.fd = INVALID_DESCRIPTOR;
|
||||
|
||||
if (path == neededPath) {
|
||||
logger->stop();
|
||||
crfSink.skipContents = false;
|
||||
crfSink.fd = STDOUT_FILENO;
|
||||
found = true;
|
||||
} else {
|
||||
crfSink.skipContents = true;
|
||||
}
|
||||
|
||||
crf(crfSink);
|
||||
}
|
||||
} sink;
|
||||
|
||||
sink.neededPath = CanonPath(path);
|
||||
/* NOTE: We still parse the whole file to validate that it's a correct NAR. */
|
||||
parseDump(sink, source);
|
||||
|
||||
if (!sink.found)
|
||||
throw Error("NAR does not contain regular file '%1%'", path);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ diff -u data.cat-nar "$storePath/foo/data"
|
|||
# Check that file contents of baz match.
|
||||
nix nar cat "$narFile" /foo/baz > baz.cat-nar
|
||||
diff -u baz.cat-nar "$storePath/foo/baz"
|
||||
nix nar cat /dev/stdin /foo/baz < "$narFile" > baz.cat-nar-pipe
|
||||
expect 1 nix nar cat "$narFile" /foo/baz/doesntexist 2>&1 | grep "NAR does not contain regular file '/foo/baz/doesntexist'"
|
||||
|
||||
nix store cat "$storePath/foo/baz" > baz.cat-nar
|
||||
diff -u baz.cat-nar "$storePath/foo/baz"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue