[diffoscope] 01/01: Add a machine-readable JSON output format. (Closes: #850791)

Chris Lamb chris at chris-lamb.co.uk
Tue Feb 7 01:15:16 CET 2017


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

lamby pushed a commit to branch master
in repository diffoscope.

commit c601f2d23450cf54dbe80af68700a449ba0e32a8
Author: Chris Lamb <lamby at debian.org>
Date:   Tue Feb 7 13:14:04 2017 +1300

    Add a machine-readable JSON output format. (Closes: #850791)
    
    Signed-off-by: Chris Lamb <lamby at debian.org>
---
 diffoscope/main.py             |  2 ++
 diffoscope/presenters/json.py  | 48 ++++++++++++++++++++++++++++++++++++++++++
 diffoscope/presenters/utils.py |  5 +++++
 tests/data/output.json         | 33 +++++++++++++++++++++++++++++
 tests/test_presenters.py       |  8 +++++++
 5 files changed, 96 insertions(+)

diff --git a/diffoscope/main.py b/diffoscope/main.py
index 5f233d4..eaccd6b 100644
--- a/diffoscope/main.py
+++ b/diffoscope/main.py
@@ -93,6 +93,8 @@ def create_parser():
                         '"disable" to disable JavaScript. When omitted '
                         'diffoscope will try to create a symlink to a system '
                         'installation. Known locations: %s' % ', '.join(JQUERY_SYSTEM_LOCATIONS))
+    group1.add_argument('--json', metavar='OUTPUT_FILE', dest='json_output',
+                        help='Write JSON text output to given file (use - for stdout)')
     group1.add_argument('--markdown', metavar='OUTPUT_FILE', dest='markdown_output',
                         help='Write Markdown text output to given file (use - for stdout)')
     group1.add_argument('--restructured-text', metavar='OUTPUT_FILE',
diff --git a/diffoscope/presenters/json.py b/diffoscope/presenters/json.py
new file mode 100644
index 0000000..d761f1f
--- /dev/null
+++ b/diffoscope/presenters/json.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+#
+# diffoscope: in-depth comparison of files, archives, and directories
+#
+# Copyright © 2017 Chris Lamb <lamby at debian.org>
+#
+# diffoscope is free software: you can redistribute it and/or modify
+# 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.
+#
+# diffoscope is distributed in the hope that it will be useful,
+# 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
+# along with diffoscope.  If not, see <https://www.gnu.org/licenses/>.
+
+import json
+
+from .base import Presenter
+
+
+class JSONPresenter(Presenter):
+    def __init__(self, print_func):
+        self.root = []
+        self.current = self.root
+        self.print_func = print_func
+
+        super().__init__()
+
+    def visit(self, difference):
+        super().visit(difference)
+
+        if self.depth == 0:
+            self.print_func(json.dumps(self.root[0], indent=2, sort_keys=True))
+
+    def visit_difference(self, difference):
+        self.current.append({
+            'source1': difference.source1,
+            'source2': difference.source2,
+            'comments': [x for x in difference.comments],
+            'differences': [],
+            'unified_diff': difference.unified_diff,
+        })
+
+        self.current = self.current[-1]['differences']
diff --git a/diffoscope/presenters/utils.py b/diffoscope/presenters/utils.py
index b472f34..4da172a 100644
--- a/diffoscope/presenters/utils.py
+++ b/diffoscope/presenters/utils.py
@@ -25,6 +25,7 @@ import contextlib
 from ..profiling import profile
 
 from .text import TextPresenter
+from .json import JSONPresenter
 from .html import output_html, output_html_directory
 from .markdown import MarkdownTextPresenter
 from .restructuredtext import RestructuredTextPresenter
@@ -49,6 +50,10 @@ def output_all(difference, parsed_args, has_differences):
             'fn': html,
             'target': parsed_args.html_output,
         },
+        'json': {
+            'klass': JSONPresenter,
+            'target': parsed_args.json_output,
+        },
         'markdown': {
             'klass': MarkdownTextPresenter,
             'target': parsed_args.markdown_output,
diff --git a/tests/data/output.json b/tests/data/output.json
new file mode 100644
index 0000000..66cfeb7
--- /dev/null
+++ b/tests/data/output.json
@@ -0,0 +1,33 @@
+{
+  "comments": [],
+  "differences": [
+    {
+      "comments": [],
+      "differences": [
+        {
+          "comments": [],
+          "differences": [
+            {
+              "comments": [
+                "symlink"
+              ],
+              "differences": [],
+              "source1": "dir/link",
+              "source2": "dir/link",
+              "unified_diff": "@@ -1 +1 @@\n-destination: broken\n+destination: really-broken\n"
+            }
+          ],
+          "source1": "dir/text",
+          "source2": "dir/text",
+          "unified_diff": "@@ -1,6 +1,12 @@\n+A common form of lorem ipsum reads:\n+\n Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor\n incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis\n nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu\n fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in\n culp [...]
+        }
+      ],
+      "source1": "file list",
+      "source2": "file list",
+      "unified_diff": "@@ -1,4 +1,4 @@\n-drwxr-xr-x   0 lunar     (1000) lunar     (1000)        0 2015-06-29 15:49:09.000000 dir/\n--rw-r--r--   0 lunar     (1000) lunar     (1000)      446 2015-06-29 15:49:09.000000 dir/text\n-crw-r--r--   0 root         (0) root         (0)    1,  3 2015-06-29 15:49:09.000000 dir/null\n-lrwxrwxrwx   0 lunar     (1000) lunar     (1000)        0 2015-06-29 15:49:09.000000 dir/link -> broken\n+drwxr-xr-x   0 lunar     (1000) lunar     (1000)        0 201 [...]
+    }
+  ],
+  "source1": "test1.tar",
+  "source2": "test2.tar",
+  "unified_diff": null
+}
diff --git a/tests/test_presenters.py b/tests/test_presenters.py
index 0e5167f..338d07b 100644
--- a/tests/test_presenters.py
+++ b/tests/test_presenters.py
@@ -96,6 +96,14 @@ def test_restructuredtext(capsys):
 
     assert out == data('output.rst')
 
+def test_json(capsys):
+    out = run(capsys, '--json', '-')
+
+    with open('tests/data/output.json', 'w') as f:
+        f.write(out)
+
+    assert out == data('output.json')
+
 def test_no_report_option(capsys):
     out = run(capsys)
 

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


More information about the diffoscope mailing list