text.py 2.95 KB
Newer Older
1 2
# -*- coding: utf-8 -*-
#
Jérémy Bobbio's avatar
Jérémy Bobbio committed
3
# diffoscope: in-depth comparison of files, archives, and directories
4
#
5
# Copyright © 2017 Chris Lamb <lamby@debian.org>
6
#
Jérémy Bobbio's avatar
Jérémy Bobbio committed
7
# diffoscope is free software: you can redistribute it and/or modify
8 9 10 11
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
Jérémy Bobbio's avatar
Jérémy Bobbio committed
12
# diffoscope is distributed in the hope that it will be useful,
13 14 15 16 17
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
18
# along with diffoscope.  If not, see <https://www.gnu.org/licenses/>.
19

20
import re
21 22
import sys
import logging
Chris Lamb's avatar
Chris Lamb committed
23

24
from diffoscope.diff import color_unified_diff
25
from diffoscope.config import Config
26

27 28 29 30
from .utils import Presenter, create_limited_print_func, PrintLimitReached, \
    make_printer

logger = logging.getLogger(__name__)
31 32


33 34 35 36 37
class TextPresenter(Presenter):
    PREFIX = u'│ '
    RE_PREFIX = re.compile(r'(^|\n)')

    def __init__(self, print_func, color):
38 39
        self.print_func = create_limited_print_func(
            print_func,
40
            Config().max_text_report_size,
41
        )
42 43 44 45
        self.color = color

        super().__init__()

46
    @classmethod
47 48
    def run(cls, data, difference, parsed_args):
        with make_printer(data['target']) as fn:
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
            color = {
                'auto': fn.output.isatty(),
                'never': False,
                'always': True,
            }[parsed_args.text_color]

            presenter = cls(fn, color)

            try:
                presenter.start(difference)
            except UnicodeEncodeError:
                logger.critical(
                    "Console is unable to print Unicode characters. Set e.g. "
                    "PYTHONIOENCODING=utf-8"
                )
                sys.exit(2)

66 67 68 69 70 71
    def start(self, difference):
        try:
            super().start(difference)
        except PrintLimitReached:
            self.print_func("Max output size reached.", force=True)

72 73 74 75 76 77
    def visit_difference(self, difference):
        if self.depth == 0:
            self.output("--- {}".format(difference.source1))
            self.output("+++ {}".format(difference.source2))
        elif difference.source1 == difference.source2:
            self.output(u"├── {}".format(difference.source1))
78
        else:
79 80 81 82 83 84 85 86 87 88 89 90
            self.output(u"│   --- {}".format(difference.source1))
            self.output(u"├── +++ {}".format(difference.source2))

        for x in difference.comments:
            self.output(u"│┄ {}".format(x))

        diff = difference.unified_diff

        if diff:
            self.output(color_unified_diff(diff) if self.color else diff, True)

    def output(self, val, raw=False):
91
        self.print_func(
92
            self.indent(val, self.PREFIX * (self.depth + (0 if raw else -1))),
93
        )