altis-core
altis-core copied to clipboard
Introduce a JSON schema for composer.json
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?
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?
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
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.
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
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.
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.
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).