Add shared development execpolicy rules

This commit is contained in:
Adam Perry
2026-06-22 22:50:37 +00:00
parent 9f06cf1a09
commit 96d6717fc5
6 changed files with 317 additions and 0 deletions
+1
View File
@@ -72,6 +72,7 @@ def buildifier_formatter_group(*, check: bool) -> FormatterGroup:
or name.endswith((".BUILD.bazel", ".MODULE.bazel", ".bzl", ".sky"))
or ".bzl." in name
or ".sky." in name
or (path.parent == Path(".codex/rules") and path.suffix == ".rules")
):
buildifier_files.append(path.as_posix())
buildifier_files.sort()
+92
View File
@@ -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())
+47
View File
@@ -0,0 +1,47 @@
#!/usr/bin/env python3
import importlib.util
from pathlib import Path
import sys
import unittest
from unittest.mock import patch
FORMAT_SCRIPT_PATH = Path(__file__).with_name("format.py")
FORMAT_SCRIPT_SPEC = importlib.util.spec_from_file_location(
"codex_format_script",
FORMAT_SCRIPT_PATH,
)
if FORMAT_SCRIPT_SPEC is None or FORMAT_SCRIPT_SPEC.loader is None:
raise RuntimeError(f"could not load {FORMAT_SCRIPT_PATH}")
format_script = importlib.util.module_from_spec(FORMAT_SCRIPT_SPEC)
sys.modules[FORMAT_SCRIPT_SPEC.name] = format_script
FORMAT_SCRIPT_SPEC.loader.exec_module(format_script)
class BuildifierFormatterGroupTest(unittest.TestCase):
def test_includes_top_level_codex_rule_files(self) -> None:
repository_files = b"\0".join(
[
b".codex/rules/z.rules",
b".codex/rules/a.rules",
b".codex/rules/nested/ignored.rules",
b"elsewhere.rules",
]
)
with patch.object(
format_script.subprocess,
"check_output",
return_value=repository_files,
):
group = format_script.buildifier_formatter_group(check=True)
self.assertEqual(
group.commands[0].args[4:],
(".codex/rules/a.rules", ".codex/rules/z.rules"),
)
if __name__ == "__main__":
unittest.main()
+87
View File
@@ -0,0 +1,87 @@
#!/usr/bin/env python3
from contextlib import redirect_stdout
import io
from pathlib import Path
import sys
import unittest
from unittest.mock import patch
sys.path.insert(0, str(Path(__file__).resolve().parent))
import setup_dev_execpolicy
class SetupDevExecpolicyTest(unittest.TestCase):
def test_discovers_absolute_paths_without_resolving_them(self) -> None:
paths = {
"cargo": "/tools/bin/cargo",
"just": "/tools/bin/just",
}
self.assertEqual(
setup_dev_execpolicy.discover_host_executables(
tuple(paths),
which=paths.get,
),
{
"cargo": Path("/tools/bin/cargo"),
"just": Path("/tools/bin/just"),
},
)
def test_reports_all_missing_executables(self) -> None:
with self.assertRaisesRegex(
RuntimeError,
"missing required host executables on PATH: just, pnpm",
):
setup_dev_execpolicy.discover_host_executables(
("cargo", "just", "pnpm"),
which=lambda name: "/tools/bin/cargo" if name == "cargo" else None,
)
def test_renders_host_executable_rules(self) -> None:
self.assertEqual(
setup_dev_execpolicy.render_host_executable_rules(
{
"cargo": Path("/tools/bin/cargo"),
"bazel": Path("/tools/bin/bazel"),
}
),
"""# Generated by scripts/setup_dev_execpolicy.py. Do not edit.
host_executable(
name = "cargo",
paths = ["/tools/bin/cargo"],
)
host_executable(
name = "bazel",
paths = ["/tools/bin/bazel"],
)
""",
)
def test_main_prints_rules(self) -> None:
executables = {"cargo": Path("/tools/bin/cargo")}
stdout = io.StringIO()
with (
patch.object(
setup_dev_execpolicy,
"discover_host_executables",
return_value=executables,
),
redirect_stdout(stdout),
):
result = setup_dev_execpolicy.main()
self.assertEqual(result, 0)
self.assertEqual(
stdout.getvalue(),
setup_dev_execpolicy.render_host_executable_rules(executables),
)
if __name__ == "__main__":
unittest.main()