flywheel-bootstrap-staging 0.1.9.202601271835__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.
bootstrap/install.py ADDED
@@ -0,0 +1,129 @@
1
+ """Codex install/detection helpers (skeleton)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import shutil
6
+ import sys
7
+ import tarfile
8
+ import urllib.request
9
+ from pathlib import Path
10
+ import subprocess
11
+ import tempfile
12
+ import platform
13
+
14
+ from bootstrap.constants import CODEX_RELEASE_BASE, DEFAULT_CODEX_VERSION
15
+
16
+
17
+ def codex_on_path() -> bool:
18
+ """Return True if `codex` is already available on PATH."""
19
+ # On Windows, explicitly look for codex.exe to avoid conflicts with
20
+ # other tools named "codex" (e.g., npm packages)
21
+ if sys.platform == "win32":
22
+ return shutil.which("codex.exe") is not None
23
+ return shutil.which("codex") is not None
24
+
25
+
26
+ def codex_login_status_ok(executable: Path | str = "codex") -> bool:
27
+ """Return True if `codex login status` succeeds."""
28
+ cmd = [str(executable), "login", "status"]
29
+ print(f"[bootstrap] running: {cmd}", file=sys.stderr)
30
+ try:
31
+ result = subprocess.run(
32
+ cmd,
33
+ stdout=subprocess.PIPE,
34
+ stderr=subprocess.PIPE,
35
+ text=True,
36
+ check=False,
37
+ )
38
+ return result.returncode == 0
39
+ except FileNotFoundError:
40
+ return False
41
+ except OSError as e:
42
+ print(f"[bootstrap] OSError running codex: {e}", file=sys.stderr)
43
+ raise
44
+
45
+
46
+ def ensure_codex(version: str | None = None, download_dir: Path | None = None) -> Path:
47
+ """Ensure codex binary is available.
48
+
49
+ Args:
50
+ version: Optional explicit version string to install.
51
+ download_dir: Optional directory where the tarball should be unpacked.
52
+
53
+ Returns:
54
+ Path to the resolved codex executable.
55
+ """
56
+ if codex_on_path():
57
+ path = shutil.which("codex")
58
+ assert path
59
+ return Path(path)
60
+
61
+ resolved_dir = download_dir or Path(tempfile.mkdtemp())
62
+ resolved_dir.mkdir(parents=True, exist_ok=True)
63
+
64
+ url, archive_type = _build_download_url(version)
65
+
66
+ if archive_type == "exe":
67
+ # Windows: direct .exe download, no extraction needed
68
+ codex_path = resolved_dir / "codex.exe"
69
+ _download(url, codex_path)
70
+ elif archive_type == "tar.gz":
71
+ archive_path = resolved_dir / "codex.tar.gz"
72
+ _download(url, archive_path)
73
+ with tarfile.open(archive_path, "r:gz") as tf:
74
+ tf.extractall(path=resolved_dir)
75
+ # Unix: look for codex binary
76
+ found_codex = next(resolved_dir.rglob("codex"), None)
77
+ if found_codex is None:
78
+ raise RuntimeError("codex binary not found after extraction")
79
+ codex_path = found_codex
80
+ else:
81
+ raise RuntimeError(f"unsupported archive type: {archive_type}")
82
+
83
+ codex_path.chmod(codex_path.stat().st_mode | 0o111)
84
+ return codex_path.resolve()
85
+
86
+
87
+ def _build_download_url(version: str | None) -> tuple[str, str]:
88
+ """Build the download URL for Codex.
89
+
90
+ Returns:
91
+ Tuple of (url, archive_type) where archive_type is "exe" or "tar.gz".
92
+ """
93
+ ver = version or DEFAULT_CODEX_VERSION or "latest"
94
+ system = sys.platform
95
+ machine = platform.machine().lower()
96
+
97
+ # Determine architecture tag
98
+ if "arm" in machine or "aarch64" in machine:
99
+ arch = "aarch64"
100
+ else:
101
+ arch = "x86_64"
102
+
103
+ # Build platform-specific URL
104
+ # Windows uses: codex-{arch}-pc-windows-msvc.exe
105
+ # macOS uses: codex-{arch}-apple-darwin.tar.gz
106
+ # Linux uses: codex-{arch}-unknown-linux-gnu.tar.gz
107
+ if system == "win32":
108
+ filename = f"codex-{arch}-pc-windows-msvc.exe"
109
+ archive_type = "exe"
110
+ elif system.startswith("darwin"):
111
+ filename = f"codex-{arch}-apple-darwin.tar.gz"
112
+ archive_type = "tar.gz"
113
+ elif system.startswith("linux"):
114
+ filename = f"codex-{arch}-unknown-linux-gnu.tar.gz"
115
+ archive_type = "tar.gz"
116
+ else:
117
+ raise RuntimeError(f"unsupported platform: {system}")
118
+
119
+ if ver == "latest":
120
+ return f"{CODEX_RELEASE_BASE}/{filename}", archive_type
121
+ return (
122
+ f"https://github.com/openai/codex/releases/download/{ver}/{filename}",
123
+ archive_type,
124
+ )
125
+
126
+
127
+ def _download(url: str, dest: Path) -> None:
128
+ with urllib.request.urlopen(url) as resp, dest.open("wb") as fh:
129
+ fh.write(resp.read())