From 0704bf2c794dc690b17eb1e402fc66787e7ad01e Mon Sep 17 00:00:00 2001 From: Evan Rittenhouse Date: Thu, 11 May 2023 21:32:44 -0500 Subject: [PATCH] Change prefix from TDO to TD --- .../flake8_todo/{TDO001.py => TD001.py} | 1 - .../flake8_todo/{TDO002.py => TD002.py} | 0 .../flake8_todo/{TDO003.py => TD003.py} | 0 .../flake8_todo/{TDO004.py => TD004.py} | 2 +- .../flake8_todo/{TDO005.py => TD005.py} | 0 .../flake8_todo/{TDO006.py => TD006.py} | 0 .../flake8_todo/{TDO007.py => TD007.py} | 0 crates/ruff/src/registry.rs | 2 +- crates/ruff/src/rules/flake8_todo/mod.rs | 14 ++--- crates/ruff/src/rules/flake8_todo/rules.rs | 54 ++++++++++--------- ...valid-capitalization-in-todo_TD006.py.snap | 38 +++++++++++++ ...odo__tests__invalid-todo-tag_TD001.py.snap | 20 +++++++ ...ests__missing-author-in-todo_TD002.py.snap | 31 +++++++++++ ...tests__missing-colon-in-todo_TD004.py.snap | 31 +++++++++++ ..._tests__missing-link-in-todo_TD003.py.snap | 30 +++++++++++ ...ng-space-after-colon-in-todo_TD007.py.snap | 41 ++++++++++++++ ..._tests__missing-text-in-todo_TD005.py.snap | 31 +++++++++++ 17 files changed, 260 insertions(+), 35 deletions(-) rename crates/ruff/resources/test/fixtures/flake8_todo/{TDO001.py => TD001.py} (85%) rename crates/ruff/resources/test/fixtures/flake8_todo/{TDO002.py => TD002.py} (100%) rename crates/ruff/resources/test/fixtures/flake8_todo/{TDO003.py => TD003.py} (100%) rename crates/ruff/resources/test/fixtures/flake8_todo/{TDO004.py => TD004.py} (72%) rename crates/ruff/resources/test/fixtures/flake8_todo/{TDO005.py => TD005.py} (100%) rename crates/ruff/resources/test/fixtures/flake8_todo/{TDO006.py => TD006.py} (100%) rename crates/ruff/resources/test/fixtures/flake8_todo/{TDO007.py => TD007.py} (100%) create mode 100644 crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__invalid-capitalization-in-todo_TD006.py.snap create mode 100644 crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__invalid-todo-tag_TD001.py.snap create mode 100644 crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-author-in-todo_TD002.py.snap create mode 100644 crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-colon-in-todo_TD004.py.snap create mode 100644 crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-link-in-todo_TD003.py.snap create mode 100644 crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-space-after-colon-in-todo_TD007.py.snap create mode 100644 crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-text-in-todo_TD005.py.snap diff --git a/crates/ruff/resources/test/fixtures/flake8_todo/TDO001.py b/crates/ruff/resources/test/fixtures/flake8_todo/TD001.py similarity index 85% rename from crates/ruff/resources/test/fixtures/flake8_todo/TDO001.py rename to crates/ruff/resources/test/fixtures/flake8_todo/TD001.py index 90fb9fb30fc92..542db85c72491 100644 --- a/crates/ruff/resources/test/fixtures/flake8_todo/TDO001.py +++ b/crates/ruff/resources/test/fixtures/flake8_todo/TD001.py @@ -5,5 +5,4 @@ # T001 - errors # XXX (evanrittenhouse): this is not fine -# BUG (evanrittenhouse): this is not fine # FIXME (evanrittenhouse): this is not fine diff --git a/crates/ruff/resources/test/fixtures/flake8_todo/TDO002.py b/crates/ruff/resources/test/fixtures/flake8_todo/TD002.py similarity index 100% rename from crates/ruff/resources/test/fixtures/flake8_todo/TDO002.py rename to crates/ruff/resources/test/fixtures/flake8_todo/TD002.py diff --git a/crates/ruff/resources/test/fixtures/flake8_todo/TDO003.py b/crates/ruff/resources/test/fixtures/flake8_todo/TD003.py similarity index 100% rename from crates/ruff/resources/test/fixtures/flake8_todo/TDO003.py rename to crates/ruff/resources/test/fixtures/flake8_todo/TD003.py diff --git a/crates/ruff/resources/test/fixtures/flake8_todo/TDO004.py b/crates/ruff/resources/test/fixtures/flake8_todo/TD004.py similarity index 72% rename from crates/ruff/resources/test/fixtures/flake8_todo/TDO004.py rename to crates/ruff/resources/test/fixtures/flake8_todo/TD004.py index fb3a43e5fd3a9..50dd9a78ad814 100644 --- a/crates/ruff/resources/test/fixtures/flake8_todo/TDO004.py +++ b/crates/ruff/resources/test/fixtures/flake8_todo/TD004.py @@ -2,5 +2,5 @@ # TODO(evanrittenhouse): this has a colon # T004 - errors # TODO this has no colon -# TODO(evanrittenhouse) this has no colon +# TODO(evanrittenhouse 😀) this has no colon # FIXME add a colon diff --git a/crates/ruff/resources/test/fixtures/flake8_todo/TDO005.py b/crates/ruff/resources/test/fixtures/flake8_todo/TD005.py similarity index 100% rename from crates/ruff/resources/test/fixtures/flake8_todo/TDO005.py rename to crates/ruff/resources/test/fixtures/flake8_todo/TD005.py diff --git a/crates/ruff/resources/test/fixtures/flake8_todo/TDO006.py b/crates/ruff/resources/test/fixtures/flake8_todo/TD006.py similarity index 100% rename from crates/ruff/resources/test/fixtures/flake8_todo/TDO006.py rename to crates/ruff/resources/test/fixtures/flake8_todo/TD006.py diff --git a/crates/ruff/resources/test/fixtures/flake8_todo/TDO007.py b/crates/ruff/resources/test/fixtures/flake8_todo/TD007.py similarity index 100% rename from crates/ruff/resources/test/fixtures/flake8_todo/TDO007.py rename to crates/ruff/resources/test/fixtures/flake8_todo/TD007.py diff --git a/crates/ruff/src/registry.rs b/crates/ruff/src/registry.rs index d52d06247ef67..fb1473781651f 100644 --- a/crates/ruff/src/registry.rs +++ b/crates/ruff/src/registry.rs @@ -822,7 +822,7 @@ pub enum Linter { #[prefix = "PTH"] Flake8UsePathlib, /// [flake8-todos](https://github.com/orsinium-labs/flake8-todos/) - #[prefix = "TDO"] + #[prefix = "TD"] Flake8Todo, /// [eradicate](https://pypi.org/project/eradicate/) #[prefix = "ERA"] diff --git a/crates/ruff/src/rules/flake8_todo/mod.rs b/crates/ruff/src/rules/flake8_todo/mod.rs index e6fb9957170b3..e5c90364d1e0f 100644 --- a/crates/ruff/src/rules/flake8_todo/mod.rs +++ b/crates/ruff/src/rules/flake8_todo/mod.rs @@ -12,13 +12,13 @@ mod tests { use crate::test::test_path; use crate::{assert_messages, settings}; - #[test_case(Rule::InvalidTodoTag, Path::new("TDO001.py"); "TDO001")] - #[test_case(Rule::MissingAuthorInTodo, Path::new("TDO002.py"); "TDO002")] - #[test_case(Rule::MissingLinkInTodo, Path::new("TDO003.py"); "TDO003")] - #[test_case(Rule::MissingColonInTodo, Path::new("TDO004.py"); "TDO004")] - #[test_case(Rule::MissingTextInTodo, Path::new("TDO005.py"); "TDO005")] - #[test_case(Rule::InvalidCapitalizationInTodo, Path::new("TDO006.py"); "TDO006")] - #[test_case(Rule::MissingSpaceAfterColonInTodo, Path::new("TDO007.py"); "TDO007")] + #[test_case(Rule::InvalidTodoTag, Path::new("TD001.py"); "TD001")] + #[test_case(Rule::MissingAuthorInTodo, Path::new("TD002.py"); "TD002")] + #[test_case(Rule::MissingLinkInTodo, Path::new("TD003.py"); "TD003")] + #[test_case(Rule::MissingColonInTodo, Path::new("TD004.py"); "TD004")] + #[test_case(Rule::MissingTextInTodo, Path::new("TD005.py"); "TD005")] + #[test_case(Rule::InvalidCapitalizationInTodo, Path::new("TD006.py"); "TD006")] + #[test_case(Rule::MissingSpaceAfterColonInTodo, Path::new("TD007.py"); "TD007")] fn rules(rule_code: Rule, path: &Path) -> Result<()> { let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy()); let diagnostics = test_path( diff --git a/crates/ruff/src/rules/flake8_todo/rules.rs b/crates/ruff/src/rules/flake8_todo/rules.rs index e0b7b674bad63..29bcab018d85f 100644 --- a/crates/ruff/src/rules/flake8_todo/rules.rs +++ b/crates/ruff/src/rules/flake8_todo/rules.rs @@ -1,11 +1,11 @@ -use std::collections::HashMap; + use once_cell::sync::Lazy; use regex::RegexSet; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_text_size::{TextRange, TextSize}; +use ruff_text_size::{TextLen, TextRange, TextSize}; use rustpython_parser::lexer::LexResult; use rustpython_parser::Tok; @@ -220,13 +220,13 @@ static TODO_REGEX_SET: Lazy = Lazy::new(|| { // Maps the index of a particular Regex (specified by its index in the above PATTERNS slice) to the length of the // tag that we're trying to capture. -static PATTERN_TAG_LENGTH: &'static [usize; 3] = &["TODO".len(), "FIXME".len(), "XXX".len()]; +static PATTERN_TAG_LENGTH: &[usize; 3] = &["TODO".len(), "FIXME".len(), "XXX".len()]; static ISSUE_LINK_REGEX_SET: Lazy = Lazy::new(|| { RegexSet::new([ r#"^#\s*(http|https)://.*"#, // issue link r#"^#\s*\d+$"#, // issue code - like "003" - r#"^#\s*[A-Z]{1,6}\-?\d+$"#, // issue code - like "TDO-003" + r#"^#\s*[A-Z]{1,6}\-?\d+$"#, // issue code - like "TD-003" ]) .unwrap() }); @@ -261,7 +261,7 @@ pub fn check_todos( check_for_tag_errors(&tag, &mut diagnostics, autofix, settings); check_for_static_errors(comment, *token_range, &tag, &mut diagnostics); - // TDO-003 + // TD-003 if let Some((next_token, _next_range)) = iter.peek() { if let Tok::Comment(next_comment) = next_token { if ISSUE_LINK_REGEX_SET.is_match(next_comment) { @@ -312,30 +312,29 @@ fn check_for_tag_errors( autofix: flags::Autofix, settings: &Settings, ) { - if tag.content != "TODO" { - if tag.content.to_uppercase() == "TODO" { - // TDO-006 - let mut invalid_capitalization = Diagnostic::new( - InvalidCapitalizationInTodo { - tag: tag.content.to_string(), - }, - tag.range, - ); - - if autofix.into() && settings.rules.should_fix(Rule::InvalidCapitalizationInTodo) { - invalid_capitalization.set_fix(Fix::unspecified(Edit::range_replacement( - "TODO".to_string(), - tag.range, - ))); - } + if tag.content == "TODO" { + return; + } - diagnostics.push(invalid_capitalization); + if tag.content.to_uppercase() == "TODO" { + // TD-006 + let mut invalid_capitalization = Diagnostic::new( + InvalidCapitalizationInTodo { + tag: tag.content.to_string(), + }, + tag.range, + ); - // Avoid pushing multiple diagnostics for the same range. - return; + if autofix.into() && settings.rules.should_fix(Rule::InvalidCapitalizationInTodo) { + invalid_capitalization.set_fix(Fix::unspecified(Edit::range_replacement( + "TODO".to_string(), + tag.range, + ))); } - // TDO-001 + diagnostics.push(invalid_capitalization); + } else { + // TD-001 diagnostics.push(Diagnostic::new( InvalidTodoTag { tag: tag.content.to_string(), @@ -361,6 +360,11 @@ fn check_for_static_errors( // Absolute offset of the comment's colon from the start of the file. let mut colon_offset: Option = None; + let comment_rest = &comment[usize::from(relative_offset)..]; + let trimmed_start = comment_rest.trim_start(); + // Relative offset from the end of the tag to the start of the rest of the comment + let whitespace_offset = comment_rest.text_len(); + // An "author block" must be contained in parentheses, like "(ruff)". To check if it exists, // we can check the first non-whitespace character after the tag. If that first character is a // left parenthesis, we can say that we have an author's block. diff --git a/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__invalid-capitalization-in-todo_TD006.py.snap b/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__invalid-capitalization-in-todo_TD006.py.snap new file mode 100644 index 0000000000000..6cfcc242d4ac5 --- /dev/null +++ b/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__invalid-capitalization-in-todo_TD006.py.snap @@ -0,0 +1,38 @@ +--- +source: crates/ruff/src/rules/flake8_todo/mod.rs +--- +TD006.py:4:3: TD006 [*] Invalid TODO capitalization: `ToDo` should be `TODO` + | +4 | # TODO (evanrittenhouse): this is a valid TODO +5 | # TDO006 - error +6 | # ToDo (evanrittenhouse): invalid capitalization + | ^^^^ TD006 +7 | # todo (evanrittenhouse): another invalid capitalization + | + = help: Replace `ToDo` with `TODO` + +ℹ Suggested fix +1 1 | # TDO006 - accepted +2 2 | # TODO (evanrittenhouse): this is a valid TODO +3 3 | # TDO006 - error +4 |-# ToDo (evanrittenhouse): invalid capitalization + 4 |+# TODO (evanrittenhouse): invalid capitalization +5 5 | # todo (evanrittenhouse): another invalid capitalization + +TD006.py:5:3: TD006 [*] Invalid TODO capitalization: `todo` should be `TODO` + | +5 | # TDO006 - error +6 | # ToDo (evanrittenhouse): invalid capitalization +7 | # todo (evanrittenhouse): another invalid capitalization + | ^^^^ TD006 + | + = help: Replace `todo` with `TODO` + +ℹ Suggested fix +2 2 | # TODO (evanrittenhouse): this is a valid TODO +3 3 | # TDO006 - error +4 4 | # ToDo (evanrittenhouse): invalid capitalization +5 |-# todo (evanrittenhouse): another invalid capitalization + 5 |+# TODO (evanrittenhouse): another invalid capitalization + + diff --git a/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__invalid-todo-tag_TD001.py.snap b/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__invalid-todo-tag_TD001.py.snap new file mode 100644 index 0000000000000..0e1d66bb56ed3 --- /dev/null +++ b/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__invalid-todo-tag_TD001.py.snap @@ -0,0 +1,20 @@ +--- +source: crates/ruff/src/rules/flake8_todo/mod.rs +--- +TD001.py:7:3: TD001 Invalid TODO tag: `XXX` should be `TODO` + | +7 | # T001 - errors +8 | # XXX (evanrittenhouse): this is not fine + | ^^^ TD001 +9 | # FIXME (evanrittenhouse): this is not fine + | + +TD001.py:8:3: TD001 Invalid TODO tag: `FIXME` should be `TODO` + | + 8 | # T001 - errors + 9 | # XXX (evanrittenhouse): this is not fine +10 | # FIXME (evanrittenhouse): this is not fine + | ^^^^^ TD001 + | + + diff --git a/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-author-in-todo_TD002.py.snap b/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-author-in-todo_TD002.py.snap new file mode 100644 index 0000000000000..e8d669e483b1a --- /dev/null +++ b/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-author-in-todo_TD002.py.snap @@ -0,0 +1,31 @@ +--- +source: crates/ruff/src/rules/flake8_todo/mod.rs +--- +TD002.py:5:7: TD002 Missing author in TODO. Try: # TODO (): ... + | +5 | # TODO(evanrittenhouse): this also has an author +6 | # T002 - errors +7 | # TODO: this has no author + | ^ TD002 +8 | # FIXME: neither does this +9 | # TODO : and neither does this + | + +TD002.py:6:8: TD002 Missing author in TODO. Try: # TODO (): ... + | +6 | # T002 - errors +7 | # TODO: this has no author +8 | # FIXME: neither does this + | ^ TD002 +9 | # TODO : and neither does this + | + +TD002.py:7:7: TD002 Missing author in TODO. Try: # TODO (): ... + | +7 | # TODO: this has no author +8 | # FIXME: neither does this +9 | # TODO : and neither does this + | ^ TD002 + | + + diff --git a/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-colon-in-todo_TD004.py.snap b/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-colon-in-todo_TD004.py.snap new file mode 100644 index 0000000000000..f34f24b3377b6 --- /dev/null +++ b/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-colon-in-todo_TD004.py.snap @@ -0,0 +1,31 @@ +--- +source: crates/ruff/src/rules/flake8_todo/mod.rs +--- +TD004.py:4:7: TD004 Missing colon in TODO. Try: # TODO: ... + | +4 | # TODO(evanrittenhouse): this has a colon +5 | # T004 - errors +6 | # TODO this has no colon + | ^ TD004 +7 | # TODO(evanrittenhouse) this has no colon +8 | # FIXME add a colon + | + +TD004.py:5:24: TD004 Missing colon in TODO. Try: # TODO: ... + | +5 | # T004 - errors +6 | # TODO this has no colon +7 | # TODO(evanrittenhouse) this has no colon + | ^ TD004 +8 | # FIXME add a colon + | + +TD004.py:6:8: TD004 Missing colon in TODO. Try: # TODO: ... + | +6 | # TODO this has no colon +7 | # TODO(evanrittenhouse) this has no colon +8 | # FIXME add a colon + | ^ TD004 + | + + diff --git a/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-link-in-todo_TD003.py.snap b/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-link-in-todo_TD003.py.snap new file mode 100644 index 0000000000000..78bdea115e1d7 --- /dev/null +++ b/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-link-in-todo_TD003.py.snap @@ -0,0 +1,30 @@ +--- +source: crates/ruff/src/rules/flake8_todo/mod.rs +--- +TD003.py:9:3: TD003 Missing issue link on the line following this TODO + | + 9 | # TDO003 - errors +10 | # TODO: this comment has no + | ^^^^ TD003 +11 | # link after it + | + +TD003.py:12:3: TD003 Missing issue link on the line following this TODO + | +12 | # link after it +13 | +14 | # TODO: here's a TODO with no link after it + | ^^^^ TD003 +15 | def foo(x): +16 | return x + | + +TD003.py:16:3: TD003 Missing issue link on the line following this TODO + | +16 | return x +17 | +18 | # TODO: here's a TODO on the last line with no link + | ^^^^ TD003 + | + + diff --git a/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-space-after-colon-in-todo_TD007.py.snap b/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-space-after-colon-in-todo_TD007.py.snap new file mode 100644 index 0000000000000..8cd0638415d0e --- /dev/null +++ b/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-space-after-colon-in-todo_TD007.py.snap @@ -0,0 +1,41 @@ +--- +source: crates/ruff/src/rules/flake8_todo/mod.rs +--- +TD007.py:5:25: TD007 Missing space after colon in TODO + | +5 | # TODO: so does this +6 | # T007 - errors +7 | # TODO(evanrittenhouse):this has no space after a colon + | ^ TD007 +8 | # TODO (evanrittenhouse):this doesn't either +9 | # TODO:neither does this + | + +TD007.py:6:26: TD007 Missing space after colon in TODO + | + 6 | # T007 - errors + 7 | # TODO(evanrittenhouse):this has no space after a colon + 8 | # TODO (evanrittenhouse):this doesn't either + | ^ TD007 + 9 | # TODO:neither does this +10 | # FIXME:and lastly neither does this + | + +TD007.py:7:8: TD007 Missing space after colon in TODO + | + 7 | # TODO(evanrittenhouse):this has no space after a colon + 8 | # TODO (evanrittenhouse):this doesn't either + 9 | # TODO:neither does this + | ^ TD007 +10 | # FIXME:and lastly neither does this + | + +TD007.py:8:9: TD007 Missing space after colon in TODO + | + 8 | # TODO (evanrittenhouse):this doesn't either + 9 | # TODO:neither does this +10 | # FIXME:and lastly neither does this + | ^ TD007 + | + + diff --git a/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-text-in-todo_TD005.py.snap b/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-text-in-todo_TD005.py.snap new file mode 100644 index 0000000000000..cde6587acbd08 --- /dev/null +++ b/crates/ruff/src/rules/flake8_todo/snapshots/ruff__rules__flake8_todo__tests__missing-text-in-todo_TD005.py.snap @@ -0,0 +1,31 @@ +--- +source: crates/ruff/src/rules/flake8_todo/mod.rs +--- +TD005.py:4:25: TD005 Missing text after 'TODO' + | +4 | # TODO(evanrittenhouse): this has text, while the errors do not +5 | # T005 - errors +6 | # TODO(evanrittenhouse): + | ^ TD005 +7 | # TODO(evanrittenhouse) +8 | # FIXME + | + +TD005.py:5:24: TD005 Missing text after 'TODO' + | +5 | # T005 - errors +6 | # TODO(evanrittenhouse): +7 | # TODO(evanrittenhouse) + | ^ TD005 +8 | # FIXME + | + +TD005.py:6:8: TD005 Missing text after 'TODO' + | +6 | # TODO(evanrittenhouse): +7 | # TODO(evanrittenhouse) +8 | # FIXME + | ^ TD005 + | + +