[`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:
Dylan 2025-01-15 17:47:33 -06:00 committed by GitHub
parent c53ee608a1
commit d2656e88a3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 12 deletions

View File

@ -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

View File

@ -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;
} }

View File

@ -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
| |