3131import tarfile
3232import tempfile
3333import textwrap
34- import time
3534import typing
3635import warnings
3736
@@ -872,6 +871,7 @@ def sdist(self, directory: Path) -> pathlib.Path:
872871 meson_dist_name = f'{ self ._meson_name } -{ self ._meson_version } '
873872 meson_dist_path = pathlib .Path (self ._build_dir , 'meson-dist' , f'{ meson_dist_name } .tar.gz' )
874873 sdist_path = pathlib .Path (directory , f'{ dist_name } .tar.gz' )
874+ pyproject_toml_mtime = 0
875875
876876 with tarfile .open (meson_dist_path , 'r:gz' ) as meson_dist , mesonpy ._util .create_targz (sdist_path ) as sdist :
877877 for member in meson_dist .getmembers ():
@@ -898,6 +898,9 @@ def sdist(self, directory: Path) -> pathlib.Path:
898898 stem = member .name .split ('/' , 1 )[1 ]
899899 member .name = '/' .join ((dist_name , stem ))
900900
901+ if stem == 'pyproject.toml' :
902+ pyproject_toml_mtime = member .mtime
903+
901904 # Reset owner and group to root:root. This mimics what
902905 # 'git archive' does and makes the sdist reproducible upon
903906 # being built by different users.
@@ -910,7 +913,23 @@ def sdist(self, directory: Path) -> pathlib.Path:
910913 member = tarfile .TarInfo (f'{ dist_name } /PKG-INFO' )
911914 member .uid = member .gid = 0
912915 member .uname = member .gname = 'root'
913- member .mtime = time .time ()
916+
917+ # Set the 'PKG-INFO' modification time to the modification time of
918+ # 'pyproject.toml' in the archive generated by 'meson dist'. In
919+ # turn this is the last commit time, unless touched by a dist
920+ # script. This makes the sdist reproducible upon being built at
921+ # different times, when dist scripts are not used, which should be
922+ # the majority of cases.
923+ #
924+ # Note that support for dynamic version in project metadata allows
925+ # the version to depend on the build time. Therefore, setting the
926+ # 'PKG-INFO' modification time to the 'pyproject.toml'
927+ # modification time can be seen as not strictly correct. However,
928+ # the sdist standard does not dictate which modification time to
929+ # use for 'PKG-INFO'. This choice allows to make the sdist
930+ # byte-for-byte reproducible in the most common case.
931+ member .mtime = pyproject_toml_mtime
932+
914933 metadata = bytes (self ._metadata .as_rfc822 ())
915934 member .size = len (metadata )
916935 sdist .addfile (member , io .BytesIO (metadata ))
0 commit comments