mirror of
https://github.com/openai/codex.git
synced 2026-09-13 11:47:17 +00:00
Use released DotSlash package for argument-comment lint
This commit is contained in:
61
.github/workflows/rust-ci.yml
vendored
61
.github/workflows/rust-ci.yml
vendored
@@ -91,17 +91,13 @@ jobs:
|
||||
- name: cargo shear
|
||||
run: cargo shear
|
||||
|
||||
argument_comment_lint:
|
||||
name: Argument comment lint
|
||||
argument_comment_lint_package:
|
||||
name: Argument comment lint package
|
||||
runs-on: ubuntu-24.04
|
||||
needs: changed
|
||||
if: ${{ needs.changed.outputs.argument_comment_lint == 'true' || needs.changed.outputs.workflows == 'true' || github.event_name == 'push' }}
|
||||
if: ${{ needs.changed.outputs.argument_comment_lint_package == 'true' || github.event_name == 'push' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install Linux sandbox build dependencies
|
||||
run: |
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get update
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends pkg-config libcap-dev
|
||||
- uses: dtolnay/rust-toolchain@1.93.0
|
||||
with:
|
||||
toolchain: nightly-2025-09-18
|
||||
@@ -120,14 +116,46 @@ jobs:
|
||||
- name: Install cargo-dylint tooling
|
||||
if: ${{ steps.cargo_dylint_cache.outputs.cache-hit != 'true' }}
|
||||
run: cargo install --locked cargo-dylint dylint-link
|
||||
- name: Check source wrapper syntax
|
||||
run: bash -n tools/argument-comment-lint/run.sh
|
||||
- name: Test argument comment lint package
|
||||
if: ${{ needs.changed.outputs.argument_comment_lint_package == 'true' || github.event_name == 'push' }}
|
||||
working-directory: tools/argument-comment-lint
|
||||
run: cargo test
|
||||
- name: Run argument comment lint on codex-rs
|
||||
|
||||
argument_comment_lint_prebuilt:
|
||||
name: Argument comment lint - ${{ matrix.name }}
|
||||
runs-on: ${{ matrix.runs_on || matrix.runner }}
|
||||
needs: changed
|
||||
if: ${{ needs.changed.outputs.argument_comment_lint == 'true' || needs.changed.outputs.workflows == 'true' || github.event_name == 'push' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: Linux
|
||||
runner: ubuntu-24.04
|
||||
- name: macOS
|
||||
runner: macos-15-xlarge
|
||||
- name: Windows
|
||||
runner: windows-x64
|
||||
runs_on:
|
||||
group: codex-runners
|
||||
labels: codex-windows-x64
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install Linux sandbox build dependencies
|
||||
if: ${{ runner.os == 'Linux' }}
|
||||
shell: bash
|
||||
run: |
|
||||
bash -n tools/argument-comment-lint/run.sh
|
||||
./tools/argument-comment-lint/run.sh
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get update
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends pkg-config libcap-dev
|
||||
- uses: dtolnay/rust-toolchain@1.93.0
|
||||
with:
|
||||
toolchain: nightly-2025-09-18
|
||||
components: llvm-tools-preview, rustc-dev, rust-src
|
||||
- uses: facebook/install-dotslash@v2
|
||||
- name: Run argument comment lint on codex-rs
|
||||
shell: bash
|
||||
run: ./tools/argument-comment-lint/run-prebuilt-linter.sh
|
||||
|
||||
# --- CI to validate on different os/targets --------------------------------
|
||||
lint_build:
|
||||
@@ -708,14 +736,15 @@ jobs:
|
||||
results:
|
||||
name: CI results (required)
|
||||
needs:
|
||||
[changed, general, cargo_shear, argument_comment_lint, lint_build, tests]
|
||||
[changed, general, cargo_shear, argument_comment_lint_package, argument_comment_lint_prebuilt, lint_build, tests]
|
||||
if: always()
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Summarize
|
||||
shell: bash
|
||||
run: |
|
||||
echo "arglint: ${{ needs.argument_comment_lint.result }}"
|
||||
echo "argpkg : ${{ needs.argument_comment_lint_package.result }}"
|
||||
echo "arglint: ${{ needs.argument_comment_lint_prebuilt.result }}"
|
||||
echo "general: ${{ needs.general.result }}"
|
||||
echo "shear : ${{ needs.cargo_shear.result }}"
|
||||
echo "lint : ${{ needs.lint_build.result }}"
|
||||
@@ -728,8 +757,12 @@ jobs:
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ '${{ needs.changed.outputs.argument_comment_lint_package }}' == 'true' || '${{ github.event_name }}' == 'push' ]]; then
|
||||
[[ '${{ needs.argument_comment_lint_package.result }}' == 'success' ]] || { echo 'argument_comment_lint_package failed'; exit 1; }
|
||||
fi
|
||||
|
||||
if [[ '${{ needs.changed.outputs.argument_comment_lint }}' == 'true' || '${{ needs.changed.outputs.workflows }}' == 'true' || '${{ github.event_name }}' == 'push' ]]; then
|
||||
[[ '${{ needs.argument_comment_lint.result }}' == 'success' ]] || { echo 'argument_comment_lint failed'; exit 1; }
|
||||
[[ '${{ needs.argument_comment_lint_prebuilt.result }}' == 'success' ]] || { echo 'argument_comment_lint_prebuilt failed'; exit 1; }
|
||||
fi
|
||||
|
||||
if [[ '${{ needs.changed.outputs.codex }}' == 'true' || '${{ needs.changed.outputs.workflows }}' == 'true' || '${{ github.event_name }}' == 'push' ]]; then
|
||||
|
||||
@@ -48,6 +48,8 @@ Run `just fmt` (in `codex-rs` directory) automatically after you have finished m
|
||||
|
||||
Before finalizing a large change to `codex-rs`, run `just fix -p <project>` (in `codex-rs` directory) to fix any linter issues in the code. Prefer scoping with `-p` to avoid slow workspace‑wide Clippy builds; only run `just fix` without `-p` if you changed shared crates. Do not re-run tests after running `fix` or `fmt`.
|
||||
|
||||
Also run `just argument-comment-lint` to ensure the codebase is clean of comment lint errors.
|
||||
|
||||
## TUI style conventions
|
||||
|
||||
See `codex-rs/tui/styles.md`.
|
||||
|
||||
@@ -251,15 +251,15 @@ async fn run_command_under_sandbox(
|
||||
&config.permissions.file_system_sandbox_policy,
|
||||
config.permissions.network_sandbox_policy,
|
||||
sandbox_policy_cwd.as_path(),
|
||||
false,
|
||||
/*enforce_managed_network*/ false,
|
||||
network.as_ref(),
|
||||
None,
|
||||
/*extensions*/ None,
|
||||
);
|
||||
let network_policy = config.permissions.network_sandbox_policy;
|
||||
spawn_debug_sandbox_child(
|
||||
PathBuf::from("/usr/bin/sandbox-exec"),
|
||||
args,
|
||||
None,
|
||||
/*arg0*/ None,
|
||||
cwd,
|
||||
network_policy,
|
||||
env,
|
||||
|
||||
6
justfile
6
justfile
@@ -30,7 +30,7 @@ fmt:
|
||||
fix *args:
|
||||
cargo clippy --fix --tests --allow-dirty "$@"
|
||||
|
||||
clippy:
|
||||
clippy *args:
|
||||
cargo clippy --tests "$@"
|
||||
|
||||
install:
|
||||
@@ -89,6 +89,10 @@ write-hooks-schema:
|
||||
# Run the argument-comment Dylint checks across codex-rs.
|
||||
[no-cd]
|
||||
argument-comment-lint *args:
|
||||
./tools/argument-comment-lint/run-prebuilt-linter.sh "$@"
|
||||
|
||||
[no-cd]
|
||||
argument-comment-lint-from-source *args:
|
||||
./tools/argument-comment-lint/run.sh "$@"
|
||||
|
||||
# Tail logs from the state SQLite database
|
||||
|
||||
@@ -73,21 +73,71 @@ GitHub releases also publish a DotSlash file named
|
||||
x64. The published package contains a small runner executable, a bundled
|
||||
`cargo-dylint`, and the prebuilt lint library.
|
||||
|
||||
Run the lint against `codex-rs` from the repo root:
|
||||
The package is not a full Rust toolchain. Running the prebuilt path still
|
||||
requires the pinned nightly toolchain to be installed via `rustup`:
|
||||
|
||||
```bash
|
||||
rustup toolchain install nightly-2025-09-18 \
|
||||
--component llvm-tools-preview \
|
||||
--component rustc-dev \
|
||||
--component rust-src
|
||||
```
|
||||
|
||||
The checked-in DotSlash file lives at `tools/argument-comment-lint/argument-comment-lint`.
|
||||
`run-prebuilt-linter.sh` resolves that file via `dotslash` and is the path used by
|
||||
`just clippy`, `just argument-comment-lint`, and the Rust CI job. The
|
||||
source-build path remains available in `run.sh` for people
|
||||
iterating on the lint crate itself.
|
||||
|
||||
The Unix archive layout is:
|
||||
|
||||
```text
|
||||
argument-comment-lint/
|
||||
bin/
|
||||
argument-comment-lint
|
||||
cargo-dylint
|
||||
lib/
|
||||
libargument_comment_lint@nightly-2025-09-18-<target>.dylib|so
|
||||
```
|
||||
|
||||
On Windows the same layout is published as a `.zip`, with `.exe` and `.dll`
|
||||
filenames instead.
|
||||
|
||||
DotSlash resolves the package entrypoint to `argument-comment-lint/bin/argument-comment-lint`
|
||||
(or `.exe` on Windows). That runner finds the sibling bundled `cargo-dylint`
|
||||
binary and the single packaged Dylint library under `lib/`, normalizes the
|
||||
host-qualified nightly filename to the plain `nightly-2025-09-18` channel when
|
||||
needed, and then invokes `cargo-dylint dylint --lib-path <that-library>` with
|
||||
the repo's default `DYLINT_RUSTFLAGS` and `CARGO_INCREMENTAL=0` settings.
|
||||
|
||||
The checked-in `run-prebuilt-linter.sh` wrapper uses the fetched package
|
||||
contents directly so the current checked-in alpha artifact works the same way.
|
||||
It also makes sure the `rustup` shims stay ahead of any direct toolchain
|
||||
`cargo` binary on `PATH`, and sets `RUSTUP_HOME` from `rustup show home` when
|
||||
the environment does not already provide it. That extra `RUSTUP_HOME` export is
|
||||
required for the current Windows Dylint driver path.
|
||||
|
||||
If you are changing the lint crate itself, use the source-build wrapper:
|
||||
|
||||
```bash
|
||||
./tools/argument-comment-lint/run.sh -p codex-core
|
||||
```
|
||||
|
||||
Run the lint against `codex-rs` from the repo root:
|
||||
|
||||
```bash
|
||||
./tools/argument-comment-lint/run-prebuilt-linter.sh -p codex-core
|
||||
just argument-comment-lint -p codex-core
|
||||
```
|
||||
|
||||
If no package selection is provided, `run.sh` defaults to checking the
|
||||
If no package selection is provided, `run-prebuilt-linter.sh` defaults to checking the
|
||||
`codex-rs` workspace with `--workspace --no-deps`.
|
||||
|
||||
Repo runs also promote `uncommented_anonymous_literal_argument` to an error by
|
||||
default:
|
||||
|
||||
```bash
|
||||
./tools/argument-comment-lint/run.sh -p codex-core
|
||||
./tools/argument-comment-lint/run-prebuilt-linter.sh -p codex-core
|
||||
```
|
||||
|
||||
The wrapper does that by setting `DYLINT_RUSTFLAGS`, and it leaves an explicit
|
||||
@@ -105,5 +155,5 @@ CARGO_INCREMENTAL=1 \
|
||||
To expand target coverage for an ad hoc run:
|
||||
|
||||
```bash
|
||||
./tools/argument-comment-lint/run.sh -p codex-core -- --all-targets
|
||||
./tools/argument-comment-lint/run-prebuilt-linter.sh -p codex-core -- --all-targets
|
||||
```
|
||||
|
||||
79
tools/argument-comment-lint/argument-comment-lint
Executable file
79
tools/argument-comment-lint/argument-comment-lint
Executable file
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env dotslash
|
||||
|
||||
{
|
||||
"name": "argument-comment-lint",
|
||||
"platforms": {
|
||||
"macos-aarch64": {
|
||||
"size": 3402747,
|
||||
"hash": "blake3",
|
||||
"digest": "a11669d2f184a2c6f226cedce1bf10d1ec478d53413c42fe80d17dd873fdb2d7",
|
||||
"format": "tar.gz",
|
||||
"path": "argument-comment-lint/bin/argument-comment-lint",
|
||||
"providers": [
|
||||
{
|
||||
"url": "https://github.com/openai/codex/releases/download/rust-v0.117.0-alpha.2/argument-comment-lint-aarch64-apple-darwin.tar.gz"
|
||||
},
|
||||
{
|
||||
"type": "github-release",
|
||||
"repo": "https://github.com/openai/codex",
|
||||
"tag": "rust-v0.117.0-alpha.2",
|
||||
"name": "argument-comment-lint-aarch64-apple-darwin.tar.gz"
|
||||
}
|
||||
]
|
||||
},
|
||||
"linux-x86_64": {
|
||||
"size": 3869711,
|
||||
"hash": "blake3",
|
||||
"digest": "1015f4ba07d57edc5ec79c8f6709ddc1516f64c903e909820437a4b89d8d853a",
|
||||
"format": "tar.gz",
|
||||
"path": "argument-comment-lint/bin/argument-comment-lint",
|
||||
"providers": [
|
||||
{
|
||||
"url": "https://github.com/openai/codex/releases/download/rust-v0.117.0-alpha.2/argument-comment-lint-x86_64-unknown-linux-gnu.tar.gz"
|
||||
},
|
||||
{
|
||||
"type": "github-release",
|
||||
"repo": "https://github.com/openai/codex",
|
||||
"tag": "rust-v0.117.0-alpha.2",
|
||||
"name": "argument-comment-lint-x86_64-unknown-linux-gnu.tar.gz"
|
||||
}
|
||||
]
|
||||
},
|
||||
"linux-aarch64": {
|
||||
"size": 3759446,
|
||||
"hash": "blake3",
|
||||
"digest": "91f2a31e6390ca728ad09ae1aa6b6f379c67d996efcc22956001df89f068af5b",
|
||||
"format": "tar.gz",
|
||||
"path": "argument-comment-lint/bin/argument-comment-lint",
|
||||
"providers": [
|
||||
{
|
||||
"url": "https://github.com/openai/codex/releases/download/rust-v0.117.0-alpha.2/argument-comment-lint-aarch64-unknown-linux-gnu.tar.gz"
|
||||
},
|
||||
{
|
||||
"type": "github-release",
|
||||
"repo": "https://github.com/openai/codex",
|
||||
"tag": "rust-v0.117.0-alpha.2",
|
||||
"name": "argument-comment-lint-aarch64-unknown-linux-gnu.tar.gz"
|
||||
}
|
||||
]
|
||||
},
|
||||
"windows-x86_64": {
|
||||
"size": 3244599,
|
||||
"hash": "blake3",
|
||||
"digest": "dc711c6d85b1cabbe52447dda3872deb20c2e64b155da8be0ecb207c7c391683",
|
||||
"format": "zip",
|
||||
"path": "argument-comment-lint/bin/argument-comment-lint.exe",
|
||||
"providers": [
|
||||
{
|
||||
"url": "https://github.com/openai/codex/releases/download/rust-v0.117.0-alpha.2/argument-comment-lint-x86_64-pc-windows-msvc.zip"
|
||||
},
|
||||
{
|
||||
"type": "github-release",
|
||||
"repo": "https://github.com/openai/codex",
|
||||
"tag": "rust-v0.117.0-alpha.2",
|
||||
"name": "argument-comment-lint-x86_64-pc-windows-msvc.zip"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
164
tools/argument-comment-lint/run-prebuilt-linter.sh
Executable file
164
tools/argument-comment-lint/run-prebuilt-linter.sh
Executable file
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
manifest_path="$repo_root/codex-rs/Cargo.toml"
|
||||
dotslash_manifest="$repo_root/tools/argument-comment-lint/argument-comment-lint"
|
||||
|
||||
has_manifest_path=false
|
||||
has_package_selection=false
|
||||
has_library_selection=false
|
||||
has_no_deps=false
|
||||
expect_value=""
|
||||
|
||||
for arg in "$@"; do
|
||||
if [[ -n "$expect_value" ]]; then
|
||||
case "$expect_value" in
|
||||
manifest_path)
|
||||
has_manifest_path=true
|
||||
;;
|
||||
package_selection)
|
||||
has_package_selection=true
|
||||
;;
|
||||
library_selection)
|
||||
has_library_selection=true
|
||||
;;
|
||||
esac
|
||||
expect_value=""
|
||||
continue
|
||||
fi
|
||||
|
||||
case "$arg" in
|
||||
--)
|
||||
break
|
||||
;;
|
||||
--manifest-path)
|
||||
expect_value="manifest_path"
|
||||
;;
|
||||
--manifest-path=*)
|
||||
has_manifest_path=true
|
||||
;;
|
||||
-p|--package)
|
||||
expect_value="package_selection"
|
||||
;;
|
||||
--package=*)
|
||||
has_package_selection=true
|
||||
;;
|
||||
--lib|--lib-path)
|
||||
expect_value="library_selection"
|
||||
;;
|
||||
--lib=*|--lib-path=*)
|
||||
has_library_selection=true
|
||||
;;
|
||||
--workspace)
|
||||
has_package_selection=true
|
||||
;;
|
||||
--no-deps)
|
||||
has_no_deps=true
|
||||
;;
|
||||
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 ! command -v dotslash >/dev/null 2>&1; then
|
||||
cat >&2 <<EOF
|
||||
argument-comment-lint prebuilt wrapper requires dotslash.
|
||||
Install dotslash, or use:
|
||||
./tools/argument-comment-lint/run.sh ...
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if command -v rustup >/dev/null 2>&1; then
|
||||
rustup_bin_dir="$(dirname "$(command -v rustup)")"
|
||||
path_entries=()
|
||||
while IFS= read -r entry; do
|
||||
[[ -n "$entry" && "$entry" != "$rustup_bin_dir" ]] && path_entries+=("$entry")
|
||||
done < <(printf '%s\n' "${PATH//:/$'\n'}")
|
||||
PATH="$rustup_bin_dir"
|
||||
if ((${#path_entries[@]} > 0)); then
|
||||
PATH+=":$(IFS=:; echo "${path_entries[*]}")"
|
||||
fi
|
||||
export PATH
|
||||
|
||||
if [[ -z "${RUSTUP_HOME:-}" ]]; then
|
||||
rustup_home="$(rustup show home 2>/dev/null || true)"
|
||||
if [[ -n "$rustup_home" ]]; then
|
||||
export RUSTUP_HOME="$rustup_home"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
package_entrypoint="$(dotslash -- fetch "$dotslash_manifest")"
|
||||
bin_dir="$(cd "$(dirname "$package_entrypoint")" && pwd)"
|
||||
package_root="$(cd "$bin_dir/.." && pwd)"
|
||||
library_dir="$package_root/lib"
|
||||
|
||||
cargo_dylint="$bin_dir/cargo-dylint"
|
||||
if [[ ! -x "$cargo_dylint" ]]; then
|
||||
cargo_dylint="$bin_dir/cargo-dylint.exe"
|
||||
fi
|
||||
if [[ ! -x "$cargo_dylint" ]]; then
|
||||
echo "bundled cargo-dylint executable not found under $bin_dir" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
shopt -s nullglob
|
||||
libraries=("$library_dir"/*@*)
|
||||
shopt -u nullglob
|
||||
if [[ ${#libraries[@]} -eq 0 ]]; then
|
||||
echo "no packaged Dylint library found in $library_dir" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ${#libraries[@]} -ne 1 ]]; then
|
||||
echo "expected exactly one packaged Dylint library in $library_dir" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
library_path="${libraries[0]}"
|
||||
library_filename="$(basename "$library_path")"
|
||||
normalized_library_path="$library_path"
|
||||
library_ext=".${library_filename##*.}"
|
||||
library_stem="${library_filename%.*}"
|
||||
if [[ "$library_stem" =~ ^(.+@nightly-[0-9]{4}-[0-9]{2}-[0-9]{2})-.+$ ]]; then
|
||||
normalized_library_filename="${BASH_REMATCH[1]}$library_ext"
|
||||
temp_dir="$(mktemp -d "${TMPDIR:-/tmp}/argument-comment-lint.XXXXXX")"
|
||||
normalized_library_path="$temp_dir/$normalized_library_filename"
|
||||
cp "$library_path" "$normalized_library_path"
|
||||
fi
|
||||
|
||||
if [[ -n "${DYLINT_RUSTFLAGS:-}" ]]; then
|
||||
if [[ "$DYLINT_RUSTFLAGS" != *"-D uncommented-anonymous-literal-argument"* ]]; then
|
||||
DYLINT_RUSTFLAGS+=" -D uncommented-anonymous-literal-argument"
|
||||
fi
|
||||
if [[ "$DYLINT_RUSTFLAGS" != *"-A unknown_lints"* ]]; then
|
||||
DYLINT_RUSTFLAGS+=" -A unknown_lints"
|
||||
fi
|
||||
else
|
||||
DYLINT_RUSTFLAGS="-D uncommented-anonymous-literal-argument -A unknown_lints"
|
||||
fi
|
||||
export DYLINT_RUSTFLAGS
|
||||
|
||||
if [[ -z "${CARGO_INCREMENTAL:-}" ]]; then
|
||||
export CARGO_INCREMENTAL=0
|
||||
fi
|
||||
|
||||
command=("$cargo_dylint" dylint --lib-path "$normalized_library_path")
|
||||
if [[ "$has_library_selection" == false ]]; then
|
||||
command+=(--all)
|
||||
fi
|
||||
command+=("${lint_args[@]}")
|
||||
|
||||
exec "${command[@]}"
|
||||
@@ -5,6 +5,7 @@ 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"
|
||||
toolchain_channel="nightly-2025-09-18"
|
||||
strict_lint="uncommented-anonymous-literal-argument"
|
||||
noise_lint="unknown_lints"
|
||||
|
||||
@@ -14,6 +15,42 @@ has_no_deps=false
|
||||
has_library_selection=false
|
||||
expect_value=""
|
||||
|
||||
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 source wrapper 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 source wrapper 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 +99,25 @@ 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+=("$@")
|
||||
|
||||
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[@]}"
|
||||
|
||||
@@ -5,6 +5,8 @@ use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::process::ExitCode;
|
||||
use std::time::SystemTime;
|
||||
use std::time::UNIX_EPOCH;
|
||||
|
||||
fn main() -> ExitCode {
|
||||
match run() {
|
||||
@@ -33,7 +35,7 @@ fn run() -> Result<ExitCode, String> {
|
||||
})?;
|
||||
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)?;
|
||||
let library_path = prepare_library_path_for_dylint(&find_bundled_library(&library_dir)?)?;
|
||||
|
||||
ensure_exists(&cargo_dylint, "bundled cargo-dylint executable")?;
|
||||
ensure_exists(
|
||||
@@ -49,7 +51,7 @@ fn run() -> Result<ExitCode, String> {
|
||||
command.arg("--all");
|
||||
}
|
||||
command.args(&args);
|
||||
set_default_env(&mut command);
|
||||
set_default_env(&mut command)?;
|
||||
|
||||
let status = command
|
||||
.status()
|
||||
@@ -80,7 +82,7 @@ fn has_library_selection(args: &[OsString]) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn set_default_env(command: &mut Command) {
|
||||
fn set_default_env(command: &mut Command) -> Result<(), String> {
|
||||
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");
|
||||
@@ -96,6 +98,14 @@ fn set_default_env(command: &mut Command) {
|
||||
if env::var_os("CARGO_INCREMENTAL").is_none() {
|
||||
command.env("CARGO_INCREMENTAL", "0");
|
||||
}
|
||||
|
||||
if env::var_os("RUSTUP_HOME").is_none()
|
||||
&& let Some(rustup_home) = infer_rustup_home()?
|
||||
{
|
||||
command.env("RUSTUP_HOME", rustup_home);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn append_flag_if_missing(flags: &mut String, flag: &str) {
|
||||
@@ -117,6 +127,28 @@ fn cargo_dylint_binary_name() -> &'static str {
|
||||
}
|
||||
}
|
||||
|
||||
fn infer_rustup_home() -> Result<Option<OsString>, String> {
|
||||
let output = Command::new("rustup")
|
||||
.args(["show", "home"])
|
||||
.output()
|
||||
.map_err(|err| format!("failed to query rustup home via `rustup show home`: {err}"))?;
|
||||
if !output.status.success() {
|
||||
return Err(format!(
|
||||
"`rustup show home` failed: {}",
|
||||
String::from_utf8_lossy(&output.stderr).trim()
|
||||
));
|
||||
}
|
||||
|
||||
let home = String::from_utf8(output.stdout)
|
||||
.map_err(|err| format!("`rustup show home` returned invalid UTF-8: {err}"))?;
|
||||
let home = home.trim();
|
||||
if home.is_empty() {
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(OsString::from(home)))
|
||||
}
|
||||
}
|
||||
|
||||
fn ensure_exists(path: &Path, label: &str) -> Result<(), String> {
|
||||
if path.exists() {
|
||||
Ok(())
|
||||
@@ -158,7 +190,90 @@ fn find_bundled_library(library_dir: &Path) -> Result<PathBuf, String> {
|
||||
Ok(first)
|
||||
}
|
||||
|
||||
fn prepare_library_path_for_dylint(library_path: &Path) -> Result<PathBuf, String> {
|
||||
let Some(normalized_filename) = normalize_nightly_library_filename(library_path) else {
|
||||
return Ok(library_path.to_path_buf());
|
||||
};
|
||||
|
||||
let temp_dir = env::temp_dir().join(format!(
|
||||
"argument-comment-lint-{}-{}",
|
||||
std::process::id(),
|
||||
SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.map_err(|err| format!("failed to compute timestamp for temp dir: {err}"))?
|
||||
.as_nanos()
|
||||
));
|
||||
fs::create_dir_all(&temp_dir).map_err(|err| {
|
||||
format!(
|
||||
"failed to create temporary directory {}: {err}",
|
||||
temp_dir.display()
|
||||
)
|
||||
})?;
|
||||
let normalized_path = temp_dir.join(normalized_filename);
|
||||
fs::copy(library_path, &normalized_path).map_err(|err| {
|
||||
format!(
|
||||
"failed to copy packaged library {} to {}: {err}",
|
||||
library_path.display(),
|
||||
normalized_path.display()
|
||||
)
|
||||
})?;
|
||||
Ok(normalized_path)
|
||||
}
|
||||
|
||||
fn normalize_nightly_library_filename(library_path: &Path) -> Option<String> {
|
||||
let stem = library_path.file_stem()?.to_string_lossy();
|
||||
let extension = library_path.extension()?.to_string_lossy();
|
||||
let (lib_name, toolchain) = stem.rsplit_once('@')?;
|
||||
let normalized_toolchain = normalize_nightly_toolchain(toolchain)?;
|
||||
Some(format!("{lib_name}@{normalized_toolchain}.{extension}"))
|
||||
}
|
||||
|
||||
fn normalize_nightly_toolchain(toolchain: &str) -> Option<String> {
|
||||
let parts: Vec<_> = toolchain.split('-').collect();
|
||||
if parts.len() > 4
|
||||
&& parts[0] == "nightly"
|
||||
&& parts[1].len() == 4
|
||||
&& parts[2].len() == 2
|
||||
&& parts[3].len() == 2
|
||||
&& parts[1..4]
|
||||
.iter()
|
||||
.all(|part| part.chars().all(|ch| ch.is_ascii_digit()))
|
||||
{
|
||||
Some(format!("nightly-{}-{}-{}", parts[1], parts[2], parts[3]))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::normalize_nightly_library_filename;
|
||||
use std::path::Path;
|
||||
|
||||
#[test]
|
||||
fn strips_host_triple_from_nightly_filename() {
|
||||
assert_eq!(
|
||||
normalize_nightly_library_filename(Path::new(
|
||||
"libargument_comment_lint@nightly-2025-09-18-aarch64-apple-darwin.dylib"
|
||||
)),
|
||||
Some(String::from(
|
||||
"libargument_comment_lint@nightly-2025-09-18.dylib"
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn leaves_unqualified_nightly_filename_alone() {
|
||||
assert_eq!(
|
||||
normalize_nightly_library_filename(Path::new(
|
||||
"libargument_comment_lint@nightly-2025-09-18.dylib"
|
||||
)),
|
||||
None
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user