Documentation
¶
Index ¶
- Variables
- func Bundle(ctx context.Context, schema *Schema, outputDir, bundleRoot string, ...) error
- func BundleRemoveIDs(schema *Schema) error
- func BundleSchema(ctx context.Context, loader Loader, schema *Schema, basePathForIDs string) error
- func ContextWithLoaderReferrer(parent context.Context, referrer string) context.Context
- func ContextWithLogger(parent context.Context, logger Logger) context.Context
- func GenerateJsonSchema(ctx context.Context, config *Config) error
- func NewCmd() *cobra.Command
- func ParseHelmDocsPath(path string) ([]string, error)
- func RemoveUnusedDefs(schema *Schema)
- func SplitHelmDocsComment(headComment string) (before, helmDocs []string)
- func WriteOutput(ctx context.Context, mergedSchema *Schema, outputPath, indent string) error
- type CacheLoader
- type CachedResponse
- type Config
- type DummyHTTPCache
- type DummyLoader
- type FileLoader
- type HTTPCache
- type HTTPFileCache
- type HTTPLoader
- func (loader HTTPLoader) Load(ctx context.Context, ref *url.URL) (*Schema, error)
- func (loader HTTPLoader) LoadCache(req *http.Request) (CachedResponse, *Schema, error)
- func (loader HTTPLoader) SaveCache(req *http.Request, resp *http.Response, body []byte) (CachedResponse, error)
- func (loader HTTPLoader) SaveCacheETag(req *http.Request, resp *http.Response, cached CachedResponse) (CachedResponse, *Schema, error)
- type HTTPMemoryCache
- type HelmDocsComment
- type LimitedReaderWithError
- type Loader
- type Logger
- type Ptr
- func (p Ptr) Add(other ...Ptr) Ptr
- func (p Ptr) CutPrefix(prefix Ptr) (after Ptr, ok bool)
- func (p Ptr) Equals(other Ptr) bool
- func (p Ptr) HasPrefix(prefix Ptr) bool
- func (p Ptr) Item(index ...int) Ptr
- func (p Ptr) Prop(name ...string) Ptr
- func (ptr Ptr) Resolve(schema *Schema) []ResolvedSchema
- func (p Ptr) String() string
- type RefFile
- type Referrer
- type ResolvedSchema
- type RootFS
- type Schema
- func (s *Schema) IsType(t string) bool
- func (s *Schema) IsZero() bool
- func (s *Schema) Kind() SchemaKind
- func (s *Schema) MarshalJSON() ([]byte, error)
- func (s *Schema) MarshalYAML() (any, error)
- func (s *Schema) ParseRef() (*url.URL, error)
- func (s *Schema) SetKind(kind SchemaKind)
- func (s *Schema) SetReferrer(ref Referrer)
- func (schema *Schema) Subschemas() iter.Seq2[Ptr, *Schema]
- func (s *Schema) UnmarshalJSON(data []byte) error
- func (s *Schema) UnmarshalYAML(value *yaml.Node) error
- type SchemaKind
- type SchemaRoot
- type URLSchemeLoader
- type WriterLogger
Constants ¶
This section is empty.
Variables ¶
var DefaultConfig = Config{ Values: []string{"values.yaml"}, Output: "values.schema.json", Draft: 2020, Indent: 4, K8sSchemaURL: "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/{{ .K8sSchemaVersion }}/", }
var HTTPLoaderDefaultUserAgent = ""
Functions ¶
func Bundle ¶
func Bundle(ctx context.Context, schema *Schema, outputDir, bundleRoot string, withoutIDs bool) error
Bundle will use default loader settings to bundle all $ref into $defs using BundleSchema and optionally remove any IDs using BundleRemoveIDs.
This function will update the schema in-place.
The paths, outputDir & bundleRoot, are only used to change absolute paths into relative paths in a solely cosmetic way.
func BundleRemoveIDs ¶
BundleRemoveIDs removes "$id" references to "$defs" and updates the "$ref" to point to the "$defs" elements directly inside the same document. This is non-standard behavior, but helps adding compatibility with non-compliant implementations such as the JSON & YAML language servers found in Visual Studio Code: https://github.com/microsoft/vscode-json-languageservice/issues/224
For example, before:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"foo": {
"$ref": "https://example.com/schema.json",
}
},
"$defs": {
"values.schema.json": {
"$id": "https://example.com/schema.json"
}
}
}
After:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"foo": {
"$ref": "#/$defs/values.schema.json",
}
},
"$defs": {
"values.schema.json": {
}
}
}
This function will update the schema in-place.
func BundleSchema ¶
BundleSchema will use the Loader to load any "$ref" references and store them in "$defs".
This function will update the schema in-place.
The basePathForIDs is an absolute path used to change the resulting $ref & $id absolute paths of bundled local files to relative paths. It is only used cosmetically and has no impact of how files are loaded.
func ContextWithLogger ¶ added in v2.1.0
ContextWithLogger returns a derived context that sets the current logger. This logger is later retrieved using LoggerFromContext.
func GenerateJsonSchema ¶
Generate JSON schema
func ParseHelmDocsPath ¶
ParseHelmDocsPath parses the path part of a helm-docs comment. This has some weird parsing logic, but it's created to try replicate the logic observed when running helm-docs. We can't just copy or reference their implementation due to licensing conflicts (MIT vs GPL v3.0)
Example:
# some-path.foobar -- This is my description
or also with quoted syntax:
# labels."kubernetes.io/hostname" -- This is my description
func RemoveUnusedDefs ¶
func RemoveUnusedDefs(schema *Schema)
RemoveUnusedDefs will try clean up all unused $defs to reduce the size of the final bundled schema.
func SplitHelmDocsComment ¶
SplitHelmDocsComment will split a head comment by line and return:
- Lines from last comment block, up until any helm-docs comments
- Liens from helm-docs comments
Types ¶
type CacheLoader ¶
type CacheLoader struct {
// contains filtered or unexported fields
}
CacheLoader stores loaded schemas in memory and reuses (or "memoizes", if you will) calls to the underlying Loader.
func NewCacheLoader ¶
func NewCacheLoader(loader Loader) *CacheLoader
type CachedResponse ¶
type CachedResponse struct {
CachedAt time.Time `cbor:"cachedAt"`
MaxAge time.Duration `cbor:"maxAge"`
ETag string `cbor:"etag"`
Data []byte `cbor:"data"`
}
func (CachedResponse) Expired ¶
func (c CachedResponse) Expired() bool
func (CachedResponse) Expiry ¶
func (c CachedResponse) Expiry() time.Time
type Config ¶
type Config struct {
Values []string `yaml:"values" koanf:"values"`
Output string `yaml:"output" koanf:"output"`
Draft int `yaml:"draft" koanf:"draft"`
Indent int `yaml:"indent" koanf:"indent"`
NoAdditionalProperties bool `yaml:"noAdditionalProperties" koanf:"no-additional-properties"`
NoDefaultGlobal bool `yaml:"noDefaultGlobal" koanf:"no-default-global"`
Bundle bool `yaml:"bundle" koanf:"bundle"`
BundleRoot string `yaml:"bundleRoot" koanf:"bundle-root"`
BundleWithoutID bool `yaml:"bundleWithoutID" koanf:"bundle-without-id"`
K8sSchemaURL string `yaml:"k8sSchemaURL" koanf:"k8s-schema-url"`
K8sSchemaVersion string `yaml:"k8sSchemaVersion" koanf:"k8s-schema-version"`
UseHelmDocs bool `yaml:"useHelmDocs" koanf:"use-helm-docs"`
SchemaRoot SchemaRoot `yaml:"schemaRoot" koanf:"schema-root"`
}
Save values of parsed flags in Config
type DummyHTTPCache ¶
type DummyHTTPCache struct {
LoadCacheFunc func(req *http.Request) (CachedResponse, error)
SaveCacheFunc func(req *http.Request, resp *http.Response, body []byte) (CachedResponse, error)
}
func (DummyHTTPCache) LoadCache ¶
func (d DummyHTTPCache) LoadCache(req *http.Request) (CachedResponse, error)
func (DummyHTTPCache) SaveCache ¶
func (d DummyHTTPCache) SaveCache(req *http.Request, resp *http.Response, body []byte) (CachedResponse, error)
type DummyLoader ¶
DummyLoader is a dummy implementation of Loader meant to be used in tests.
type FileLoader ¶
type FileLoader struct {
// contains filtered or unexported fields
}
FileLoader loads a schema from a "$ref: file:/some/path" reference from the local file-system.
func NewFileLoader ¶
func NewFileLoader(fs fs.FS, fsRootPath string) FileLoader
NewFileLoader returns a new file loader.
The fsRootPath parameter is used to convert absolute paths into relative paths when loading the files, and should be the absolute path of the file system's root directory. This value mostly matters when using os.Root.
This is only a cosmetic change as it will make error messages have more readable relative paths instead of absolute paths.
type HTTPFileCache ¶
type HTTPFileCache struct {
// contains filtered or unexported fields
}
func NewHTTPCache ¶
func NewHTTPCache() *HTTPFileCache
func (*HTTPFileCache) LoadCache ¶
func (h *HTTPFileCache) LoadCache(req *http.Request) (CachedResponse, error)
func (*HTTPFileCache) SaveCache ¶
func (h *HTTPFileCache) SaveCache(req *http.Request, resp *http.Response, body []byte) (CachedResponse, error)
type HTTPLoader ¶
type HTTPLoader struct {
SizeLimit int64
UserAgent string
// contains filtered or unexported fields
}
func NewHTTPLoader ¶
func NewHTTPLoader(client *http.Client, cache HTTPCache) HTTPLoader
func (HTTPLoader) LoadCache ¶
func (loader HTTPLoader) LoadCache(req *http.Request) (CachedResponse, *Schema, error)
func (HTTPLoader) SaveCache ¶
func (loader HTTPLoader) SaveCache(req *http.Request, resp *http.Response, body []byte) (CachedResponse, error)
func (HTTPLoader) SaveCacheETag ¶
func (loader HTTPLoader) SaveCacheETag(req *http.Request, resp *http.Response, cached CachedResponse) (CachedResponse, *Schema, error)
type HTTPMemoryCache ¶
type HTTPMemoryCache struct {
Map map[string]CachedResponse
Now func() time.Time
}
func NewHTTPMemoryCache ¶
func NewHTTPMemoryCache() *HTTPMemoryCache
func (*HTTPMemoryCache) LoadCache ¶
func (h *HTTPMemoryCache) LoadCache(req *http.Request) (CachedResponse, error)
func (*HTTPMemoryCache) SaveCache ¶
func (h *HTTPMemoryCache) SaveCache(req *http.Request, resp *http.Response, body []byte) (CachedResponse, error)
type HelmDocsComment ¶
type HelmDocsComment struct {
Path []string // Example: "# myPath.foo.bar -- My description"
Description string // Example: "# -- My description"
Type string // Example: "# -- (myType) My description"
NotationType string // Example: "# @notationType -- myType"
Default string // Example: "# @default -- myDefault"
Section string // Example: "# @section -- mySection"
}
func ParseHelmDocsComment ¶
func ParseHelmDocsComment(helmDocsComments []string) (HelmDocsComment, error)
type LimitedReaderWithError ¶
type LimitedReaderWithError struct {
Reader *io.LimitedReader
Err error
}
LimitedReaderWithError is a wrapper around io.LimitedReader that returns a custom error when the limit is reached instead of io.EOF.
func LimitReaderWithError ¶
func LimitReaderWithError(r io.Reader, n int64, err error) LimitedReaderWithError
LimitReaderWithError returns a wrapper around io.LimitedReader that returns a custom error when the limit is reached instead of io.EOF.
type Logger ¶ added in v2.1.0
type Logger interface {
// Prints message as a line.
// No need to suffix with a newline.
Log(a ...any)
// Prints formatted message as a line.
// No need to suffix with a newline.
Logf(format string, a ...any)
}
Logger is an interface that allows writing log messages to the user.
The interface is intentionally shaped to also allow testing.T as a logger.
type Ptr ¶
type Ptr []string
Ptr is a JSON Ptr [https://datatracker.ietf.org/doc/html/rfc6901].
The type is meant to be used in an immutable way, where all methods return a new pointer with the appropriate changes.
You don't have to initialize this struct with the NewPtr function. A nil value is equivalent to an empty path: "/"
func (Ptr) Resolve ¶ added in v2.3.0
func (ptr Ptr) Resolve(schema *Schema) []ResolvedSchema
Resolve returns all of the matched subschemas. The last slice element is the deepest subschema along the pointer's path.
For example:
Resolve(schema, NewPtr("/$defs/foo/items/type"))
// => []*Schema{ "/$defs", "/$defs/foo", "/$defs/foo/items" }
type RefFile ¶
RefFile is a parsed "$ref: file://" schema property
func ParseRefFile ¶
func ParseRefFileURLAllowAbs ¶ added in v2.1.0
type Referrer ¶
type Referrer struct {
// contains filtered or unexported fields
}
Referrer holds information about what is referencing a schema. This is used when resolving $ref to load the appropriate files or URLs. Only one of "File" or "URL" should to be set at a time.
func ReferrerDir ¶
ReferrerDir returns a Referrer using an path to a directory.
func ReferrerURL ¶
ReferrerURL returns a Referrer using a URL.
type ResolvedSchema ¶ added in v2.3.0
type RootFS ¶
RootFS is a replacement for os.Root.FS that intentionally doesn't call fs.ValidPath as that messes up the error messages and doesn't add any security guarantees as all the security is implemented in os.Root already.
type Schema ¶
type Schema struct {
// Field ordering is taken from https://github.com/sourcemeta/core/blob/429eb970f3e303c3f61ba3cf066c7bd766453e15/src/core/jsonschema/jsonschema.cc#L459-L546
Schema string `json:"$schema,omitempty" yaml:"$schema,omitempty"`
ID string `json:"$id,omitempty" yaml:"$id,omitempty"`
Vocabulary map[string]bool `json:"$vocabulary,omitempty" yaml:"$vocabulary,omitempty"`
Anchor string `json:"$anchor,omitempty" yaml:"$anchor,omitempty"`
DynamicAnchor string `json:"$dynamicAnchor,omitempty" yaml:"$dynamicAnchor,omitempty"`
RecursiveAnchor string `json:"$recursiveAnchor,omitempty" yaml:"$recursiveAnchor,omitempty"` // Deprecated. Replaced by $dynamicAnchor
Title string `json:"title,omitempty" yaml:"title,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Comment string `json:"$comment,omitempty" yaml:"$comment,omitempty"`
Examples []any `json:"examples,omitempty" yaml:"examples,omitempty"`
Deprecated bool `json:"decrecated,omitempty" yaml:"deprecated,omitempty"`
ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"`
WriteOnly bool `json:"writeOnly,omitempty" yaml:"writeOnly,omitempty"`
Default any `json:"default,omitempty" yaml:"default,omitempty"`
Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
RefReferrer Referrer `json:"-" yaml:"-"`
DynamicRef string `json:"$dynamicRef,omitempty" yaml:"$dynamicRef,omitempty"`
DynamicRefReferrer Referrer `json:"-" yaml:"-"`
RecursiveRef string `json:"$recursiveRef,omitempty" yaml:"$recursiveRef,omitempty"` // Deprecated. Replaced by $dynamicRef
Type any `json:"type,omitempty" yaml:"type,omitempty"`
Const any `json:"const,omitempty" yaml:"const,omitempty"`
Enum []any `json:"enum,omitempty" yaml:"enum,omitempty"`
AllOf []*Schema `json:"allOf,omitempty" yaml:"allOf,omitempty"`
AnyOf []*Schema `json:"anyOf,omitempty" yaml:"anyOf,omitempty"`
OneOf []*Schema `json:"oneOf,omitempty" yaml:"oneOf,omitempty"`
Not *Schema `json:"not,omitempty" yaml:"not,omitempty"`
If *Schema `json:"if,omitempty" yaml:"if,omitempty"`
Then *Schema `json:"then,omitempty" yaml:"then,omitempty"`
Else *Schema `json:"else,omitempty" yaml:"else,omitempty"`
ExclusiveMaximum *float64 `json:"exclusiveMaximum,omitempty" yaml:"exclusiveMaximum,omitempty"`
Maximum *float64 `json:"maximum,omitempty" yaml:"maximum,omitempty"`
ExclusiveMinimum *float64 `json:"exclusiveMinimum,omitempty" yaml:"exclusiveMinimum,omitempty"`
Minimum *float64 `json:"minimum,omitempty" yaml:"minimum,omitempty"`
MultipleOf *float64 `json:"multipleOf,omitempty" yaml:"multipleOf,omitempty"`
Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"`
Format string `json:"format,omitempty" yaml:"format,omitempty"`
MaxLength *uint64 `json:"maxLength,omitempty" yaml:"maxLength,omitempty"`
MinLength *uint64 `json:"minLength,omitempty" yaml:"minLength,omitempty"`
ContentEncoding string `json:"contentEncoding,omitempty" yaml:"contentEncoding,omitempty"`
ContentMediaType string `json:"contentMediaType,omitempty" yaml:"contentMediaType,omitempty"`
ContentSchema *Schema `json:"contentSchema,omitempty" yaml:"contentSchema,omitempty"`
MaxItems *uint64 `json:"maxItems,omitempty" yaml:"maxItems,omitempty"`
MinItems *uint64 `json:"minItems,omitempty" yaml:"minItems,omitempty"`
UniqueItems bool `json:"uniqueItems,omitempty" yaml:"uniqueItems,omitempty"`
MaxContains *uint64 `json:"maxContains,omitempty" yaml:"maxContains,omitempty"`
MinContains *uint64 `json:"minContains,omitempty" yaml:"minContains,omitempty"`
Contains *Schema `json:"contains,omitempty" yaml:"contains,omitempty"`
PrefixItems []*Schema `json:"prefixItems,omitempty" yaml:"prefixItems,omitempty"`
Items *Schema `json:"items,omitempty" yaml:"items,omitempty"`
AdditionalItems *Schema `json:"additionalItems,omitempty" yaml:"additionalItems,omitempty"`
UnevaluatedItems *Schema `json:"unevaluatedItems,omitempty" yaml:"unevaluatedItems,omitempty"`
Required []string `json:"required,omitempty" yaml:"required,omitempty"`
MaxProperties *uint64 `json:"maxProperties,omitempty" yaml:"maxProperties,omitempty"`
MinProperties *uint64 `json:"minProperties,omitempty" yaml:"minProperties,omitempty"`
PropertyNames *Schema `json:"propertyNames,omitempty" yaml:"propertyNames,omitempty"`
Properties map[string]*Schema `json:"properties,omitempty" yaml:"properties,omitempty"`
PatternProperties map[string]*Schema `json:"patternProperties,omitempty" yaml:"patternProperties,omitempty"`
AdditionalProperties *Schema `json:"additionalProperties,omitempty" yaml:"additionalProperties,omitempty"`
UnevaluatedProperties *Schema `json:"unevaluatedProperties,omitempty" yaml:"unevaluatedProperties,omitempty"`
DependentRequired map[string][]string `json:"dependentRequired,omitempty" yaml:"dependentRequired,omitempty"`
Dependencies any `json:"dependencies,omitempty" yaml:"dependencies,omitempty"` // Deprecated. Replaced by "dependentSchemas" and "dependentRequired"
DependentSchemas map[string]*Schema `json:"dependentSchemas,omitempty" yaml:"dependentSchemas,omitempty"`
Defs map[string]*Schema `json:"$defs,omitempty" yaml:"$defs,omitempty"`
// Deprecated: This field was renamed to "$defs" in draft 2019-09,
// but the field is kept in this struct to allow bundled schemas to use them.
Definitions map[string]*Schema `json:"definitions,omitempty" yaml:"definitions,omitempty"`
SkipProperties bool `json:"-" yaml:"-"`
MergeProperties bool `json:"-" yaml:"-"`
Hidden bool `json:"-" yaml:"-"`
RequiredByParent bool `json:"-" yaml:"-"`
// contains filtered or unexported fields
}
func Load ¶
Load uses a bundle Loader to resolve a schema "$ref". Depending on the loader implementation, it may read from cache, read files from disk, or fetch files from the web using HTTP.
The basePathForIDs is an absolute path used to change the resulting $ref & $id absolute paths of bundled local files to relative paths. It is only used cosmetically and has no impact of how files are loaded.
func SchemaBool ¶
func SchemaFalse ¶
func SchemaFalse() *Schema
SchemaTrue returns a newly allocated schema that just evaluates to "false" when encoded as JSON/YAML.
func SchemaTrue ¶
func SchemaTrue() *Schema
SchemaTrue returns a newly allocated schema that just evaluates to "true" when encoded as JSON/YAML.
func (*Schema) Kind ¶
func (s *Schema) Kind() SchemaKind
func (*Schema) MarshalJSON ¶
MarshalJSON implements json.Marshaler.
func (*Schema) MarshalYAML ¶
MarshalYAML implements yaml.Marshaler.
func (*Schema) SetKind ¶
func (s *Schema) SetKind(kind SchemaKind)
func (*Schema) SetReferrer ¶
func (*Schema) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler.
func (*Schema) UnmarshalYAML ¶
UnmarshalYAML implements yaml.Unmarshaler.
type SchemaKind ¶
type SchemaKind byte
SchemaKind is an internal enum used to be able to parse an entire schema as a boolean, which is used on fields like "additionalProperties".
The zero value is "treat this as an object".
const ( SchemaKindObject SchemaKind = iota SchemaKindTrue SchemaKindFalse )
func (SchemaKind) GoString ¶
func (k SchemaKind) GoString() string
GoString implements fmt.GoStringer, and is used in debug output such as:
fmt.Sprint("%#v", kind)
func (SchemaKind) IsBool ¶
func (k SchemaKind) IsBool() bool
IsBool returns true when the Schema represents a boolean value instead of an object.
type SchemaRoot ¶
type SchemaRoot struct {
ID string `yaml:"id" koanf:"id"`
Ref string `yaml:"ref" koanf:"ref"`
RefReferrer Referrer `yaml:"-" koanf:"-"`
Title string `yaml:"title" koanf:"title"`
Description string `yaml:"description" koanf:"description"`
AdditionalProperties *bool `yaml:"additionalProperties" koanf:"additional-properties"`
}
SchemaRoot struct defines root object of schema
type URLSchemeLoader ¶
URLSchemeLoader delegates to other Loader implementations based on the url.URL scheme.
type WriterLogger ¶ added in v2.1.0
WriterLogger is a Logger implementation that writes to a io.Writer.
func NewLogger ¶ added in v2.1.0
func NewLogger(output io.Writer) WriterLogger
NewLogger returns a new logger using the provided writer.
func (WriterLogger) Log ¶ added in v2.1.0
func (logger WriterLogger) Log(a ...any)
func (WriterLogger) Logf ¶ added in v2.1.0
func (logger WriterLogger) Logf(format string, a ...any)