Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions .github/workflows/_lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ on:
runs-on:
required: true
type: string
run-dylint:
required: false
type: boolean
default: false

jobs:
lint:
Expand Down Expand Up @@ -77,7 +81,7 @@ jobs:
# Native dylint caching: caches cargo-dylint/dylint-link binaries and
# the dylint driver dir, exposing dylint-cache-hit so we can skip the
# expensive cargo installs below (#170).
dylint-cache: true
dylint-cache: ${{ inputs.run-dylint }}
dylint-toolchain: nightly-2026-05-28
cargo-dylint-version: "6.0.3"
dylint-link-version: "6.0.3"
Expand All @@ -86,10 +90,15 @@ jobs:
run: uv sync --group dev

- name: Prepare published Dylint tools
if: inputs.run-dylint
run: env -u RUSTUP_TOOLCHAIN soldr dylint prepare

- name: Lint
- name: Lint with Dylint
if: inputs.run-dylint
run: ./lint
- name: Lint without Dylint
if: ${{ !inputs.run-dylint }}
run: ./lint --skip-dylint

- name: Upload failure logs
if: failure()
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/linux-x86-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ jobs:
with:
source-sha: ${{ github.event_name == 'workflow_dispatch' && inputs.candidate_sha || github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
runs-on: ubuntu-24.04
run-dylint: true
20 changes: 14 additions & 6 deletions lint
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ set -e

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"

if [[ $# -gt 1 || ($# -eq 1 && "$1" != "--skip-dylint") ]]; then
echo "Usage: ./lint [--skip-dylint]" >&2
exit 2
fi
SKIP_DYLINT=${1:-}

LINT_PATHS=(src tests ci)

# Python stages run first: they need no Rust toolchain, so a host without
Expand All @@ -29,13 +35,15 @@ soldr cargo fmt --all --check
echo Running cargo clippy
soldr cargo clippy --workspace --all-targets -- -D warnings

echo Running ban_std_pathbuf dylint
export SOLDR_FORCE_MANAGED_CARGO_SUBCOMMANDS=1
if ! env -u RUSTUP_TOOLCHAIN soldr dylint prepare; then
echo "Error: dylint prerequisites are missing: soldr dylint prepare failed" >&2
exit 1
if [[ "$SKIP_DYLINT" != "--skip-dylint" ]]; then
echo Running ban_std_pathbuf dylint
export SOLDR_FORCE_MANAGED_CARGO_SUBCOMMANDS=1
if ! env -u RUSTUP_TOOLCHAIN soldr dylint prepare; then
echo "Error: dylint prerequisites are missing: soldr dylint prepare failed" >&2
exit 1
fi
env -u RUSTUP_TOOLCHAIN soldr dylint --all -- --workspace --all-targets
fi
env -u RUSTUP_TOOLCHAIN soldr dylint --all -- --workspace --all-targets

echo Linting complete!
exit 0
21 changes: 18 additions & 3 deletions tests/unit/test_lint_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def _path_entry_has_dylint_or_rustup(entry: str) -> bool:


def _run_lint(
tmp_path: Path, *, ci: bool
tmp_path: Path, *, ci: bool, args: tuple[str, ...] = ()
) -> tuple[subprocess.CompletedProcess[str], list[str]]:
bin_dir = tmp_path / "bin"
bin_dir.mkdir()
Expand Down Expand Up @@ -58,7 +58,7 @@ def _run_lint(
env.pop("CI", None)

result = subprocess.run(
["bash", str(REPO_ROOT / "lint")],
["bash", str(REPO_ROOT / "lint"), *args],
cwd=REPO_ROOT,
env=env,
capture_output=True,
Expand Down Expand Up @@ -120,6 +120,13 @@ def test_missing_dylint_is_a_hard_failure_in_ci(tmp_path: Path) -> None:
assert _log_has_match(log_lines, r"^uv (run )?pyright src tests ci$")


def test_explicit_skip_keeps_other_lints_but_does_not_run_dylint(tmp_path: Path) -> None:
result, log_lines = _run_lint(tmp_path, ci=True, args=("--skip-dylint",))
assert result.returncode == 0
assert any(line.startswith("soldr cargo clippy") for line in log_lines)
assert not any("dylint" in line for line in log_lines)


def test_python_stages_precede_the_rust_stages(tmp_path: Path) -> None:
_result, log_lines = _run_lint(tmp_path, ci=False)

Expand All @@ -144,10 +151,18 @@ def test_python_stages_precede_the_rust_stages(tmp_path: Path) -> None:
"windows-x86-lint.yml",
],
)
def test_native_dylint_runs_on_unlabelled_pr(workflow: str) -> None:
def test_native_lint_without_dylint_runs_on_unlabelled_pr(workflow: str) -> None:
source = (REPO_ROOT / ".github" / "workflows" / workflow).read_text(
encoding="utf-8"
)
assert "pull_request:" in source
assert "uses: ./.github/workflows/_lint.yml" in source
assert "run-dylint: true" not in source
assert "contains(github.event.pull_request.labels.*.name, 'ci-full')" not in source


def test_only_linux_x86_runs_unified_dylint() -> None:
source = (REPO_ROOT / ".github" / "workflows" / "linux-x86-lint.yml").read_text(
encoding="utf-8"
)
assert "run-dylint: true" in source
Loading