prefix-dev / recipe-format

BSD 3-Clause "New" or "Revised" License
5 stars 5 forks source link

Add more standards-based conventions to schema #29

Open bollwyvl opened 1 month ago

bollwyvl commented 1 month ago

thanks for starting this work :heart:!

elevator pitch

Add #/{$id,$schema,title,description} to the top-level schema object, and a top-level #/properties/$schema to be validated in instance documents.

motivation

The current guidance of using tool-specific comment annotation, pointing at a "hot" file on a repo to get a reasonable developer experience seems like a backslide into the Bad Old Days of # [meta] selectors.

Using a standards-based representation of this metadata, tools would not have to parse magic comments to determine what schema should be used to validate a given instance.

While $schema only strictly has to be an identifier, making it a locator would mean that it could resolve directly, such that it would work with yaml-language-server out of the box, and other tools would not require a comment-aware parser to use the data programmatically.

design ideas

"$id": "https://prefix-dev.github.io/recipe-format/v0.0.0/schema/recipe/schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "conda recipe",
"description": "A declarative description of the build and test processes of a conda package: see https://prefix-dev.github.io/recipe-format/v0.0.0/schema/recipe/schema.html",
"properties": {
  "$schema": {
    "type": "string",
    "title": "Schema"
    "description": "An identifier for the schema used to validate this recipe",
    "format": "uri-reference",
    "default": "https://prefix-dev.github.io/recipe-format/v0.0.0/schema/recipe/schema.json"
  }
}

Or, in pydantic-ese, which generally makes a muck of human-readable schema:

VERSION = "0.0.0"  # or arrived at by other means, such as `pyproject.toml`
URL_BASE = "https://prefix-dev.github.io/recipe-format/v{VERSION}"
SCHEMA_URI = f"{URL_BASE}/schema/recipe/schema.json"  # leave space for related documents, if needed
SCHEMA_HTML = f"{URL_BASE}/schema/recipe/schema.html" # for humans (and SEO bots), a la #21
SCHEMA_DRAFT =  "http://json-schema.org/draft-07/schema#" # or the oldest compatible with pydantic magic used

class Whatever(BaseModel):

    class Config:
        json_schema_extra = {
            "$id": SCHEMA_URI,
            "$schema": SCHEMA_DRAFT,
            "title": "conda recipe",
            "description": f"A declarative description of the build and test processes of a conda package: see {SCHEMA_HTML}"
        }

    schema_: str | None = Field(
        SCHEMA_URI,
        alias="$schema",
        title="Schema",
        description="An identifier for the schema used to validate this recipe",
        format="uri-reference",
    )

alternatives

follow-on

references

baszalmstra commented 1 month ago

I would be very happy to accept a PR! Would you be able to make one?

bollwyvl commented 1 month ago

This is actually going fairly well, but one of my assumptions was poor, and it turns yls does not in fact support an explicit $schema.

As having to specify a long URI twice is worse than the status quo, I'll hold on opening the PR here until I get some feedback on https://github.com/redhat-developer/yaml-language-server/pull/970.