mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-25 07:16:17 +02:00
Split tarball-specific logic from GitFileSystemObjectSink
This commit is contained in:
parent
5e83c0427f
commit
e0012b97ab
5 changed files with 37 additions and 20 deletions
|
@ -486,6 +486,24 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
||||||
|
|
||||||
return narHash;
|
return narHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Hash dereferenceSingletonDirectory(const Hash & oid_) override
|
||||||
|
{
|
||||||
|
auto oid = hashToOID(oid_);
|
||||||
|
|
||||||
|
/* If the root directory contains */
|
||||||
|
auto _tree = lookupObject(*this, oid, GIT_OBJECT_TREE);
|
||||||
|
auto tree = (const git_tree *) &*_tree;
|
||||||
|
|
||||||
|
if (git_tree_entrycount(tree) == 1) {
|
||||||
|
auto entry = git_tree_entry_byindex(tree, 0);
|
||||||
|
auto mode = git_tree_entry_filemode(entry);
|
||||||
|
if (mode == GIT_FILEMODE_BLOB || mode == GIT_FILEMODE_TREE)
|
||||||
|
oid = *git_tree_entry_id(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
return toHash(oid);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ref<GitRepo> GitRepo::openRepo(const std::filesystem::path & path, bool create, bool bare)
|
ref<GitRepo> GitRepo::openRepo(const std::filesystem::path & path, bool create, bool bare)
|
||||||
|
@ -991,21 +1009,6 @@ struct GitFileSystemObjectSinkImpl : GitFileSystemObjectSink
|
||||||
|
|
||||||
auto [oid, _name] = popBuilder();
|
auto [oid, _name] = popBuilder();
|
||||||
|
|
||||||
/* If the root directory contains a single entry that is a
|
|
||||||
directory or a non-executable regular file, return that as
|
|
||||||
the top-level object. We don't do this for executables
|
|
||||||
because they don't have a tree hash in the Git object
|
|
||||||
model. */
|
|
||||||
auto _tree = lookupObject(*repo, oid, GIT_OBJECT_TREE);
|
|
||||||
auto tree = (const git_tree *) &*_tree;
|
|
||||||
|
|
||||||
if (git_tree_entrycount(tree) == 1) {
|
|
||||||
auto entry = git_tree_entry_byindex(tree, 0);
|
|
||||||
auto mode = git_tree_entry_filemode(entry);
|
|
||||||
if (mode == GIT_FILEMODE_BLOB || mode == GIT_FILEMODE_TREE)
|
|
||||||
oid = *git_tree_entry_id(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
return toHash(oid);
|
return toHash(oid);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -98,6 +98,17 @@ struct GitRepo
|
||||||
* serialisation. This is memoised on-disk.
|
* serialisation. This is memoised on-disk.
|
||||||
*/
|
*/
|
||||||
virtual Hash treeHashToNarHash(const Hash & treeHash) = 0;
|
virtual Hash treeHashToNarHash(const Hash & treeHash) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the specified Git object is a directory with a single entry
|
||||||
|
* that is a directory or a non-executable regular file, return
|
||||||
|
* the ID of that object.
|
||||||
|
*
|
||||||
|
* Note: We don't do this for executable files because they don't
|
||||||
|
* have a tree hash in the Git object model that distinguishes
|
||||||
|
* them from non-executable files.
|
||||||
|
*/
|
||||||
|
virtual Hash dereferenceSingletonDirectory(const Hash & oid) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
ref<GitRepo> getTarballCache();
|
ref<GitRepo> getTarballCache();
|
||||||
|
|
|
@ -255,11 +255,12 @@ struct GitArchiveInputScheme : InputScheme
|
||||||
});
|
});
|
||||||
|
|
||||||
TarArchive archive { *source };
|
TarArchive archive { *source };
|
||||||
auto parseSink = getTarballCache()->getFileSystemObjectSink();
|
auto tarballCache = getTarballCache();
|
||||||
|
auto parseSink = tarballCache->getFileSystemObjectSink();
|
||||||
auto lastModified = unpackTarfileToSink(archive, *parseSink);
|
auto lastModified = unpackTarfileToSink(archive, *parseSink);
|
||||||
|
|
||||||
TarballInfo tarballInfo {
|
TarballInfo tarballInfo {
|
||||||
.treeHash = parseSink->sync(),
|
.treeHash = tarballCache->dereferenceSingletonDirectory(parseSink->sync()),
|
||||||
.lastModified = lastModified
|
.lastModified = lastModified
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,8 @@ DownloadTarballResult downloadTarball(
|
||||||
TarArchive{path};
|
TarArchive{path};
|
||||||
})
|
})
|
||||||
: TarArchive{*source};
|
: TarArchive{*source};
|
||||||
auto parseSink = getTarballCache()->getFileSystemObjectSink();
|
auto tarballCache = getTarballCache();
|
||||||
|
auto parseSink = tarballCache->getFileSystemObjectSink();
|
||||||
auto lastModified = unpackTarfileToSink(archive, *parseSink);
|
auto lastModified = unpackTarfileToSink(archive, *parseSink);
|
||||||
|
|
||||||
auto res(_res->lock());
|
auto res(_res->lock());
|
||||||
|
@ -177,7 +178,8 @@ DownloadTarballResult downloadTarball(
|
||||||
infoAttrs = cached->value;
|
infoAttrs = cached->value;
|
||||||
} else {
|
} else {
|
||||||
infoAttrs.insert_or_assign("etag", res->etag);
|
infoAttrs.insert_or_assign("etag", res->etag);
|
||||||
infoAttrs.insert_or_assign("treeHash", parseSink->sync().gitRev());
|
infoAttrs.insert_or_assign("treeHash",
|
||||||
|
tarballCache->dereferenceSingletonDirectory(parseSink->sync()).gitRev());
|
||||||
infoAttrs.insert_or_assign("lastModified", uint64_t(lastModified));
|
infoAttrs.insert_or_assign("lastModified", uint64_t(lastModified));
|
||||||
if (res->immutableUrl)
|
if (res->immutableUrl)
|
||||||
infoAttrs.insert_or_assign("immutableUrl", *res->immutableUrl);
|
infoAttrs.insert_or_assign("immutableUrl", *res->immutableUrl);
|
||||||
|
|
|
@ -77,7 +77,7 @@ TEST_F(GitUtilsTest, sink_basic)
|
||||||
|
|
||||||
// sink->createHardlink("foo-1.1/links/foo-2", CanonPath("foo-1.1/hello"));
|
// sink->createHardlink("foo-1.1/links/foo-2", CanonPath("foo-1.1/hello"));
|
||||||
|
|
||||||
auto result = sink->sync();
|
auto result = repo->dereferenceSingletonDirectory(sink->sync());
|
||||||
auto accessor = repo->getAccessor(result, false);
|
auto accessor = repo->getAccessor(result, false);
|
||||||
auto entries = accessor->readDirectory(CanonPath::root);
|
auto entries = accessor->readDirectory(CanonPath::root);
|
||||||
ASSERT_EQ(entries.size(), 5);
|
ASSERT_EQ(entries.size(), 5);
|
||||||
|
|
Loading…
Reference in a new issue