89 lines
3.1 KiB
Python
89 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Create the private runtime used by the platform wrappers."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import venv
|
|
|
|
|
|
def default_venv() -> Path:
|
|
override = os.environ.get("CODEX_IMAGEGEN_VENV", "").strip()
|
|
if override:
|
|
return Path(override).expanduser()
|
|
if os.name == "nt":
|
|
documents = os.environ.get("CODEX_DOCUMENTS") or (Path.home() / "Documents")
|
|
return Path(documents) / "Codex" / ".shared" / "image-gen-custom" / "venv"
|
|
if sys.platform == "darwin":
|
|
return Path.home() / "Library" / "Caches" / "Codex" / "image-gen-custom" / "venv"
|
|
root = os.environ.get("XDG_CACHE_HOME") or (Path.home() / ".cache")
|
|
return Path(root) / "codex" / "image-gen-custom" / "venv"
|
|
|
|
|
|
def bootstrap_python() -> list[str]:
|
|
override = os.environ.get("CODEX_IMAGEGEN_PYTHON", "").strip()
|
|
if override:
|
|
return [override]
|
|
candidates: list[list[str]] = []
|
|
if os.name == "nt":
|
|
cache_root = Path.home() / ".cache" / "codex-runtimes"
|
|
for path in sorted(cache_root.glob("**/dependencies/python/python.exe")):
|
|
if path.is_file():
|
|
candidates.append([str(path)])
|
|
for candidate in ("py", "python", "python3"):
|
|
found = shutil.which(candidate)
|
|
if found:
|
|
candidates.append([found, "-3"] if candidate == "py" else [found])
|
|
else:
|
|
for candidate in ("python3", "python"):
|
|
found = shutil.which(candidate)
|
|
if found:
|
|
candidates.append([found])
|
|
probe = "import sys"
|
|
for candidate in candidates:
|
|
try:
|
|
result = subprocess.run([*candidate, "-c", probe], check=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
except OSError:
|
|
continue
|
|
if result.returncode == 0:
|
|
return candidate
|
|
raise RuntimeError("Python 3 was not found; install Python or set CODEX_IMAGEGEN_PYTHON")
|
|
|
|
|
|
def ensure_runtime(require_keyring: bool = False) -> Path:
|
|
target = default_venv()
|
|
python_path = target / ("Scripts/python.exe" if os.name == "nt" else "bin/python")
|
|
if not python_path.exists():
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
command = bootstrap_python() + ["-m", "venv", str(target)]
|
|
subprocess.run(command, check=True)
|
|
if require_keyring:
|
|
check = subprocess.run([str(python_path), "-c", "import keyring"], check=False)
|
|
else:
|
|
check = None
|
|
if check is not None and check.returncode:
|
|
packages = ["keyring"]
|
|
subprocess.run(
|
|
[str(python_path), "-m", "pip", "install", "--disable-pip-version-check", *packages],
|
|
check=True,
|
|
stdout=subprocess.DEVNULL,
|
|
)
|
|
return python_path
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--keyring", action="store_true")
|
|
options = parser.parse_args()
|
|
try:
|
|
print(ensure_runtime(options.keyring))
|
|
except Exception as exc:
|
|
print(f"Error: {exc}", file=sys.stderr)
|
|
raise SystemExit(1)
|