mirror of https://github.com/astral-sh/ruff
[`flake8-todos`] Allow VSCode GitHub PR extension style links in `missing-todo-link` (`TD003`) (#15519)
## Summary Allow links to issues that appear on the same line as the TODO directive, if they conform to the format that VSCode's GitHub PR extension produces. Revival of #9627 (the branch was stale enough that rebasing was a lot harder than just making the changes anew). Credit should go to the author of that PR though. Closes #8061 Co-authored-by: Martin Bernstorff <martinbernstorff@gmail.com>
This commit is contained in:
parent
c53ee608a1
commit
d2656e88a3
|
|
@ -34,4 +34,10 @@ def foo(x):
|
||||||
|
|
||||||
# foo # TODO: no link!
|
# foo # TODO: no link!
|
||||||
|
|
||||||
|
# TODO: https://github.com/astral-sh/ruff/pull/9627 A todo with a link on the same line
|
||||||
|
|
||||||
|
# TODO: #9627 A todo with a number on the same line
|
||||||
|
|
||||||
|
# TODO: A todo with a random number, 5431
|
||||||
|
|
||||||
# TODO: here's a TODO on the last line with no link
|
# TODO: here's a TODO on the last line with no link
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,12 @@ impl Violation for MissingTodoAuthor {
|
||||||
/// # TODO(charlie): this comment has a 3-digit issue code
|
/// # TODO(charlie): this comment has a 3-digit issue code
|
||||||
/// # 003
|
/// # 003
|
||||||
///
|
///
|
||||||
|
/// # TODO(charlie): https://github.com/astral-sh/ruff/issues/3870
|
||||||
|
/// # this comment has an issue link
|
||||||
|
///
|
||||||
|
/// # TODO(charlie): #003 this comment has a 3-digit issue code
|
||||||
|
/// # with leading character `#`
|
||||||
|
///
|
||||||
/// # TODO(charlie): this comment has an issue code (matches the regex `[A-Z]+\-?\d+`)
|
/// # TODO(charlie): this comment has an issue code (matches the regex `[A-Z]+\-?\d+`)
|
||||||
/// # SIXCHR-003
|
/// # SIXCHR-003
|
||||||
/// ```
|
/// ```
|
||||||
|
|
@ -100,7 +106,7 @@ pub(crate) struct MissingTodoLink;
|
||||||
impl Violation for MissingTodoLink {
|
impl Violation for MissingTodoLink {
|
||||||
#[derive_message_formats]
|
#[derive_message_formats]
|
||||||
fn message(&self) -> String {
|
fn message(&self) -> String {
|
||||||
"Missing issue link on the line following this TODO".to_string()
|
"Missing issue link for this TODO".to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -224,7 +230,7 @@ impl Violation for MissingSpaceAfterTodoColon {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ISSUE_LINK_REGEX_SET: LazyLock<RegexSet> = LazyLock::new(|| {
|
static ISSUE_LINK_OWN_LINE_REGEX_SET: LazyLock<RegexSet> = LazyLock::new(|| {
|
||||||
RegexSet::new([
|
RegexSet::new([
|
||||||
r"^#\s*(http|https)://.*", // issue link
|
r"^#\s*(http|https)://.*", // issue link
|
||||||
r"^#\s*\d+$", // issue code - like "003"
|
r"^#\s*\d+$", // issue code - like "003"
|
||||||
|
|
@ -233,6 +239,14 @@ static ISSUE_LINK_REGEX_SET: LazyLock<RegexSet> = LazyLock::new(|| {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
static ISSUE_LINK_TODO_LINE_REGEX_SET: LazyLock<RegexSet> = LazyLock::new(|| {
|
||||||
|
RegexSet::new([
|
||||||
|
r"\s*(http|https)://.*", // issue link
|
||||||
|
r"\s*#\d+.*", // issue code - like "#003"
|
||||||
|
])
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
pub(crate) fn todos(
|
pub(crate) fn todos(
|
||||||
diagnostics: &mut Vec<Diagnostic>,
|
diagnostics: &mut Vec<Diagnostic>,
|
||||||
todo_comments: &[TodoComment],
|
todo_comments: &[TodoComment],
|
||||||
|
|
@ -257,6 +271,13 @@ pub(crate) fn todos(
|
||||||
static_errors(diagnostics, content, range, directive);
|
static_errors(diagnostics, content, range, directive);
|
||||||
|
|
||||||
let mut has_issue_link = false;
|
let mut has_issue_link = false;
|
||||||
|
// VSCode recommended links on same line are ok:
|
||||||
|
// `# TODO(dylan): #1234`
|
||||||
|
if ISSUE_LINK_TODO_LINE_REGEX_SET
|
||||||
|
.is_match(locator.slice(TextRange::new(directive.range.end(), range.end())))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let mut curr_range = range;
|
let mut curr_range = range;
|
||||||
for next_range in comment_ranges.iter().skip(range_index + 1).copied() {
|
for next_range in comment_ranges.iter().skip(range_index + 1).copied() {
|
||||||
// Ensure that next_comment_range is in the same multiline comment "block" as
|
// Ensure that next_comment_range is in the same multiline comment "block" as
|
||||||
|
|
@ -274,7 +295,7 @@ pub(crate) fn todos(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ISSUE_LINK_REGEX_SET.is_match(next_comment) {
|
if ISSUE_LINK_OWN_LINE_REGEX_SET.is_match(next_comment) {
|
||||||
has_issue_link = true;
|
has_issue_link = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
source: crates/ruff_linter/src/rules/flake8_todos/mod.rs
|
source: crates/ruff_linter/src/rules/flake8_todos/mod.rs
|
||||||
---
|
---
|
||||||
TD003.py:15:3: TD003 Missing issue link on the line following this TODO
|
TD003.py:15:3: TD003 Missing issue link for this TODO
|
||||||
|
|
|
|
||||||
14 | # TDO003 - errors
|
14 | # TDO003 - errors
|
||||||
15 | # TODO: this comment has no
|
15 | # TODO: this comment has no
|
||||||
|
|
@ -9,7 +9,7 @@ TD003.py:15:3: TD003 Missing issue link on the line following this TODO
|
||||||
16 | # link after it
|
16 | # link after it
|
||||||
|
|
|
|
||||||
|
|
||||||
TD003.py:18:3: TD003 Missing issue link on the line following this TODO
|
TD003.py:18:3: TD003 Missing issue link for this TODO
|
||||||
|
|
|
|
||||||
16 | # link after it
|
16 | # link after it
|
||||||
17 |
|
17 |
|
||||||
|
|
@ -19,7 +19,7 @@ TD003.py:18:3: TD003 Missing issue link on the line following this TODO
|
||||||
20 | return x
|
20 | return x
|
||||||
|
|
|
|
||||||
|
|
||||||
TD003.py:31:3: TD003 Missing issue link on the line following this TODO
|
TD003.py:31:3: TD003 Missing issue link for this TODO
|
||||||
|
|
|
|
||||||
29 | # TDO-3870
|
29 | # TDO-3870
|
||||||
30 |
|
30 |
|
||||||
|
|
@ -29,20 +29,30 @@ TD003.py:31:3: TD003 Missing issue link on the line following this TODO
|
||||||
33 | # TDO-3870
|
33 | # TDO-3870
|
||||||
|
|
|
|
||||||
|
|
||||||
TD003.py:35:9: TD003 Missing issue link on the line following this TODO
|
TD003.py:35:9: TD003 Missing issue link for this TODO
|
||||||
|
|
|
|
||||||
33 | # TDO-3870
|
33 | # TDO-3870
|
||||||
34 |
|
34 |
|
||||||
35 | # foo # TODO: no link!
|
35 | # foo # TODO: no link!
|
||||||
| ^^^^ TD003
|
| ^^^^ TD003
|
||||||
36 |
|
36 |
|
||||||
37 | # TODO: here's a TODO on the last line with no link
|
37 | # TODO: https://github.com/astral-sh/ruff/pull/9627 A todo with a link on the same line
|
||||||
|
|
|
|
||||||
|
|
||||||
TD003.py:37:3: TD003 Missing issue link on the line following this TODO
|
TD003.py:41:3: TD003 Missing issue link for this TODO
|
||||||
|
|
|
|
||||||
35 | # foo # TODO: no link!
|
39 | # TODO: #9627 A todo with a number on the same line
|
||||||
36 |
|
40 |
|
||||||
37 | # TODO: here's a TODO on the last line with no link
|
41 | # TODO: A todo with a random number, 5431
|
||||||
|
| ^^^^ TD003
|
||||||
|
42 |
|
||||||
|
43 | # TODO: here's a TODO on the last line with no link
|
||||||
|
|
|
||||||
|
|
||||||
|
TD003.py:43:3: TD003 Missing issue link for this TODO
|
||||||
|
|
|
||||||
|
41 | # TODO: A todo with a random number, 5431
|
||||||
|
42 |
|
||||||
|
43 | # TODO: here's a TODO on the last line with no link
|
||||||
| ^^^^ TD003
|
| ^^^^ TD003
|
||||||
|
|
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue