Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: fix mtime of sdist archive members #452

Merged
merged 2 commits into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions mesonpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import tarfile
import tempfile
import textwrap
import time
import typing
import warnings

Expand Down Expand Up @@ -928,7 +929,7 @@ def sdist(self, directory: Path) -> pathlib.Path:
meson_dist_path = pathlib.Path(self._build_dir, 'meson-dist', f'{meson_dist_name}.tar.gz')
sdist = pathlib.Path(directory, f'{dist_name}.tar.gz')

with tarfile.open(meson_dist_path, 'r:gz') as meson_dist, mesonpy._util.create_targz(sdist) as (tar, mtime):
with tarfile.open(meson_dist_path, 'r:gz') as meson_dist, mesonpy._util.create_targz(sdist) as tar:
for member in meson_dist.getmembers():
# calculate the file path in the source directory
assert member.name, member.name
Expand All @@ -955,6 +956,7 @@ def sdist(self, directory: Path) -> pathlib.Path:

info = tarfile.TarInfo(member.name)
file_stat = os.stat(path)
info.mtime = member.mtime
info.size = file_stat.st_size
info.mode = int(oct(file_stat.st_mode)[-3:], 8)

Expand All @@ -970,8 +972,7 @@ def sdist(self, directory: Path) -> pathlib.Path:

# add PKG-INFO to dist file to make it a sdist
pkginfo_info = tarfile.TarInfo(f'{dist_name}/PKG-INFO')
if mtime:
pkginfo_info.mtime = mtime
pkginfo_info.mtime = time.time() # type: ignore[assignment]
pkginfo_info.size = len(self.metadata)
tar.addfile(pkginfo_info, fileobj=io.BytesIO(self.metadata))

Expand Down
26 changes: 3 additions & 23 deletions mesonpy/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@


if typing.TYPE_CHECKING: # pragma: no cover
from typing import Optional, Tuple

from mesonpy._compat import Iterable, Iterator, Path
from mesonpy._compat import Iterator, Path


@contextlib.contextmanager
Expand All @@ -35,31 +33,13 @@ def chdir(path: Path) -> Iterator[Path]:


@contextlib.contextmanager
def add_ld_path(paths: Iterable[str]) -> Iterator[None]:
"""Context manager helper to add a path to LD_LIBRARY_PATH."""
old_value = os.environ.get('LD_LIBRARY_PATH')
old_paths = old_value.split(os.pathsep) if old_value else []
os.environ['LD_LIBRARY_PATH'] = os.pathsep.join([*paths, *old_paths])
try:
yield
finally:
if old_value is not None: # pragma: no cover
os.environ['LD_LIBRARY_PATH'] = old_value


@contextlib.contextmanager
def create_targz(path: Path) -> Iterator[Tuple[tarfile.TarFile, Optional[int]]]:
def create_targz(path: Path) -> Iterator[tarfile.TarFile]:
"""Opens a .tar.gz file in the file system for edition.."""

# reproducibility
source_date_epoch = os.environ.get('SOURCE_DATE_EPOCH')
mtime = int(source_date_epoch) if source_date_epoch else None

os.makedirs(os.path.dirname(path), exist_ok=True)
file = typing.cast(IO[bytes], gzip.GzipFile(
path,
mode='wb',
mtime=mtime,
))
tar = tarfile.TarFile(
mode='w',
Expand All @@ -68,7 +48,7 @@ def create_targz(path: Path) -> Iterator[Tuple[tarfile.TarFile, Optional[int]]]:
)

with contextlib.closing(file), tar:
yield tar, mtime
yield tar


class CLICounter:
Expand Down
29 changes: 23 additions & 6 deletions tests/test_sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@

def test_contents(sdist_library):
with tarfile.open(sdist_library, 'r:gz') as sdist:
names = set(sdist.getnames())
names = {member.name for member in sdist.getmembers()}
mtimes = {member.mtime for member in sdist.getmembers()}

assert names == {
'library-1.0.0/example.c',
Expand All @@ -28,10 +29,14 @@ def test_contents(sdist_library):
'library-1.0.0/PKG-INFO',
}

# All the archive members have a valid mtime.
assert 0 not in mtimes


def test_contents_subdirs(sdist_subdirs):
with tarfile.open(sdist_subdirs, 'r:gz') as sdist:
names = set(sdist.getnames())
names = {member.name for member in sdist.getmembers()}
mtimes = {member.mtime for member in sdist.getmembers()}

assert names == {
'subdirs-1.0.0/PKG-INFO',
Expand All @@ -43,6 +48,9 @@ def test_contents_subdirs(sdist_subdirs):
'subdirs-1.0.0/subdirs/b/c.py',
}

# All the archive members have a valid mtime.
assert 0 not in mtimes


def test_contents_unstaged(package_pure, tmp_path):
new_data = textwrap.dedent('''
Expand All @@ -65,7 +73,8 @@ def bar():
os.unlink('crap')

with tarfile.open(tmp_path / sdist_path, 'r:gz') as sdist:
names = set(sdist.getnames())
names = {member.name for member in sdist.getmembers()}
mtimes = {member.mtime for member in sdist.getmembers()}
read_data = sdist.extractfile('pure-1.0.0/pure.py').read().replace(b'\r\n', b'\n')

assert names == {
Expand All @@ -76,6 +85,9 @@ def bar():
}
assert read_data == new_data.encode()

# All the archive members have a valid mtime.
assert 0 not in mtimes


@pytest.mark.skipif(sys.platform in {'win32', 'cygwin'}, reason='Platform does not support executable bit')
def test_executable_bit(sdist_executable_bit):
Expand All @@ -94,7 +106,11 @@ def test_executable_bit(sdist_executable_bit):


def test_generated_files(sdist_generated_files):
expected = {
with tarfile.open(sdist_generated_files, 'r:gz') as sdist:
names = {member.name for member in sdist.getmembers()}
mtimes = {member.mtime for member in sdist.getmembers()}

assert names == {
'executable_bit-1.0.0/PKG-INFO',
'executable_bit-1.0.0/example-script.py',
'executable_bit-1.0.0/example.c',
Expand All @@ -104,5 +120,6 @@ def test_generated_files(sdist_generated_files):
'executable_bit-1.0.0/_version_meson.py',
'executable_bit-1.0.0/generate_version.py',
}
with tarfile.open(sdist_generated_files, 'r:gz') as sdist:
assert {tar.name for tar in sdist.getmembers()} == expected

# All the archive members have a valid mtime.
assert 0 not in mtimes
Loading