Skip to content

Latest commit

 

History

History
125 lines (95 loc) · 3.69 KB

README.md

File metadata and controls

125 lines (95 loc) · 3.69 KB

📅 Schema YAML

SchemaYAML processes a YAML file that is constrained by JSON schema by filling in default values and comments found in the schema. Additionally, the user input (the overrides) can be validated (or not with SkipValidate) to be compliant with the JSON schema or return an error if not the case.

The processing is configurable to restrict returning only the required properties, which can be useful when writing the user configuration to disk. This provides a minimal configuration example for the user while when processing the file all remaining defaults can be automatically filled in (by scheyaml). See Usage for an example.

ScheYAML returns either the textual representation (configurable with WithCommentMaxLength and WithIndent) or the raw *yaml.Node representation.

ScheYAML uses xeipuuv/gojsonschema's jsonschema.Schema as input.

⬇️ Installation

go get github.com/survivorbat/go-scheyaml

📋 Usage

A simple implementation assuming that a json-schema.json file is present is for example:

package main

import (
	_ "embed"
	"fmt"

	"github.com/kaptinlin/jsonschema"
	"github.com/survivorbat/go-scheyaml"
)

//go:embed json-schema.json
var file []byte

func main() {
	// load the jsonschema
	compiler := jsonschema.NewCompiler()
	schema, err := compiler.Compile(file)
	if err != nil {
		panic(err)
	}

	result, err := scheyaml.SchemaToYAML(schema, scheyaml.WithOverrideValues(map[string]any{
		"hello": "world",
	}))
	if err != nil {
		panic(err)
	}

	fmt.Println(result)
}

But using this ScheYAML can be especially useful when also generating the config structs based on the JSON schema using e.g. omissis/go-jsonschema:

$ go-jsonschema --capitalization=API --extra-imports json-schema.json --struct-name-from-title -o config.go -p config

Given some simple schema:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "Config",
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "default": "Hello World"
    }
  }
}

Will generate the following (simplified) Go struct:

type Config struct {
	// Name corresponds to the JSON schema field "name".
	Name string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"`
}

Given some config file that should be valid (an empty file):

# yaml-language-server: $schema=json-schema.json

Normally, the default values are "lost" when unmarshalling. That's where scheyaml can output a processed version according to the json schema of the input that can be read, in this case as if the user would have supplied:

# yaml-language-server: $schema=json-schema.json
name: Hello World

See the example tests in ./examples_test.go for more details.

Override- / Default Value Rules

When override values are supplied or the json schema contains default values, the following rules apply when determining which value to use:

  1. if the schema is nullable ("type": ["<type>", "null"]) and an override is specified for this key, use the override
  2. if the schema is not nullable and the override is not nil, use the override value
  3. if the schema has a default ("default": "abc") use the default value of the property
  4. if 1..N pattern properties match, use the first pattern property which has a default value (if any)

✅ Support

  • Feature to override values in output
  • Feature to override the comment on a missing default value
  • Basic types (string, number, integer, null)
  • Object type
  • Array
  • Refs
  • Pattern Properties
  • AnyOf
  • AllOf

🔭 Plans

Not much yet.