Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for RF 7.2 GROUP syntax #733

Merged
merged 1 commit into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion robotidy/api.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Methods for transforming Robot Framework ast model programmatically.
"""

from __future__ import annotations

from pathlib import Path
Expand Down Expand Up @@ -37,7 +38,8 @@ def transform_model(model, root_dir: str, output: str | None = None, **kwargs) -
"""
robotidy_class = get_robotidy(root_dir, output, **kwargs)
disabler_finder = disablers.RegisterDisablers(
robotidy_class.config.formatting.start_line, robotidy_class.config.formatting.end_line
robotidy_class.config.formatting.start_line,
robotidy_class.config.formatting.end_line,
)
disabler_finder.visit(model)
if disabler_finder.is_disabled_in_file(disablers.ALL_TRANSFORMERS):
Expand Down
12 changes: 10 additions & 2 deletions robotidy/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ def transform_files(self):
self.output_diff(model_path, old_model, new_model)
changed_files += 1
except DataError as err:
click.echo(f"Failed to decode {source} with an error: {err}\nSkipping file", err=True)
click.echo(
f"Failed to decode {source} with an error: {err}\nSkipping file",
err=True,
)
changed_files = previous_changed_files
skipped_files += 1
return self.formatting_result(all_files, changed_files, skipped_files, stdin)
Expand Down Expand Up @@ -141,7 +144,12 @@ def get_line_ending(self, path: str):
return f.newlines[0]
return self.config.formatting.line_sep

def output_diff(self, path: str, old_model: misc.StatementLinesCollector, new_model: misc.StatementLinesCollector):
def output_diff(
self,
path: str,
old_model: misc.StatementLinesCollector,
new_model: misc.StatementLinesCollector,
):
if not self.config.show_diff:
return
old = [l + "\n" for l in old_model.text.splitlines()]
Expand Down
23 changes: 19 additions & 4 deletions robotidy/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@
"--endline",
],
},
{"name": "File exclusion", "options": ["--exclude", "--extend-exclude", "--skip-gitignore"]},
{
"name": "File exclusion",
"options": ["--exclude", "--extend-exclude", "--skip-gitignore"],
},
skip.option_group,
{
"name": "Other",
Expand Down Expand Up @@ -124,7 +127,11 @@ def print_transformer_docs(transformer):
@decorators.optional_rich
def print_description(name: str, target_version: int):
# TODO: --desc works only for default transformers, it should also print custom transformer desc
transformers = load_transformers(TransformConfigMap([], [], []), allow_disabled=True, target_version=target_version)
transformers = load_transformers(
TransformConfigMap([], [], []),
allow_disabled=True,
target_version=target_version,
)
transformer_by_names = {transformer.name: transformer for transformer in transformers}
if name == "all":
for transformer in transformers:
Expand Down Expand Up @@ -159,7 +166,11 @@ def print_transformers_list(global_config: config_module.MainConfig):
table = Table(title="Transformers", header_style="bold red")
table.add_column("Name", justify="left", no_wrap=True)
table.add_column("Enabled")
transformers = load_transformers(TransformConfigMap([], [], []), allow_disabled=True, target_version=target_version)
transformers = load_transformers(
TransformConfigMap([], [], []),
allow_disabled=True,
target_version=target_version,
)
transformers.extend(_load_external_transformers(transformers, config.transformers_config, target_version))

for transformer in transformers:
Expand Down Expand Up @@ -194,7 +205,11 @@ def generate_config(global_config: config_module.MainConfig):
raise exceptions.MissingOptionalTomliWDependencyError()
target_version = global_config.default.target_version
config = global_config.default_loaded
transformers = load_transformers(TransformConfigMap([], [], []), allow_disabled=True, target_version=target_version)
transformers = load_transformers(
TransformConfigMap([], [], []),
allow_disabled=True,
target_version=target_version,
)
transformers.extend(_load_external_transformers(transformers, config.transformers_config, target_version))

toml_config = {
Expand Down
22 changes: 18 additions & 4 deletions robotidy/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,12 @@ def convert_transformers_config(
is_config: bool = False,
) -> list[TransformConfig]:
return [
TransformConfig(tr, force_include=force_included, custom_transformer=custom_transformer, is_config=is_config)
TransformConfig(
tr,
force_include=force_included,
custom_transformer=custom_transformer,
is_config=is_config,
)
for tr in config.get(param_name, ())
]

Expand Down Expand Up @@ -186,7 +191,10 @@ def from_config_file(self, config: dict, config_path: Path) -> "RawConfig":
Dictionary key:values needs to be normalized and parsed to correct types.
"""
options_map = map_class_fields_with_their_types(self)
parsed_config = {"defined_in_config": {"defined_in_config", "config_path"}, "config_path": config_path}
parsed_config = {
"defined_in_config": {"defined_in_config", "config_path"},
"config_path": config_path,
}
for key, value in config.items():
# workaround to be able to use two option names for same action - backward compatibility change
if key == "load_transformers":
Expand All @@ -206,7 +214,10 @@ def from_config_file(self, config: dict, config_path: Path) -> "RawConfig":
parsed_config[key] = [convert_transform_config(val, key) for val in value]
elif key == "src":
parsed_config[key] = tuple(value)
elif value_type in ("Pattern", Pattern): # future typing for 3.8 provides type as str
elif value_type in (
"Pattern",
Pattern,
): # future typing for 3.8 provides type as str
parsed_config[key] = misc.validate_regex(value)
else:
parsed_config[key] = value
Expand Down Expand Up @@ -273,7 +284,10 @@ def get_sources(self, sources: tuple[str, ...]) -> tuple[str, ...] | None:

def get_sources_with_configs(self):
sources = files.get_paths(
self.sources, self.default.exclude, self.default.extend_exclude, self.default.skip_gitignore
self.sources,
self.default.exclude,
self.default.extend_exclude,
self.default.skip_gitignore,
)
for source in sources:
if self.default.config:
Expand Down
7 changes: 6 additions & 1 deletion robotidy/disablers.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,12 @@ def is_line_start(node):


class DisablersInFile:
def __init__(self, start_line: Optional[int], end_line: Optional[int], file_end: Optional[int] = None):
def __init__(
self,
start_line: Optional[int],
end_line: Optional[int],
file_end: Optional[int] = None,
):
self.start_line = start_line
self.end_line = end_line
self.file_end = file_end
Expand Down
7 changes: 6 additions & 1 deletion robotidy/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,12 @@ def get_path_relative_to_project_root(path: Path, root_parent: Path) -> Path:
return path


def get_paths(src: tuple[str, ...], exclude: Pattern | None, extend_exclude: Pattern | None, skip_gitignore: bool):
def get_paths(
src: tuple[str, ...],
exclude: Pattern | None,
extend_exclude: Pattern | None,
skip_gitignore: bool,
):
root = find_project_root(src)
if skip_gitignore:
gitignore = None
Expand Down
16 changes: 14 additions & 2 deletions robotidy/skip.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,16 @@ def __init__(self, skip_config: SkipConfig):

@staticmethod
def parse_skip_settings(skip_config):
settings = {"settings", "arguments", "setup", "teardown", "timeout", "template", "return_statement", "tags"}
settings = {
"settings",
"arguments",
"setup",
"teardown",
"timeout",
"template",
"return_statement",
"tags",
}
skip_settings = set()
for setting in settings:
if getattr(skip_config, setting):
Expand Down Expand Up @@ -156,7 +165,10 @@ def section(self, name):
documentation_option = click.option("--skip-documentation", is_flag=True, help="Skip formatting of documentation")
return_values_option = click.option("--skip-return-values", is_flag=True, help="Skip formatting of return values")
keyword_call_option = click.option(
"--skip-keyword-call", type=str, multiple=True, help="Keyword call name that should not be formatted"
"--skip-keyword-call",
type=str,
multiple=True,
help="Keyword call name that should not be formatted",
)
keyword_call_pattern_option = click.option(
"--skip-keyword-call-pattern",
Expand Down
8 changes: 7 additions & 1 deletion robotidy/transformers/AlignSettingsSection.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,13 @@ def align_rows(self, statements, look_up):
def calc_separator(self, index, up_to, indent_arg, token, look_up):
if index < up_to:
if self.fixed_width:
return max(self.fixed_width - len(token.value), self.formatting_config.space_count) * " "
return (
max(
self.fixed_width - len(token.value),
self.formatting_config.space_count,
)
* " "
)
arg_indent = self.argument_indent if indent_arg else 0
if indent_arg and index != 0:
return (
Expand Down
8 changes: 7 additions & 1 deletion robotidy/transformers/AlignTemplatedTestCases.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,13 @@ def align_header(self, statement):
for index, token in enumerate(statement.data_tokens[:-1]):
tokens.append(token)
if self.min_width:
separator = max(self.formatting_config.space_count, self.min_width - len(token.value)) * " "
separator = (
max(
self.formatting_config.space_count,
self.min_width - len(token.value),
)
* " "
)
else:
separator = (self.widths[index] - len(token.value) + self.formatting_config.space_count) * " "
tokens.append(Token(Token.SEPARATOR, separator))
Expand Down
16 changes: 14 additions & 2 deletions robotidy/transformers/AlignVariablesSection.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,13 @@ class AlignVariablesSection(Transformer):
To align all columns set ``up_to_column`` to 0.
"""

def __init__(self, up_to_column: int = 2, skip_types: str = "", min_width: int = None, fixed_width: int = None):
def __init__(
self,
up_to_column: int = 2,
skip_types: str = "",
min_width: int = None,
fixed_width: int = None,
):
super().__init__()
self.up_to_column = up_to_column - 1
self.min_width = min_width
Expand Down Expand Up @@ -121,7 +127,13 @@ def align_rows(self, statements, look_up):
def get_separator(self, index: int, up_to: int, token, look_up: dict[int, int]) -> str:
if index < up_to:
if self.fixed_width:
return max(self.fixed_width - len(token.value), self.formatting_config.space_count) * " "
return (
max(
self.fixed_width - len(token.value),
self.formatting_config.space_count,
)
* " "
)
return (look_up[index] - len(token.value)) * " "
else:
return self.formatting_config.separator
Expand Down
19 changes: 16 additions & 3 deletions robotidy/transformers/GenerateDocumentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,12 @@ class GenerateDocumentation(Transformer):

WHITESPACE_PATTERN = re.compile(r"(\s{2,}|\t)", re.UNICODE)

def __init__(self, overwrite: bool = False, doc_template: str = "google", template_directory: str | None = None):
def __init__(
self,
overwrite: bool = False,
doc_template: str = "google",
template_directory: str | None = None,
):
self.overwrite = overwrite
self.doc_template = self.load_template(doc_template, template_directory)
self.args_returns_finder = ArgumentsAndReturnsVisitor()
Expand Down Expand Up @@ -174,7 +179,11 @@ def visit_Keyword(self, node): # noqa
if not self.overwrite and self.args_returns_finder.doc_exists:
return node
formatting = FormattingData(self.formatting_config.continuation_indent, self.formatting_config.separator)
kw_data = KeywordData(node.name, self.args_returns_finder.arguments, self.args_returns_finder.returns)
kw_data = KeywordData(
node.name,
self.args_returns_finder.arguments,
self.args_returns_finder.returns,
)
generated = self.doc_template.render(keyword=kw_data, formatting=formatting)
doc_node = self.create_documentation_from_string(generated)
if self.overwrite:
Expand All @@ -186,7 +195,11 @@ def visit_Documentation(self, node): # noqa
return None

def create_documentation_from_string(self, doc_string):
new_line = [Token(Token.EOL), Token(Token.SEPARATOR, self.formatting_config.indent), Token(Token.CONTINUATION)]
new_line = [
Token(Token.EOL),
Token(Token.SEPARATOR, self.formatting_config.indent),
Token(Token.CONTINUATION),
]
tokens = [
Token(Token.SEPARATOR, self.formatting_config.indent),
Token(Token.DOCUMENTATION, "[Documentation]"),
Expand Down
13 changes: 11 additions & 2 deletions robotidy/transformers/IndentNestedKeywords.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,11 @@ def visit_SuiteSetup(self, node): # noqa
comments = misc.collect_comments_from_tokens(node.tokens, indent=None)
separator = self.get_separator()
new_line = misc.get_new_line()
tokens = [node.data_tokens[0], separator, *misc.join_tokens_with_token(lines[0][1], separator)]
tokens = [
node.data_tokens[0],
separator,
*misc.join_tokens_with_token(lines[0][1], separator),
]
formatted_tokens = self.parse_keyword_lines(lines, tokens, new_line, eol=node.tokens[-1])
if self.node_was_transformed(node.tokens, formatted_tokens):
node.tokens = formatted_tokens
Expand All @@ -144,7 +148,12 @@ def visit_Setup(self, node): # noqa
indent = node.tokens[0]
separator = self.get_separator()
new_line = misc.get_new_line(indent)
tokens = [indent, node.data_tokens[0], separator, *misc.join_tokens_with_token(lines[0][1], separator)]
tokens = [
indent,
node.data_tokens[0],
separator,
*misc.join_tokens_with_token(lines[0][1], separator),
]
comment = misc.merge_comments_into_one(node.tokens)
if comment:
# need to add comments on first line for [Setup] / [Teardown] settings
Expand Down
19 changes: 15 additions & 4 deletions robotidy/transformers/InlineIf.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,11 @@ def inline_if_from_branch(self, node, indent):
# check for ElseIfHeader first since it's child of IfHeader class
if isinstance(node.header, ElseIfHeader):
header = ElseIfHeader(
[Token(Token.ELSE_IF), Token(Token.SEPARATOR, separator), Token(Token.ARGUMENT, node.header.condition)]
[
Token(Token.ELSE_IF),
Token(Token.SEPARATOR, separator),
Token(Token.ARGUMENT, node.header.condition),
]
)
elif isinstance(node.header, IfHeader):
tokens = [Token(Token.SEPARATOR, indent)]
Expand All @@ -202,7 +206,10 @@ def inline_if_from_branch(self, node, indent):

@staticmethod
def to_inline_keyword(keyword, separator, last_token):
tokens = [Token(Token.SEPARATOR, separator), Token(Token.KEYWORD, keyword.keyword)]
tokens = [
Token(Token.SEPARATOR, separator),
Token(Token.KEYWORD, keyword.keyword),
]
for arg in keyword.get_tokens(Token.ARGUMENT):
tokens.extend([Token(Token.SEPARATOR, separator), arg])
tokens.append(last_token)
Expand Down Expand Up @@ -321,11 +328,15 @@ def handle_inline_if_create(self, node, indent, assign):
else_found = False
if isinstance(node.header, InlineIfHeader):
header = IfHeader.from_params(
condition=node.condition, indent=indent, separator=self.formatting_config.separator
condition=node.condition,
indent=indent,
separator=self.formatting_config.separator,
)
elif isinstance(node.header, ElseIfHeader):
header = ElseIfHeader.from_params(
condition=node.condition, indent=indent, separator=self.formatting_config.separator
condition=node.condition,
indent=indent,
separator=self.formatting_config.separator,
)
else:
header = ElseHeader.from_params(indent=indent)
Expand Down
5 changes: 4 additions & 1 deletion robotidy/transformers/NormalizeAssignments.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ class NormalizeAssignments(Transformer):
HANDLES_SKIP = frozenset({"skip_sections"})

def __init__(
self, equal_sign_type: str = "autodetect", equal_sign_type_variables: str = "remove", skip: Skip = None
self,
equal_sign_type: str = "autodetect",
equal_sign_type_variables: str = "remove",
skip: Skip = None,
):
super().__init__(skip)
self.remove_equal_sign = re.compile(r"\s?=$")
Expand Down
2 changes: 1 addition & 1 deletion robotidy/transformers/NormalizeNewLines.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def visit_If(self, node): # noqa
self.trim_empty_lines(node)
return self.generic_visit(node)

visit_For = visit_While = visit_Try = visit_If
visit_For = visit_While = visit_Group = visit_Try = visit_If

def visit_Statement(self, node): # noqa
tokens = []
Expand Down
Loading
Loading