Create and publish `.regal/config.yaml` schema to JSON schema store
We should create a JSON schema for the Regal configuration file format and have it published to the JSON schema store. This allows tools like the YAML language server (which is used by editors like VS Code and Zed) to automatically provide auto-completions and corrections based on the schema when the filename matches .regal/config.yaml.
Note that we should avoid having the schema auto-generated from Go structs, as both categories and rule names are dynamic. I'd suggest we use properties for all known categories and rule names, likely generated from the default config. We could provide one strict version, where only these names are allowed (to help identify typos), and one version where additional properties are allowed, for those who might have custom rules.
Note that we should avoid having the schema auto-generated from Go structs, as both categories and rule names are dynamic. I'd suggest we use properties for all known categories and rule names, likely generated from the default config. We could provide one strict version, where only these names are allowed (to help identify typos), and one version where additional properties are allowed, for those who might have custom rules.
The generators aren't that bad these days. We could start with one and see what needs to be adjusted or added.
This is what a reflection-based JSON Schema generator (https://github.com/swaggest/jsonschema-go) gives us:
{
"definitions": {
"ConfigBuiltin": {
"properties": {
"decl": {
"$ref": "#/definitions/ConfigDecl"
}
},
"type": "object"
},
"ConfigCapabilities": {
"properties": {
"builtins": {
"additionalProperties": {
"$ref": "#/definitions/ConfigBuiltin"
},
"type": [
"object",
"null"
]
},
"features": {
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
},
"future_keywords": {
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
}
},
"type": "object"
},
"ConfigCategory": {
"additionalProperties": {
"$ref": "#/definitions/ConfigRule"
},
"type": "object"
},
"ConfigDecl": {
"properties": {
"args": {
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
},
"result": {
"type": "string"
}
},
"type": "object"
},
"ConfigFeatures": {
"properties": {
"remote": {
"$ref": "#/definitions/ConfigRemoteFeatures"
}
},
"type": "object"
},
"ConfigIgnore": {
"properties": {
"files": {
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
},
"ConfigProject": {
"properties": {
"rego-version": {
"type": [
"null",
"integer"
]
},
"roots": {
"items": {
"$ref": "#/definitions/ConfigRoot"
},
"type": [
"null",
"array"
]
}
},
"type": "object"
},
"ConfigRemoteFeatures": {
"properties": {
"check-version": {
"type": "boolean"
}
},
"type": "object"
},
"ConfigRoot": {
"properties": {
"rego-version": {
"type": [
"null",
"integer"
]
}
},
"type": "object"
},
"ConfigRule": {
"properties": {
"ignore": {
"$ref": "#/definitions/ConfigIgnore"
},
},
"type": "object"
}
},
"properties": {
"capabilities": {
"$ref": "#/definitions/ConfigCapabilities"
},
"capabilities_url": {
"type": "string"
},
"features": {
"$ref": "#/definitions/ConfigFeatures"
},
"ignore": {
"$ref": "#/definitions/ConfigIgnore"
},
"project": {
"$ref": "#/definitions/ConfigProject"
},
"rules": {
"additionalProperties": {
"$ref": "#/definitions/ConfigCategory"
},
"type": [
"object",
"null"
]
}
},
"type": "object"
}
The pain points there:
- (as you've mentioned) custom rule settings are not captured, so we cannot add
additionalProperties: falseto ConfigRule. -
project/rootsdoesn't work -- the generated schema puts it down as object, but we also allow strings
Regarding issue number 2, it should be possible to anyOf (or whatever is equivalent) to allow either strings or objects, right? I'm not sure how advanced/modern constructs the YAML LSP supports though. Up until very recently I have seen warnings in my JSON schemas about some features not being supported in the schemas I have written (for other purposes). Only one way to know, I suppose..