From e045c6c511e61ac74c90373ca7ec7cfe0705d71a Mon Sep 17 00:00:00 2001 From: Benjamin Schubert Date: Tue, 8 Nov 2022 20:09:45 +0000 Subject: [PATCH] Allow showing the diff when using --in-place or --check with --diff It can be useful to show the difference, e.g. in CI so that users know what is or should be changed. This adds a `--diff` option, that, when combined with `--check` or `--in-place`, will, in addition, show the diff to stdout. --- src/docformatter/configuration.py | 6 ++++ src/docformatter/format.py | 13 ++++++--- tests/test_docformatter.py | 47 ++++++++++++++++++++++++++----- 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/docformatter/configuration.py b/src/docformatter/configuration.py index be1be5d..ea43aec 100644 --- a/src/docformatter/configuration.py +++ b/src/docformatter/configuration.py @@ -102,6 +102,12 @@ def do_parse_arguments(self) -> None: action="store_true", help="only check and report incorrectly formatted files", ) + self.parser.add_argument( + "-d", + "--diff", + action="store_true", + help="when used with `--check` or `--in-place`, also what changes would be made", + ) self.parser.add_argument( "-r", "--recursive", diff --git a/src/docformatter/format.py b/src/docformatter/format.py index 506c182..0f32942 100644 --- a/src/docformatter/format.py +++ b/src/docformatter/format.py @@ -155,8 +155,6 @@ def do_format_files(self): try: result = self._do_format_file(filename) outcomes[result] += 1 - if result == FormatResult.check_failed: - print(unicode(filename), file=self.stderror) except IOError as exception: outcomes[FormatResult.error] += 1 print(unicode(exception), file=self.stderror) @@ -190,9 +188,13 @@ def _do_format_file(self, filename): source = input_file.read() formatted_source = self._do_format_code(source) + ret = FormatResult.ok + show_diff = self.args.diff + if source != formatted_source: if self.args.check: - return FormatResult.check_failed + print(unicode(filename), file=self.stderror) + ret = FormatResult.check_failed elif self.args.in_place: with self.encodor.do_open_with_encoding( filename, @@ -200,6 +202,9 @@ def _do_format_file(self, filename): ) as output_file: output_file.write(formatted_source) else: + show_diff = True + + if show_diff: # Standard Library Imports import difflib @@ -212,7 +217,7 @@ def _do_format_file(self, filename): ) self.stdout.write("\n".join(list(diff) + [""])) - return FormatResult.ok + return ret def _do_format_code(self, source): """Return source code with docstrings formatted. diff --git a/tests/test_docformatter.py b/tests/test_docformatter.py index 20007ee..f2b26ac 100644 --- a/tests/test_docformatter.py +++ b/tests/test_docformatter.py @@ -97,11 +97,18 @@ def foo(): ''' ], ) - def test_in_place(self, temporary_file, contents): + @pytest.mark.parametrize( + "diff", [True, False], ids=["show-diff", "no-diff"] + ) + def test_in_place(self, temporary_file, contents, diff): """Should make changes and save back to file.""" output_file = io.StringIO() + args = ["my_fake_program", "--in-place", temporary_file] + if diff: + args.append("--diff") + main._main( - argv=["my_fake_program", "--in-place", temporary_file], + argv=args, standard_out=output_file, standard_error=None, standard_in=None, @@ -115,6 +122,11 @@ def foo(): == f.read() ) + if diff: + assert "def foo" in output_file.getvalue() + else: + assert "def foo" not in output_file + @pytest.mark.system @pytest.mark.parametrize( "contents", @@ -167,12 +179,21 @@ def test_io_error_exit_code(self): "contents", ["""Totally fine docstring, do not report anything."""], ) - def test_check_mode_correct_docstring(self, temporary_file, contents): + @pytest.mark.parametrize( + "diff", [True, False], ids=["show-diff", "no-diff"] + ) + def test_check_mode_correct_docstring( + self, temporary_file, contents, diff + ): """""" stdout = io.StringIO() stderr = io.StringIO() + args = ["my_fake_program", "--check", temporary_file] + if diff: + args.append("--diff") + ret_code = main._main( - argv=["my_fake_program", "--check", temporary_file], + argv=args, standard_out=stdout, standard_error=stderr, standard_in=None, @@ -193,18 +214,30 @@ def test_check_mode_correct_docstring(self, temporary_file, contents): ''' ], ) - def test_check_mode_incorrect_docstring(self, temporary_file, contents): + @pytest.mark.parametrize( + "diff", [True, False], ids=["show-diff", "no-diff"] + ) + def test_check_mode_incorrect_docstring( + self, temporary_file, contents, diff + ): """""" stdout = io.StringIO() stderr = io.StringIO() + args = ["my_fake_program", "--check", temporary_file] + if diff: + args.append("--diff") + ret_code = main._main( - argv=["my_fake_program", "--check", temporary_file], + argv=args, standard_out=stdout, standard_error=stderr, standard_in=None, ) assert ret_code == 3 # FormatResult.check_failed - assert stdout.getvalue() == "" + if diff: + assert "Print my path" in stdout.getvalue() + else: + assert stdout.getvalue() == "" assert stderr.getvalue().strip() == temporary_file