Skip to content

Commit

Permalink
Formatting summary & verbose output (#608)
Browse files Browse the repository at this point in the history
  • Loading branch information
bhirsz authored Dec 24, 2023
1 parent a9aead9 commit 83cd472
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 25 deletions.
33 changes: 33 additions & 0 deletions docs/releasenotes/unreleased/other.1.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
More verbose output (#572)
---------------------------

Robotidy output is now more verbose. If the file is formatted (or would be formatted if not for
``--check`` or ``--no-overwrite options) the file path and run summary is displayed:
```
> robotidy --check .
Would reformat D:\test_repository\resources\db_keywords.resource file
Would reformat D:\test_repository\tests\ui\login.robot file

2 files would be reformatted, 112 files would be left unchanged.
```

```
> robotidy .
Formatting D:\test_repository\resources\db_keywords.resource file
Formatting D:\test_repository\tests\ui\login.robot file

2 files reformatted, 112 files left unchanged.
```

```
> robotidy --verbose .
Found D:\test_repository\resources\ui_keywords.resource file
Found (...)
Formatting D:\test_repository\resources\db_keywords.resource file
Found (...)
Formatting D:\test_repository\tests\ui\login.robot file
Found (...)

2 files reformatted, 112 files left unchanged.
```
29 changes: 28 additions & 1 deletion robotidy/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ def get_model(self, source):

def transform_files(self):
changed_files = 0
all_files = 0
stdin = False
for source, config in self.main_config.get_sources_with_configs():
self.config = config
all_files += 1
disabler_finder = RegisterDisablers(self.config.formatting.start_line, self.config.formatting.end_line)
try:
stdin = False
Expand All @@ -40,14 +43,15 @@ def transform_files(self):
click.echo("Loading file from stdin")
source = self.load_from_stdin()
elif self.config.verbose:
click.echo(f"Transforming {source} file")
click.echo(f"Found {source} file")
model = self.get_model(source)
model_path = model.source
disabler_finder.visit(model)
if disabler_finder.file_disabled:
continue
diff, old_model, new_model, model = self.transform_until_stable(model, disabler_finder)
if diff:
self.log_formatted_source(source, stdin)
changed_files += 1
self.output_diff(model_path, old_model, new_model)
if stdin:
Expand All @@ -59,10 +63,33 @@ def transform_files(self):
f"Failed to decode {source}. Default supported encoding by Robot Framework is UTF-8. Skipping file"
)
pass
return self.formatting_result(all_files, changed_files, stdin)

def formatting_result(self, all_files: int, changed_files: int, stdin: bool):
"""
Print formatting summary and return status code.
"""
if not stdin:
all_files = all_files - changed_files
all_files_plurar = "" if all_files == 1 else "s"
changed_files_plurar = "" if changed_files == 1 else "s"
future_tense = "" if self.config.overwrite else " would be"
click.echo(
f"\n{changed_files} file{changed_files_plurar}{future_tense} reformatted, "
f"{all_files} file{all_files_plurar}{future_tense} left unchanged."
)
if not self.config.check or not changed_files:
return 0
return 1

def log_formatted_source(self, source: str, stdin: bool):
if stdin:
return
if not self.config.overwrite:
click.echo(f"Would reformat {source}")
else:
click.echo(f"Reformatted {source}")

def transform_until_stable(self, model, disabler_finder):
diff, old_model, new_model = self.transform(model, disabler_finder.disablers)
reruns = self.config.reruns
Expand Down
68 changes: 44 additions & 24 deletions tests/utest/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,6 @@ def switch_cwd(new_cwd):
os.chdir(prev_cwd)


@contextmanager
def switch_cwd(new_cwd):
prev_cwd = Path.cwd()
os.chdir(new_cwd)
try:
yield
finally:
os.chdir(prev_cwd)


class TestCli:
@pytest.mark.parametrize(
"name, similar",
Expand Down Expand Up @@ -320,28 +310,46 @@ def test_help(self, flag):
result = run_tidy([flag])
assert f"Robotidy is a tool for formatting" in result.output

@pytest.mark.parametrize("source, return_status", [("golden.robot", 0), ("not_golden.robot", 1)])
def test_check(self, source, return_status):
@pytest.mark.parametrize(
"source, return_status, expected_output",
[
("golden.robot", 0, "\n0 files would be reformatted, 1 file would be left unchanged.\n"),
("not_golden.robot", 1, "\n1 file would be reformatted, 0 files would be left unchanged.\n"),
],
)
def test_check(self, source, return_status, expected_output):
source = TEST_DATA_DIR / "check" / source
if return_status:
expected_output = f"Would reformat {source}\n{expected_output}"
with patch("robotidy.utils.misc.ModelWriter") as mock_writer:
run_tidy(
result = run_tidy(
["--check", "--transform", "NormalizeSectionHeaderName", str(source)],
exit_code=return_status,
)
mock_writer.assert_not_called()
assert result.output == expected_output

@pytest.mark.parametrize("source, return_status", [("golden.robot", 0), ("not_golden.robot", 1)])
def test_check_overwrite(self, source, return_status):
@pytest.mark.parametrize(
"source, return_status, expected_output",
[
("golden.robot", 0, "\n0 files reformatted, 1 file left unchanged.\n"),
("not_golden.robot", 1, "\n1 file reformatted, 0 files left unchanged.\n"),
],
)
def test_check_overwrite(self, source, return_status, expected_output):
source = TEST_DATA_DIR / "check" / source
if return_status:
expected_output = f"Reformatted {source}\n{expected_output}"
with patch("robotidy.utils.misc.ModelWriter") as mock_writer:
run_tidy(
result = run_tidy(
["--check", "--overwrite", "--transform", "NormalizeSectionHeaderName", str(source)],
exit_code=return_status,
)
if return_status:
mock_writer.assert_called()
else:
mock_writer.assert_not_called()
assert result.output == expected_output

@pytest.mark.parametrize("color_flag", ["--color", "--no-color", None])
@pytest.mark.parametrize("color_env", [True, False])
Expand Down Expand Up @@ -409,26 +417,38 @@ def test_exclude_gitignore(self, exclude, extend_exclude, skip_gitignore, allowe
assert paths == allowed_paths

@pytest.mark.parametrize(
"source, should_parse",
"source, should_parse, summary",
[
(None, ["test.robot", "resources/test.robot"]), # calls: robotidy
("test3.robot", ["test3.robot"]), # calls: robotidy test3.robot
("test.robot", ["test.robot"]),
(".", ["test.robot", "test3.robot", "resources/test.robot"]),
(
None,
["test.robot", "resources/test.robot"],
"0 files reformatted, 2 files left unchanged.",
), # calls: robotidy
(
"test3.robot",
["test3.robot"],
"0 files reformatted, 1 file left unchanged.",
), # calls: robotidy test3.robot
("test.robot", ["test.robot"], "0 files reformatted, 1 file left unchanged."),
(
".",
["test.robot", "test3.robot", "resources/test.robot"],
"0 files reformatted, 3 files left unchanged.",
),
],
)
def test_src_and_space_in_param_in_configuration(self, source, should_parse):
def test_src_and_space_in_param_in_configuration(self, source, should_parse, summary):
source_dir = TEST_DATA_DIR / "pyproject_with_src"
os.chdir(source_dir)
if source is not None:
source = source_dir / source
result = run_tidy([str(source)])
else:
result = run_tidy()
expected = [f"Loaded configuration from {source_dir / 'pyproject.toml'}"]
expected = [f"Loaded configuration from {source_dir / 'pyproject.toml'}", summary]
for file in should_parse:
path = source_dir / file
expected.append(f"Transforming {path} file")
expected.append(f"Found {path} file")
actual = sorted(line for line in result.output.split("\n") if line.strip())
assert actual == sorted(expected)

Expand Down

0 comments on commit 83cd472

Please sign in to comment.