-
Notifications
You must be signed in to change notification settings - Fork 8
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
Improve JSON schema #64
Conversation
Refactor some of the logic to handle attribute types to reduce code duplication between the reST parsing and creating the JSON schema.
Add ability to specify indentation to the schema builder. Add an option (currently set to '2') to specify the indentation via the Sphinx configuration file. This makes the schema easier for humans to read at the expense of increased file size.
Add a link to the generated JSON schema from the main documentation. This required a bit of fiddling to be able to link to a file that is generated, but not by Sphinx (proper), as there does not seem to be any built-in way to give a relative link to something that Sphinx doesn't know about. On the plus side, having to concoct such a mechanism allowed providing a role that obtains the proper file name from the site configuration. This is a very odd role, in that the input is taken as the link text, and the link reference is controlled by the site configuration, but it works for now. A better solution might be to provide a built-in target definition, but I'm not sure how to do that, or if it would permit "undefined" local links. (The approach here sort of "tricks" Sphinx into thinking the link is external.)
Add and use a custom Pygments style that more closely reflects the style used elsewhere in the documentation. Change the "language" of the sample CPS file from JavaScript to JSON.
Remove unused imports and fix "comment style" in conf.py. The latter is actually a line of code that's commented out, but adding a space after the '#' is harmless and makes flake8 happier.
FYI @autoantwort, this should fix a couple of the issues you raised. I'd appreciate if you can verify whether I did it right; thanks! |
@@ -90,6 +90,7 @@ By definition, none of the following attributes are required. | |||
.. cps:attribute:: website | |||
:type: string | |||
:context: package | |||
:format: uri |
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.
It seems that this does not work. I have not found format
in the resulting schema
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.
Oops, that's because of a dumb typo; the Python code uses the variable name typeformat
because format
is a built-in, but accidentally used that also as the name of the reST option to inspect. Should be fixed; thanks for the catch!
A suggestion, why not invert the generator to have |
Make default values part of the "machine readable" portion of an attribute specification. This makes them stand out more in the documentation, and also allows them to be exported to the JSON schema. Also add value format, which is exported to the JSON schema but does not appear in the main documentation.
@LecrisUT, #25 did something similar (albeit without reST generation). The major reason is that reST is significantly more friendly to edit than a JSON schema. It's also unclear how well generating reST from something else allows reST markup to be used in the "something else" (even at best, editing is going to lost editor syntax highlighting), and generating reST also complicates building the documentation. The reality is that the reST is the source of truth and the JSON schema is supplemental and is intended primarily for use in machine validation. |
A few pointers:
The schema objects that
Initially, making the transition might take a lot of effort, but generating the rst and documentation is actually trivial. I did not dig into the current rst generation though but a recommended pattern is to expose components of the json schema one at a time, e.g. .. jsonschema:: schema.json#/definitions/package
.. jsonschema:: schema.json#/definitions/components PS: this would also make it easier to publish in https://github.com/SchemaStore/schemastore |
@LecrisUT, let's consider an example: .. cps:attribute:: clr_vendor
:type: string
:context: platform
Specifies that the package's CLR (.NET) components
require the specified `Common Language Runtime`_ vendor.
Typical (case-insensitive) values include
:string:`"microsoft"` and
:string:`"mono"`. How would that be written, without loss of expressiveness, in YAML?
|
There are 2 options, either use #schema.json
definitions:
clr_vendor:
type: string
description: ...fill short description for ide...
$$description: |
Specifies that the package's CLR (.NET) components
require the specified `Common Language Runtime`_ vendor.
Typical (case-insensitive) values include
:string:`"microsoft"` and
:string:`"mono"`. or my preferred approach is to integrate the text in the rst document: #schema.json
definitions:
clr_vendor:
type: string
description: ...fill short description for ide... Schemas.rst
===========
.. schema.json#/definitions/clr_vendor
Specifies that the package's CLR (.NET) components
require the specified `Common Language Runtime`_ vendor.
Typical (case-insensitive) values include
:string:`"microsoft"` and
:string:`"mono"`. Note: I am not sure of the indentation necessary here, definitely works without the indentation for the text. This one works by making each In this example I used
With
In the first case, indeed it would not work nice, but the second option should work smoothly. Only some
You could use plain rst markups, but ymmv when it comes to the IDE displaying it. My recommendation is the yaml section to be as compact as possible, since people will have the online documentation when needed. CMake adopts a similar approach.
Referencing an external json schema inside a json schema is technically possible, but I did not investigate it (it's the same
type: object
# If you want specific keys to be allowed only
properties:
key:
type: string
# Or a regex pattern
patternProperties:
".*":
type: string
# Or take anything
additionalProperties:
type: string Reference: https://json-schema.org/understanding-json-schema/reference/object
Depends, you can either have 1 yaml file per object/rule or combine them and use |
...but that's not unlike what I'm already doing; |
I want to challenge this claim. The issue is that the generation goes from rst to json-schema in a custom generator. This means that new contributors wanting to dip their toes and start contributing will have to learn yet another markup, e.g. they would need to decipher what something like this means Lines 297 to 298 in 2bfdc4b
So the quality of contributors can only go as far as the documentation made for contributors and the willingness for them to overcome. On the other hand, there would always be people familiar with sphinx and json-schema who would be able to jump in and out to do random fixes as long as the structure is familiar to them.
There is a difference here. The proposal is to move all of the logic and metadata to a static json-schema document, and the rst document would only contain the detail text and markup. There are various benefits of such an approach:
|
This is now in the way of other changes that need to be made. Since it's been sitting a long while with only one relevant comment (which has been addressed weeks ago), I'm going to go ahead and merge it. Any further fixes needed will have to wait for their own PRs. |
What's "static"? "Unchanging"? Clearly that isn't the case, as some of your claimed advantages make clear. Nor am I convinced that splitting the schema into multiple formats is an improvement. I also am skeptical of your assertion that the current system is difficult to comprehend, especially if someone employs the simple step of comparing the source to the output. That said, nothing is stopping someone from making a pull request. I definitely do not have time right now to make such sweeping changes. |
Static as in static file. A file that is not generated.
I am not proposing that. There would only be 1 json schema in either a yaml or json format. Unfortunately that does mean the way to migrate is to fully migrate. Regarding PR contribution, what I can write is the skeleton for this, but I would need to do a bunch more changes:
It is quite cumbersome to make each of these changes as individual PRs as they can be strongly dependent on one another, at most I could make them as individual commits. And this is all balancing on whether or not you are open for these changes and review so that I should know beforehand if I should go forward with prototyping these or not. |
Add a link to the JSON schema from the main documentation. Pretty-print said schema and add
format
anddefault
, with the latter also moving to the "machine readable" block in the primary documentation. Add custom Pygments style to reflect the coloring used elsewhere in the documentation, and "fix" the language of the sample CPS file. Factor out some duplicated code. Fix someflake8
warnings.