diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py index e734ca8..cbc1b19 100644 --- a/pre_commit_hooks/pretty_format_json.py +++ b/pre_commit_hooks/pretty_format_json.py @@ -5,6 +5,7 @@ import io import json import sys from collections import OrderedDict +from difflib import unified_diff from typing import List from typing import Mapping from typing import Optional @@ -55,6 +56,13 @@ def parse_topkeys(s): # type: (str) -> List[str] return s.split(',') +def get_diff(source, target, file): # type: (str, str, str) -> str + source_lines = source.splitlines(True) + target_lines = target.splitlines(True) + diff = unified_diff(source_lines, target_lines, fromfile=file, tofile=file) + return ''.join(diff) + + def main(argv=None): # type: (Optional[Sequence[str]]) -> int parser = argparse.ArgumentParser() parser.add_argument( @@ -96,7 +104,6 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int default=[], help='Ordered list of keys to keep at the top of JSON hashes', ) - parser.add_argument('filenames', nargs='*', help='Filenames to fix') args = parser.parse_args(argv) @@ -113,10 +120,19 @@ def main(argv=None): # type: (Optional[Sequence[str]]) -> int ) if contents != pretty_contents: - print('File {} is not pretty-formatted'.format(json_file)) + print( + 'File {} is not pretty-formatted'.format(json_file), + file=sys.stderr, + ) + sys.stderr.flush() if args.autofix: _autofix(json_file, pretty_contents) + else: + print( + get_diff(contents, pretty_contents, json_file), + end='', + ) status = 1 except ValueError: diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py index 3b7b9a2..6cfe772 100644 --- a/tests/pretty_format_json_test.py +++ b/tests/pretty_format_json_test.py @@ -1,3 +1,4 @@ +import os import shutil import pytest @@ -105,3 +106,36 @@ def test_top_sorted_get_pretty_format(): def test_badfile_main(): ret = main([get_resource_path('ok_yaml.yaml')]) assert ret == 1 + + +def test_diffing_output(capsys): + resource_path = get_resource_path('not_pretty_formatted_json.json') + expected_retval = 1 + a = os.path.join('a', resource_path) + b = os.path.join('b', resource_path) + expected_out = '''\ +--- {} ++++ {} +@@ -1,6 +1,9 @@ + {{ +- "foo": +- "bar", +- "alist": [2, 34, 234], +- "blah": null ++ "alist": [ ++ 2, ++ 34, ++ 234 ++ ], ++ "blah": null, ++ "foo": "bar" + }} +'''.format(a, b) + expected_err = 'File {} is not pretty-formatted\n'.format(resource_path) + + actual_retval = main([resource_path]) + actual_out, actual_err = capsys.readouterr() + + assert actual_retval == expected_retval + assert actual_out == expected_out + assert actual_err == expected_err