[`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!
# 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

View File

@ -91,6 +91,12 @@ impl Violation for MissingTodoAuthor {
/// # TODO(charlie): this comment has a 3-digit issue code
/// # 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+`)
/// # SIXCHR-003
/// ```
@ -100,7 +106,7 @@ pub(crate) struct MissingTodoLink;
impl Violation for MissingTodoLink {
#[derive_message_formats]
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([
r"^#\s*(http|https)://.*", // issue link
r"^#\s*\d+$", // issue code - like "003"
@ -233,6 +239,14 @@ static ISSUE_LINK_REGEX_SET: LazyLock<RegexSet> = LazyLock::new(|| {
.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(
diagnostics: &mut Vec<Diagnostic>,
todo_comments: &[TodoComment],
@ -257,6 +271,13 @@ pub(crate) fn todos(
static_errors(diagnostics, content, range, directive);
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;
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
@ -274,7 +295,7 @@ pub(crate) fn todos(
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;
}

View File

@ -1,7 +1,7 @@
---
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
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
|
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
17 |
@ -19,7 +19,7 @@ TD003.py:18:3: TD003 Missing issue link on the line following this TODO
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
30 |
@ -29,20 +29,30 @@ TD003.py:31:3: TD003 Missing issue link on the line following this TODO
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
34 |
35 | # foo # TODO: no link!
| ^^^^ TD003
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!
36 |
37 | # TODO: here's a TODO on the last line with no link
39 | # TODO: #9627 A todo with a number on the same line
40 |
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
|