mirror of
https://github.com/openai/codex.git
synced 2026-11-09 20:50:33 +00:00
93 lines
2.5 KiB
Python
93 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Print host executable pins for Codex development commands."""
|
|
|
|
from collections.abc import Callable
|
|
from collections.abc import Mapping
|
|
from collections.abc import Sequence
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import shutil
|
|
import sys
|
|
|
|
|
|
# Keep this explicit: justfile recipes can delegate to scripts that invoke other tools.
|
|
HOST_EXECUTABLES = ("cargo", "just", "bazel", "pnpm")
|
|
GENERATED_HEADER = "# Generated by scripts/setup_dev_execpolicy.py. Do not edit."
|
|
WINDOWS_EXECUTABLE_SUFFIXES = (".exe", ".cmd", ".bat", ".com")
|
|
|
|
|
|
def executable_lookup_name(path: Path, *, windows: bool = os.name == "nt") -> str:
|
|
name = path.name
|
|
if not windows:
|
|
return name
|
|
|
|
name = name.lower()
|
|
for suffix in WINDOWS_EXECUTABLE_SUFFIXES:
|
|
if name.endswith(suffix):
|
|
return name[: -len(suffix)]
|
|
return name
|
|
|
|
|
|
def absolute_without_resolving(path: str) -> Path:
|
|
return Path(os.path.abspath(os.path.expanduser(path)))
|
|
|
|
|
|
def discover_host_executables(
|
|
names: Sequence[str] = HOST_EXECUTABLES,
|
|
*,
|
|
which: Callable[[str], str | None] = shutil.which,
|
|
) -> dict[str, Path]:
|
|
executables: dict[str, Path] = {}
|
|
missing: list[str] = []
|
|
|
|
for name in names:
|
|
raw_path = which(name)
|
|
if raw_path is None:
|
|
missing.append(name)
|
|
continue
|
|
|
|
path = absolute_without_resolving(raw_path)
|
|
if executable_lookup_name(path) != executable_lookup_name(Path(name)):
|
|
raise RuntimeError(
|
|
f"resolved path for {name!r} must retain that executable name: {path}"
|
|
)
|
|
executables[name] = path
|
|
|
|
if missing:
|
|
raise RuntimeError(
|
|
"missing required host executables on PATH: " + ", ".join(missing)
|
|
)
|
|
return executables
|
|
|
|
|
|
def render_host_executable_rules(executables: Mapping[str, Path]) -> str:
|
|
blocks = []
|
|
for name, path in executables.items():
|
|
blocks.append(
|
|
"\n".join(
|
|
[
|
|
"host_executable(",
|
|
f" name = {json.dumps(name)},",
|
|
f" paths = [{json.dumps(str(path))}],",
|
|
")",
|
|
]
|
|
)
|
|
)
|
|
return f"{GENERATED_HEADER}\n\n" + "\n\n".join(blocks) + "\n"
|
|
|
|
|
|
def main() -> int:
|
|
try:
|
|
executables = discover_host_executables()
|
|
except RuntimeError as error:
|
|
print(f"error: {error}", file=sys.stderr)
|
|
return 1
|
|
|
|
sys.stdout.write(render_host_executable_rules(executables))
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|