archive.py: fix include_parent_directories=True with path_to_name (#48570)

This commit is contained in:
Harmen Stoppels 2025-01-20 10:21:32 +01:00 committed by GitHub
parent c44edf1e8d
commit ecd14f0ad9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 34 additions and 2 deletions

View File

@ -154,3 +154,35 @@ def test_gzip_compressed_tarball_is_reproducible(tmpdir):
== spack.util.crypto.checksum_stream(hashlib.sha256, f)
== spack.util.crypto.checksum_stream(hashlib.sha256, g)
)
def test_reproducible_tarfile_from_prefix_path_to_name(tmp_path: Path):
prefix = tmp_path / "example"
prefix.mkdir()
(prefix / "file1").write_bytes(b"file")
(prefix / "file2").write_bytes(b"file")
def map_prefix(path: str) -> str:
"""maps <prefix>/<path> to some/common/prefix/<path>"""
p = PurePath(path)
assert p.parts[: len(prefix.parts)] == prefix.parts, f"{path} is not under {prefix}"
return PurePath("some", "common", "prefix", *p.parts[len(prefix.parts) :]).as_posix()
with tarfile.open(tmp_path / "example.tar", "w") as tar:
reproducible_tarfile_from_prefix(
tar,
str(tmp_path / "example"),
include_parent_directories=True,
path_to_name=map_prefix,
)
with tarfile.open(tmp_path / "example.tar", "r") as tar:
assert [t.name for t in tar.getmembers() if t.isdir()] == [
"some",
"some/common",
"some/common/prefix",
]
assert [t.name for t in tar.getmembers() if t.isfile()] == [
"some/common/prefix/file1",
"some/common/prefix/file2",
]

View File

@ -172,10 +172,10 @@ def reproducible_tarfile_from_prefix(
hardlink_to_tarinfo_name: Dict[Tuple[int, int], str] = dict()
if include_parent_directories:
parent_dirs = reversed(pathlib.Path(prefix).parents)
parent_dirs = reversed(pathlib.PurePosixPath(path_to_name(prefix)).parents)
next(parent_dirs) # skip the root: slices are supported from python 3.10
for parent_dir in parent_dirs:
dir_info = tarfile.TarInfo(path_to_name(str(parent_dir)))
dir_info = tarfile.TarInfo(str(parent_dir))
dir_info.type = tarfile.DIRTYPE
dir_info.mode = 0o755
tar.addfile(dir_info)