summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/buildtool/main/archive.cpp27
-rw-r--r--test/end-to-end/cli/install-archive.sh3
2 files changed, 24 insertions, 6 deletions
diff --git a/src/buildtool/main/archive.cpp b/src/buildtool/main/archive.cpp
index 92610397..08c6b9a9 100644
--- a/src/buildtool/main/archive.cpp
+++ b/src/buildtool/main/archive.cpp
@@ -52,8 +52,9 @@ auto add_to_archive(archive* archive,
IExecutionApi const& api,
const Artifact::ObjectInfo& artifact,
const std::filesystem::path& location) -> bool {
- auto constexpr kExecutable = 0555;
- auto constexpr kFile = 0444;
+ auto constexpr kExecutablePerm = 0555;
+ auto constexpr kFilePerm = 0444;
+ auto constexpr kDefaultPerm = 07777;
auto payload = api.RetrieveToMemory(artifact);
if (not payload) {
@@ -70,9 +71,10 @@ auto add_to_archive(archive* archive,
archive_entry_set_pathname(entry.get(), location.string().c_str());
archive_entry_set_size(entry.get(), payload->size());
archive_entry_set_filetype(entry.get(), AE_IFREG);
- archive_entry_set_perm(
- entry.get(),
- artifact.type == ObjectType::Executable ? kExecutable : kFile);
+ archive_entry_set_perm(entry.get(),
+ artifact.type == ObjectType::Executable
+ ? kExecutablePerm
+ : kFilePerm);
archive_write_header(archive, entry.get());
auto data = *payload;
archive_write_data(archive, data.c_str(), data.size());
@@ -81,11 +83,26 @@ auto add_to_archive(archive* archive,
std::unique_ptr<archive_entry, decltype(&archive_entry_cleanup)>
entry{archive_entry_new(), archive_entry_cleanup};
archive_entry_set_pathname(entry.get(), location.string().c_str());
+ archive_entry_set_size(entry.get(), payload->size());
archive_entry_set_filetype(entry.get(), AE_IFLNK);
archive_entry_set_symlink(entry.get(), payload->c_str());
+ archive_entry_set_perm(entry.get(), kDefaultPerm);
archive_write_header(archive, entry.get());
+ auto data = *payload;
+ archive_write_data(archive, data.c_str(), data.size());
} break;
case ObjectType::Tree: {
+ // avoid creating empty unnamed folder for the initial call
+ if (not location.empty()) {
+ std::unique_ptr<archive_entry, decltype(&archive_entry_cleanup)>
+ entry{archive_entry_new(), archive_entry_cleanup};
+ archive_entry_set_pathname(entry.get(),
+ location.string().c_str());
+ archive_entry_set_size(entry.get(), 0U);
+ archive_entry_set_filetype(entry.get(), AE_IFDIR);
+ archive_entry_set_perm(entry.get(), kDefaultPerm);
+ archive_write_header(archive, entry.get());
+ }
auto git_tree = GitRepo::ReadTreeData(
*payload,
artifact.digest.hash(),
diff --git a/test/end-to-end/cli/install-archive.sh b/test/end-to-end/cli/install-archive.sh
index b3965870..b5a5821d 100644
--- a/test/end-to-end/cli/install-archive.sh
+++ b/test/end-to-end/cli/install-archive.sh
@@ -28,6 +28,7 @@ echo simple file > src/foo.txt
(cd src && ln -s foo symlink)
mkdir -p src/foo/bar
echo another file > src/foo/bar/data.txt
+mkdir -p src/empty # empty dir
echo
TREE=$("${JUST}" add-to-cas --local-build-root "${BUILD_ROOT_A}" src)
@@ -84,7 +85,7 @@ RECONSTRUCTED_TREE=$(jq -r '.repositories."".workspace_root[1]' "${CONF}")
# Build to get the tree unconditionally known to the local build root
"${JUST}" build --local-build-root "${BUILD_ROOT_B}" -C "${CONF}" 2>&1
-# - installing the the tree as archive should give the same fiel
+# - installing the tree as archive should give the same file
"${JUST}" install-cas --local-build-root "${BUILD_ROOT_B}" \
-o "${ROOT}/reconstructed.tar" --archive "${TREE}::t" 2>&1
cmp "${ROOT}/src.tar" "${ROOT}/reconstructed.tar" 2>&1