Migrating to Robocop 6¶
Robocop 6.0 is a major release of both Robocop and Robotidy tools. Nearly all core functionality has been
rewritten, refactored, or replaced. This causes several breaking changes and requires some changes in your
configuration.
The following document describes the most important changes and how to migrate your configuration. Use migrate
command to migrate existing TOML configuration to the new format. Custom rules and argument files (now deprecated)
need to be migrated manually.
At first, adjust how you run Robocop using new check and format commands:
migrate command¶
To migrate your configuration to the new version, use migrate command:
It will create a new file named <config_path>_migrated.toml with translated option names and their structure.
Rule ids are also converted to the new format, but patterns are not migrated (such as 02*).
Most of the configuration options are migrated automatically, but some of them require manual changes.
Breaking changes in Robocop 6.0¶
Command line options changes¶
Most of the options were renamed to normalise naming between two tools or to make it more user-friendly.
Some of the old options (like --exclude) are now used for something else.
Rule selection options are now renamed:
-i/--includebecame-s/--select-e/--excludebecame-i/--ignore
File inclusion changes:
Previously, Robocop used paths argument and Robotidy src for selecting paths. It was then additionally
configured using options for filtering based on directory names or file types.
Now the role of paths was taken by include and --default--include (*.robot and .resource) options.
It is recommended to use cli for selecting a directory and leave it to robocop to find and filter out files.
If nothing is configured (we only run robocop check / robocop format) then it will start from the current
directory. List of new or deprecated options:
pathsbecame--include-ft/--filetypesis now deprecated in favour of using--includeor--default-includeoption-g/--ignorebecame-e/--exclude(additionally excluded paths)-gd/--ignore-defaultbecame--default-exclude(paths excluded by default)
More on how to configure file paths in the file discovery section in the documentation.
--list options were overhauled and became commands:
- Robocop
--listused to list available rules becamelist rulescommand:
- Robocop
-lr/--list-reportsused to list available reports became ``list reports command:
- Robocop
-lc / --list-configurableswas overhauled and was incorporated todocscommand:
This command will print rule documentation and possible parameters.
- Robotidy
--listused to list available formatters becamelist formatterscommand:
Describe options (--desc) are now replaced by docs command which can print rule, report or formatter
documentation.
Issue format --format is now renamed to --issue-format. Please note that --issue-format is used only
for simple output format and extended output format is now used as a default.
Formatting options from Robotidy:
--lineseparatorbecame--line-ending--spacecountbecame--space-count-sl/--startlinebecame--start-line-el/--endlinebecame--end-line
-rules / --ext-rules can be now only used under --custom-rules name.
--load-transformers / --custom-transformers is now renamed to --custom-formatters. In Robocop 7.0 it is
renamed to --extend-select.
-nr / --no-recursive is now deprecated. Similar behaviour can be reached by passing file paths to robocop or
configuring --exclude option.
(Robotidy) Formatter deprecated --transform option¶
--transform option used to select formatters is now deprecated. It has been replaced by --select which function
in a similar way but has one key difference: it does not support configuration. Configuration can be now passed only
to the dedicated --configure option.
Previous command:
robotidy --transform YourTransformer:parameter=value --configure DefaultTransformer:other_parameter=value
Can be now achieved by:
robocop format --select YourTransformer --configure YourTransformer.parameter=value --configure DefaultTransformer.other_parameter=value
All other transform mentions were also deprecated, for example:
TRANSFORMERSlist inside custom formatters to indicate order of the formatting should be now namedFORMATTERSTransformerclass was renamed toFormatter
(Robocop) linter deprecated argument file¶
Linter alternative configuration file format - --argumentfile / .robocop file is now deprecated.
From now on we will only support one configuration file format (toml based).
More information on the current configuration file syntax at configuration.
Linter and formatter configuration syntax change¶
Robocop used two : to separate param and value in --config option. Robotidy used : and =.
New Robocop now uses . and =. Previous configuration changed from:
to:
robocop check --configure rule_or_report.param=value
robocop format --configure formatter.param=value
It is also no longer possible to chain multiple configurations in one configure call. The following example:
For readability reasons it can be now done only using separate options:
Passing configuration through file names that contain formatter is also deprecated:
Use the implicit name of the formatter instead:
Configuration file syntax changes¶
Due to the merge of the tool, the syntax of the configuration file has changed. Most of the changes originate from the changes to option names etc. Some changes are, however, dictated by the merge itself.
General settings are now available under tool.robocop section:
Linter- or formatter-specific settings are available under lint or format sections:
[tool.robocop.lint]
configure = [
"line-too-long.line_length=110"
]
[tool.robocop.format]
skip = ["documentation"]
configure = [
"NormalizeSeparators.skip_documentation=False"
]
Documentation describes with examples where particular options should be configured.
--target-version different input syntax¶
Formatter --target-version can now only accept numbers. Previous configuration such as --target-version RF5
should be now --target-version 5.
Issue source is now relative by default¶
Relative path to source is now used by default when printing the linter issues.
Previous output, if run from robot_project directory:
D:/code/robot_project/tests/test.robot:19:59 [W] 0601 Tag '${var} space' should not contain spaces (tag-with-space)
New output:
robot_project/tests/test.robot:19:59 [W] 0601 Tag '${var} space' should not contain spaces (tag-with-space)
Previous issue format keyword source_rel is deprecated and source is used instead. It is still possible to use
absolute paths in output by configuring issue format to source_abs:
Replaced --output option with the text_file report¶
As part of the improved and safer design, linter option --output is now deprecated.
Instead, text_file report can be used:
text_file report supports only simple issue output format.
Deprecated singular global skip options in the formatter (Robotidy)¶
Robotidy offered multiple options to skip formatting of different statement types if the formatter allows it:
--skip-documentation
--skip-return-values
--skip-keyword-call
--skip-keyword-call-pattern
--skip-settings
--skip-arguments
--skip-setup
--skip-teardown
--skip-timeout
--skip-template
--skip-return
--skip-tags
--skip-comments
--skip-block-comments
--skip-sections
Several options were combined under a single option named skip:
--skip documentation
--skip return-values
--skip settings
--skip arguments
--skip setup
--skip teardown
--skip timeout
--skip template
--skip return
--skip tags
--skip comments
--skip block-comments
--skip-sections
--skip-keyword-call
--skip-keyword-call-pattern
skip accept multiple values from the cli or the configuration files.
Overriding skip on the formatter level still uses the previous syntax:
return_status report is now optional¶
Return status (exit code) of Robocop depended on internal, always enabled return_status report. It was calculated
based on parameter quality_gate. Default configuration:
It means that any error or warning will count towards exit code. Information messages by default were not counted towards exit code. Actual exit code is the number of issues over the set limit, up to 255 (for example, with 'W': 100 and 105 warnings, exit code will be 5).
This behaviour wasn't clear to most and makes Robocop unpredictable when run in CI/CD pipelines. That's why we are
now making return_status report optional. It means that now exit code follows different logic:
- 0, if no rule violations were found
- 1, if violations were found
- 2, if Robocop terminated abnormally
It is possible to always return 0, ignoring any violations, with new --exit-zero flag. The previous behaviour
can be reproduced by simply enabling return_status report again:
compare_runs report is replaced with --compare¶
compare_runs was special report that had to be enabled to compare reports results from current run with previous
runs. It was a bit of a workaround, that's why it was removed.
To compare results, use --compare flag:
Remember that you still need results from previous run (saved with --persistent) and comparison is done on results
from the reports. Full example:
Community rules are now simply 'non-default' rules¶
We have introduced non-default, 'community' rules in an effort to increase contributions from the community. However, we noticed that it does not make sense to split our rules into 'internal' and 'community' ones. Rules contributed from the users are often added as the default rules. For rules that should be optional, it is enough to set them as non-default rules.
For that reason we are deprecating the term 'community' rules and all options related to it, such as filtering a list of rules by community rules.
Rule severity is now separate from the rule id¶
Robocop previously allowed selecting / ignoring / configuring rules using rule id with rule severity. For example:
Since rule severity is configurable, it could be potentially confusing. Additionally, it caused unindented issues when
using rule id with non-numeric characters (for example ERR001 could be interpreted as RR001 instead).
For those reasons it's not possible any more to refer to a rule using rule id with its severity. Use rule id without
severity or rule name instead:
Rules changes¶
We have reviewed all the rules to improve rule ids, names, documentation, messages, and overall design. It would be too much to list of all the changes, but we will list all changes that have an impact on the users.
Renamed messages
Multiple rules messages were updated to avoid words such as should be or suggestions for fixes and to simply
state what's the actual issue. For example bad-block-indent message:
Indent expected. Provide 2 or more spaces of indentation for statements inside block
became:
Not enough indentation inside block
The goal was to have clear and shorter messages. The actual issue is well described thanks to the rule documentation and new output format (which displays a source around the issue).
Rule id changes
Previous rule ids consisted of group id and unique rule number. For example 0201 - 02 was documentation group
id while 01 was unique rule number. This naming scheme wasn't clear and made it harder to categorise rule at first
glance. That's why we have switched to alphanumeric group names (for example DOC instead of 02).
Various groups are also additionally split into smaller subgroups. This change leads to backward incompatible
changes to all rule ids.
Documentation rules are now grouped under the 'DOC' group:
0201becameDOC01(missing-doc-keyword)0202becameDOC02(missing-doc-test-case)0203becameDOC03(missing-doc-suite)0204becameDOC04(missing-doc-resource-file)
Tags rules are now grouped under the 'TAG' group:
0601becameTAG01(tag-with-space)0602becameTAG02(tag-with-or-and)0603becameTAG03(tag-with-reserved-word)0605becameTAG05(could-be-test-tags)0606becameTAG06(tag-already-set-in-test-tags)0607becameTAG07(unnecessary-default-tags)0608becameTAG08(empty-tags)0609becameTAG09(duplicated-tags)0610becameTAG10(could-be-keyword-tags)0611becameTAG11(tag-already-set-in-keyword-tags)
Comments rules are now grouped under the 'COM' group:
0701becameCOM01(todo-in-comment)0702becameCOM02(missing-space-after-comment)0703becameCOM03(invalid-comment)0704becameCOM04(ignored-data)0705becameCOM05(bom-encoding-in-file)
Import-related rules are now grouped under the 'IMP' group:
0911becameIMP01(wrong-import-order)0926becameIMP02(builtin-imports-not-sorted)10101becameIMP03(non-builtin-imports-not-sorted)10102becameIMP04(resources-imports-not-sorted)
Spacing and whitespace-related rules are now grouped under the 'SPC' group:
1001becameSPC01(trailing-whitespace)1002becameSPC02(missing-trailing-blank-line)1003becameSPC03(empty-lines-between-sections)1004becameSPC04(empty-lines-between-test-cases)1005becameSPC05(empty-lines-between-keywords)1006becameSPC06(mixed-tabs-and-spaces)1008becameSPC08(bad-indent)1009becameSPC09(empty-line-after-section)1010becameSPC10(too-many-trailing-blank-lines)1011becameSPC11(misaligned-continuation)1012becameSPC12(consecutive-empty-lines)1013becameSPC13(empty-lines-in-statement)1014becameSPC14(variable-should-be-left-aligned->variable-not-left-aligned)1015becameSPC15(misaligned-continuation-row)1016becameSPC16(suite-setting-should-be-left-aligned->suite-setting-not-left-aligned)1017becameSPC17(bad-block-indent)1018becameSPC18(first-argument-in-new-line)0402becameSPC19(not-enough-whitespace-after-setting)0406becameSPC20(not-enough-whitespace-after-newline-marker)0410becameSPC21(not-enough-whitespace-after-variable)0411becameSPC22(not-enough-whitespace-after-suite-setting)
Duplications related rules are now grouped under the 'DUP' group:
0801becameDUP01(duplicated-test-case")0802becameDUP02(duplicated-keyword)0803becameDUP03(duplicated-variable)0804becameDUP04(duplicated-resource)0805becameDUP05(duplicated-library)0806becameDUP06(duplicated-metadata)0807becameDUP07(duplicated-variables-import)0808becameDUP08(section-already-defined)0810becameDUP09(both-tests-and-tasks)0813becameDUP10(duplicated-setting)
Length-related rules are now grouped under the 'LEN' group:
0501becameLEN01(too-long-keyword)0502becameLEN02(too-few-calls-in-keyword)0503becameLEN03(too-many-calls-in-keyword)0504becameLEN04(too-long-test-case)0528becameLEN05(too-few-calls-in-test-case)0505becameLEN06(too-many-calls-in-test-case)0507becameLEN07(too-many-arguments)0508becameLEN08(line-too-long)0509becameLEN09(empty-section)0510becameLEN10(number-of-returned-values)0511becameLEN11(empty-metadata)0512becameLEN12(empty-documentation)0513becameLEN13(empty-force-tags)0514becameLEN14(empty-default-tags)0515becameLEN15(empty-variables-import)0516becameLEN16(empty-resource-import)0517becameLEN17(empty-library-import)0518becameLEN18(empty-setup)0519becameLEN19(empty-suite-setup)0520becameLEN20(empty-test-setup)0521becameLEN21(empty-teardown)0522becameLEN22(empty-suite-teardown)0523becameLEN23(empty-test-teardown)0524becameLEN24(empty-timeout)0525becameLEN25(empty-test-timeout)0526becameLEN26(empty-arguments)0527becameLEN27(too-many-test-cases)0506becameLEN28(file-too-long)0529becameLEN29(empty-test-template)0530becameLEN30(empty-template)0531becameLEN31(empty-keyword-tags)
Variable-related rules are now grouped under the 'VAR' group:
0912becameVAR01(empty-variable)0920becameVAR02(unused-variable)0922becameVAR03(variable-overwritten-before-usage)0929becameVAR04(no-global-variable)0930becameVAR05(no-suite-variable)0931becameVAR06(no-test-variable)0310becameVAR07(non-local-variables-should-be-uppercase)0316becameVAR08(possible-variable-overwriting)0317becameVAR09(hyphen-in-variable-name)0323becameVAR10(inconsistent-variable-name)0324becameVAR11(overwriting-reserved-variable)0812becameVAR12(duplicated-assigned-var-name)
Argument-related rules are now grouped under the 'ARG' group:
0919becameARG01(unused-argument)0921becameARG02(argument-overwritten-before-usage)0932becameARG03(undefined-argument-default)0933becameARG04(undefined-argument-value)0407becameARG05(invalid-argument)0811becameARG06(duplicated-argument-name)0532becameARG07(arguments-per-line)
Deprecated syntax or code replacement recommendations are now grouped under the 'DEPR' group:
0908becameDEPR01(if-can-be-used)0319becameDEPR02(deprecated-statement)0321becameDEPR03(deprecated-with-name)0322becameDEPR04(deprecated-singular-header)0327becameDEPR05(replace-set-variable-with-var)0328becameDEPR06(replace-create-with-var)
Naming rules are now grouped under the 'NAME' group:
0301becameNAME01(not-allowed-char-in-name)0302becameNAME02(wrong-case-in-keyword-name)0303becameNAME03(keyword-name-is-reserved-word)0305becameNAME04(underscore-in-keyword-name)0306becameNAME05(setting-name-not-in-title-case)0307becameNAME06(section-name-invalid)0308becameNAME07(not-capitalized-test-case-title)0309becameNAME08(section-variable-not-uppercase)0311becameNAME09(else-not-upper-case)0312becameNAME10(keyword-name-is-empty)0313becameNAME11(test-case-name-is-empty)0314becameNAME12(empty-library-alias)0315becameNAME13(duplicated-library-alias)0318becameNAME14(bdd-without-keyword-call)0320becameNAME15(not-allowed-char-in-filename)0325becameNAME16(invalid-section)0326becameNAME17(mixed-task-test-settings)
Other rules are now grouped under the 'MISC' group:
0901becameMISC01(keyword-after-return)0903becameMISC02(empty-return)0907becameMISC03(nested-for-loop)0909becameMISC04(inconsistent-assignment)0910becameMISC05(inconsistent-assignment-in-variables)0913becameMISC06(can-be-resource-file)0914becameMISC07(if-can-be-merged)0915becameMISC08(statement-outside-loop)0916becameMISC09(inline-if-can-be-used)0917becameMISC10(unreachable-code)0918becameMISC11(multiline-inline-if)0923becameMISC12(unnecessary-string-conversion)0924becameMISC13(expression-can-be-simplified)0925becameMISC14(misplaced-negative-condition)
Miscellaneous keyword-related rules are now grouped under the 'KW' group:
10001becameKW01(sleep-keyword-used)10002becameKW02(not-allowed-keyword)10003becameKW03(no-embedded-keyword-arguments)10101becameKW04(unused-keyword)
Order-related rules (except imports) are now grouped under the 'ORD' group:
0927becameORD01(test-case-section-out-of-order)0928becameORD02(keyword-section-out-of-order)
New syntax for custom rules¶
Previous rule design is deprecated in favour of a new, more OOP-like design.
Example of the old syntax:
from robocop.checkers import VisitorChecker
from robocop.rules import Rule, RuleSeverity
rules = {
"1101": Rule(rule_id="1101", name="smth", msg="Keyword call after [Return] statement", severity=RuleSeverity.ERROR)
}
class SmthChecker(VisitorChecker):
"""Checker for keyword calls after the [Return] statement."""
reports = ("smth",)
def visit_Keyword(self, node): # noqa: N802
(...)
self.report("smth", node=node)
Rules are no longer defined in the global dictionaries. Each rule should be defined in their own class:
from robocop.linter.rules import Rule, RuleSeverity, VisitorChecker
class ExternalRule(Rule):
"""
Keyword call after the ``[Return]`` statement.
``[Return]`` setting does not return from the keyword and only sets which variables will be returned.
To avoid confusion, it is better to define it at the end of the keyword.
"""
name = "smth"
rule_id = "EXT01"
message = "Keyword call after [Return] statement"
severity = RuleSeverity.ERROR
class SmthChecker(VisitorChecker):
"""Checker for keyword calls after the [Return] statement."""
smth: ExternalRule
def visit_Keyword(self, node): # noqa: N802
(...)
self.report(self.smth, node=node)
Rules can be 'attached' to checkers that will be using them by using a class attribute together with a type hint:
Robocop will find and instantiate such attributes.
Rule params should use now refer directly to such an attribute instead of previous
self.param("rule_name", "param_name") calls:
Thanks to this design, it's also possible to move part of the implementation inside a rule class, with less rule-specific code in the visitor.
Note that various import paths also changed. For example, from:
to:
New disabler syntax¶
We normalised Robocop and Robotidy disablers several releases ago, but the old syntax was still allowed. We are now
deprecating it for good. Due to merge and deprecation of Robotidy, we also deprecate robotidy directive.
Currently supported syntax for linter:
And formatter:
Deprecated syntax:
New syntax still supports disabling selected rules or formatters (# robocop: off=rule_name).
Dropped support for Jinja templates in a rule message¶
Rule messages used Jinja templates:
It was unnecessarily complex as we only used it for value substitution. There is no need to use any other Jinja features. It is now replaced with Python format syntax:
It's important only for users who have custom rules using templates in messages.
Dropped support for Robot Framework 3.2¶
Since Robocop supported Robot Framework >=3.2.2 and Robotidy >= 4.0, we had to use 4.0 as a baseline version. Robocop can still be used to lint code written for RF 3, but you need an environment with at least RF 4 to run Robocop.
Dropped support for Python 3.8¶
Python 3.8 is no longer supported by Python foundation, and we are also dropping support for it.
Normalised output path configuration in JSON and sarif reports¶
In this release we have added several new reports that are file-based (such as gitlab, sonarqube etc. reports). To make it simpler and more logical, I have standardised how the output path can be configured for such reports.
The following configuration parameters are now deprecated in JSON and sarif reports:
- output_dir
- report_filename
Instead, we can use output_path to configure both directory and filename: