mirror of
https://github.com/openai/codex.git
synced 2026-11-09 20:50:33 +00:00
Add shared development execpolicy rules
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
#!/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())
|
||||
Reference in New Issue
Block a user