31
31
import tarfile
32
32
import tempfile
33
33
import textwrap
34
- import time
35
34
import typing
36
35
import warnings
37
36
@@ -872,6 +871,7 @@ def sdist(self, directory: Path) -> pathlib.Path:
872
871
meson_dist_name = f'{ self ._meson_name } -{ self ._meson_version } '
873
872
meson_dist_path = pathlib .Path (self ._build_dir , 'meson-dist' , f'{ meson_dist_name } .tar.gz' )
874
873
sdist_path = pathlib .Path (directory , f'{ dist_name } .tar.gz' )
874
+ pyproject_toml_mtime = 0
875
875
876
876
with tarfile .open (meson_dist_path , 'r:gz' ) as meson_dist , mesonpy ._util .create_targz (sdist_path ) as sdist :
877
877
for member in meson_dist .getmembers ():
@@ -898,6 +898,9 @@ def sdist(self, directory: Path) -> pathlib.Path:
898
898
stem = member .name .split ('/' , 1 )[1 ]
899
899
member .name = '/' .join ((dist_name , stem ))
900
900
901
+ if stem == 'pyproject.toml' :
902
+ pyproject_toml_mtime = member .mtime
903
+
901
904
# Reset owner and group to root:root. This mimics what
902
905
# 'git archive' does and makes the sdist reproducible upon
903
906
# being built by different users.
@@ -910,7 +913,23 @@ def sdist(self, directory: Path) -> pathlib.Path:
910
913
member = tarfile .TarInfo (f'{ dist_name } /PKG-INFO' )
911
914
member .uid = member .gid = 0
912
915
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
+
914
933
metadata = bytes (self ._metadata .as_rfc822 ())
915
934
member .size = len (metadata )
916
935
sdist .addfile (member , io .BytesIO (metadata ))
0 commit comments