diff --git a/vendor_rust.py b/vendor_rust.py index 4e25214..cd8355e 100755 --- a/vendor_rust.py +++ b/vendor_rust.py @@ -2,7 +2,6 @@ """Vendor PyCA cryptography's Rust crates """ import argparse -import glob import os import re import tarfile @@ -28,6 +27,37 @@ def cargo(cmd, manifest): ) +def tar_reset(tarinfo): + """Reset user, group, mtime, and mode to create reproducible tar""" + tarinfo.uid = 0 + tarinfo.gid = 0 + tarinfo.uname = "root" + tarinfo.gname = "root" + tarinfo.mtime = 0 + if tarinfo.type == tarfile.DIRTYPE: + tarinfo.mode = 0o755 + else: + tarinfo.mode = 0o644 + if tarinfo.pax_headers: + raise ValueError(tarinfo.name, tarinfo.pax_headers) + return tarinfo + + +def tar_reproducible(tar, basedir): + """Create reproducible tar file""" + + content = [basedir] + for root, dirs, files in os.walk(basedir): + for directory in dirs: + content.append(os.path.join(root, directory)) + for filename in files: + content.append(os.path.join(root, filename)) + content.sort() + + for fn in content: + tar.add(fn, filter=tar_reset, recursive=False, arcname=fn) + + def main(): args = parser.parse_args() spec = args.spec @@ -70,7 +100,7 @@ def main(): print("\nCreating tar ball...", file=sys.stderr) with tarfile.open(vendor_file, "x:bz2") as tar: - tar.add(VENDOR_DIR) + tar_reproducible(tar, VENDOR_DIR) # remove vendor dir shutil.rmtree(VENDOR_DIR)