main: consolidate integrated changes after v0.1.54
This commit is contained in:
73
scripts/zip_deterministic.py
Executable file
73
scripts/zip_deterministic.py
Executable file
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Create deterministic zip archives.
|
||||
|
||||
Usage:
|
||||
zip_deterministic.py <zip_path> <root_dir>
|
||||
|
||||
The archive will include the root directory itself and all files under it.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _timestamp() -> tuple[int, int, int, int, int, int]:
|
||||
epoch = os.environ.get("SOURCE_DATE_EPOCH")
|
||||
if epoch:
|
||||
try:
|
||||
value = int(epoch)
|
||||
return time.gmtime(value)[:6]
|
||||
except Exception:
|
||||
pass
|
||||
return (2000, 1, 1, 0, 0, 0)
|
||||
|
||||
|
||||
def _iter_files(root: Path):
|
||||
for dirpath, dirnames, filenames in os.walk(root):
|
||||
dirnames[:] = sorted([d for d in dirnames if d != "__pycache__"])
|
||||
for filename in sorted(filenames):
|
||||
if filename.endswith(".pyc"):
|
||||
continue
|
||||
yield Path(dirpath) / filename
|
||||
|
||||
|
||||
def _add_file(zf: zipfile.ZipFile, file_path: Path, arcname: str) -> None:
|
||||
info = zipfile.ZipInfo(arcname, date_time=_timestamp())
|
||||
info.compress_type = zipfile.ZIP_DEFLATED
|
||||
info.external_attr = (0o644 & 0xFFFF) << 16
|
||||
with file_path.open("rb") as handle:
|
||||
data = handle.read()
|
||||
zf.writestr(info, data, compress_type=zipfile.ZIP_DEFLATED)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if len(sys.argv) != 3:
|
||||
print("Usage: zip_deterministic.py <zip_path> <root_dir>")
|
||||
return 2
|
||||
|
||||
zip_path = Path(sys.argv[1]).resolve()
|
||||
root = Path(sys.argv[2]).resolve()
|
||||
if not root.exists() or not root.is_dir():
|
||||
print(f"Missing root dir: {root}")
|
||||
return 2
|
||||
|
||||
base = root.parent
|
||||
zip_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
if zip_path.exists():
|
||||
zip_path.unlink()
|
||||
|
||||
with zipfile.ZipFile(zip_path, "w") as zf:
|
||||
for file_path in sorted(_iter_files(root)):
|
||||
arcname = str(file_path.relative_to(base)).replace(os.sep, "/")
|
||||
_add_file(zf, file_path, arcname)
|
||||
|
||||
print(str(zip_path))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user