Skip to content

Commit

Permalink
cli: handle malformed input files
Browse files Browse the repository at this point in the history
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 <cory.todd@canonical.com>
  • Loading branch information
Cory Todd committed Sep 5, 2023
1 parent d446c2f commit a33a371
Showing 1 changed file with 37 additions and 29 deletions.
66 changes: 37 additions & 29 deletions jsondiff/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)

0 comments on commit a33a371

Please sign in to comment.