import json from typing import IO, Any import click import black def generate_schema_from_click( cmd: click.Command, ) -> dict[str, Any]: result: dict[str, dict[str, Any]] = {} for param in cmd.params: if not isinstance(param, click.Option) or param.is_eager: continue assert param.name name = param.name.replace("_", "-") result[name] = {} match param.type: case click.types.IntParamType(): result[name]["type"] = "integer" case click.types.StringParamType() | click.types.Path(): result[name]["type"] = "string" case click.types.Choice(choices=choices): result[name]["enum"] = choices case click.types.BoolParamType(): result[name]["type"] = "boolean" case _: msg = f"{param.type!r} not a known type for {param}" raise TypeError(msg) if param.multiple: result[name] = {"type": "array", "items": result[name]} result[name]["description"] = param.help if param.default is not None and not param.multiple: result[name]["default"] = param.default return result @click.command(context_settings={"help_option_names": ["-h", "--help"]}) @click.option("--schemastore", is_flag=True, help="SchemaStore format") @click.option("--outfile", type=click.File(mode="w"), help="Write to file") def main(schemastore: bool, outfile: IO[str]) -> None: properties = generate_schema_from_click(black.main) del properties["line-ranges"] schema: dict[str, Any] = { "$schema": "http://json-schema.org/draft-07/schema#", "$id": ( "https://github.com/psf/black/blob/main/src/black/resources/black.schema.json" ), "$comment": "tool.black table in pyproject.toml", "type": "object", "additionalProperties": False, "properties": properties, } if schemastore: schema["$id"] = "https://json.schemastore.org/partial-black.json" # The precise list of unstable features may change frequently, so don't # bother putting it in SchemaStore schema["properties"]["enable-unstable-feature"]["items"] = {"type": "string"} print(json.dumps(schema, indent=2), file=outfile) if __name__ == "__main__": main()