Loading diffoscope/diff.py +7 −0 Original line number Diff line number Diff line Loading @@ -252,6 +252,13 @@ def diff(feeder1, feeder2): return run_diff(fifo1_path, fifo2_path, fifo1.end_nl_q, fifo2.end_nl_q) def diff_split_lines(diff, keepends=True): lines = diff.split("\n") if not keepends: return lines return [line + "\n" for line in lines[:-1]] + ([lines[-1]] if lines[-1] else []) def reverse_unified_diff(diff): res = [] for line in diff.splitlines(keepends=True): Loading diffoscope/difference.py +29 −11 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ import logging from . import feeders from .exc import RequiredToolNotFound from .diff import diff, reverse_unified_diff from .diff import diff, reverse_unified_diff, diff_split_lines from .excludes import command_excluded logger = logging.getLogger(__name__) Loading Loading @@ -70,27 +70,45 @@ class Difference(object): self._details, ) def get_reverse(self): logger.debug("Reverse orig %s %s", self.source1, self.source2) def map_lines(self, f_diff, f_comment): unified_diff = self.unified_diff return self.__class__( "".join(map(f_diff, diff_split_lines(unified_diff))) if unified_diff is not None else None, self.source1, self.source2, comment=["".join(map(f_comment, diff_split_lines(comment))) for comment in self.comments], has_internal_linenos=self.has_internal_linenos, details=self._details, ) def fmap(self, f): if self._visuals: raise NotImplementedError( "Reversing VisualDifference is not yet implemented", "fmap on VisualDifference is not yet implemented", ) return f(self.__class__( self.unified_diff, self.source1, self.source2, comment=self.comments, has_internal_linenos=self.has_internal_linenos, details=[d.fmap(f) for d in self._details], )) diff = self.unified_diff if diff is not None: diff = reverse_unified_diff(self.unified_diff) return Difference( diff, def _reverse_self(self): return self.__class__( reverse_unified_diff(self.unified_diff) if self.unified_diff is not None else None, self.source2, self.source1, comment=self.comments, has_internal_linenos=self.has_internal_linenos, details=[d.get_reverse() for d in self._details], details=self._details, ) def get_reverse(self): logger.debug("Reverse orig %s %s", self.source1, self.source2) return self.fmap(Difference._reverse_self) def equals(self, other): return self == other or ( self.unified_diff == other.unified_diff and Loading diffoscope/readers/__init__.py +1 −1 Original line number Diff line number Diff line Loading @@ -28,4 +28,4 @@ def load_diff_from_path(path): def load_diff(fp, path): return JSONReaderV1().load(fp, 'stdin') return JSONReaderV1().load(fp, path) tests/data/debian-bug-875281.collapsed-diff.json 0 → 100644 +3934 −0 File added.Preview size limit exceeded, changes collapsed. Show changes tests/test_presenters.py +21 −1 Original line number Diff line number Diff line Loading @@ -17,14 +17,18 @@ # You should have received a copy of the GNU General Public License # along with diffoscope. If not, see <https://www.gnu.org/licenses/>. import io import os import re import pytest from diffoscope.main import main from diffoscope.readers import load_diff_from_path from diffoscope.presenters.utils import create_limited_print_func, PrintLimitReached, PartialString from diffoscope.presenters.json import JSONPresenter from .utils.data import cwd_data, get_data from .utils import diff_expand from .utils.data import cwd_data, data, get_data from .utils.tools import skip_unless_tools_exist re_html = re.compile(r'.*<body(?P<body>.*)<div class="footer">', re.MULTILINE | re.DOTALL) Loading Loading @@ -58,6 +62,14 @@ def extract_body(val): return result def expand_collapsed_json(tmpdir, name): diff = load_diff_from_path(data(name + ".collapsed-diff.json")) diff_path = str(tmpdir.join(name + '.diff.json')) with open(diff_path, 'w') as fp: JSONPresenter(lambda x: print(x, file=fp)).start(diff.fmap(diff_expand)) return diff_path def test_text_option_is_default(capsys): out = run(capsys) Loading Loading @@ -158,6 +170,14 @@ def test_html_option_with_stdout(capsys): assert body.count('div class="difference"') == 4 def test_html_regression_875281(tmpdir, capsys): # this test fails when you `git revert -Xtheirs ccd926f` diff_path = expand_collapsed_json(tmpdir, 'debian-bug-875281') report_path = str(tmpdir.join('report.html')) out = run(capsys, '--html', report_path, pair=(diff_path,)) assert out == '' def test_limited_print(): def fake(x): return None with pytest.raises(PrintLimitReached): Loading Loading
diffoscope/diff.py +7 −0 Original line number Diff line number Diff line Loading @@ -252,6 +252,13 @@ def diff(feeder1, feeder2): return run_diff(fifo1_path, fifo2_path, fifo1.end_nl_q, fifo2.end_nl_q) def diff_split_lines(diff, keepends=True): lines = diff.split("\n") if not keepends: return lines return [line + "\n" for line in lines[:-1]] + ([lines[-1]] if lines[-1] else []) def reverse_unified_diff(diff): res = [] for line in diff.splitlines(keepends=True): Loading
diffoscope/difference.py +29 −11 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ import logging from . import feeders from .exc import RequiredToolNotFound from .diff import diff, reverse_unified_diff from .diff import diff, reverse_unified_diff, diff_split_lines from .excludes import command_excluded logger = logging.getLogger(__name__) Loading Loading @@ -70,27 +70,45 @@ class Difference(object): self._details, ) def get_reverse(self): logger.debug("Reverse orig %s %s", self.source1, self.source2) def map_lines(self, f_diff, f_comment): unified_diff = self.unified_diff return self.__class__( "".join(map(f_diff, diff_split_lines(unified_diff))) if unified_diff is not None else None, self.source1, self.source2, comment=["".join(map(f_comment, diff_split_lines(comment))) for comment in self.comments], has_internal_linenos=self.has_internal_linenos, details=self._details, ) def fmap(self, f): if self._visuals: raise NotImplementedError( "Reversing VisualDifference is not yet implemented", "fmap on VisualDifference is not yet implemented", ) return f(self.__class__( self.unified_diff, self.source1, self.source2, comment=self.comments, has_internal_linenos=self.has_internal_linenos, details=[d.fmap(f) for d in self._details], )) diff = self.unified_diff if diff is not None: diff = reverse_unified_diff(self.unified_diff) return Difference( diff, def _reverse_self(self): return self.__class__( reverse_unified_diff(self.unified_diff) if self.unified_diff is not None else None, self.source2, self.source1, comment=self.comments, has_internal_linenos=self.has_internal_linenos, details=[d.get_reverse() for d in self._details], details=self._details, ) def get_reverse(self): logger.debug("Reverse orig %s %s", self.source1, self.source2) return self.fmap(Difference._reverse_self) def equals(self, other): return self == other or ( self.unified_diff == other.unified_diff and Loading
diffoscope/readers/__init__.py +1 −1 Original line number Diff line number Diff line Loading @@ -28,4 +28,4 @@ def load_diff_from_path(path): def load_diff(fp, path): return JSONReaderV1().load(fp, 'stdin') return JSONReaderV1().load(fp, path)
tests/data/debian-bug-875281.collapsed-diff.json 0 → 100644 +3934 −0 File added.Preview size limit exceeded, changes collapsed. Show changes
tests/test_presenters.py +21 −1 Original line number Diff line number Diff line Loading @@ -17,14 +17,18 @@ # You should have received a copy of the GNU General Public License # along with diffoscope. If not, see <https://www.gnu.org/licenses/>. import io import os import re import pytest from diffoscope.main import main from diffoscope.readers import load_diff_from_path from diffoscope.presenters.utils import create_limited_print_func, PrintLimitReached, PartialString from diffoscope.presenters.json import JSONPresenter from .utils.data import cwd_data, get_data from .utils import diff_expand from .utils.data import cwd_data, data, get_data from .utils.tools import skip_unless_tools_exist re_html = re.compile(r'.*<body(?P<body>.*)<div class="footer">', re.MULTILINE | re.DOTALL) Loading Loading @@ -58,6 +62,14 @@ def extract_body(val): return result def expand_collapsed_json(tmpdir, name): diff = load_diff_from_path(data(name + ".collapsed-diff.json")) diff_path = str(tmpdir.join(name + '.diff.json')) with open(diff_path, 'w') as fp: JSONPresenter(lambda x: print(x, file=fp)).start(diff.fmap(diff_expand)) return diff_path def test_text_option_is_default(capsys): out = run(capsys) Loading Loading @@ -158,6 +170,14 @@ def test_html_option_with_stdout(capsys): assert body.count('div class="difference"') == 4 def test_html_regression_875281(tmpdir, capsys): # this test fails when you `git revert -Xtheirs ccd926f` diff_path = expand_collapsed_json(tmpdir, 'debian-bug-875281') report_path = str(tmpdir.join('report.html')) out = run(capsys, '--html', report_path, pair=(diff_path,)) assert out == '' def test_limited_print(): def fake(x): return None with pytest.raises(PrintLimitReached): Loading