[diffoscope] 01/01: Output coloured diff using colordiff(1) via --text-color={never, auto, always}

Ximin Luo infinity0 at debian.org
Tue Nov 29 22:01:17 CET 2016


This is an automated email from the git hooks/post-receive script.

infinity0 pushed a commit to branch master
in repository diffoscope.

commit 266878a136cf0b2540b04ede34d046a54c8cdbbd
Author: Ximin Luo <infinity0 at debian.org>
Date:   Tue Nov 29 22:00:49 2016 +0100

    Output coloured diff using colordiff(1) via --text-color={never,auto,always}
---
 diffoscope/exc.py             |  4 ++++
 diffoscope/main.py            | 18 ++++++++++++++++--
 diffoscope/presenters/text.py | 25 +++++++++++++++++--------
 3 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/diffoscope/exc.py b/diffoscope/exc.py
index 116e813..4cdea92 100644
--- a/diffoscope/exc.py
+++ b/diffoscope/exc.py
@@ -40,6 +40,10 @@ class RequiredToolNotFound(Exception):
             'debian': 'diffutils',
             'arch': 'diffutils',
         },
+        'colordiff': {
+            'debian': 'colordiff',
+            'arch': 'colordiff',
+        },
         'cpio': {
             'debian': 'cpio',
             'arch': 'cpio',
diff --git a/diffoscope/main.py b/diffoscope/main.py
index 1290f59..e0c7d79 100644
--- a/diffoscope/main.py
+++ b/diffoscope/main.py
@@ -30,7 +30,7 @@ import contextlib
 
 import diffoscope.comparators
 
-from diffoscope import logger, VERSION, set_locale, clean_all_temp_files
+from diffoscope import logger, VERSION, set_locale, clean_all_temp_files, tool_required
 from diffoscope.exc import RequiredToolNotFound
 from diffoscope.config import Config
 from diffoscope.difference import Difference
@@ -73,6 +73,11 @@ def create_parser():
     group1 = parser.add_argument_group('output types')
     group1.add_argument('--text', metavar='OUTPUT_FILE', dest='text_output',
                         help='Write plain text output to given file (use - for stdout)')
+    group1.add_argument('--text-color', metavar='WHEN', default='auto',
+                        choices=['never', 'auto', 'always'],
+                        help='When to output color diff, using colordiff(1). '
+                        'WHEN is one of {%(choices)s}. Default: auto, meaning '
+                        'yes if the output is a terminal, otherwise no.')
     group1.add_argument('--output-empty', action='store_true',
                         help='If there was no difference, then output an empty '
                         'diff for each output type that was specified. (For '
@@ -171,6 +176,7 @@ def make_printer(path):
     def print_func(*args, **kwargs):
         kwargs['file'] = output
         print(*args, **kwargs)
+    print_func.output = output
     yield print_func
     if path != '-':
         output.close()
@@ -218,6 +224,7 @@ def maybe_set_limit(config, parsed_args, key):
         setattr(config, key, float("inf"))
 
 
+ at tool_required('colordiff')
 def run_diffoscope(parsed_args):
     if not tlsh and Config().fuzzy_threshold != parsed_args.fuzzy_threshold:
         logger.warning('Fuzzy-matching is currently disabled as the "tlsh" module is unavailable.')
@@ -252,7 +259,14 @@ def run_diffoscope(parsed_args):
                 open(parsed_args.text_output, 'w').close()
             else:
                 with make_printer(parsed_args.text_output or '-') as print_func:
-                    output_text(difference, print_func=print_func)
+                    text_color = parsed_args.text_color
+                    if text_color == 'auto':
+                        color = print_func.output.isatty()
+                    elif text_color == 'always':
+                        color = True
+                    elif text_color == 'never':
+                        color = False
+                    output_text(difference, print_func=print_func, color=color)
         if parsed_args.html_output:
             with make_printer(parsed_args.html_output) as print_func:
                 output_html(difference, css_url=parsed_args.css_url, print_func=print_func)
diff --git a/diffoscope/presenters/text.py b/diffoscope/presenters/text.py
index 306fb5b..6fffe24 100644
--- a/diffoscope/presenters/text.py
+++ b/diffoscope/presenters/text.py
@@ -18,20 +18,29 @@
 # You should have received a copy of the GNU General Public License
 # along with diffoscope.  If not, see <http://www.gnu.org/licenses/>.
 
+import subprocess
 import sys
 
 from diffoscope import logger
 
 
-def print_difference(difference, print_func):
+def print_difference(difference, print_func, color=False):
     if difference.comments:
         for comment in difference.comments:
             print_func(u"│┄ %s" % comment)
     if difference.unified_diff:
-        for line in difference.unified_diff.splitlines():
+        if color:
+            with subprocess.Popen(["colordiff"],
+                                  stdin=subprocess.PIPE,
+                                  stdout=subprocess.PIPE,
+                                  universal_newlines=True) as proc:
+                diff_output, _ = proc.communicate(difference.unified_diff)
+        else:
+            diff_output = difference.unified_diff
+        for line in diff_output.splitlines():
             print_func(u"│ %s" % line)
 
-def print_details(difference, print_func):
+def print_details(difference, print_func, color=False):
     if not difference.details:
         return
     for detail in difference.details:
@@ -40,18 +49,18 @@ def print_details(difference, print_func):
         else:
             print_func(u"│   --- %s" % (detail.source1))
             print_func(u"├── +++ %s" % (detail.source2))
-        print_difference(detail, print_func)
+        print_difference(detail, print_func, color)
         def new_print_func(*args, **kwargs):
             print_func(u'│  ', *args, **kwargs)
-        print_details(detail, new_print_func)
+        print_details(detail, new_print_func, color)
     print_func(u'╵')
 
-def output_text(difference, print_func):
+def output_text(difference, print_func, color=False):
     try:
         print_func("--- %s" % (difference.source1))
         print_func("+++ %s" % (difference.source2))
-        print_difference(difference, print_func)
-        print_details(difference, print_func)
+        print_difference(difference, print_func, color)
+        print_details(difference, print_func, color)
     except UnicodeEncodeError:
         logger.critical('Console is unable to print Unicode characters. Set e.g. PYTHONIOENCODING=utf-8')
         sys.exit(2)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/diffoscope.git


More information about the diffoscope mailing list