-
-
Notifications
You must be signed in to change notification settings - Fork 593
[CLI] Improve the overall console output (fix #623) #661
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CLI] Improve the overall console output (fix #623) #661
Conversation
Thanks -- I'm definitely not opposed to a PR like this, but the "advantage" of the current ugly format is it's machine parsable in some sense. I.e. you can grep it, and it's one line per error. Possibly that's still not great, and there should be a I'm not opposed to having a human-readable one either as you're adding, but we should probably preserve the existing one, and leave room to add the new one (JSON output). |
I agree with your comments. I applied a different strategy (leading to a lot of new code, I’m sorry) which should suits you more.
Here is an overview of the result: Default behaviour $ jsonschema -i data.json -i data.good.json -i data.corrupt.json schema.json
{'foo': None}: 'bar' is a required property
None: None is not of type 'string'
Failed to parse data.corrupt.json. Got the following error: Expecting property name enclosed in double quotes: line 2 column 2 (char 3) Human readable $ jsonschema -H -i data.json -i data.good.json -i data.corrupt.json schema.json
===[ERROR]===(data.json)===
'bar' is a required property
Failed validating 'required' in schema:
{'$schema': 'http://json-schema.org/draft-07/schema#',
'properties': {'bar': {'type': 'string'}, 'foo': {'type': 'string'}},
'required': ['bar'],
'type': 'object'}
On instance:
{'foo': None}
===[ERROR]===(data.json)===
None is not of type 'string'
Failed validating 'type' in schema['properties']['foo']:
{'type': 'string'}
On instance['foo']:
None
===[SUCCESS]===(data.good.json)===
===[ERROR]===(data.corrupt.json)===
Failed to parse data.corrupt.json. Got the following error: Expecting property name enclosed in double quotes: line 2 column 2 (char 3) And what if the schema is corrupted ? $ jsonschema -i data.json schema.corrupt.json
Failed to parse schema schema.corrupt.json. Got the following error: Expecting property name enclosed in double quotes: line 4 column 3 (char 84) That one is not changed with I think the path is clear to implement the |
Thanks. It's definitely important we agree on approach. Because of the third output format I mentioned (JSON), I'd rather see an option-based argument rather than a flag -- i.e. rather than Also stylistically, I'd prefer we use helper functions, rather than comments -- if the function does too much usually to me that's a sign it should be split up, rather than have comments divide up sections of it. I try to keep functions to be 10 lines or less. The code though will likely change, so we can think about ways to do that perhaps after the above. This is now also definitely enough code to bring up we should have tests for the new behavior. You'll notice also some of the existing ones are failing after the change. There's quite a bit here, so perhaps you can see how to unit test the changes to the output? |
Codecov Report
@@ Coverage Diff @@
## master #661 +/- ##
=========================================
Coverage ? 95.04%
=========================================
Files ? 18
Lines ? 2621
Branches ? 324
=========================================
Hits ? 2491
Misses ? 107
Partials ? 23 |
- Add a human-readable option that changes every messages displayed - Catch several exceptions to improve their readability. - Let default behaviour as the machine-readable one, with one result per line. - Add some comments in cli.py to improve code readability
Add class CliOutputWriter to centralize output management.
Schema and instances can no longer be given to run() as objects. They MUST be paths to existing files. That is why a new directory has been made, containing JSON files.
c5d39c7
to
192fa26
Compare
192fa26
to
e5f12dd
Compare
I am really sorry that I had to make some force-pushes, but I had an identity issue and cannot let that as it was. I finally managed to update the existing tests to make them pass. Now I am going to create some new ones to complete the coverage. |
Hi @Julian ! I finally reached a version I am happy with. It implements what you suggested, it is fully retrocompatible, and lets room for further improvements. The console output is still the same than in my previous comment. I fixed the existing tests and added some new ones. The coverage does not reach 100% because I don’t think we can test the If everything is ok for you, I am done with it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Well done, much appreciated.
I left some initial comments, including a minor approach one, but we are definitely getting close.
I'm going to try to read things a bit more carefully over the weekend but wanted to get a first pass out immediately.
Thanks again for seeing this through!
jsonschema/cli.py
Outdated
# ------------------------------------------------------------------------------ | ||
# CLASSES | ||
# ------------------------------------------------------------------------------ | ||
class CliOutputWriter(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For better or worse this module is still public (which #600 will fix) -- so we should be careful not to add any more public things to it. Can you rename this to be private?
But also -- I think you have the right idea here of an output writer, but if you use object polymorphism, things get even nicer.
I.e., rather than have every method have if whatever == "pretty": do_something_pretty()
, have _PrettyOutputWriter
and _PlainOutputWriter
with the same interface, and then just select which writer is used based on the command line flag.
Lemme know if that makes sense to you, otherwise happy to elaborate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course that is much better ! I just didn’t think about it. But it is definitely the kind of things I like to write in Python.
jsonschema/cli.py
Outdated
|
||
def write_valid_error(self, object_name, error_obj): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we avoid abbreviations? Here write_valid_error
is particularly confusing, I assume this means write_validation_error
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. This is a confusing abbreviation, I did not notice it myself sorry.
Not in this case, but in many, having them there is dangerous if the context manager has a bug and doesn't re-raise its exception (in which case the asserts will never run).
* origin/master: Sigh, remove -q from spelling which is required to see the misspelled words.
Also means it's now formally represented where messages go for each type of message. Hooray patterns.
No need to ensure it's an empty list specifically.
This needs to disappear entirely, but better consistent than not.
Still want these to go away entirely.
So! After quite a bit of noodling, some of which not directly related to the PR, but this file needed some love, I'm going to merge. There's still a bit more work I want to do to clean some of these files up but your contribution is very much appreciated! Thank you for jumping in! Getting these things off the ground is 90% of the trouble typically, so if it weren't for you it wouldn't have happened :). |
@Julian nice !!! Thank you very much for your support ! I have another PR coming for you 😚 |
6afa9b38d Merge pull request #664 from santhosh-tekuri/empty-tokens e4bceb1ad Bump the python-jsonschema version used for the sanity check. 8025fc0d5 Merge pull request #128 from iainbeeston/foundations-of-json-schema-paper cf7677078 Make all root $ids absolute URIs 07fd389a3 Added test cases from Foundations of JSON Schema research paper 1008edcee ref: test empty tokens in json-pointer 9beb3cfba Merge pull request #627 from json-schema-org/ether/output-readme-fixes f2b0490ba minor edit to trigger gh action c305ce54f Merge pull request #669 from hauner/typo 5e2845c1e Merge pull request #668 from hauner/if-without-then-else-creates-annotations 2f1df2293 typo c1fae0022 test unevaluated* can see annotations from if without then/else 987a4c8fc Merge pull request #666 from json-schema-org/gregsdennis/file-refs 90b2a58ce fix *nix uris 68d18c6ac rename tests to fix sanity check e9166bcbe fix indentation 1d1ec749a add file-id ref tests fb60ed17c Merge pull request #663 from json-schema-org/ether/restore-format-tests f32cd8b80 Revert "Revert "by default, "format" only annotates, not validates"" 47958f82d Merge pull request #654 from santhosh-tekuri/output-escape 5262997e1 Merge pull request #661 from santhosh-tekuri/2019-output ce2c16573 output-tests: correct 2019 output-schema.json c9d943856 output: ensure ~ and / are escaped in json-pointer f6b2324bf minor spelling and markdown formatting fixes; `valid` has also been removed from the tests git-subtree-dir: json git-subtree-split: 6afa9b38d84d45550ec703123eb4e8ec67a8ae75
Fixes #623
This is just a suggestion, as there are plenty of ways to improve the visual. The current result is described below.
schema:
data:
Command line: