From d4e2a5a354ce29ea27abfb29befcdae91f71d899 Mon Sep 17 00:00:00 2001 From: Szymon Slodkowski Date: Tue, 4 Jun 2024 18:45:30 +0200 Subject: [PATCH 1/4] Add rules checking that builtin and custom libraries are imported in alphabetical order. --- robocop/checkers/misc.py | 57 ++++++++++++++++++- .../builtin_imports_not_sorted/__init__.py | 0 .../expected_output.txt | 4 ++ .../no_builtins.robot | 11 ++++ .../no_imports.robot | 9 +++ .../only_builtins.robot | 13 +++++ .../builtin_imports_not_sorted/test.robot | 16 ++++++ .../builtin_imports_not_sorted/test_rule.py | 6 ++ .../custom_imports_not_sorted/__init__.py | 0 .../expected_output.txt | 2 + .../no_builtins.robot | 11 ++++ .../no_imports.robot | 9 +++ .../only_builtins.robot | 12 ++++ .../misc/custom_imports_not_sorted/test.robot | 18 ++++++ .../custom_imports_not_sorted/test_rule.py | 6 ++ 15 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 tests/atest/rules/misc/builtin_imports_not_sorted/__init__.py create mode 100644 tests/atest/rules/misc/builtin_imports_not_sorted/expected_output.txt create mode 100644 tests/atest/rules/misc/builtin_imports_not_sorted/no_builtins.robot create mode 100644 tests/atest/rules/misc/builtin_imports_not_sorted/no_imports.robot create mode 100644 tests/atest/rules/misc/builtin_imports_not_sorted/only_builtins.robot create mode 100644 tests/atest/rules/misc/builtin_imports_not_sorted/test.robot create mode 100644 tests/atest/rules/misc/builtin_imports_not_sorted/test_rule.py create mode 100644 tests/atest/rules/misc/custom_imports_not_sorted/__init__.py create mode 100644 tests/atest/rules/misc/custom_imports_not_sorted/expected_output.txt create mode 100644 tests/atest/rules/misc/custom_imports_not_sorted/no_builtins.robot create mode 100644 tests/atest/rules/misc/custom_imports_not_sorted/no_imports.robot create mode 100644 tests/atest/rules/misc/custom_imports_not_sorted/only_builtins.robot create mode 100644 tests/atest/rules/misc/custom_imports_not_sorted/test.robot create mode 100644 tests/atest/rules/misc/custom_imports_not_sorted/test_rule.py diff --git a/robocop/checkers/misc.py b/robocop/checkers/misc.py index e2da669a2..b1bba9f85 100644 --- a/robocop/checkers/misc.py +++ b/robocop/checkers/misc.py @@ -586,6 +586,35 @@ """, added_in_version="4.0.0", ), + "0926": Rule( + rule_id="0926", + name="builtin-imports-not-sorted", + msg="BuiltIn library import '{{ builtin_import }}' should be placed before '{{ previous_builtin_import }}'", + severity=RuleSeverity.WARNING, + docs=""" + Example of rule violation:: + + *** Settings *** + Library OperatingSystem + Library Collections # BuiltIn libraries imported not in alphabetical order + + """, + ), + "0927": Rule( + rule_id="0927", + name="custom-imports-not-sorted", + msg="Custom library import '{{ custom_import }}' should be placed before '{{ previous_custom_import }}'", + severity=RuleSeverity.WARNING, + docs=""" + Example of rule violation:: + + *** Settings *** + Library Collections + Library CustomLibrary + Library AnotherCustomLibrary # AnotherCustomLibrary library defined after custom CustomLibrary + + """, + ), } @@ -796,7 +825,7 @@ class SettingsOrderChecker(VisitorChecker): BuiltIn libraries imports should always be placed before other libraries imports. """ - reports = ("wrong-import-order",) + reports = ("wrong-import-order", "builtin-imports-not-sorted", "custom-imports-not-sorted") def __init__(self): self.libraries = [] @@ -806,6 +835,8 @@ def visit_File(self, node): # noqa self.libraries = [] self.generic_visit(node) first_non_builtin = None + previous_builtin = None + previous_non_builtin = None for library in self.libraries: if first_non_builtin is None: if library.name not in STDLIBS: @@ -821,6 +852,30 @@ def visit_File(self, node): # noqa col=lib_name.col_offset + 1, end_col=lib_name.end_col_offset + 1, ) + if library.name in STDLIBS: + if previous_builtin is not None and library.name < previous_builtin.name: + lib_name = library.get_token(Token.NAME) + self.report( + "builtin-imports-not-sorted", + builtin_import=library.name, + previous_builtin_import=previous_builtin.name, + node=library, + col=lib_name.col_offset + 1, + end_col=lib_name.end_col_offset + 1, + ) + previous_builtin = library + else: + if previous_non_builtin is not None and library.name < previous_non_builtin.name: + lib_name = library.get_token(Token.NAME) + self.report( + "custom-imports-not-sorted", + custom_import=library.name, + previous_custom_import=previous_non_builtin.name, + node=library, + col=lib_name.col_offset + 1, + end_col=lib_name.end_col_offset + 1, + ) + previous_non_builtin = library def visit_LibraryImport(self, node): # noqa if not node.name: diff --git a/tests/atest/rules/misc/builtin_imports_not_sorted/__init__.py b/tests/atest/rules/misc/builtin_imports_not_sorted/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/atest/rules/misc/builtin_imports_not_sorted/expected_output.txt b/tests/atest/rules/misc/builtin_imports_not_sorted/expected_output.txt new file mode 100644 index 000000000..02290520f --- /dev/null +++ b/tests/atest/rules/misc/builtin_imports_not_sorted/expected_output.txt @@ -0,0 +1,4 @@ +only_builtins.robot:4:12 [W] 0926 BuiltIn library import 'String' should be placed before 'XML' +only_builtins.robot:8:12 [W] 0926 BuiltIn library import 'BuiltIn' should be placed before 'String' +test.robot:3:12 [W] 0926 BuiltIn library import 'Collections' should be placed before 'DateTime' +test.robot:6:12 [W] 0926 BuiltIn library import 'String' should be placed before 'XML' \ No newline at end of file diff --git a/tests/atest/rules/misc/builtin_imports_not_sorted/no_builtins.robot b/tests/atest/rules/misc/builtin_imports_not_sorted/no_builtins.robot new file mode 100644 index 000000000..a4d1cacf9 --- /dev/null +++ b/tests/atest/rules/misc/builtin_imports_not_sorted/no_builtins.robot @@ -0,0 +1,11 @@ +*** Settings *** +Library RequestsLibrary +Resource ..${/}Libs${/}MyResource.robot +Library OwnLib.py +Variables variables.py +Test Template Keyword + + +*** Keywords *** +Keyword + No Operation diff --git a/tests/atest/rules/misc/builtin_imports_not_sorted/no_imports.robot b/tests/atest/rules/misc/builtin_imports_not_sorted/no_imports.robot new file mode 100644 index 000000000..8b3fbab29 --- /dev/null +++ b/tests/atest/rules/misc/builtin_imports_not_sorted/no_imports.robot @@ -0,0 +1,9 @@ +*** Settings *** +Resource ..${/}Libs${/}MyResource.robot +Variables variables.py +Test Template Keyword + + +*** Keywords *** +Keyword + No Operation diff --git a/tests/atest/rules/misc/builtin_imports_not_sorted/only_builtins.robot b/tests/atest/rules/misc/builtin_imports_not_sorted/only_builtins.robot new file mode 100644 index 000000000..7f14f7d45 --- /dev/null +++ b/tests/atest/rules/misc/builtin_imports_not_sorted/only_builtins.robot @@ -0,0 +1,13 @@ +*** Settings *** +Library Collections +Library XML +Library String +Resource ..${/}Libs${/}MyResource.robot +Variables variables.py +Test Template Keyword +Library BuiltIn + + +*** Keywords *** +Keyword + No Operation diff --git a/tests/atest/rules/misc/builtin_imports_not_sorted/test.robot b/tests/atest/rules/misc/builtin_imports_not_sorted/test.robot new file mode 100644 index 000000000..e8b8f139f --- /dev/null +++ b/tests/atest/rules/misc/builtin_imports_not_sorted/test.robot @@ -0,0 +1,16 @@ +*** Settings *** +Library DateTime +Library Collections +Library OperatingSystem +Library XML +Library String +Library RequestsLibrary +Resource ..${/}Libs${/}MyResource.robot +Library OwnLib.py +Variables variables.py +Test Template Keyword + + +*** Keywords *** +Keyword + No Operation diff --git a/tests/atest/rules/misc/builtin_imports_not_sorted/test_rule.py b/tests/atest/rules/misc/builtin_imports_not_sorted/test_rule.py new file mode 100644 index 000000000..88377fa01 --- /dev/null +++ b/tests/atest/rules/misc/builtin_imports_not_sorted/test_rule.py @@ -0,0 +1,6 @@ +from tests.atest.utils import RuleAcceptance + + +class TestRuleAcceptance(RuleAcceptance): + def test_rule(self): + self.check_rule(expected_file="expected_output.txt") diff --git a/tests/atest/rules/misc/custom_imports_not_sorted/__init__.py b/tests/atest/rules/misc/custom_imports_not_sorted/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/atest/rules/misc/custom_imports_not_sorted/expected_output.txt b/tests/atest/rules/misc/custom_imports_not_sorted/expected_output.txt new file mode 100644 index 000000000..103b4c387 --- /dev/null +++ b/tests/atest/rules/misc/custom_imports_not_sorted/expected_output.txt @@ -0,0 +1,2 @@ +no_builtins.robot:4:12 [W] 0927 Custom library import 'OwnLib.py' should be placed before 'RequestsLibrary' +test.robot:9:12 [W] 0927 Custom library import 'AnotherLibrary' should be placed before 'RequestsLibrary' \ No newline at end of file diff --git a/tests/atest/rules/misc/custom_imports_not_sorted/no_builtins.robot b/tests/atest/rules/misc/custom_imports_not_sorted/no_builtins.robot new file mode 100644 index 000000000..a4d1cacf9 --- /dev/null +++ b/tests/atest/rules/misc/custom_imports_not_sorted/no_builtins.robot @@ -0,0 +1,11 @@ +*** Settings *** +Library RequestsLibrary +Resource ..${/}Libs${/}MyResource.robot +Library OwnLib.py +Variables variables.py +Test Template Keyword + + +*** Keywords *** +Keyword + No Operation diff --git a/tests/atest/rules/misc/custom_imports_not_sorted/no_imports.robot b/tests/atest/rules/misc/custom_imports_not_sorted/no_imports.robot new file mode 100644 index 000000000..8b3fbab29 --- /dev/null +++ b/tests/atest/rules/misc/custom_imports_not_sorted/no_imports.robot @@ -0,0 +1,9 @@ +*** Settings *** +Resource ..${/}Libs${/}MyResource.robot +Variables variables.py +Test Template Keyword + + +*** Keywords *** +Keyword + No Operation diff --git a/tests/atest/rules/misc/custom_imports_not_sorted/only_builtins.robot b/tests/atest/rules/misc/custom_imports_not_sorted/only_builtins.robot new file mode 100644 index 000000000..464a2bb4d --- /dev/null +++ b/tests/atest/rules/misc/custom_imports_not_sorted/only_builtins.robot @@ -0,0 +1,12 @@ +*** Settings *** +Library Collections +Library String +Resource ..${/}Libs${/}MyResource.robot +Variables variables.py +Test Template Keyword +Library BuiltIn + + +*** Keywords *** +Keyword + No Operation diff --git a/tests/atest/rules/misc/custom_imports_not_sorted/test.robot b/tests/atest/rules/misc/custom_imports_not_sorted/test.robot new file mode 100644 index 000000000..cef9b9d9a --- /dev/null +++ b/tests/atest/rules/misc/custom_imports_not_sorted/test.robot @@ -0,0 +1,18 @@ +*** Settings *** +Library DateTime +Library Collections +Library OperatingSystem +Library XML +Library String +Library OwnLib.py +Library RequestsLibrary +Library AnotherLibrary +Resource ..${/}Libs${/}MyResource.robot + +Variables variables.py +Test Template Keyword + + +*** Keywords *** +Keyword + No Operation diff --git a/tests/atest/rules/misc/custom_imports_not_sorted/test_rule.py b/tests/atest/rules/misc/custom_imports_not_sorted/test_rule.py new file mode 100644 index 000000000..88377fa01 --- /dev/null +++ b/tests/atest/rules/misc/custom_imports_not_sorted/test_rule.py @@ -0,0 +1,6 @@ +from tests.atest.utils import RuleAcceptance + + +class TestRuleAcceptance(RuleAcceptance): + def test_rule(self): + self.check_rule(expected_file="expected_output.txt") From 327023e29fec314230b673afd97d0c89c0813993 Mon Sep 17 00:00:00 2001 From: Szymon Slodkowski Date: Thu, 6 Jun 2024 10:43:57 +0200 Subject: [PATCH 2/4] Move rule checking order of non builtin libraries imports to community rules. --- robocop/checkers/community_rules/misc.py | 61 +++++++++++++++++++ robocop/checkers/misc.py | 34 ++--------- .../__init__.py | 0 .../expected_output.txt | 2 + .../no_builtins.robot | 0 .../no_imports.robot | 0 .../only_builtins.robot | 0 .../test.robot | 0 .../test_rule.py | 0 .../expected_output.txt | 2 - 10 files changed, 68 insertions(+), 31 deletions(-) create mode 100644 robocop/checkers/community_rules/misc.py rename tests/atest/rules/{misc/custom_imports_not_sorted => community_rules/misc/non_builtin_imports_not_sorted}/__init__.py (100%) create mode 100644 tests/atest/rules/community_rules/misc/non_builtin_imports_not_sorted/expected_output.txt rename tests/atest/rules/{misc/custom_imports_not_sorted => community_rules/misc/non_builtin_imports_not_sorted}/no_builtins.robot (100%) rename tests/atest/rules/{misc/custom_imports_not_sorted => community_rules/misc/non_builtin_imports_not_sorted}/no_imports.robot (100%) rename tests/atest/rules/{misc/custom_imports_not_sorted => community_rules/misc/non_builtin_imports_not_sorted}/only_builtins.robot (100%) rename tests/atest/rules/{misc/custom_imports_not_sorted => community_rules/misc/non_builtin_imports_not_sorted}/test.robot (100%) rename tests/atest/rules/{misc/custom_imports_not_sorted => community_rules/misc/non_builtin_imports_not_sorted}/test_rule.py (100%) delete mode 100644 tests/atest/rules/misc/custom_imports_not_sorted/expected_output.txt diff --git a/robocop/checkers/community_rules/misc.py b/robocop/checkers/community_rules/misc.py new file mode 100644 index 000000000..88c40daa1 --- /dev/null +++ b/robocop/checkers/community_rules/misc.py @@ -0,0 +1,61 @@ +from robot.api import Token +from robot.libraries import STDLIBS + +from robocop.checkers import VisitorChecker +from robocop.rules import Rule, RuleSeverity + +RULE_CATEGORY_ID = "01" + + +rules = { + "10101": Rule( + rule_id="10101", + name="non-builtin-imports-not-sorted", + msg="Non builtin library import '{{ custom_import }}' should be placed before '{{ previous_custom_import }}'", + severity=RuleSeverity.WARNING, + enabled=False, + docs=""" + Example of rule violation: + + *** Settings *** + Library Collections + Library CustomLibrary + Library AnotherCustomLibrary # AnotherCustomLibrary library defined after custom CustomLibrary + + """, + added_in_version="5.2.0", + ), +} + + +class NonBuiltinLibrariesImportOrderChecker(VisitorChecker): + """ + Find and report Non Builtin Libraries imported not in alphabetical order. + """ + + reports = ("non-builtin-imports-not-sorted",) + + def __init__(self): + self.non_builtin_libraries = [] + super().__init__() + + def visit_File(self, node): # noqa + self.non_builtin_libraries = [] + self.generic_visit(node) + previous = None + for library in self.non_builtin_libraries: + if previous is not None and library.name < previous.name: + lib_name = library.get_token(Token.NAME) + self.report( + "non-builtin-imports-not-sorted", + custom_import=library.name, + previous_custom_import=previous.name, + node=library, + col=lib_name.col_offset + 1, + end_col=lib_name.end_col_offset + 1, + ) + previous = library + + def visit_LibraryImport(self, node): # noqa + if node.name and node.name not in STDLIBS: + self.non_builtin_libraries.append(node) diff --git a/robocop/checkers/misc.py b/robocop/checkers/misc.py index b1bba9f85..6d23fbe9d 100644 --- a/robocop/checkers/misc.py +++ b/robocop/checkers/misc.py @@ -599,21 +599,7 @@ Library Collections # BuiltIn libraries imported not in alphabetical order """, - ), - "0927": Rule( - rule_id="0927", - name="custom-imports-not-sorted", - msg="Custom library import '{{ custom_import }}' should be placed before '{{ previous_custom_import }}'", - severity=RuleSeverity.WARNING, - docs=""" - Example of rule violation:: - - *** Settings *** - Library Collections - Library CustomLibrary - Library AnotherCustomLibrary # AnotherCustomLibrary library defined after custom CustomLibrary - - """, + added_in_version="5.2.0", ), } @@ -825,7 +811,10 @@ class SettingsOrderChecker(VisitorChecker): BuiltIn libraries imports should always be placed before other libraries imports. """ - reports = ("wrong-import-order", "builtin-imports-not-sorted", "custom-imports-not-sorted") + reports = ( + "wrong-import-order", + "builtin-imports-not-sorted", + ) def __init__(self): self.libraries = [] @@ -836,7 +825,6 @@ def visit_File(self, node): # noqa self.generic_visit(node) first_non_builtin = None previous_builtin = None - previous_non_builtin = None for library in self.libraries: if first_non_builtin is None: if library.name not in STDLIBS: @@ -864,18 +852,6 @@ def visit_File(self, node): # noqa end_col=lib_name.end_col_offset + 1, ) previous_builtin = library - else: - if previous_non_builtin is not None and library.name < previous_non_builtin.name: - lib_name = library.get_token(Token.NAME) - self.report( - "custom-imports-not-sorted", - custom_import=library.name, - previous_custom_import=previous_non_builtin.name, - node=library, - col=lib_name.col_offset + 1, - end_col=lib_name.end_col_offset + 1, - ) - previous_non_builtin = library def visit_LibraryImport(self, node): # noqa if not node.name: diff --git a/tests/atest/rules/misc/custom_imports_not_sorted/__init__.py b/tests/atest/rules/community_rules/misc/non_builtin_imports_not_sorted/__init__.py similarity index 100% rename from tests/atest/rules/misc/custom_imports_not_sorted/__init__.py rename to tests/atest/rules/community_rules/misc/non_builtin_imports_not_sorted/__init__.py diff --git a/tests/atest/rules/community_rules/misc/non_builtin_imports_not_sorted/expected_output.txt b/tests/atest/rules/community_rules/misc/non_builtin_imports_not_sorted/expected_output.txt new file mode 100644 index 000000000..6b2ff6656 --- /dev/null +++ b/tests/atest/rules/community_rules/misc/non_builtin_imports_not_sorted/expected_output.txt @@ -0,0 +1,2 @@ +no_builtins.robot:4:12 [W] 10101 Non builtin library import 'OwnLib.py' should be placed before 'RequestsLibrary' +test.robot:9:12 [W] 10101 Non builtin library import 'AnotherLibrary' should be placed before 'RequestsLibrary' \ No newline at end of file diff --git a/tests/atest/rules/misc/custom_imports_not_sorted/no_builtins.robot b/tests/atest/rules/community_rules/misc/non_builtin_imports_not_sorted/no_builtins.robot similarity index 100% rename from tests/atest/rules/misc/custom_imports_not_sorted/no_builtins.robot rename to tests/atest/rules/community_rules/misc/non_builtin_imports_not_sorted/no_builtins.robot diff --git a/tests/atest/rules/misc/custom_imports_not_sorted/no_imports.robot b/tests/atest/rules/community_rules/misc/non_builtin_imports_not_sorted/no_imports.robot similarity index 100% rename from tests/atest/rules/misc/custom_imports_not_sorted/no_imports.robot rename to tests/atest/rules/community_rules/misc/non_builtin_imports_not_sorted/no_imports.robot diff --git a/tests/atest/rules/misc/custom_imports_not_sorted/only_builtins.robot b/tests/atest/rules/community_rules/misc/non_builtin_imports_not_sorted/only_builtins.robot similarity index 100% rename from tests/atest/rules/misc/custom_imports_not_sorted/only_builtins.robot rename to tests/atest/rules/community_rules/misc/non_builtin_imports_not_sorted/only_builtins.robot diff --git a/tests/atest/rules/misc/custom_imports_not_sorted/test.robot b/tests/atest/rules/community_rules/misc/non_builtin_imports_not_sorted/test.robot similarity index 100% rename from tests/atest/rules/misc/custom_imports_not_sorted/test.robot rename to tests/atest/rules/community_rules/misc/non_builtin_imports_not_sorted/test.robot diff --git a/tests/atest/rules/misc/custom_imports_not_sorted/test_rule.py b/tests/atest/rules/community_rules/misc/non_builtin_imports_not_sorted/test_rule.py similarity index 100% rename from tests/atest/rules/misc/custom_imports_not_sorted/test_rule.py rename to tests/atest/rules/community_rules/misc/non_builtin_imports_not_sorted/test_rule.py diff --git a/tests/atest/rules/misc/custom_imports_not_sorted/expected_output.txt b/tests/atest/rules/misc/custom_imports_not_sorted/expected_output.txt deleted file mode 100644 index 103b4c387..000000000 --- a/tests/atest/rules/misc/custom_imports_not_sorted/expected_output.txt +++ /dev/null @@ -1,2 +0,0 @@ -no_builtins.robot:4:12 [W] 0927 Custom library import 'OwnLib.py' should be placed before 'RequestsLibrary' -test.robot:9:12 [W] 0927 Custom library import 'AnotherLibrary' should be placed before 'RequestsLibrary' \ No newline at end of file From b4827f240b1a64937231ad42e1e9dd868a028714 Mon Sep 17 00:00:00 2001 From: Szymon Slodkowski Date: Thu, 6 Jun 2024 10:51:42 +0200 Subject: [PATCH 3/4] Add community rule checking order of Resource imports --- robocop/checkers/community_rules/misc.py | 43 ++++++++++++++++++- .../resources_imports_not_sorted/__init__.py | 0 .../expected_output.txt | 2 + .../no_resources.robot | 9 ++++ .../resources_imports_not_sorted/test.robot | 14 ++++++ .../resources_imports_not_sorted/test_rule.py | 6 +++ tests/atest/utils/__init__.py | 9 +++- 7 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 tests/atest/rules/community_rules/misc/resources_imports_not_sorted/__init__.py create mode 100644 tests/atest/rules/community_rules/misc/resources_imports_not_sorted/expected_output.txt create mode 100644 tests/atest/rules/community_rules/misc/resources_imports_not_sorted/no_resources.robot create mode 100644 tests/atest/rules/community_rules/misc/resources_imports_not_sorted/test.robot create mode 100644 tests/atest/rules/community_rules/misc/resources_imports_not_sorted/test_rule.py diff --git a/robocop/checkers/community_rules/misc.py b/robocop/checkers/community_rules/misc.py index 88c40daa1..cbb03f7e0 100644 --- a/robocop/checkers/community_rules/misc.py +++ b/robocop/checkers/community_rules/misc.py @@ -25,22 +25,43 @@ """, added_in_version="5.2.0", ), + "10102": Rule( + rule_id="10102", + name="resources-imports-not-sorted", + msg="Resource import '{{ resource_import }}' should be placed before '{{ previous_resource_import }}'", + severity=RuleSeverity.WARNING, + enabled=False, + docs=""" + Example of rule violation: + + *** Settings *** + Resource CustomResource.resource + Resource AnotherFile.resource + + """, + added_in_version="5.2.0", + ), } class NonBuiltinLibrariesImportOrderChecker(VisitorChecker): """ - Find and report Non Builtin Libraries imported not in alphabetical order. + Find and report Non Builtin Libraries or Resources imported not in alphabetical order. """ - reports = ("non-builtin-imports-not-sorted",) + reports = ( + "non-builtin-imports-not-sorted", + "resources-imports-not-sorted", + ) def __init__(self): self.non_builtin_libraries = [] + self.resources = [] super().__init__() def visit_File(self, node): # noqa self.non_builtin_libraries = [] + self.resources = [] self.generic_visit(node) previous = None for library in self.non_builtin_libraries: @@ -55,7 +76,25 @@ def visit_File(self, node): # noqa end_col=lib_name.end_col_offset + 1, ) previous = library + previous = None + for resource in self.resources: + if previous is not None and resource.name < previous.name: + resource_name = resource.get_token(Token.NAME) + self.report( + "resources-imports-not-sorted", + resource_import=resource.name, + previous_resource_import=previous.name, + node=resource, + col=resource_name.col_offset + 1, + end_col=resource_name.end_col_offset + 1, + ) + previous = resource def visit_LibraryImport(self, node): # noqa if node.name and node.name not in STDLIBS: self.non_builtin_libraries.append(node) + + def visit_ResourceImport(self, node): # noqa + if not node.name: + return + self.resources.append(node) diff --git a/tests/atest/rules/community_rules/misc/resources_imports_not_sorted/__init__.py b/tests/atest/rules/community_rules/misc/resources_imports_not_sorted/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/atest/rules/community_rules/misc/resources_imports_not_sorted/expected_output.txt b/tests/atest/rules/community_rules/misc/resources_imports_not_sorted/expected_output.txt new file mode 100644 index 000000000..e8005bcba --- /dev/null +++ b/tests/atest/rules/community_rules/misc/resources_imports_not_sorted/expected_output.txt @@ -0,0 +1,2 @@ +test.robot:5:12 [W] 10102 Resource import 'AnotherFile.resource' should be placed before 'CustomResource.resource' +test.robot:6:12 [W] 10102 Resource import '..\${/}Libs\${/}MyResource.robot' should be placed before 'AnotherFile.resource' \ No newline at end of file diff --git a/tests/atest/rules/community_rules/misc/resources_imports_not_sorted/no_resources.robot b/tests/atest/rules/community_rules/misc/resources_imports_not_sorted/no_resources.robot new file mode 100644 index 000000000..f95b100af --- /dev/null +++ b/tests/atest/rules/community_rules/misc/resources_imports_not_sorted/no_resources.robot @@ -0,0 +1,9 @@ +*** Settings *** +Library RequestsLibrary +Variables variables.py +Test Template Keyword + + +*** Keywords *** +Keyword + No Operation diff --git a/tests/atest/rules/community_rules/misc/resources_imports_not_sorted/test.robot b/tests/atest/rules/community_rules/misc/resources_imports_not_sorted/test.robot new file mode 100644 index 000000000..56846f078 --- /dev/null +++ b/tests/atest/rules/community_rules/misc/resources_imports_not_sorted/test.robot @@ -0,0 +1,14 @@ +*** Settings *** +Library DateTime +Library RequestsLibrary +Resource CustomResource.resource +Resource AnotherFile.resource +Resource ..${/}Libs${/}MyResource.robot + +Variables variables.py +Test Template Keyword + + +*** Keywords *** +Keyword + No Operation diff --git a/tests/atest/rules/community_rules/misc/resources_imports_not_sorted/test_rule.py b/tests/atest/rules/community_rules/misc/resources_imports_not_sorted/test_rule.py new file mode 100644 index 000000000..88377fa01 --- /dev/null +++ b/tests/atest/rules/community_rules/misc/resources_imports_not_sorted/test_rule.py @@ -0,0 +1,6 @@ +from tests.atest.utils import RuleAcceptance + + +class TestRuleAcceptance(RuleAcceptance): + def test_rule(self): + self.check_rule(expected_file="expected_output.txt") diff --git a/tests/atest/utils/__init__.py b/tests/atest/utils/__init__.py index a42289089..f9c5510e0 100644 --- a/tests/atest/utils/__init__.py +++ b/tests/atest/utils/__init__.py @@ -46,7 +46,14 @@ def load_expected_file(test_data, expected_file): return [] expected = test_data / expected_file with open(expected, encoding="utf-8") as f: - return sorted([line.rstrip("\n").replace(r"${/}", os.path.sep) for line in f]) + return sorted( + [ + re.sub(r"(? Date: Thu, 6 Jun 2024 11:31:59 +0200 Subject: [PATCH 4/4] Reformat Rules definitions to be consistence with existing --- robocop/checkers/community_rules/misc.py | 4 ++-- robocop/checkers/misc.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/robocop/checkers/community_rules/misc.py b/robocop/checkers/community_rules/misc.py index cbb03f7e0..bb3314bb8 100644 --- a/robocop/checkers/community_rules/misc.py +++ b/robocop/checkers/community_rules/misc.py @@ -13,6 +13,7 @@ name="non-builtin-imports-not-sorted", msg="Non builtin library import '{{ custom_import }}' should be placed before '{{ previous_custom_import }}'", severity=RuleSeverity.WARNING, + added_in_version="5.2.0", enabled=False, docs=""" Example of rule violation: @@ -23,13 +24,13 @@ Library AnotherCustomLibrary # AnotherCustomLibrary library defined after custom CustomLibrary """, - added_in_version="5.2.0", ), "10102": Rule( rule_id="10102", name="resources-imports-not-sorted", msg="Resource import '{{ resource_import }}' should be placed before '{{ previous_resource_import }}'", severity=RuleSeverity.WARNING, + added_in_version="5.2.0", enabled=False, docs=""" Example of rule violation: @@ -39,7 +40,6 @@ Resource AnotherFile.resource """, - added_in_version="5.2.0", ), } diff --git a/robocop/checkers/misc.py b/robocop/checkers/misc.py index 6d23fbe9d..16b5e2587 100644 --- a/robocop/checkers/misc.py +++ b/robocop/checkers/misc.py @@ -591,6 +591,7 @@ name="builtin-imports-not-sorted", msg="BuiltIn library import '{{ builtin_import }}' should be placed before '{{ previous_builtin_import }}'", severity=RuleSeverity.WARNING, + added_in_version="5.2.0", docs=""" Example of rule violation:: @@ -599,7 +600,6 @@ Library Collections # BuiltIn libraries imported not in alphabetical order """, - added_in_version="5.2.0", ), }