altis-core icon indicating copy to clipboard operation
altis-core copied to clipboard

Introduce a JSON schema for composer.json

Open johnbillion opened this issue 1 year ago • 7 comments

It's possible to use allOf in JSON Schema to combine the constraints from multiple schemas into one. This means we can create a schema for composer.json which is a combination of the official Composer schema with our own schema for the extra.altis properties.

Adding "$schema": "vendor/altis/core/schema.json", to the top of an application-level composer.json file means VS Code provides all the JSON schema goodness you'd expect for a complete schema, including autocomplete, hover documentation with links, and validation, both for the Composer properties and for the custom Altis properties within extra.altis.

By using a root definitions we also allow all the module definitions to appear in extra.altis.modules as well as each environment within extra.altis.environments[...] without duplicating everything five times.

Related: #28

Screenshots

Top level modules:

Environment modules:

Module property:

Autocomplete

Status

This is a proof of concept. There is a maintenance overhead for such a schema so we could make more use of $ref in order to pull in each module definition from its place in the vendor directory if that's preferable.

Thoughts?

johnbillion avatar Apr 20 '23 15:04 johnbillion

This seems like a good idea, John. I vaguely remember something about wanting to validate config settings once upon a time.

Would the next step of this be to define each module's schema in the individual modules or add them all into this one?

mikelittle avatar Apr 26 '23 13:04 mikelittle

Yeah, the difficulty of this is the decentralised nature of the configuration; we'd need to pull them together somehow without centralising it somewhere. Alternatively, we could bodge it into a central config, but I'd really prefer not to.

Definitely something we should look at implementing though imo

rmccue avatar Apr 26 '23 13:04 rmccue

we'd need to pull them together somehow

Yeah we can do this by putting a schema.json into each module which contains its module definition, and then the main schema.json in altis/core would pull each of them in via "$ref": "../analytics/schema.json".

I'll put aside a couple of hours next week to carry on with the proof of concept.

johnbillion avatar Apr 27 '23 08:04 johnbillion

Yeah we can do this by putting a schema.json into each module which contains its module definition, and then the main schema.json in altis/core would pull each of them in via "$ref": "../analytics/schema.json".

Right, but that then centralises a dependency in altis/core on each module. We could have that live in altis/altis if we have to (rather than core) but that's kind of what I mean

rmccue avatar Apr 27 '23 09:04 rmccue

I think centralising the list of modules for this purpose is reasonable and manageable. As far as I know we don't have a high turnover of new or removed modules. The alternative would be to come up with a build step that combines the schemas from all the modules, but I'm not too keen on that, and presumably that would also require centralising a list of the modules to combine.

The schemas for the modules themselves would live within each module so maintaining the module schemas would remain the responsibility of each module.

We could have that live in altis/altis if we have to

Yeah I used altis/core only because altis/altis is a meta package and doesn't result in anything being present in vendor/altis/altis for an application. With altis/core we already have the vendor/altis/core directory in which to place the schema.

johnbillion avatar Apr 27 '23 10:04 johnbillion

As far as I know we don't have a high turnover of new or removed modules

That is true, but it also breaks the conceptual modularity by having dependencies between the modules, so we want to avoid it as much as possible.

Additionally, we support both custom modules and a mixed list of modules depending on which plan a user is on; the latter is a minimal problem for something like this was the worst case is you get too many suggestions, but still avoidable I think.

The alternative would be to come up with a build step that combines the schemas from all the modules, but I'm not too keen on that, and presumably that would also require centralising a list of the modules to combine.

This can be decentralised using the same mechanism we use for installation path overrides, where modules could specify a extra.altis.config-schema in their composer.json, and we'd build all of that together; see also, how we do install overrides.

That's definitely my preferred option, provided the schema will work correctly with a local file rather than a full URL, which it seems is perfectly fine.

rmccue avatar Apr 27 '23 10:04 rmccue

As a start, could we atleast define the altis config block and modules / environments keys. Those are not specific to any modules, and then we could add module-specific config (hopefully pulling the schema from each module).

joehoyle avatar Jul 26 '23 12:07 joehoyle