repak-sonar 0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
File without changes
repak_sonar/_unpak.py ADDED
@@ -0,0 +1,102 @@
1
+ """Self-contained extractor embedded into every repak-generated wheel.
2
+
3
+ This module ships *inside* the synthetic wheel as ``<pkg>/_unpak.py`` and is
4
+ wired to the ``unpak-{name}`` console script. It must depend only on the
5
+ Python standard library: repak is not installed on the destination side.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import argparse
11
+ import hashlib
12
+ import io
13
+ import os
14
+ import sys
15
+ import tarfile
16
+ from importlib import resources
17
+ from pathlib import Path
18
+
19
+ PAYLOAD = "payload.tar.gz"
20
+ CHECKSUM = "payload.sha256"
21
+
22
+
23
+ def _read_resource(name: str) -> bytes:
24
+ return resources.files(__package__).joinpath(name).read_bytes()
25
+
26
+
27
+ def _safe_members(tar: tarfile.TarFile, dest: Path):
28
+ """Yield only members that extract safely under ``dest``.
29
+
30
+ Rejects absolute paths and ``..`` traversal; restricts to regular files
31
+ and directories (mirrors the intent of tarfile's ``data`` filter while
32
+ remaining compatible with Python 3.9).
33
+ """
34
+ dest = dest.resolve()
35
+ for member in tar.getmembers():
36
+ name = member.name
37
+ if name.startswith("/") or os.path.isabs(name):
38
+ raise ValueError(f"unsafe absolute path in archive: {name!r}")
39
+ target = (dest / name).resolve()
40
+ if target != dest and dest not in target.parents:
41
+ raise ValueError(f"unsafe path traversal in archive: {name!r}")
42
+ if member.isdir() or member.isreg():
43
+ yield member
44
+ else:
45
+ raise ValueError(
46
+ f"archive contains unsupported entry {name!r} "
47
+ f"(type {member.type!r})"
48
+ )
49
+
50
+
51
+ def _extract(data: bytes, dest: Path) -> None:
52
+ dest.mkdir(parents=True, exist_ok=True)
53
+ with tarfile.open(fileobj=io.BytesIO(data), mode="r:gz") as tar:
54
+ members = list(_safe_members(tar, dest))
55
+ for member in members:
56
+ out = dest / member.name
57
+ if member.isdir():
58
+ out.mkdir(parents=True, exist_ok=True)
59
+ continue
60
+ out.parent.mkdir(parents=True, exist_ok=True)
61
+ src = tar.extractfile(member)
62
+ if src is None:
63
+ continue
64
+ with open(out, "wb") as fh:
65
+ fh.write(src.read())
66
+ os.chmod(out, member.mode & 0o777)
67
+
68
+
69
+ def main(argv=None) -> int:
70
+ parser = argparse.ArgumentParser(
71
+ prog=f"unpak ({__package__})",
72
+ description="Verify and extract a repak-transported directory.",
73
+ )
74
+ parser.add_argument(
75
+ "target",
76
+ help="Destination folder; created if missing. Existing unrelated "
77
+ "files are left untouched (overwrite/merge).",
78
+ )
79
+ args = parser.parse_args(argv)
80
+
81
+ data = _read_resource(PAYLOAD)
82
+ expected = _read_resource(CHECKSUM).decode("ascii").strip()
83
+ actual = hashlib.sha256(data).hexdigest()
84
+ if actual != expected:
85
+ sys.stderr.write(
86
+ "ERROR: checksum verification failed; the payload is corrupt "
87
+ "and nothing was written.\n"
88
+ f" expected: {expected}\n"
89
+ f" actual: {actual}\n"
90
+ )
91
+ return 1
92
+
93
+ dest = Path(args.target)
94
+ _extract(data, dest)
95
+ sys.stdout.write(
96
+ f"Verified SHA-256 and extracted contents to {dest.resolve()}\n"
97
+ )
98
+ return 0
99
+
100
+
101
+ if __name__ == "__main__":
102
+ raise SystemExit(main())
@@ -0,0 +1 @@
1
+ 5a196bcb3f8f52ae92d7c0e5592e491a499ff57b779cd4e247646f973041d043
Binary file
@@ -0,0 +1,5 @@
1
+ Metadata-Version: 2.1
2
+ Name: repak-sonar
3
+ Version: 0.1
4
+ Summary: Directory payload transported by repak.
5
+ Keywords: repak-transport-container
@@ -0,0 +1,8 @@
1
+ repak_sonar/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ repak_sonar/_unpak.py,sha256=AkBMA5uMXtsdiuTGur3mSzvUWX0qcNLCFNgS3Q004Bo,3299
3
+ repak_sonar/payload.tar.gz,sha256=Whlryz-PUq6S18DlWS5JGkmf9Xt3nNTiR2RvlzBB0EM,43345157
4
+ repak_sonar/payload.sha256,sha256=bpF0ZWc14huss3wIUNVpCQ-zTzXjRJn8xQOjVmwdyvo,65
5
+ repak_sonar-0.1.dist-info/METADATA,sha256=M1Ae2Wyvp_Bi4mBmwDcm56Z1i8RQVheAUj9QEROV96c,138
6
+ repak_sonar-0.1.dist-info/WHEEL,sha256=op7MFSc46_y5sL4zAFN7MdFDa9k3cTXf3KNjxLf63JQ,84
7
+ repak_sonar-0.1.dist-info/entry_points.txt,sha256=v-fA8YOz9z2eQRSKBzHEcBNk7uBnDA8tQirU37wcWhw,56
8
+ repak_sonar-0.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: repak (0.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ unpak-sonar = repak_sonar._unpak:main