oxymake 0.1.0__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.
@@ -0,0 +1,32 @@
1
+ Metadata-Version: 2.4
2
+ Name: oxymake
3
+ Version: 0.1.0
4
+ Summary: Content-addressable workflow engine — git checkout no longer rebuilds everything
5
+ Project-URL: Homepage, https://oxymake.dev
6
+ Project-URL: Repository, https://github.com/noogram/oxymake
7
+ Project-URL: Releases, https://github.com/noogram/oxymake/releases
8
+ Author-email: Emmanuel Sérié <emmanuel@serie.dev>
9
+ License: MIT OR Apache-2.0
10
+ Keywords: build,cache,pipeline,snakemake,workflow
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown
13
+
14
+ # OxyMake (Python launcher)
15
+
16
+ A content-addressable workflow engine. You `git checkout` an old branch, re-run
17
+ your pipeline, and it **does not** rebuild everything — change detection is a
18
+ BLAKE3 hash of file *content*, not timestamps.
19
+
20
+ ```bash
21
+ uv tool install oxymake # or: pipx install oxymake
22
+ ox --help
23
+ ```
24
+
25
+ This package is a thin launcher: on first run it downloads the prebuilt `ox`
26
+ binary for your platform from the
27
+ [GitHub release](https://github.com/noogram/oxymake/releases/latest), verifies
28
+ its SHA-256, caches it, and execs it. No Rust toolchain required — which is the
29
+ point: bioinformatics and data-science users who live in conda/pip can try
30
+ OxyMake without a source build.
31
+
32
+ Full documentation: <https://github.com/noogram/oxymake>
@@ -0,0 +1,5 @@
1
+ oxymake_launcher.py,sha256=rXBVhu5vhPoyc2KVNYjtmsSVx13-L5EACXSRDH72Itk,3074
2
+ oxymake-0.1.0.dist-info/METADATA,sha256=q8hq6pgDBckHJ5xe8uRUXSne3eA2bIwrr3o_vwmK_aE,1258
3
+ oxymake-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
4
+ oxymake-0.1.0.dist-info/entry_points.txt,sha256=y5yi2BPajfAS6EvK_LpkZKaQxES9ipdNhzUuRGhDQqk,77
5
+ oxymake-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ ox = oxymake_launcher:main
3
+ oxymake = oxymake_launcher:main
oxymake_launcher.py ADDED
@@ -0,0 +1,101 @@
1
+ """Thin launcher for the OxyMake `ox` binary.
2
+
3
+ Installed via `uv tool install oxymake` / `pipx install oxymake`, this module
4
+ exposes the `ox` and `oxymake` console scripts. On first invocation it downloads
5
+ the prebuilt binary matching the host platform from the GitHub release, verifies
6
+ its SHA-256 against the `.sha256` sidecar, caches it under the user cache dir,
7
+ and execs it. No Rust toolchain is required.
8
+
9
+ This keeps the conda/pip onboarding path open: the audience that lives in Python
10
+ never has to `cargo install` from source.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import hashlib
16
+ import os
17
+ import platform
18
+ import stat
19
+ import sys
20
+ import tarfile
21
+ import tempfile
22
+ import urllib.request
23
+ from pathlib import Path
24
+
25
+ __version__ = "0.1.0"
26
+
27
+ _REPO = "noogram/oxymake"
28
+ _BASE = f"https://github.com/{_REPO}/releases/download/v{__version__}"
29
+
30
+ # (sys.platform startswith, machine) -> release target triple
31
+ _TARGETS = {
32
+ ("darwin", "arm64"): "aarch64-apple-darwin",
33
+ ("darwin", "x86_64"): "x86_64-apple-darwin",
34
+ ("linux", "x86_64"): "x86_64-unknown-linux-gnu",
35
+ ("linux", "amd64"): "x86_64-unknown-linux-gnu",
36
+ }
37
+
38
+
39
+ def _target() -> str:
40
+ key = (sys.platform, platform.machine().lower())
41
+ target = _TARGETS.get(key)
42
+ if target is None:
43
+ raise SystemExit(
44
+ f"oxymake: no prebuilt binary for {key}. "
45
+ f"Build from source: https://github.com/{_REPO}#install"
46
+ )
47
+ return target
48
+
49
+
50
+ def _cache_dir() -> Path:
51
+ root = os.environ.get("XDG_CACHE_HOME") or str(Path.home() / ".cache")
52
+ d = Path(root) / "oxymake" / __version__
53
+ d.mkdir(parents=True, exist_ok=True)
54
+ return d
55
+
56
+
57
+ def _download(url: str, dest: Path) -> None:
58
+ with urllib.request.urlopen(url) as resp, open(dest, "wb") as fh: # noqa: S310
59
+ fh.write(resp.read())
60
+
61
+
62
+ def _verify(tarball: Path, target: str) -> None:
63
+ """Verify the tarball against its published .sha256 sidecar."""
64
+ expected = _download_text(f"{_BASE}/ox-{target}.tar.gz.sha256").split()[0].strip()
65
+ actual = hashlib.sha256(tarball.read_bytes()).hexdigest()
66
+ if actual != expected:
67
+ raise SystemExit(
68
+ f"oxymake: checksum mismatch for ox-{target}.tar.gz "
69
+ f"(expected {expected}, got {actual}). Refusing to run."
70
+ )
71
+
72
+
73
+ def _download_text(url: str) -> str:
74
+ with urllib.request.urlopen(url) as resp: # noqa: S310
75
+ return resp.read().decode()
76
+
77
+
78
+ def _ensure_binary() -> Path:
79
+ target = _target()
80
+ binary = _cache_dir() / "ox"
81
+ if binary.exists():
82
+ return binary
83
+
84
+ url = f"{_BASE}/ox-{target}.tar.gz"
85
+ with tempfile.TemporaryDirectory() as tmp:
86
+ tarball = Path(tmp) / "ox.tar.gz"
87
+ _download(url, tarball)
88
+ _verify(tarball, target)
89
+ with tarfile.open(tarball) as tf:
90
+ tf.extract("ox", _cache_dir()) # noqa: S202 - controlled, verified archive
91
+ binary.chmod(binary.stat().st_mode | stat.S_IEXEC)
92
+ return binary
93
+
94
+
95
+ def main() -> "int":
96
+ binary = _ensure_binary()
97
+ os.execv(str(binary), [str(binary), *sys.argv[1:]])
98
+
99
+
100
+ if __name__ == "__main__":
101
+ main()