diff --git a/mesonpy/__init__.py b/mesonpy/__init__.py index 7051a6757..22e93399c 100644 --- a/mesonpy/__init__.py +++ b/mesonpy/__init__.py @@ -31,6 +31,7 @@ import tarfile import tempfile import textwrap +import time import typing import warnings @@ -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 @@ -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) @@ -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)) diff --git a/mesonpy/_util.py b/mesonpy/_util.py index b21edd2cd..b2d333ed6 100644 --- a/mesonpy/_util.py +++ b/mesonpy/_util.py @@ -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 @@ -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', @@ -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: diff --git a/tests/test_sdist.py b/tests/test_sdist.py index 8ead35cbd..89124d44e 100644 --- a/tests/test_sdist.py +++ b/tests/test_sdist.py @@ -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', @@ -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', @@ -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(''' @@ -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 == { @@ -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): @@ -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', @@ -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