mirror of
https://github.com/openai/codex.git
synced 2026-04-24 06:35:50 +00:00
## Why Bazel clippy now catches lints that `cargo clippy` can still miss when a crate under `codex-rs` forgets to opt into workspace lints. The concrete example here was `codex-rs/app-server/tests/common/Cargo.toml`: Bazel flagged a clippy violation in `models_cache.rs`, but Cargo did not because that crate inherited workspace package metadata without declaring `[lints] workspace = true`. We already mirror the workspace clippy deny list into Bazel after [#15955](https://github.com/openai/codex/pull/15955), so we also need a repo-side check that keeps every `codex-rs` manifest opted into the same workspace settings. ## What changed - add `.github/scripts/verify_cargo_workspace_manifests.py`, which parses every `codex-rs/**/Cargo.toml` with `tomllib` and verifies: - `version.workspace = true` - `edition.workspace = true` - `license.workspace = true` - `[lints] workspace = true` - top-level crate names follow the `codex-*` / `codex-utils-*` conventions, with explicit exceptions for `windows-sandbox-rs` and `utils/path-utils` - run that script in `.github/workflows/ci.yml` - update the current outlier manifests so the check is enforceable immediately - fix the newly exposed clippy violations in the affected crates (`app-server/tests/common`, `file-search`, `feedback`, `shell-escalation`, and `debug-client`) --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/16353). * #16351 * __->__ #16353
126 lines
3.5 KiB
Python
126 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
|
|
|
"""Verify that codex-rs crates inherit workspace metadata, lints, and names.
|
|
|
|
This keeps `cargo clippy` aligned with the workspace lint policy by ensuring
|
|
each crate opts into `[lints] workspace = true`, and it also checks the crate
|
|
name conventions for top-level `codex-rs/*` crates and `codex-rs/utils/*`
|
|
crates.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
import tomllib
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
CARGO_RS_ROOT = ROOT / "codex-rs"
|
|
WORKSPACE_PACKAGE_FIELDS = ("version", "edition", "license")
|
|
TOP_LEVEL_NAME_EXCEPTIONS = {
|
|
"windows-sandbox-rs": "codex-windows-sandbox",
|
|
}
|
|
UTILITY_NAME_EXCEPTIONS = {
|
|
"path-utils": "codex-utils-path",
|
|
}
|
|
|
|
|
|
def main() -> int:
|
|
failures = [
|
|
(path.relative_to(ROOT), errors)
|
|
for path in cargo_manifests()
|
|
if (errors := manifest_errors(path))
|
|
]
|
|
if not failures:
|
|
return 0
|
|
|
|
print(
|
|
"Cargo manifests under codex-rs must inherit workspace package metadata and "
|
|
"opt into workspace lints."
|
|
)
|
|
print(
|
|
"Cargo only applies `codex-rs/Cargo.toml` `[workspace.lints.clippy]` "
|
|
"entries to a crate when that crate declares:"
|
|
)
|
|
print()
|
|
print("[lints]")
|
|
print("workspace = true")
|
|
print()
|
|
print(
|
|
"Without that opt-in, `cargo clippy` can miss violations that Bazel clippy "
|
|
"catches."
|
|
)
|
|
print()
|
|
print(
|
|
"Package-name checks apply to `codex-rs/<crate>/Cargo.toml` and "
|
|
"`codex-rs/utils/<crate>/Cargo.toml`."
|
|
)
|
|
print()
|
|
for path, errors in failures:
|
|
print(f"{path}:")
|
|
for error in errors:
|
|
print(f" - {error}")
|
|
|
|
return 1
|
|
|
|
|
|
def manifest_errors(path: Path) -> list[str]:
|
|
manifest = load_manifest(path)
|
|
package = manifest.get("package")
|
|
if not isinstance(package, dict):
|
|
return []
|
|
|
|
errors = []
|
|
for field in WORKSPACE_PACKAGE_FIELDS:
|
|
if not is_workspace_reference(package.get(field)):
|
|
errors.append(f"set `{field}.workspace = true` in `[package]`")
|
|
|
|
lints = manifest.get("lints")
|
|
if not (isinstance(lints, dict) and lints.get("workspace") is True):
|
|
errors.append("add `[lints]` with `workspace = true`")
|
|
|
|
expected_name = expected_package_name(path)
|
|
if expected_name is not None:
|
|
actual_name = package.get("name")
|
|
if actual_name != expected_name:
|
|
errors.append(
|
|
f"set `[package].name` to `{expected_name}` (found `{actual_name}`)"
|
|
)
|
|
|
|
return errors
|
|
|
|
|
|
def expected_package_name(path: Path) -> str | None:
|
|
parts = path.relative_to(CARGO_RS_ROOT).parts
|
|
if len(parts) == 2 and parts[1] == "Cargo.toml":
|
|
directory = parts[0]
|
|
return TOP_LEVEL_NAME_EXCEPTIONS.get(
|
|
directory,
|
|
directory if directory.startswith("codex-") else f"codex-{directory}",
|
|
)
|
|
if len(parts) == 3 and parts[0] == "utils" and parts[2] == "Cargo.toml":
|
|
directory = parts[1]
|
|
return UTILITY_NAME_EXCEPTIONS.get(directory, f"codex-utils-{directory}")
|
|
return None
|
|
|
|
|
|
def is_workspace_reference(value: object) -> bool:
|
|
return isinstance(value, dict) and value.get("workspace") is True
|
|
|
|
|
|
def load_manifest(path: Path) -> dict:
|
|
return tomllib.loads(path.read_text())
|
|
|
|
|
|
def cargo_manifests() -> list[Path]:
|
|
return sorted(
|
|
path
|
|
for path in CARGO_RS_ROOT.rglob("Cargo.toml")
|
|
if path != CARGO_RS_ROOT / "Cargo.toml"
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|