mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-27 04:19:18 +00:00
Automatically linkify option references in rule documentation
Previously the rule documentation referenced configuration options via full https:// URLs, which was bad for several reasons: * changing the website would mean you'd have to change all URLs * the links didn't work when building mkdocs locally * the URLs showed up in the `ruff rule` output * broken references weren't detected by our CI This commit solves all of these problems by post-processing the Markdown, recognizing sections such as: ## Options * `flake8-tidy-imports.ban-relative-imports` `cargo dev generate-all` will automatically linkify such references and panic if the referenced option doesn't exist. Note that the option can also be linked in the other Markdown sections via e.g. [`flake8-tidy-imports.ban-relative-imports`] since the post-processing code generates a CommonMark link definition. Resolves #2766.
This commit is contained in:
parent
fc4c927788
commit
28c9263722
13 changed files with 122 additions and 41 deletions
|
@ -24,10 +24,9 @@ define_violation!(
|
||||||
/// `__init__.py` file is typically meant to be a regular package, and
|
/// `__init__.py` file is typically meant to be a regular package, and
|
||||||
/// the absence of the `__init__.py` file is probably an oversight.
|
/// the absence of the `__init__.py` file is probably an oversight.
|
||||||
///
|
///
|
||||||
/// Note that namespace packages can be specified via the
|
/// ## Options
|
||||||
/// [`namespace-packages`](https://github.com/charliermarsh/ruff#namespace-packages)
|
///
|
||||||
/// configuration option. Adding a namespace package to the configuration
|
/// * `namespace-packages`
|
||||||
/// will suppress this violation for a given package.
|
|
||||||
pub struct ImplicitNamespacePackage {
|
pub struct ImplicitNamespacePackage {
|
||||||
pub filename: String,
|
pub filename: String,
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,13 +14,16 @@ use crate::violation::AlwaysAutofixableViolation;
|
||||||
define_violation!(
|
define_violation!(
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
/// Checks for inline strings that use single quotes or double quotes,
|
/// Checks for inline strings that use single quotes or double quotes,
|
||||||
/// depending on the value of the [`inline-quotes`](https://github.com/charliermarsh/ruff#inline-quotes)
|
/// depending on the value of the [`flake8-quotes.inline-quotes`] option.
|
||||||
/// setting.
|
|
||||||
///
|
///
|
||||||
/// ## Why is this bad?
|
/// ## Why is this bad?
|
||||||
/// Consistency is good. Use either single or double quotes for inline
|
/// Consistency is good. Use either single or double quotes for inline
|
||||||
/// strings, but be consistent.
|
/// strings, but be consistent.
|
||||||
///
|
///
|
||||||
|
/// ## Options
|
||||||
|
///
|
||||||
|
/// * `flake8-quotes.inline-quotes`
|
||||||
|
///
|
||||||
/// ## Example
|
/// ## Example
|
||||||
/// ```python
|
/// ```python
|
||||||
/// foo = 'bar'
|
/// foo = 'bar'
|
||||||
|
@ -56,13 +59,17 @@ impl AlwaysAutofixableViolation for BadQuotesInlineString {
|
||||||
define_violation!(
|
define_violation!(
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
/// Checks for multiline strings that use single quotes or double quotes,
|
/// Checks for multiline strings that use single quotes or double quotes,
|
||||||
/// depending on the value of the [`multiline-quotes`](https://github.com/charliermarsh/ruff#multiline-quotes)
|
/// depending on the value of the [`flake8-quotes.multiline-quotes`]
|
||||||
/// setting.
|
/// setting.
|
||||||
///
|
///
|
||||||
/// ## Why is this bad?
|
/// ## Why is this bad?
|
||||||
/// Consistency is good. Use either single or double quotes for multiline
|
/// Consistency is good. Use either single or double quotes for multiline
|
||||||
/// strings, but be consistent.
|
/// strings, but be consistent.
|
||||||
///
|
///
|
||||||
|
/// ## Options
|
||||||
|
///
|
||||||
|
/// * `flake8-quotes.multiline-quotes`
|
||||||
|
///
|
||||||
/// ## Example
|
/// ## Example
|
||||||
/// ```python
|
/// ```python
|
||||||
/// foo = '''
|
/// foo = '''
|
||||||
|
@ -101,13 +108,17 @@ impl AlwaysAutofixableViolation for BadQuotesMultilineString {
|
||||||
|
|
||||||
define_violation!(
|
define_violation!(
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
/// Checks for docstrings that use single quotes or double quotes, depending on the value of the [`docstring-quotes`](https://github.com/charliermarsh/ruff#docstring-quotes)
|
/// Checks for docstrings that use single quotes or double quotes, depending
|
||||||
/// setting.
|
/// on the value of the [`flake8-quotes.docstring-quotes`] setting.
|
||||||
///
|
///
|
||||||
/// ## Why is this bad?
|
/// ## Why is this bad?
|
||||||
/// Consistency is good. Use either single or double quotes for docstring
|
/// Consistency is good. Use either single or double quotes for docstring
|
||||||
/// strings, but be consistent.
|
/// strings, but be consistent.
|
||||||
///
|
///
|
||||||
|
/// ## Options
|
||||||
|
///
|
||||||
|
/// * `flake8-quotes.docstring-quotes`
|
||||||
|
///
|
||||||
/// ## Example
|
/// ## Example
|
||||||
/// ```python
|
/// ```python
|
||||||
/// '''
|
/// '''
|
||||||
|
|
|
@ -48,11 +48,9 @@ define_violation!(
|
||||||
/// > from .sibling import example
|
/// > from .sibling import example
|
||||||
/// > ```
|
/// > ```
|
||||||
///
|
///
|
||||||
/// Note that degree of strictness packages can be specified via the
|
/// ## Options
|
||||||
/// [`ban-relative-imports`](https://github.com/charliermarsh/ruff#ban-relative-imports)
|
///
|
||||||
/// configuration option, which allows banning all relative imports
|
/// * `flake8-tidy-imports.ban-relative-imports`
|
||||||
/// (`ban-relative-imports = "all"`) or only those that extend into the parent module or beyond
|
|
||||||
/// (`ban-relative-imports = "parents"`, the default).
|
|
||||||
///
|
///
|
||||||
/// ## Example
|
/// ## Example
|
||||||
/// ```python
|
/// ```python
|
||||||
|
|
|
@ -18,6 +18,10 @@ define_violation!(
|
||||||
/// ## Why is this bad?
|
/// ## Why is this bad?
|
||||||
/// Functions with a high complexity are hard to understand and maintain.
|
/// Functions with a high complexity are hard to understand and maintain.
|
||||||
///
|
///
|
||||||
|
/// ## Options
|
||||||
|
///
|
||||||
|
/// * `mccabe.max-complexity`
|
||||||
|
///
|
||||||
/// ## Example
|
/// ## Example
|
||||||
/// ```python
|
/// ```python
|
||||||
/// def foo(a, b, c):
|
/// def foo(a, b, c):
|
||||||
|
|
|
@ -23,9 +23,13 @@ define_violation!(
|
||||||
/// A variable that is defined but not used is likely a mistake, and should be
|
/// A variable that is defined but not used is likely a mistake, and should be
|
||||||
/// removed to avoid confusion.
|
/// removed to avoid confusion.
|
||||||
///
|
///
|
||||||
/// If a variable is intentionally defined-but-not-used, it should be prefixed
|
/// If a variable is intentionally defined-but-not-used, it should be
|
||||||
/// with an underscore, or some other value that adheres to the
|
/// prefixed with an underscore, or some other value that adheres to the
|
||||||
/// [`dummy-variable-rgx`](https://github.com/charliermarsh/ruff#dummy-variable-rgx) pattern.
|
/// [`dummy-variable-rgx`] pattern.
|
||||||
|
///
|
||||||
|
/// ## Options
|
||||||
|
///
|
||||||
|
/// * `dummy-variable-rgx`
|
||||||
///
|
///
|
||||||
/// ## Example
|
/// ## Example
|
||||||
/// ```python
|
/// ```python
|
||||||
|
|
|
@ -5,6 +5,8 @@ use std::fs;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use ruff::registry::{Linter, Rule, RuleNamespace};
|
use ruff::registry::{Linter, Rule, RuleNamespace};
|
||||||
|
use ruff::settings::options::Options;
|
||||||
|
use ruff::settings::options_base::ConfigurationOptions;
|
||||||
use ruff::AutofixAvailability;
|
use ruff::AutofixAvailability;
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
|
@ -37,7 +39,7 @@ pub fn main(args: &Args) -> Result<()> {
|
||||||
output.push('\n');
|
output.push('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
output.push_str(explanation.trim());
|
process_documentation(explanation.trim(), &mut output);
|
||||||
|
|
||||||
if args.dry_run {
|
if args.dry_run {
|
||||||
println!("{output}");
|
println!("{output}");
|
||||||
|
@ -49,3 +51,35 @@ pub fn main(args: &Args) -> Result<()> {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn process_documentation(documentation: &str, out: &mut String) {
|
||||||
|
let mut in_options = false;
|
||||||
|
let mut after = String::new();
|
||||||
|
|
||||||
|
for line in documentation.split_inclusive('\n') {
|
||||||
|
if line.starts_with("## ") {
|
||||||
|
in_options = line == "## Options\n";
|
||||||
|
} else if in_options {
|
||||||
|
if let Some(rest) = line.strip_prefix("* `") {
|
||||||
|
let option = rest.trim_end().trim_end_matches('`');
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
Options::get(Some(option)).is_some(),
|
||||||
|
"unknown option {option}"
|
||||||
|
);
|
||||||
|
|
||||||
|
let anchor = option.rsplit('.').next().unwrap();
|
||||||
|
out.push_str(&format!("* [`{option}`]\n"));
|
||||||
|
after.push_str(&format!("[`{option}`]: ../../settings#{anchor}"));
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.push_str(line);
|
||||||
|
}
|
||||||
|
if !after.is_empty() {
|
||||||
|
out.push_str("\n\n");
|
||||||
|
out.push_str(&after);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,13 +5,17 @@ Derived from the **flake8-quotes** linter.
|
||||||
Autofix is always available.
|
Autofix is always available.
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
Checks for docstrings that use single quotes or double quotes, depending on the value of the [`docstring-quotes`](https://github.com/charliermarsh/ruff#docstring-quotes)
|
Checks for docstrings that use single quotes or double quotes, depending
|
||||||
setting.
|
on the value of the [`flake8-quotes.docstring-quotes`] setting.
|
||||||
|
|
||||||
## Why is this bad?
|
## Why is this bad?
|
||||||
Consistency is good. Use either single or double quotes for docstring
|
Consistency is good. Use either single or double quotes for docstring
|
||||||
strings, but be consistent.
|
strings, but be consistent.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* [`flake8-quotes.docstring-quotes`]
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
```python
|
```python
|
||||||
'''
|
'''
|
||||||
|
@ -25,3 +29,5 @@ Assuming `docstring-quotes` is set to `double`, use instead:
|
||||||
bar
|
bar
|
||||||
"""
|
"""
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[`flake8-quotes.docstring-quotes`]: ../../settings#docstring-quotes
|
|
@ -6,13 +6,16 @@ Autofix is always available.
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
Checks for inline strings that use single quotes or double quotes,
|
Checks for inline strings that use single quotes or double quotes,
|
||||||
depending on the value of the [`inline-quotes`](https://github.com/charliermarsh/ruff#inline-quotes)
|
depending on the value of the [`flake8-quotes.inline-quotes`] option.
|
||||||
setting.
|
|
||||||
|
|
||||||
## Why is this bad?
|
## Why is this bad?
|
||||||
Consistency is good. Use either single or double quotes for inline
|
Consistency is good. Use either single or double quotes for inline
|
||||||
strings, but be consistent.
|
strings, but be consistent.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* [`flake8-quotes.inline-quotes`]
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
```python
|
```python
|
||||||
foo = 'bar'
|
foo = 'bar'
|
||||||
|
@ -22,3 +25,5 @@ Assuming `inline-quotes` is set to `double`, use instead:
|
||||||
```python
|
```python
|
||||||
foo = "bar"
|
foo = "bar"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[`flake8-quotes.inline-quotes`]: ../../settings#inline-quotes
|
|
@ -6,13 +6,17 @@ Autofix is always available.
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
Checks for multiline strings that use single quotes or double quotes,
|
Checks for multiline strings that use single quotes or double quotes,
|
||||||
depending on the value of the [`multiline-quotes`](https://github.com/charliermarsh/ruff#multiline-quotes)
|
depending on the value of the [`flake8-quotes.multiline-quotes`]
|
||||||
setting.
|
setting.
|
||||||
|
|
||||||
## Why is this bad?
|
## Why is this bad?
|
||||||
Consistency is good. Use either single or double quotes for multiline
|
Consistency is good. Use either single or double quotes for multiline
|
||||||
strings, but be consistent.
|
strings, but be consistent.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* [`flake8-quotes.multiline-quotes`]
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
```python
|
```python
|
||||||
foo = '''
|
foo = '''
|
||||||
|
@ -26,3 +30,5 @@ foo = """
|
||||||
bar
|
bar
|
||||||
"""
|
"""
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[`flake8-quotes.multiline-quotes`]: ../../settings#multiline-quotes
|
|
@ -13,6 +13,10 @@ the code where the program has a choice of two or more paths to follow.
|
||||||
## Why is this bad?
|
## Why is this bad?
|
||||||
Functions with a high complexity are hard to understand and maintain.
|
Functions with a high complexity are hard to understand and maintain.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* [`mccabe.max-complexity`]
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
```python
|
```python
|
||||||
def foo(a, b, c):
|
def foo(a, b, c):
|
||||||
|
@ -39,3 +43,5 @@ def foo(a, b, c):
|
||||||
return 2
|
return 2
|
||||||
return 1
|
return 1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[`mccabe.max-complexity`]: ../../settings#max-complexity
|
|
@ -18,7 +18,9 @@ Namespace packages are less widely used, so a package that lacks an
|
||||||
`__init__.py` file is typically meant to be a regular package, and
|
`__init__.py` file is typically meant to be a regular package, and
|
||||||
the absence of the `__init__.py` file is probably an oversight.
|
the absence of the `__init__.py` file is probably an oversight.
|
||||||
|
|
||||||
Note that namespace packages can be specified via the
|
## Options
|
||||||
[`namespace-packages`](https://github.com/charliermarsh/ruff#namespace-packages)
|
|
||||||
configuration option. Adding a namespace package to the configuration
|
* [`namespace-packages`]
|
||||||
will suppress this violation for a given package.
|
|
||||||
|
|
||||||
|
[`namespace-packages`]: ../../settings#namespace-packages
|
|
@ -24,11 +24,9 @@ Absolute imports, or relative imports from siblings, are recommended by [PEP 8](
|
||||||
> from .sibling import example
|
> from .sibling import example
|
||||||
> ```
|
> ```
|
||||||
|
|
||||||
Note that degree of strictness packages can be specified via the
|
## Options
|
||||||
[`ban-relative-imports`](https://github.com/charliermarsh/ruff#ban-relative-imports)
|
|
||||||
configuration option, which allows banning all relative imports
|
* [`flake8-tidy-imports.ban-relative-imports`]
|
||||||
(`ban-relative-imports = "all"`) or only those that extend into the parent module or beyond
|
|
||||||
(`ban-relative-imports = "parents"`, the default).
|
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
```python
|
```python
|
||||||
|
@ -39,3 +37,5 @@ Use instead:
|
||||||
```python
|
```python
|
||||||
from mypkg import foo
|
from mypkg import foo
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[`flake8-tidy-imports.ban-relative-imports`]: ../../settings#ban-relative-imports
|
|
@ -11,9 +11,13 @@ Checks for the presence of unused variables in function scopes.
|
||||||
A variable that is defined but not used is likely a mistake, and should be
|
A variable that is defined but not used is likely a mistake, and should be
|
||||||
removed to avoid confusion.
|
removed to avoid confusion.
|
||||||
|
|
||||||
If a variable is intentionally defined-but-not-used, it should be prefixed
|
If a variable is intentionally defined-but-not-used, it should be
|
||||||
with an underscore, or some other value that adheres to the
|
prefixed with an underscore, or some other value that adheres to the
|
||||||
[`dummy-variable-rgx`](https://github.com/charliermarsh/ruff#dummy-variable-rgx) pattern.
|
[`dummy-variable-rgx`] pattern.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* [`dummy-variable-rgx`]
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
```python
|
```python
|
||||||
|
@ -29,3 +33,5 @@ def foo():
|
||||||
x = 1
|
x = 1
|
||||||
return x
|
return x
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[`dummy-variable-rgx`]: ../../settings#dummy-variable-rgx
|
Loading…
Add table
Add a link
Reference in a new issue