From a33a3714227266287dc0186641c7daae4454ebbe Mon Sep 17 00:00:00 2001 From: Cory Todd Date: Tue, 5 Sep 2023 14:09:49 -0700 Subject: [PATCH] cli: handle malformed input files Do not show a stacktrace on the cli tool when an invalid file is specified. Instead, use the new Serializer class to abstract the load process and handle the unified ValueError. Also handle FileNotFound because that's a fairly normal user input scenario as well. Set return code on sys.exit to indicate abnormal exit. Fixes #71 Signed-off-by: Cory Todd --- jsondiff/cli.py | 66 +++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/jsondiff/cli.py b/jsondiff/cli.py index a6e1a12..dd066e4 100644 --- a/jsondiff/cli.py +++ b/jsondiff/cli.py @@ -2,6 +2,16 @@ import jsondiff import sys +def load_file(serializer, file_path): + with open(file_path, "r") as f: + parsed = None + try: + parsed = serializer.deserialize_file(f) + except ValueError: + print(f"{file_path} is not valid {serializer.file_format}") + except FileNotFoundError: + print(f"{file_path} does not exist") + return parsed def main(): parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) @@ -18,35 +28,33 @@ def main(): args = parser.parse_args() - # pyyaml _can_ load json but is ~20 times slower and has known issues so use - # the json from stdlib when json is specified. - serializers = { - "json": (jsondiff.JsonLoader(), jsondiff.JsonDumper(indent=args.indent)), - "yaml": (jsondiff.YamlLoader(), jsondiff.YamlDumper(indent=args.indent)), - } - loader, dumper = serializers[args.format] - - with open(args.first, "r") as f: - with open(args.second, "r") as g: - jf = loader(f) - jg = loader(g) - if args.patch: - x = jsondiff.patch( - jf, - jg, - marshal=True, - syntax=args.syntax - ) - else: - x = jsondiff.diff( - jf, - jg, - marshal=True, - syntax=args.syntax - ) - - dumper(x, sys.stdout) + serializer = jsondiff.Serializer(args.format, args.indent) + parsed_first = load_file(serializer, args.first) + parsed_second = load_file(serializer, args.second) + + if not (parsed_first and parsed_second): + return 1 + + if args.patch: + x = jsondiff.patch( + parsed_first, + parsed_second, + marshal=True, + syntax=args.syntax + ) + else: + x = jsondiff.diff( + parsed_first, + parsed_second, + marshal=True, + syntax=args.syntax + ) + + serializer.serialize_data(x, sys.stdout) + + return 0 if __name__ == '__main__': - main() + ret = main() + sys.exit(ret)