From 1ae5448cc01bd1bc3af6e12a23b58337ee20e241 Mon Sep 17 00:00:00 2001 From: Kentaro Wada Date: Mon, 5 Sep 2022 02:36:16 +0900 Subject: [PATCH 1/3] Apply more granular changes by using # fmt: skip --- src/darker/__main__.py | 54 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/src/darker/__main__.py b/src/darker/__main__.py index 5dd3d390a..150e53f03 100644 --- a/src/darker/__main__.py +++ b/src/darker/__main__.py @@ -10,6 +10,8 @@ from pathlib import Path from typing import Collection, Generator, List, Tuple +from black.comments import FMT_SKIP + from darker.black_diff import ( BlackConfig, filter_python_files, @@ -191,15 +193,63 @@ def _blacken_single_file( # pylint: disable=too-many-arguments,too-many-locals """ absolute_path_in_rev2 = root / relative_path_in_rev2 + # find the fmt_skip comment that won't conflict with the code + fmt_skip = None + for comment in FMT_SKIP: + if comment not in rev2_isorted.string: + fmt_skip = comment + if fmt_skip is None: + logger.warning( + "Detected the mixed styles of `# fmt: skip` comments in " + f"{absolute_path_in_rev2}, " + "please use one style to get the best result" + ) + # decorate lines with fmt_skip + lines = [] + modified_line_nums = edited_linenums_differ.revision_vs_lines( + relative_path_in_repo, rev2_isorted, 0 + ) + for i, line in enumerate(rev2_isorted.lines): + line_num = i + 1 + if ( + fmt_skip is not None + and line_num not in modified_line_nums + and not any(f in line for f in FMT_SKIP) + ): + line = f"{line} {fmt_skip}" + lines.append(line) + rev2_isorted_decorated = TextDocument.from_lines( + lines, + encoding=rev2_isorted.encoding, + newline=rev2_isorted.newline, + mtime=rev2_isorted.mtime, + ) + # 4. run black - formatted = run_black(rev2_isorted, black_config) + formatted = run_black(rev2_isorted_decorated, black_config) logger.debug( "Read %s lines from edited file %s", - len(rev2_isorted.lines), + len(rev2_isorted_decorated.lines), absolute_path_in_rev2, ) logger.debug("Black reformat resulted in %s lines", len(formatted.lines)) + # redecorate lines without fmt_skip + lines = [] + for line in formatted.lines: + if fmt_skip is not None: + if line.endswith(f" {fmt_skip}"): + line = line[: -len(f" {fmt_skip}")] + elif line == fmt_skip: + line = "" + lines.append(line) + formatted = TextDocument.from_lines( + lines, + encoding=formatted.encoding, + newline=formatted.newline, + mtime=formatted.mtime, + ) + # 5. get the diff between the edited and reformatted file # 6. convert the diff into chunks black_chunks = diff_chunks(rev2_isorted, formatted) From 788178e16c8112c11fcdd6acaf1ea371133a57b1 Mon Sep 17 00:00:00 2001 From: Kentaro Wada Date: Mon, 5 Sep 2022 20:04:34 +0900 Subject: [PATCH 2/3] Use darker-specific decoration for fmt: skip --- src/darker/__main__.py | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/src/darker/__main__.py b/src/darker/__main__.py index 150e53f03..79afde758 100644 --- a/src/darker/__main__.py +++ b/src/darker/__main__.py @@ -10,7 +10,11 @@ from pathlib import Path from typing import Collection, Generator, List, Tuple -from black.comments import FMT_SKIP +from black.comments import FMT_SKIP, FMT_PASS + +FMT_DARKER_SKIP = "# fmt: darker-skip" +FMT_SKIP.add(FMT_DARKER_SKIP) +FMT_PASS.add(FMT_DARKER_SKIP) from darker.black_diff import ( BlackConfig, @@ -193,30 +197,15 @@ def _blacken_single_file( # pylint: disable=too-many-arguments,too-many-locals """ absolute_path_in_rev2 = root / relative_path_in_rev2 - # find the fmt_skip comment that won't conflict with the code - fmt_skip = None - for comment in FMT_SKIP: - if comment not in rev2_isorted.string: - fmt_skip = comment - if fmt_skip is None: - logger.warning( - "Detected the mixed styles of `# fmt: skip` comments in " - f"{absolute_path_in_rev2}, " - "please use one style to get the best result" - ) - # decorate lines with fmt_skip + # decorate lines with FMT_DARKER_SKIP lines = [] modified_line_nums = edited_linenums_differ.revision_vs_lines( relative_path_in_repo, rev2_isorted, 0 ) for i, line in enumerate(rev2_isorted.lines): line_num = i + 1 - if ( - fmt_skip is not None - and line_num not in modified_line_nums - and not any(f in line for f in FMT_SKIP) - ): - line = f"{line} {fmt_skip}" + if line_num not in modified_line_nums: + line = f"{line} {FMT_DARKER_SKIP}" lines.append(line) rev2_isorted_decorated = TextDocument.from_lines( lines, @@ -234,14 +223,13 @@ def _blacken_single_file( # pylint: disable=too-many-arguments,too-many-locals ) logger.debug("Black reformat resulted in %s lines", len(formatted.lines)) - # redecorate lines without fmt_skip + # redecorate lines without FMT_DARKER_SKIP lines = [] for line in formatted.lines: - if fmt_skip is not None: - if line.endswith(f" {fmt_skip}"): - line = line[: -len(f" {fmt_skip}")] - elif line == fmt_skip: - line = "" + if line.endswith(f" {FMT_DARKER_SKIP}"): + line = line[: -len(f" {FMT_DARKER_SKIP}")] + elif line == FMT_DARKER_SKIP: + line = "" lines.append(line) formatted = TextDocument.from_lines( lines, From 8b447973238953a567be5b4d4b61195b969d5cef Mon Sep 17 00:00:00 2001 From: Kentaro Wada Date: Mon, 5 Sep 2022 20:05:26 +0900 Subject: [PATCH 3/3] Support multi-line string when using fmt: skip decoration --- src/darker/__main__.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/darker/__main__.py b/src/darker/__main__.py index 79afde758..0b7236340 100644 --- a/src/darker/__main__.py +++ b/src/darker/__main__.py @@ -204,7 +204,12 @@ def _blacken_single_file( # pylint: disable=too-many-arguments,too-many-locals ) for i, line in enumerate(rev2_isorted.lines): line_num = i + 1 - if line_num not in modified_line_nums: + if ( + line_num not in modified_line_nums + and not line.endswith("\\") + and not line.endswith('"') + and not line.endswith("'") + ): line = f"{line} {FMT_DARKER_SKIP}" lines.append(line) rev2_isorted_decorated = TextDocument.from_lines(