rninja-cli 0.1.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.
rninja/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ """rninja - A drop-in replacement for Ninja with caching."""
2
+
3
+ __version__ = "0.1.1"
rninja/cli.py ADDED
@@ -0,0 +1,138 @@
1
+ """Thin CLI wrapper that delegates to the downloaded rninja binary."""
2
+
3
+ import hashlib
4
+ import os
5
+ import platform
6
+ import subprocess
7
+ import sys
8
+ import tarfile
9
+ import urllib.request
10
+ from pathlib import Path
11
+
12
+ try:
13
+ from importlib.metadata import version as get_version
14
+ except ImportError:
15
+ from importlib_metadata import version as get_version # type: ignore[no-redef]
16
+
17
+ GITHUB_OWNER = "neul-labs"
18
+ REPO = "rninja"
19
+ VERSION = get_version("rninja-cli")
20
+
21
+ ARCH_MAP = {
22
+ "x86_64": "x86_64",
23
+ "AMD64": "x86_64",
24
+ "arm64": "aarch64",
25
+ "aarch64": "aarch64",
26
+ }
27
+
28
+
29
+ def _get_binary_dir() -> Path:
30
+ """Return the directory where binaries are installed."""
31
+ return Path(__file__).parent / "bin"
32
+
33
+
34
+ def _get_download_url() -> str:
35
+ """Determine the correct tarball URL for this platform."""
36
+ system = platform.system().lower()
37
+ machine = platform.machine()
38
+ arch = ARCH_MAP.get(machine, machine)
39
+
40
+ if system == "darwin":
41
+ platform_name = "apple-darwin"
42
+ elif system == "linux":
43
+ platform_name = "unknown-linux-gnu"
44
+ else:
45
+ raise RuntimeError(f"Unsupported platform: {system}")
46
+
47
+ return (
48
+ f"https://github.com/{GITHUB_OWNER}/{REPO}/releases/download/"
49
+ f"v{VERSION}/rninja-{VERSION}-{arch}-{platform_name}.tar.gz"
50
+ )
51
+
52
+
53
+ def _download_and_extract(dest_dir: Path) -> None:
54
+ """Download the prebuilt binary tarball and extract to dest_dir."""
55
+ url = _get_download_url()
56
+ print(f"Downloading rninja {VERSION} from {url}")
57
+
58
+ dest_dir.mkdir(parents=True, exist_ok=True)
59
+ tarball_path = dest_dir / "rninja.tar.gz"
60
+ try:
61
+ urllib.request.urlretrieve(url, tarball_path)
62
+ except Exception as e:
63
+ raise RuntimeError(f"Failed to download rninja: {e}") from e
64
+
65
+ print("Extracting binaries...")
66
+ with tarfile.open(tarball_path, "r:gz") as tf:
67
+ tf.extractall(path=dest_dir)
68
+
69
+ tarball_path.unlink()
70
+
71
+ # Make binaries executable on Unix
72
+ if platform.system() != "Windows":
73
+ for binary in ["rninja", "rninja-cached", "rninja-daemon"]:
74
+ binary_path = dest_dir / binary
75
+ if binary_path.exists():
76
+ binary_path.chmod(0o755)
77
+
78
+
79
+ def _ensure_binary(name: str) -> str:
80
+ """Return the path to a binary, downloading if necessary."""
81
+ bin_dir = _get_binary_dir()
82
+
83
+ if platform.system() == "Windows":
84
+ path = bin_dir / f"{name}.exe"
85
+ if path.exists():
86
+ return str(path)
87
+ else:
88
+ path = bin_dir / name
89
+ if path.exists():
90
+ return str(path)
91
+
92
+ # Binary not found — download it
93
+ if os.environ.get("RNINJA_SKIP_DOWNLOAD"):
94
+ raise RuntimeError(
95
+ f"Binary '{name}' not found in {bin_dir} and RNINJA_SKIP_DOWNLOAD is set."
96
+ )
97
+
98
+ _download_and_extract(bin_dir)
99
+
100
+ # Check again after download
101
+ if platform.system() == "Windows":
102
+ path = bin_dir / f"{name}.exe"
103
+ else:
104
+ path = bin_dir / name
105
+
106
+ if path.exists():
107
+ return str(path)
108
+
109
+ raise RuntimeError(
110
+ f"Binary '{name}' not found in {bin_dir} after download. "
111
+ "Please reinstall the package."
112
+ )
113
+
114
+
115
+ def _run(name: str) -> None:
116
+ """Run the named binary with forwarded arguments."""
117
+ binary = _ensure_binary(name)
118
+ result = subprocess.run([binary] + sys.argv[1:])
119
+ sys.exit(result.returncode)
120
+
121
+
122
+ def main() -> None:
123
+ """Run rninja."""
124
+ _run("rninja")
125
+
126
+
127
+ def cached_main() -> None:
128
+ """Run rninja-cached."""
129
+ _run("rninja-cached")
130
+
131
+
132
+ def daemon_main() -> None:
133
+ """Run rninja-daemon."""
134
+ _run("rninja-daemon")
135
+
136
+
137
+ if __name__ == "__main__":
138
+ main()
@@ -0,0 +1,63 @@
1
+ Metadata-Version: 2.4
2
+ Name: rninja-cli
3
+ Version: 0.1.1
4
+ Summary: A drop-in replacement for Ninja build system with caching and improved scheduling
5
+ Author: Dipankar Sarkar
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/neul-labs/rninja
8
+ Project-URL: Repository, https://github.com/neul-labs/rninja
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Rust
18
+ Classifier: Topic :: Software Development :: Build Tools
19
+ Requires-Python: >=3.8
20
+ Description-Content-Type: text/markdown
21
+
22
+ # rninja
23
+
24
+ [![PyPI version](https://img.shields.io/pypi/v/rninja.svg)](https://pypi.org/project/rninja/)
25
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
26
+
27
+ **Build faster. Cache smarter. Drop-in ready.**
28
+
29
+ A Rust-powered drop-in replacement for [Ninja](https://ninja-build.org/) with built-in caching and modern scheduling. Cut your build times without changing your build files.
30
+
31
+ ## Installation
32
+
33
+ ```bash
34
+ pip install rninja-cli
35
+ ```
36
+
37
+ The package downloads the correct prebuilt binary for your platform on first use (macOS Intel/Apple Silicon, Linux x86_64/aarch64).
38
+
39
+ ## Usage
40
+
41
+ After installation, use `rninja` exactly like `ninja`:
42
+
43
+ ```bash
44
+ rninja
45
+ rninja -C out/Release
46
+ rninja -j8 my_target
47
+ ```
48
+
49
+ ## Features
50
+
51
+ - **Drop-in compatible** — Works with existing `.ninja` files from CMake, GN, Meson, or any generator
52
+ - **Built-in caching** — Content-addressed cache skips redundant work automatically
53
+ - **Modern scheduler** — Rust async runtime keeps all cores busy
54
+ - **Remote cache ready** — Share cached artifacts across machines and CI runners
55
+
56
+ ## Documentation
57
+
58
+ - [Full documentation](https://docs.neullabs.com/rninja)
59
+ - [GitHub repository](https://github.com/neul-labs/rninja)
60
+
61
+ ## License
62
+
63
+ MIT
@@ -0,0 +1,7 @@
1
+ rninja/__init__.py,sha256=PpRvF-YJFFhI7-cfQx9956JG-MtnUXOUEJBfm-ILysU,84
2
+ rninja/cli.py,sha256=CmSWcasurN-PZM-oVrc9-wetB0IvsBYnHR1-l8zvkpg,3596
3
+ rninja_cli-0.1.1.dist-info/METADATA,sha256=Ncg3Ftj0iWLUKFuVFNOmC_NEZ1PA3On71T5xpn_UbgY,2120
4
+ rninja_cli-0.1.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
5
+ rninja_cli-0.1.1.dist-info/entry_points.txt,sha256=-XkLgrRUB44E1BDnuaf9SAfxR6mhFXzUvcPNUwB2gPo,121
6
+ rninja_cli-0.1.1.dist-info/top_level.txt,sha256=UB4wcuY5CFdpjieVZVSud_XOW0KJxBJQJ8PVBjgyAN0,7
7
+ rninja_cli-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,4 @@
1
+ [console_scripts]
2
+ rninja = rninja.cli:main
3
+ rninja-cached = rninja.cli:cached_main
4
+ rninja-daemon = rninja.cli:daemon_main
@@ -0,0 +1 @@
1
+ rninja