mirror of
https://github.com/openai/codex.git
synced 2026-03-20 04:46:31 +03:00
Compare commits
1 Commits
auth-behav
...
pr15113
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b28be3bfcd |
24
.github/dotslash-argument-comment-lint-config.json
vendored
Normal file
24
.github/dotslash-argument-comment-lint-config.json
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"outputs": {
|
||||
"argument-comment-lint": {
|
||||
"platforms": {
|
||||
"macos-aarch64": {
|
||||
"regex": "^argument-comment-lint-aarch64-apple-darwin\\.tar\\.gz$",
|
||||
"path": "argument-comment-lint/bin/argument-comment-lint"
|
||||
},
|
||||
"linux-x86_64": {
|
||||
"regex": "^argument-comment-lint-x86_64-unknown-linux-gnu\\.tar\\.gz$",
|
||||
"path": "argument-comment-lint/bin/argument-comment-lint"
|
||||
},
|
||||
"linux-aarch64": {
|
||||
"regex": "^argument-comment-lint-aarch64-unknown-linux-gnu\\.tar\\.gz$",
|
||||
"path": "argument-comment-lint/bin/argument-comment-lint"
|
||||
},
|
||||
"windows-x86_64": {
|
||||
"regex": "^argument-comment-lint-x86_64-pc-windows-msvc\\.zip$",
|
||||
"path": "argument-comment-lint/bin/argument-comment-lint.exe"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
103
.github/workflows/rust-release-argument-comment-lint.yml
vendored
Normal file
103
.github/workflows/rust-release-argument-comment-lint.yml
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
name: rust-release-argument-comment-lint
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
publish:
|
||||
required: true
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
skip:
|
||||
if: ${{ !inputs.publish }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: echo "Skipping argument-comment-lint release assets for prerelease tag"
|
||||
|
||||
build:
|
||||
if: ${{ inputs.publish }}
|
||||
name: Build - ${{ matrix.runner }} - ${{ matrix.target }}
|
||||
runs-on: ${{ matrix.runs_on || matrix.runner }}
|
||||
timeout-minutes: 60
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- runner: macos-15-xlarge
|
||||
target: aarch64-apple-darwin
|
||||
archive_name: argument-comment-lint-aarch64-apple-darwin.tar.gz
|
||||
lib_name: libargument_comment_lint@nightly-2025-09-18-aarch64-apple-darwin.dylib
|
||||
runner_binary: argument-comment-lint
|
||||
cargo_dylint_binary: cargo-dylint
|
||||
- runner: ubuntu-24.04
|
||||
target: x86_64-unknown-linux-gnu
|
||||
archive_name: argument-comment-lint-x86_64-unknown-linux-gnu.tar.gz
|
||||
lib_name: libargument_comment_lint@nightly-2025-09-18-x86_64-unknown-linux-gnu.so
|
||||
runner_binary: argument-comment-lint
|
||||
cargo_dylint_binary: cargo-dylint
|
||||
- runner: ubuntu-24.04-arm
|
||||
target: aarch64-unknown-linux-gnu
|
||||
archive_name: argument-comment-lint-aarch64-unknown-linux-gnu.tar.gz
|
||||
lib_name: libargument_comment_lint@nightly-2025-09-18-aarch64-unknown-linux-gnu.so
|
||||
runner_binary: argument-comment-lint
|
||||
cargo_dylint_binary: cargo-dylint
|
||||
- runner: windows-x64
|
||||
target: x86_64-pc-windows-msvc
|
||||
archive_name: argument-comment-lint-x86_64-pc-windows-msvc.zip
|
||||
lib_name: argument_comment_lint@nightly-2025-09-18-x86_64-pc-windows-msvc.dll
|
||||
runner_binary: argument-comment-lint.exe
|
||||
cargo_dylint_binary: cargo-dylint.exe
|
||||
runs_on:
|
||||
group: codex-runners
|
||||
labels: codex-windows-x64
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: dtolnay/rust-toolchain@1.93.0
|
||||
with:
|
||||
toolchain: nightly-2025-09-18
|
||||
targets: ${{ matrix.target }}
|
||||
components: llvm-tools-preview, rustc-dev, rust-src
|
||||
|
||||
- name: Install tooling
|
||||
shell: bash
|
||||
run: |
|
||||
install_root="${RUNNER_TEMP}/argument-comment-lint-tools"
|
||||
cargo install --locked cargo-dylint --root "$install_root"
|
||||
cargo install --locked dylint-link
|
||||
echo "INSTALL_ROOT=$install_root" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Cargo build
|
||||
working-directory: tools/argument-comment-lint
|
||||
shell: bash
|
||||
run: cargo build --release --target ${{ matrix.target }}
|
||||
|
||||
- name: Stage artifact
|
||||
shell: bash
|
||||
run: |
|
||||
dest="dist/argument-comment-lint/${{ matrix.target }}"
|
||||
mkdir -p "$dest"
|
||||
package_root="${RUNNER_TEMP}/argument-comment-lint"
|
||||
rm -rf "$package_root"
|
||||
mkdir -p "$package_root/bin" "$package_root/lib"
|
||||
|
||||
cp "tools/argument-comment-lint/target/${{ matrix.target }}/release/${{ matrix.runner_binary }}" \
|
||||
"$package_root/bin/${{ matrix.runner_binary }}"
|
||||
cp "${INSTALL_ROOT}/bin/${{ matrix.cargo_dylint_binary }}" \
|
||||
"$package_root/bin/${{ matrix.cargo_dylint_binary }}"
|
||||
cp "tools/argument-comment-lint/target/${{ matrix.target }}/release/${{ matrix.lib_name }}" \
|
||||
"$package_root/lib/${{ matrix.lib_name }}"
|
||||
|
||||
archive_path="$dest/${{ matrix.archive_name }}"
|
||||
if [[ "${{ runner.os }}" == "Windows" ]]; then
|
||||
(cd "${RUNNER_TEMP}" && 7z a "$GITHUB_WORKSPACE/$archive_path" argument-comment-lint >/dev/null)
|
||||
else
|
||||
(cd "${RUNNER_TEMP}" && tar -czf "$GITHUB_WORKSPACE/$archive_path" argument-comment-lint)
|
||||
fi
|
||||
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: argument-comment-lint-${{ matrix.target }}
|
||||
path: dist/argument-comment-lint/${{ matrix.target }}/*
|
||||
16
.github/workflows/rust-release.yml
vendored
16
.github/workflows/rust-release.yml
vendored
@@ -380,11 +380,19 @@ jobs:
|
||||
publish: true
|
||||
secrets: inherit
|
||||
|
||||
argument-comment-lint-release-assets:
|
||||
name: argument-comment-lint release assets
|
||||
needs: tag-check
|
||||
uses: ./.github/workflows/rust-release-argument-comment-lint.yml
|
||||
with:
|
||||
publish: ${{ !contains(github.ref_name, '-') }}
|
||||
|
||||
release:
|
||||
needs:
|
||||
- build
|
||||
- build-windows
|
||||
- shell-tool-mcp
|
||||
- argument-comment-lint-release-assets
|
||||
name: release
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
@@ -521,6 +529,14 @@ jobs:
|
||||
tag: ${{ github.ref_name }}
|
||||
config: .github/dotslash-config.json
|
||||
|
||||
- if: ${{ !contains(steps.release_name.outputs.name, '-') }}
|
||||
uses: facebook/dotslash-publish-release@v2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag: ${{ github.ref_name }}
|
||||
config: .github/dotslash-argument-comment-lint-config.json
|
||||
|
||||
- name: Trigger developers.openai.com deploy
|
||||
# Only trigger the deploy if the release is not a pre-release.
|
||||
# The deploy is used to update the developers.openai.com website with the new config schema json file.
|
||||
|
||||
@@ -68,6 +68,20 @@ cd tools/argument-comment-lint
|
||||
cargo test
|
||||
```
|
||||
|
||||
Stable GitHub releases also publish a DotSlash file named
|
||||
`argument-comment-lint` for macOS arm64, Linux arm64, Linux x64, and Windows
|
||||
x64. The published package contains a small runner executable, a bundled
|
||||
`cargo-dylint`, and the prebuilt lint library.
|
||||
|
||||
`run.sh` prefers that packaged runner when `dotslash` is installed, and falls
|
||||
back to the local `cargo dylint --path ...` flow when the release asset is not
|
||||
available yet or `CODEX_ARGUMENT_COMMENT_LINT_USE_LOCAL=1` is set. To refresh
|
||||
the cached DotSlash manifest after a new stable release:
|
||||
|
||||
```bash
|
||||
CODEX_ARGUMENT_COMMENT_LINT_REFRESH=1 ./tools/argument-comment-lint/run.sh -p codex-core
|
||||
```
|
||||
|
||||
Run the lint against `codex-rs` from the repo root:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -5,6 +5,11 @@ set -euo pipefail
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
lint_path="$repo_root/tools/argument-comment-lint"
|
||||
manifest_path="$repo_root/codex-rs/Cargo.toml"
|
||||
release_manifest_url="https://github.com/openai/codex/releases/latest/download/argument-comment-lint"
|
||||
cache_root="${XDG_CACHE_HOME:-$HOME/.cache}/codex/argument-comment-lint"
|
||||
release_manifest_path="$cache_root/argument-comment-lint"
|
||||
dotslash_cache_root="$cache_root/dotslash"
|
||||
toolchain_channel="nightly-2025-09-18"
|
||||
strict_lint="uncommented-anonymous-literal-argument"
|
||||
noise_lint="unknown_lints"
|
||||
|
||||
@@ -14,6 +19,69 @@ has_no_deps=false
|
||||
has_library_selection=false
|
||||
expect_value=""
|
||||
|
||||
try_release_runner() {
|
||||
if [[ "${CODEX_ARGUMENT_COMMENT_LINT_USE_LOCAL:-0}" == "1" ]]; then
|
||||
return 1
|
||||
fi
|
||||
if ! command -v dotslash >/dev/null 2>&1 || ! command -v curl >/dev/null 2>&1; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
mkdir -p "$cache_root" "$dotslash_cache_root"
|
||||
if [[ ! -f "$release_manifest_path" || "${CODEX_ARGUMENT_COMMENT_LINT_REFRESH:-0}" == "1" ]]; then
|
||||
local tmp_manifest
|
||||
tmp_manifest="$(mktemp "$cache_root/argument-comment-lint.XXXXXX")"
|
||||
if ! curl -fsL "$release_manifest_url" -o "$tmp_manifest"; then
|
||||
rm -f "$tmp_manifest"
|
||||
return 1
|
||||
fi
|
||||
chmod +x "$tmp_manifest"
|
||||
mv "$tmp_manifest" "$release_manifest_path"
|
||||
fi
|
||||
|
||||
if ! DOTSLASH_CACHE="$dotslash_cache_root" dotslash -- fetch "$release_manifest_path" >/dev/null 2>&1; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
exec env DOTSLASH_CACHE="$dotslash_cache_root" "$release_manifest_path" "$@"
|
||||
}
|
||||
|
||||
ensure_local_prerequisites() {
|
||||
if ! command -v cargo-dylint >/dev/null 2>&1 || ! command -v dylint-link >/dev/null 2>&1; then
|
||||
cat >&2 <<EOF
|
||||
argument-comment-lint local fallback requires cargo-dylint and dylint-link.
|
||||
Install them with:
|
||||
cargo install --locked cargo-dylint dylint-link
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! rustup toolchain list | grep -q "^${toolchain_channel}"; then
|
||||
cat >&2 <<EOF
|
||||
argument-comment-lint local fallback requires the ${toolchain_channel} toolchain with rustc-dev support.
|
||||
Install it with:
|
||||
rustup toolchain install ${toolchain_channel} \\
|
||||
--component llvm-tools-preview \\
|
||||
--component rustc-dev \\
|
||||
--component rust-src
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
set_default_env() {
|
||||
if [[ "${DYLINT_RUSTFLAGS:-}" != *"$strict_lint"* ]]; then
|
||||
export DYLINT_RUSTFLAGS="${DYLINT_RUSTFLAGS:+${DYLINT_RUSTFLAGS} }-D $strict_lint"
|
||||
fi
|
||||
if [[ "${DYLINT_RUSTFLAGS:-}" != *"$noise_lint"* ]]; then
|
||||
export DYLINT_RUSTFLAGS="${DYLINT_RUSTFLAGS:+${DYLINT_RUSTFLAGS} }-A $noise_lint"
|
||||
fi
|
||||
|
||||
if [[ -z "${CARGO_INCREMENTAL:-}" ]]; then
|
||||
export CARGO_INCREMENTAL=0
|
||||
fi
|
||||
}
|
||||
|
||||
for arg in "$@"; do
|
||||
if [[ -n "$expect_value" ]]; then
|
||||
case "$expect_value" in
|
||||
@@ -62,30 +130,29 @@ for arg in "$@"; do
|
||||
esac
|
||||
done
|
||||
|
||||
lint_args=()
|
||||
if [[ "$has_manifest_path" == false ]]; then
|
||||
lint_args+=(--manifest-path "$manifest_path")
|
||||
fi
|
||||
if [[ "$has_package_selection" == false ]]; then
|
||||
lint_args+=(--workspace)
|
||||
fi
|
||||
if [[ "$has_no_deps" == false ]]; then
|
||||
lint_args+=(--no-deps)
|
||||
fi
|
||||
lint_args+=("$@")
|
||||
|
||||
if try_release_runner "${lint_args[@]}"; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
ensure_local_prerequisites
|
||||
set_default_env
|
||||
|
||||
cmd=(cargo dylint --path "$lint_path")
|
||||
if [[ "$has_library_selection" == false ]]; then
|
||||
cmd+=(--all)
|
||||
fi
|
||||
if [[ "$has_manifest_path" == false ]]; then
|
||||
cmd+=(--manifest-path "$manifest_path")
|
||||
fi
|
||||
if [[ "$has_package_selection" == false ]]; then
|
||||
cmd+=(--workspace)
|
||||
fi
|
||||
if [[ "$has_no_deps" == false ]]; then
|
||||
cmd+=(--no-deps)
|
||||
fi
|
||||
cmd+=("$@")
|
||||
|
||||
if [[ "${DYLINT_RUSTFLAGS:-}" != *"$strict_lint"* ]]; then
|
||||
export DYLINT_RUSTFLAGS="${DYLINT_RUSTFLAGS:+${DYLINT_RUSTFLAGS} }-D $strict_lint"
|
||||
fi
|
||||
if [[ "${DYLINT_RUSTFLAGS:-}" != *"$noise_lint"* ]]; then
|
||||
export DYLINT_RUSTFLAGS="${DYLINT_RUSTFLAGS:+${DYLINT_RUSTFLAGS} }-A $noise_lint"
|
||||
fi
|
||||
|
||||
if [[ -z "${CARGO_INCREMENTAL:-}" ]]; then
|
||||
export CARGO_INCREMENTAL=0
|
||||
fi
|
||||
cmd+=("${lint_args[@]}")
|
||||
|
||||
exec "${cmd[@]}"
|
||||
|
||||
164
tools/argument-comment-lint/src/bin/argument-comment-lint.rs
Normal file
164
tools/argument-comment-lint/src/bin/argument-comment-lint.rs
Normal file
@@ -0,0 +1,164 @@
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::process::ExitCode;
|
||||
|
||||
fn main() -> ExitCode {
|
||||
match run() {
|
||||
Ok(code) => code,
|
||||
Err(err) => {
|
||||
eprintln!("{err}");
|
||||
ExitCode::from(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<ExitCode, String> {
|
||||
let exe_path =
|
||||
env::current_exe().map_err(|err| format!("failed to locate current executable: {err}"))?;
|
||||
let bin_dir = exe_path.parent().ok_or_else(|| {
|
||||
format!(
|
||||
"failed to locate parent directory for executable {}",
|
||||
exe_path.display()
|
||||
)
|
||||
})?;
|
||||
let package_root = bin_dir.parent().ok_or_else(|| {
|
||||
format!(
|
||||
"failed to locate package root for executable {}",
|
||||
exe_path.display()
|
||||
)
|
||||
})?;
|
||||
let cargo_dylint = bin_dir.join(cargo_dylint_binary_name());
|
||||
let library_dir = package_root.join("lib");
|
||||
let library_path = find_bundled_library(&library_dir)?;
|
||||
|
||||
ensure_exists(&cargo_dylint, "bundled cargo-dylint executable")?;
|
||||
ensure_exists(
|
||||
&library_dir,
|
||||
"bundled argument-comment lint library directory",
|
||||
)?;
|
||||
|
||||
let args: Vec<OsString> = env::args_os().skip(1).collect();
|
||||
let mut command = Command::new(&cargo_dylint);
|
||||
command.arg("dylint");
|
||||
command.arg("--lib-path").arg(&library_path);
|
||||
if !has_library_selection(&args) {
|
||||
command.arg("--all");
|
||||
}
|
||||
command.args(&args);
|
||||
set_default_env(&mut command);
|
||||
|
||||
let status = command
|
||||
.status()
|
||||
.map_err(|err| format!("failed to execute {}: {err}", cargo_dylint.display()))?;
|
||||
Ok(exit_code_from_status(status.code()))
|
||||
}
|
||||
|
||||
fn has_library_selection(args: &[OsString]) -> bool {
|
||||
let mut expect_value = false;
|
||||
for arg in args {
|
||||
if expect_value {
|
||||
return true;
|
||||
}
|
||||
|
||||
match arg.to_string_lossy().as_ref() {
|
||||
"--" => break,
|
||||
"--lib" | "--lib-path" => {
|
||||
expect_value = true;
|
||||
}
|
||||
"--lib=" | "--lib-path=" => return true,
|
||||
value if value.starts_with("--lib=") || value.starts_with("--lib-path=") => {
|
||||
return true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn set_default_env(command: &mut Command) {
|
||||
if let Some(flags) = env::var_os("DYLINT_RUSTFLAGS") {
|
||||
let mut flags = flags.to_string_lossy().to_string();
|
||||
append_flag_if_missing(&mut flags, "-D uncommented-anonymous-literal-argument");
|
||||
append_flag_if_missing(&mut flags, "-A unknown_lints");
|
||||
command.env("DYLINT_RUSTFLAGS", flags);
|
||||
} else {
|
||||
command.env(
|
||||
"DYLINT_RUSTFLAGS",
|
||||
"-D uncommented-anonymous-literal-argument -A unknown_lints",
|
||||
);
|
||||
}
|
||||
|
||||
if env::var_os("CARGO_INCREMENTAL").is_none() {
|
||||
command.env("CARGO_INCREMENTAL", "0");
|
||||
}
|
||||
}
|
||||
|
||||
fn append_flag_if_missing(flags: &mut String, flag: &str) {
|
||||
if flags.contains(flag) {
|
||||
return;
|
||||
}
|
||||
|
||||
if !flags.is_empty() {
|
||||
flags.push(' ');
|
||||
}
|
||||
flags.push_str(flag);
|
||||
}
|
||||
|
||||
fn cargo_dylint_binary_name() -> &'static str {
|
||||
if cfg!(windows) {
|
||||
"cargo-dylint.exe"
|
||||
} else {
|
||||
"cargo-dylint"
|
||||
}
|
||||
}
|
||||
|
||||
fn ensure_exists(path: &Path, label: &str) -> Result<(), String> {
|
||||
if path.exists() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("{label} not found at {}", path.display()))
|
||||
}
|
||||
}
|
||||
|
||||
fn find_bundled_library(library_dir: &Path) -> Result<PathBuf, String> {
|
||||
let entries = fs::read_dir(library_dir).map_err(|err| {
|
||||
format!(
|
||||
"failed to read bundled library directory {}: {err}",
|
||||
library_dir.display()
|
||||
)
|
||||
})?;
|
||||
let mut candidates = entries
|
||||
.filter_map(Result::ok)
|
||||
.map(|entry| entry.path())
|
||||
.filter(|path| path.is_file())
|
||||
.filter(|path| {
|
||||
path.file_name()
|
||||
.map(|name| name.to_string_lossy().contains('@'))
|
||||
.unwrap_or(false)
|
||||
});
|
||||
|
||||
let Some(first) = candidates.next() else {
|
||||
return Err(format!(
|
||||
"no packaged Dylint library found in {}",
|
||||
library_dir.display()
|
||||
));
|
||||
};
|
||||
if candidates.next().is_some() {
|
||||
return Err(format!(
|
||||
"expected exactly one packaged Dylint library in {}",
|
||||
library_dir.display()
|
||||
));
|
||||
}
|
||||
|
||||
Ok(first)
|
||||
}
|
||||
|
||||
fn exit_code_from_status(code: Option<i32>) -> ExitCode {
|
||||
code.and_then(|value| u8::try_from(value).ok())
|
||||
.map_or_else(|| ExitCode::from(1), ExitCode::from)
|
||||
}
|
||||
Reference in New Issue
Block a user