mirror of
https://github.com/openai/codex.git
synced 2026-04-23 22:24:57 +00:00
Problem: The TUI still depended on `codex-core` directly in a number of places, and we had no enforcement from keeping this problem from getting worse. Solution: Route TUI core access through `codex-app-server-client::legacy_core`, add CI enforcement for that boundary, and re-export this legacy bridge inside the TUI as `crate::legacy_core` so the remaining call sites stay readable. There is no functional change in this PR — just changes to import targets. Over time, we can whittle away at the remaining symbols in this legacy namespace with the eventual goal of removing them all. In the meantime, this linter rule will prevent us from inadvertently importing new symbols from core.
90 lines
2.7 KiB
Python
90 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
|
|
"""Verify codex-tui does not depend on or import codex-core directly."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
import sys
|
|
import tomllib
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
TUI_ROOT = ROOT / "codex-rs" / "tui"
|
|
TUI_MANIFEST = TUI_ROOT / "Cargo.toml"
|
|
FORBIDDEN_PACKAGE = "codex-core"
|
|
FORBIDDEN_SOURCE_PATTERNS = (
|
|
re.compile(r"\bcodex_core::"),
|
|
re.compile(r"\buse\s+codex_core\b"),
|
|
re.compile(r"\bextern\s+crate\s+codex_core\b"),
|
|
)
|
|
|
|
|
|
def main() -> int:
|
|
failures = []
|
|
failures.extend(manifest_failures())
|
|
failures.extend(source_failures())
|
|
|
|
if not failures:
|
|
return 0
|
|
|
|
print("codex-tui must not depend on or import codex-core directly.")
|
|
print(
|
|
"Use the app-server protocol/client boundary instead; temporary embedded "
|
|
"startup gaps belong behind codex_app_server_client::legacy_core."
|
|
)
|
|
print()
|
|
for failure in failures:
|
|
print(f"- {failure}")
|
|
|
|
return 1
|
|
|
|
|
|
def manifest_failures() -> list[str]:
|
|
manifest = tomllib.loads(TUI_MANIFEST.read_text())
|
|
failures = []
|
|
for section_name, dependencies in dependency_sections(manifest):
|
|
if FORBIDDEN_PACKAGE in dependencies:
|
|
failures.append(
|
|
f"{relative_path(TUI_MANIFEST)} declares `{FORBIDDEN_PACKAGE}` "
|
|
f"in `[{section_name}]`"
|
|
)
|
|
return failures
|
|
|
|
|
|
def dependency_sections(manifest: dict) -> list[tuple[str, dict]]:
|
|
sections: list[tuple[str, dict]] = []
|
|
for section_name in ("dependencies", "dev-dependencies", "build-dependencies"):
|
|
dependencies = manifest.get(section_name)
|
|
if isinstance(dependencies, dict):
|
|
sections.append((section_name, dependencies))
|
|
|
|
for target_name, target in manifest.get("target", {}).items():
|
|
if not isinstance(target, dict):
|
|
continue
|
|
for section_name in ("dependencies", "dev-dependencies", "build-dependencies"):
|
|
dependencies = target.get(section_name)
|
|
if isinstance(dependencies, dict):
|
|
sections.append((f'target.{target_name}.{section_name}', dependencies))
|
|
|
|
return sections
|
|
|
|
|
|
def source_failures() -> list[str]:
|
|
failures = []
|
|
for path in sorted(TUI_ROOT.glob("**/*.rs")):
|
|
text = path.read_text()
|
|
for line_number, line in enumerate(text.splitlines(), start=1):
|
|
if any(pattern.search(line) for pattern in FORBIDDEN_SOURCE_PATTERNS):
|
|
failures.append(f"{relative_path(path)}:{line_number} imports `codex_core`")
|
|
return failures
|
|
|
|
|
|
def relative_path(path: Path) -> str:
|
|
return str(path.relative_to(ROOT))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|