From 2a054276cdf5f80f724ab5d7de8215792da5dc5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=91cze=20Bence?= Date: Thu, 14 Sep 2023 21:26:46 +0200 Subject: [PATCH] make data structure for shifted lines cleaner --- pydiffchecker/cli.py | 8 +++-- pydiffchecker/line_shift_checker.py | 48 ++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/pydiffchecker/cli.py b/pydiffchecker/cli.py index 1cbb0f1..436d31f 100644 --- a/pydiffchecker/cli.py +++ b/pydiffchecker/cli.py @@ -1,5 +1,4 @@ import argparse -import json from .version import get_version from .line_shift_checker import LineShiftChecker @@ -17,6 +16,9 @@ def main(): args = parser.parse_args() line_shift_checker = LineShiftChecker(args.revision_since, args.revision_until) - out = line_shift_checker.get_shifted_lines() + all_shifted_lines = line_shift_checker.get_all_shifted_lines() - print(json.dumps(out, indent=4)) + for src_path, shifted_lines in all_shifted_lines.items(): + print(f'* {src_path}->{shifted_lines.dst_path}:') + for src_line_index, dst_line_index in shifted_lines: + print(f' {src_line_index}->{dst_line_index}') diff --git a/pydiffchecker/line_shift_checker.py b/pydiffchecker/line_shift_checker.py index 9109f6c..e2d514c 100644 --- a/pydiffchecker/line_shift_checker.py +++ b/pydiffchecker/line_shift_checker.py @@ -1,8 +1,32 @@ import re -from typing import List, Dict +from typing import List, Dict, Sized, Iterable from .helper import subprocess_readlines +class ShiftedLines(Sized, Iterable): + def __init__(self, src_path: str, dst_path: str) -> None: + self.src_path = src_path + self.dst_path = dst_path + self.__lines: 'Dict[int, int | None]' = {} + + def __setitem__(self, src_line_index, dst_line_index) -> None: + self.__lines[src_line_index] = dst_line_index + + def __contains__(self, src_line_index) -> bool: + return src_line_index in self.__lines and self.__lines[src_line_index] is not None + + def __getitem__(self, src_line_index) -> 'int | None': + if src_line_index not in self.__lines: + return None + return self.__lines[src_line_index] + + def __iter__(self): + return iter(self.__lines.items()) + + def __len__(self) -> int: + return len(self.__lines) + + class LineShiftChecker: DIFF_BLOCK_REGEX = r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@' @@ -10,13 +34,9 @@ class LineShiftChecker: self.revision_since = revision_since self.revision_until = revision_until - def get_shifted_lines(self) -> Dict[str, Dict]: - shifted_lines = {} - - for file_info in self.__get_changed_files(): - shifted_lines[file_info['src']] = self.__get_shifted_lines_in_file(file_info) - - return shifted_lines + def get_all_shifted_lines(self) -> Dict[str, ShiftedLines]: + return {file_info['src']: self.__get_shifted_lines_in_file(file_info) + for file_info in self.__get_changed_files()} def __get_changed_files(self) -> List[Dict]: process_output = subprocess_readlines(['git', 'diff', '--name-status', '--diff-filter=MR', @@ -32,12 +52,12 @@ class LineShiftChecker: return file_list - def __get_shifted_lines_in_file(self, file_info) -> 'Dict[str, str | None]': + def __get_shifted_lines_in_file(self, file_info) -> ShiftedLines: process_output = subprocess_readlines(['git', 'diff', self.revision_since, self.revision_until, '--', file_info['src'], file_info['dst']]) - shifted_lines: 'Dict[str, str | None]' = {} + shifted_lines = ShiftedLines(file_info['src'], file_info['dst']) src_line_index = 1 dst_line_index = 1 diff_started = False @@ -49,7 +69,7 @@ class LineShiftChecker: # fill shifted lines between 2 diff blocks for i in range(0, diff_block_src_start - src_line_index): - shifted_lines[f'{file_info["src"]}:{src_line_index+i}'] = f'{file_info["dst"]}:{dst_line_index+i}' + shifted_lines[src_line_index+i] = dst_line_index+i src_line_index = diff_block_src_start dst_line_index = diff_block_dst_start @@ -60,19 +80,19 @@ class LineShiftChecker: continue if line.startswith(' '): - shifted_lines[f'{file_info["src"]}:{src_line_index}'] = f'{file_info["dst"]}:{dst_line_index}' + shifted_lines[src_line_index] = dst_line_index src_line_index += 1 dst_line_index += 1 elif line.startswith('+'): dst_line_index += 1 elif line.startswith('-'): - shifted_lines[f'{file_info["src"]}:{src_line_index}'] = None + shifted_lines[src_line_index] = None src_line_index += 1 # fill shifted lines until end of file lines_in_source_file = self.__count_lines_in_source_file(file_info['src']) for i in range(0, lines_in_source_file - src_line_index + 1): - shifted_lines[f'{file_info["src"]}:{src_line_index+i}'] = f'{file_info["dst"]}:{dst_line_index+i}' + shifted_lines[src_line_index+i] = dst_line_index+i assert lines_in_source_file == len(shifted_lines)