diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_executable/EXE003_uv_tool.py b/crates/ruff_linter/resources/test/fixtures/flake8_executable/EXE003_uv_tool.py new file mode 100755 index 0000000000..29fb1f5013 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_executable/EXE003_uv_tool.py @@ -0,0 +1,2 @@ +#!/usr/bin/env -S uv tool run ruff check --isolated --select EXE003 +print("hello world") diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_executable/EXE003_uvx.py b/crates/ruff_linter/resources/test/fixtures/flake8_executable/EXE003_uvx.py new file mode 100755 index 0000000000..2dbc2147bf --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_executable/EXE003_uvx.py @@ -0,0 +1,2 @@ +#!/usr/bin/env -S uvx ruff check --isolated --select EXE003 +print("hello world") diff --git a/crates/ruff_linter/src/rules/flake8_executable/mod.rs b/crates/ruff_linter/src/rules/flake8_executable/mod.rs index b54975e538..0e5c2d07af 100644 --- a/crates/ruff_linter/src/rules/flake8_executable/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_executable/mod.rs @@ -22,6 +22,8 @@ mod tests { #[test_case(Path::new("EXE002_3.py"))] #[test_case(Path::new("EXE003.py"))] #[test_case(Path::new("EXE003_uv.py"))] + #[test_case(Path::new("EXE003_uv_tool.py"))] + #[test_case(Path::new("EXE003_uvx.py"))] #[test_case(Path::new("EXE004_1.py"))] #[test_case(Path::new("EXE004_2.py"))] #[test_case(Path::new("EXE004_3.py"))] diff --git a/crates/ruff_linter/src/rules/flake8_executable/rules/shebang_missing_python.rs b/crates/ruff_linter/src/rules/flake8_executable/rules/shebang_missing_python.rs index 3c8fecbd7a..13d6b13158 100644 --- a/crates/ruff_linter/src/rules/flake8_executable/rules/shebang_missing_python.rs +++ b/crates/ruff_linter/src/rules/flake8_executable/rules/shebang_missing_python.rs @@ -47,7 +47,12 @@ pub(crate) fn shebang_missing_python( shebang: &ShebangDirective, context: &LintContext, ) { - if shebang.contains("python") || shebang.contains("pytest") || shebang.contains("uv run") { + if shebang.contains("python") + || shebang.contains("pytest") + || shebang.contains("uv run") + || shebang.contains("uvx") + || shebang.contains("uv tool run") + { return; } diff --git a/crates/ruff_linter/src/rules/flake8_executable/snapshots/ruff_linter__rules__flake8_executable__tests__EXE003_uv_tool.py.snap b/crates/ruff_linter/src/rules/flake8_executable/snapshots/ruff_linter__rules__flake8_executable__tests__EXE003_uv_tool.py.snap new file mode 100644 index 0000000000..26e075ae3e --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_executable/snapshots/ruff_linter__rules__flake8_executable__tests__EXE003_uv_tool.py.snap @@ -0,0 +1,4 @@ +--- +source: crates/ruff_linter/src/rules/flake8_executable/mod.rs +--- + diff --git a/crates/ruff_linter/src/rules/flake8_executable/snapshots/ruff_linter__rules__flake8_executable__tests__EXE003_uvx.py.snap b/crates/ruff_linter/src/rules/flake8_executable/snapshots/ruff_linter__rules__flake8_executable__tests__EXE003_uvx.py.snap new file mode 100644 index 0000000000..26e075ae3e --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_executable/snapshots/ruff_linter__rules__flake8_executable__tests__EXE003_uvx.py.snap @@ -0,0 +1,4 @@ +--- +source: crates/ruff_linter/src/rules/flake8_executable/mod.rs +--- +