diff --git a/crates/ruff/src/rules/flake8_executable/rules/shebang_missing.rs b/crates/ruff/src/rules/flake8_executable/rules/shebang_missing.rs index ea33e57d0c..7cf9daed31 100644 --- a/crates/ruff/src/rules/flake8_executable/rules/shebang_missing.rs +++ b/crates/ruff/src/rules/flake8_executable/rules/shebang_missing.rs @@ -11,6 +11,24 @@ use crate::registry::AsRule; #[cfg(target_family = "unix")] use crate::rules::flake8_executable::helpers::is_executable; +/// ## What it does +/// Checks for executable `.py` files that do not have a shebang. +/// +/// ## Why is this bad? +/// In Python, a shebang (also known as a hashbang) is the first line of a +/// script, which specifies the interpreter that should be used to run the +/// script. +/// +/// If a `.py` file is executable, but does not have a shebang, it may be run +/// with the wrong interpreter, or fail to run at all. +/// +/// If the file is meant to be executable, add a shebang; otherwise, remove the +/// executable bit from the file. +/// +/// _This rule is only available on Unix-like systems._ +/// +/// ## References +/// - [Python documentation: Executable Python Scripts](https://docs.python.org/3/tutorial/appendix.html#executable-python-scripts) #[violation] pub struct ShebangMissingExecutableFile; diff --git a/crates/ruff/src/rules/flake8_executable/rules/shebang_newline.rs b/crates/ruff/src/rules/flake8_executable/rules/shebang_newline.rs index 9c605ba940..322c68be19 100644 --- a/crates/ruff/src/rules/flake8_executable/rules/shebang_newline.rs +++ b/crates/ruff/src/rules/flake8_executable/rules/shebang_newline.rs @@ -5,6 +5,32 @@ use ruff_macros::{derive_message_formats, violation}; use crate::rules::flake8_executable::helpers::ShebangDirective; +/// ## What it does +/// Checks for a shebang directive that is not at the beginning of the file. +/// +/// ## Why is this bad? +/// In Python, a shebang (also known as a hashbang) is the first line of a +/// script, which specifies the interpreter that should be used to run the +/// script. +/// +/// The shebang's `#!` prefix must be the first two characters of a file. If +/// the shebang is not at the beginning of the file, it will be ignored, which +/// is likely a mistake. +/// +/// ## Example +/// ```python +/// foo = 1 +/// #!/usr/bin/env python3 +/// ``` +/// +/// Use instead: +/// ```python +/// #!/usr/bin/env python3 +/// foo = 1 +/// ``` +/// +/// ## References +/// - [Python documentation: Executable Python Scripts](https://docs.python.org/3/tutorial/appendix.html#executable-python-scripts) #[violation] pub struct ShebangNotFirstLine; diff --git a/crates/ruff/src/rules/flake8_executable/rules/shebang_not_executable.rs b/crates/ruff/src/rules/flake8_executable/rules/shebang_not_executable.rs index 6cfcc13887..20c542d0d4 100644 --- a/crates/ruff/src/rules/flake8_executable/rules/shebang_not_executable.rs +++ b/crates/ruff/src/rules/flake8_executable/rules/shebang_not_executable.rs @@ -12,6 +12,25 @@ use crate::registry::AsRule; use crate::rules::flake8_executable::helpers::is_executable; use crate::rules::flake8_executable::helpers::ShebangDirective; +/// ## What it does +/// Checks for a shebang directive in a file that is not executable. +/// +/// ## Why is this bad? +/// In Python, a shebang (also known as a hashbang) is the first line of a +/// script, which specifies the interpreter that should be used to run the +/// script. +/// +/// The presence of a shebang suggests that a file is intended to be +/// executable. If a file contains a shebang but is not executable, then the +/// shebang is misleading, or the file is missing the executable bit. +/// +/// If the file is meant to be executable, add a shebang; otherwise, remove the +/// executable bit from the file. +/// +/// _This rule is only available on Unix-like systems._ +/// +/// ## References +/// - [Python documentation: Executable Python Scripts](https://docs.python.org/3/tutorial/appendix.html#executable-python-scripts) #[violation] pub struct ShebangNotExecutable; diff --git a/crates/ruff/src/rules/flake8_executable/rules/shebang_python.rs b/crates/ruff/src/rules/flake8_executable/rules/shebang_python.rs index 73f3d1f333..b68eb42be9 100644 --- a/crates/ruff/src/rules/flake8_executable/rules/shebang_python.rs +++ b/crates/ruff/src/rules/flake8_executable/rules/shebang_python.rs @@ -5,6 +5,31 @@ use ruff_macros::{derive_message_formats, violation}; use crate::rules::flake8_executable::helpers::ShebangDirective; +/// ## What it does +/// Checks for a shebang directive in `.py` files that does not contain `python`. +/// +/// ## Why is this bad? +/// In Python, a shebang (also known as a hashbang) is the first line of a +/// script, which specifies the interpreter that should be used to run the +/// script. +/// +/// For Python scripts, the shebang must contain `python` to indicate that the +/// script should be executed as a Python script. If the shebang does not +/// contain `python`, then the file will be executed with the default +/// interpreter, which is likely a mistake. +/// +/// ## Example +/// ```python +/// #!/usr/bin/env bash +/// ``` +/// +/// Use instead: +/// ```python +/// #!/usr/bin/env python3 +/// ``` +/// +/// ## References +/// - [Python documentation: Executable Python Scripts](https://docs.python.org/3/tutorial/appendix.html#executable-python-scripts) #[violation] pub struct ShebangMissingPython; diff --git a/crates/ruff/src/rules/flake8_executable/rules/shebang_whitespace.rs b/crates/ruff/src/rules/flake8_executable/rules/shebang_whitespace.rs index 0458d61432..f731033924 100644 --- a/crates/ruff/src/rules/flake8_executable/rules/shebang_whitespace.rs +++ b/crates/ruff/src/rules/flake8_executable/rules/shebang_whitespace.rs @@ -5,6 +5,30 @@ use ruff_macros::{derive_message_formats, violation}; use crate::rules::flake8_executable::helpers::ShebangDirective; +/// ## What it does +/// Checks for whitespace before a shebang directive. +/// +/// ## Why is this bad? +/// In Python, a shebang (also known as a hashbang) is the first line of a +/// script, which specifies the interpreter that should be used to run the +/// script. +/// +/// The shebang's `#!` prefix must be the first two characters of a file. The +/// presence of whitespace before the shebang will cause the shebang to be +/// ignored, which is likely a mistake. +/// +/// ## Example +/// ```python +/// #!/usr/bin/env python3 +/// ``` +/// +/// Use instead: +/// ```python +/// #!/usr/bin/env python3 +/// ``` +/// +/// ## References +/// - [Python documentation: Executable Python Scripts](https://docs.python.org/3/tutorial/appendix.html#executable-python-scripts) #[violation] pub struct ShebangLeadingWhitespace; diff --git a/scripts/check_docs_formatted.py b/scripts/check_docs_formatted.py index 81752ac742..ef5ec4fc08 100755 --- a/scripts/check_docs_formatted.py +++ b/scripts/check_docs_formatted.py @@ -44,6 +44,7 @@ KNOWN_FORMATTING_VIOLATIONS = [ "no-space-after-inline-comment", "over-indented", "prohibited-trailing-comma", + "shebang-leading-whitespace", "too-few-spaces-before-inline-comment", "trailing-comma-on-bare-tuple", "unexpected-indentation-comment",