##// END OF EJS Templates
Merge pull request #12539 from rushabh-v/retar...
Matthias Bussonnier -
r26006:6c34e4a3 merge
parent child Browse files
Show More
@@ -1,65 +1,68 b''
1 1 """
2 2 Un-targz and retargz a targz file to ensure reproducible build.
3 3
4 4 usage:
5 5
6 6 $ export SOURCE_DATE_EPOCH=$(date +%s)
7 7 ...
8 8 $ python retar.py <tarfile.gz>
9 9
10 10 The process of creating an sdist can be non-reproducible:
11 11 - directory created during the process get a mtime of the creation date;
12 12 - gziping files embed the timestamp of fo zip creation.
13 13
14 14 This will untar-retar; ensuring that all mtime > SOURCE_DATE_EPOCH will be set
15 15 equal to SOURCE_DATE_EPOCH.
16 16
17 17 """
18 18
19 19 import tarfile
20 20 import sys
21 21 import os
22 22 import gzip
23 23 import io
24 24
25 from pathlib import Path
26
25 27 if len(sys.argv) > 2:
26 28 raise ValueError("Too many arguments")
27 29
28 30
29 31 timestamp = int(os.environ["SOURCE_DATE_EPOCH"])
30 32
33 path = Path(sys.argv[1])
31 34 old_buf = io.BytesIO()
32 with open(sys.argv[1], "rb") as f:
35 with open(path, "rb") as f:
33 36 old_buf.write(f.read())
34 37 old_buf.seek(0)
35 38 old = tarfile.open(fileobj=old_buf, mode="r:gz")
36 39
37 40 buf = io.BytesIO()
38 41 new = tarfile.open(fileobj=buf, mode="w", format=tarfile.GNU_FORMAT)
39 42 for i, m in enumerate(old):
40 43 data = None
41 44 # mutation does not work, copy
42 45 if m.name.endswith('.DS_Store'):
43 46 continue
44 47 m2 = tarfile.TarInfo(m.name)
45 48 m2.mtime = min(timestamp, m.mtime)
46 49 m2.size = m.size
47 50 m2.type = m.type
48 51 m2.linkname = m.linkname
49 52 m2.mode = m.mode
50 53 if m.isdir():
51 54 new.addfile(m2)
52 55 else:
53 56 data = old.extractfile(m)
54 57 new.addfile(m2, data)
55 58 new.close()
56 59 old.close()
57 60
58 61 buf.seek(0)
59 with open(sys.argv[1], "wb") as f:
62 with open(path, "wb") as f:
60 63 with gzip.GzipFile('', "wb", fileobj=f, mtime=timestamp) as gzf:
61 64 gzf.write(buf.read())
62 65
63 66 # checks the archive is valid.
64 archive = tarfile.open(sys.argv[1])
67 archive = tarfile.open(path)
65 68 names = archive.getnames()
General Comments 0
You need to be logged in to leave comments. Login now