mirror of
https://github.com/openai/codex.git
synced 2026-04-28 16:45:54 +00:00
## Why `argument-comment-lint` had become a PR bottleneck because the repo-wide lane was still effectively running a `cargo dylint`-style flow across the workspace instead of reusing Bazel's Rust dependency graph. That kept the lint enforced, but it threw away the main benefit of moving this job under Bazel in the first place: metadata reuse and cacheable per-target analysis in the same shape as Clippy. This change moves the repo-wide lint onto a native Bazel Rust aspect so Linux and macOS can lint `codex-rs` without rebuilding the world crate-by-crate through the wrapper path. ## What Changed - add a nightly Rust toolchain with `rustc-dev` for Bazel and a dedicated crate-universe repo for `tools/argument-comment-lint` - add `tools/argument-comment-lint/driver.rs` and `tools/argument-comment-lint/lint_aspect.bzl` so Bazel can run the lint as a custom `rustc_driver` - switch repo-wide `just argument-comment-lint` and the Linux/macOS `rust-ci` lanes to `bazel build --config=argument-comment-lint //codex-rs/...` - keep the Python/DotSlash wrappers as the package-scoped fallback path and as the current Windows CI path - gate the Dylint entrypoint behind a `bazel_native` feature so the Bazel-native library avoids the `dylint_*` packaging stack - update the aspect runtime environment so the driver can locate `rustc_driver` correctly under remote execution - keep the dedicated `tools/argument-comment-lint` package tests and wrapper unit tests in CI so the source and packaged entrypoints remain covered ## Verification - `python3 -m unittest discover -s tools/argument-comment-lint -p 'test_*.py'` - `cargo test` in `tools/argument-comment-lint` - `bazel build //tools/argument-comment-lint:argument-comment-lint-driver --@rules_rust//rust/toolchain/channel=nightly` - `bazel build --config=argument-comment-lint //codex-rs/utils/path-utils:all` - `bazel build --config=argument-comment-lint //codex-rs/rollout:rollout` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/16106). * #16120 * __->__ #16106
188 lines
5.8 KiB
Python
188 lines
5.8 KiB
Python
"""Bazel aspect for running argument-comment-lint on Rust targets."""
|
|
|
|
load("@rules_rust//rust:defs.bzl", "rust_common")
|
|
load("@rules_rust//rust/private:rust.bzl", "RUSTC_ATTRS")
|
|
load(
|
|
"@rules_rust//rust/private:rustc.bzl",
|
|
"collect_deps",
|
|
"collect_inputs",
|
|
"construct_arguments",
|
|
)
|
|
load(
|
|
"@rules_rust//rust/private:utils.bzl",
|
|
"determine_output_hash",
|
|
"find_cc_toolchain",
|
|
"find_toolchain",
|
|
)
|
|
|
|
_STRICT_LINT_FLAGS = [
|
|
"-Duncommented-anonymous-literal-argument",
|
|
"-Aunknown-lints",
|
|
]
|
|
|
|
def _find_rustc_driver_library(toolchain):
|
|
for file in toolchain.rustc_lib.to_list():
|
|
if file.basename.startswith("librustc_driver-") or file.basename.startswith("rustc_driver-"):
|
|
return file
|
|
return None
|
|
|
|
def _prepend_runtime_path(env, key, path, separator):
|
|
previous = env.get(key)
|
|
env[key] = "{}{}{}".format(path, separator, previous) if previous else path
|
|
|
|
def _set_driver_runtime_env(env, toolchain):
|
|
driver_library = _find_rustc_driver_library(toolchain)
|
|
if not driver_library:
|
|
return
|
|
|
|
library_dir = driver_library.dirname
|
|
if driver_library.basename.endswith(".dll"):
|
|
_prepend_runtime_path(env, "PATH", library_dir, ";")
|
|
return
|
|
|
|
# The lint driver runs in exec configuration. Under remote execution the
|
|
# exec OS can differ from the Rust target OS, so populate both Unix loader
|
|
# variables from the located driver library instead of keying off target_os.
|
|
_prepend_runtime_path(env, "LD_LIBRARY_PATH", library_dir, ":")
|
|
_prepend_runtime_path(env, "DYLD_LIBRARY_PATH", library_dir, ":")
|
|
|
|
def _get_argument_comment_lint_ready_crate_info(target, aspect_ctx):
|
|
if target.label.workspace_root.startswith("external"):
|
|
return None
|
|
|
|
if aspect_ctx:
|
|
ignore_tags = [
|
|
"no_argument_comment_lint",
|
|
"no-lint",
|
|
"no_lint",
|
|
"nolint",
|
|
]
|
|
for tag in aspect_ctx.rule.attr.tags:
|
|
if tag.replace("-", "_").lower() in ignore_tags:
|
|
return None
|
|
|
|
if rust_common.crate_info in target:
|
|
return target[rust_common.crate_info]
|
|
if rust_common.test_crate_info in target:
|
|
return target[rust_common.test_crate_info].crate
|
|
return None
|
|
|
|
def _rust_argument_comment_lint_aspect_impl(target, ctx):
|
|
if OutputGroupInfo in target and hasattr(target[OutputGroupInfo], "argument_comment_lint_checks"):
|
|
return []
|
|
|
|
crate_info = _get_argument_comment_lint_ready_crate_info(target, ctx)
|
|
if not crate_info:
|
|
return []
|
|
|
|
toolchain = find_toolchain(ctx)
|
|
cc_toolchain, feature_configuration = find_cc_toolchain(ctx)
|
|
|
|
dep_info, build_info, _ = collect_deps(
|
|
deps = crate_info.deps.to_list(),
|
|
proc_macro_deps = crate_info.proc_macro_deps.to_list(),
|
|
aliases = crate_info.aliases,
|
|
)
|
|
|
|
compile_inputs, out_dir, build_env_files, build_flags_files, linkstamp_outs, ambiguous_libs = collect_inputs(
|
|
ctx,
|
|
ctx.rule.file,
|
|
ctx.rule.files,
|
|
depset([]),
|
|
toolchain,
|
|
cc_toolchain,
|
|
feature_configuration,
|
|
crate_info,
|
|
dep_info,
|
|
build_info,
|
|
[],
|
|
)
|
|
|
|
success_marker = ctx.actions.declare_file(
|
|
ctx.label.name + ".argument_comment_lint.ok",
|
|
sibling = crate_info.output,
|
|
)
|
|
|
|
args, env = construct_arguments(
|
|
ctx = ctx,
|
|
attr = ctx.rule.attr,
|
|
file = ctx.file,
|
|
toolchain = toolchain,
|
|
tool_path = ctx.executable._driver.path,
|
|
cc_toolchain = cc_toolchain,
|
|
feature_configuration = feature_configuration,
|
|
crate_info = crate_info,
|
|
dep_info = dep_info,
|
|
linkstamp_outs = linkstamp_outs,
|
|
ambiguous_libs = ambiguous_libs,
|
|
output_hash = determine_output_hash(crate_info.root, ctx.label),
|
|
rust_flags = [],
|
|
out_dir = out_dir,
|
|
build_env_files = build_env_files,
|
|
build_flags_files = build_flags_files,
|
|
emit = ["dep-info", "metadata"],
|
|
skip_expanding_rustc_env = True,
|
|
)
|
|
|
|
if crate_info.is_test:
|
|
args.rustc_flags.add("--test")
|
|
|
|
args.process_wrapper_flags.add("--touch-file", success_marker)
|
|
args.rustc_flags.add_all(_STRICT_LINT_FLAGS)
|
|
_set_driver_runtime_env(env, toolchain)
|
|
|
|
driver_runfiles = ctx.attr._driver[DefaultInfo].default_runfiles.files
|
|
action_inputs = depset(
|
|
transitive = [
|
|
compile_inputs,
|
|
driver_runfiles,
|
|
toolchain.rustc_lib,
|
|
],
|
|
)
|
|
|
|
ctx.actions.run(
|
|
executable = ctx.executable._process_wrapper,
|
|
inputs = action_inputs,
|
|
outputs = [success_marker],
|
|
env = env,
|
|
tools = [ctx.executable._driver],
|
|
execution_requirements = {
|
|
"no-sandbox": "1",
|
|
},
|
|
arguments = args.all,
|
|
mnemonic = "ArgumentCommentLint",
|
|
progress_message = "ArgumentCommentLint %{label}",
|
|
toolchain = "@rules_rust//rust:toolchain_type",
|
|
)
|
|
|
|
return [OutputGroupInfo(argument_comment_lint_checks = depset([success_marker]))]
|
|
|
|
rust_argument_comment_lint_aspect = aspect(
|
|
implementation = _rust_argument_comment_lint_aspect_impl,
|
|
fragments = ["cpp"],
|
|
attrs = {
|
|
"_driver": attr.label(
|
|
default = Label("//tools/argument-comment-lint:argument-comment-lint-driver"),
|
|
executable = True,
|
|
cfg = "exec",
|
|
),
|
|
} | RUSTC_ATTRS,
|
|
toolchains = [
|
|
str(Label("@rules_rust//rust:toolchain_type")),
|
|
config_common.toolchain_type("@bazel_tools//tools/cpp:toolchain_type", mandatory = False),
|
|
],
|
|
required_providers = [
|
|
[rust_common.crate_info],
|
|
[rust_common.test_crate_info],
|
|
],
|
|
doc = """\
|
|
Runs argument-comment-lint on Rust targets using Bazel's Rust dependency graph.
|
|
|
|
Example:
|
|
|
|
```output
|
|
$ bazel build --config=argument-comment-lint //codex-rs/...
|
|
```
|
|
""",
|
|
)
|