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 xlwings#71

Signed-off-by: Cory Todd <cory.todd@canonical.com>
  • Loading branch information
Cory Todd committed Sep 5, 2023
1 parent 4c38815 commit a4c2cb9
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 a valid {serializer.file_format} file")
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 a4c2cb9

Please sign in to comment.