From ebddf6ed75ee99e371a1014a2b0765926e4e5e0f Mon Sep 17 00:00:00 2001 From: Aleksandar Stojanov <me@fnd.works> Date: Fri, 12 Apr 2024 17:49:21 +0200 Subject: [PATCH] add patternProperties from comments Signed-off-by: Aleksandar Stojanov <me@fnd.works> --- pkg/parser.go | 6 +++++ pkg/parser_test.go | 13 ++++++----- pkg/schema.go | 46 ++++++++++++++++++++++----------------- testdata/full.schema.json | 5 +++++ testdata/full.yaml | 2 +- 5 files changed, 45 insertions(+), 27 deletions(-) diff --git a/pkg/parser.go b/pkg/parser.go index ced7e49..970e2fa 100644 --- a/pkg/parser.go +++ b/pkg/parser.go @@ -50,6 +50,9 @@ func mergeSchemas(dest, src *Schema) *Schema { if src.MinProperties != nil { dest.MinProperties = src.MinProperties } + if src.PatternProperties != nil { + dest.PatternProperties = src.PatternProperties + } if src.Title != "" { dest.Title = src.Title } @@ -149,6 +152,9 @@ func convertSchemaToMapRec(schema *Schema, visited map[uintptr]bool) (map[string if schema.MinProperties != nil { schemaMap["minProperties"] = *schema.MinProperties } + if schema.PatternProperties != nil { + schemaMap["patternProperties"] = schema.PatternProperties + } if schema.Title != "" { schemaMap["title"] = schema.Title } diff --git a/pkg/parser_test.go b/pkg/parser_test.go index f59864e..a75916d 100644 --- a/pkg/parser_test.go +++ b/pkg/parser_test.go @@ -95,12 +95,13 @@ func TestMergeSchemas(t *testing.T) { dest: &Schema{Type: "object", Properties: map[string]*Schema{ "foo": {Type: "integer"}, }}, - src: &Schema{Type: "object", Properties: map[string]*Schema{ - "bar": {Type: "string"}, + src: &Schema{Type: "object", PatternProperties: map[string]*Schema{ + "^[a-z]$": {Type: "integer"}, }}, want: &Schema{Type: "object", Properties: map[string]*Schema{ "foo": {Type: "integer"}, - "bar": {Type: "string"}, + }, PatternProperties: map[string]*Schema{ + "^[a-z]$": {Type: "integer"}, }}, }, { @@ -150,9 +151,9 @@ func TestMergeSchemas(t *testing.T) { }, { name: "object properties", - dest: &Schema{Type: "object", MinProperties: uint64Ptr(1), MaxProperties: uint64Ptr(10)}, - src: &Schema{Type: "object", MinProperties: uint64Ptr(1), MaxProperties: uint64Ptr(10)}, - want: &Schema{Type: "object", MinProperties: uint64Ptr(1), MaxProperties: uint64Ptr(10)}, + dest: &Schema{Type: "object", MinProperties: uint64Ptr(1), MaxProperties: uint64Ptr(10), PatternProperties: map[string]*Schema{"^.$": {Type: "string"}}}, + src: &Schema{Type: "object", MinProperties: uint64Ptr(1), MaxProperties: uint64Ptr(10), PatternProperties: map[string]*Schema{"^.$": {Type: "string"}}}, + want: &Schema{Type: "object", MinProperties: uint64Ptr(1), MaxProperties: uint64Ptr(10), PatternProperties: map[string]*Schema{"^.$": {Type: "string"}}}, }, { name: "meta-data properties", diff --git a/pkg/schema.go b/pkg/schema.go index fa8abee..d6dcf6c 100644 --- a/pkg/schema.go +++ b/pkg/schema.go @@ -10,26 +10,27 @@ import ( ) type Schema struct { - Type interface{} `json:"type,omitempty"` - Enum []any `json:"enum,omitempty"` - MultipleOf *float64 `json:"multipleOf,omitempty"` - Maximum *float64 `json:"maximum,omitempty"` - Minimum *float64 `json:"minimum,omitempty"` - MaxLength *uint64 `json:"maxLength,omitempty"` - MinLength *uint64 `json:"minLength,omitempty"` - Pattern string `json:"pattern,omitempty"` - MaxItems *uint64 `json:"maxItems,omitempty"` - MinItems *uint64 `json:"minItems,omitempty"` - UniqueItems bool `json:"uniqueItems,omitempty"` - MaxProperties *uint64 `json:"maxProperties,omitempty"` - MinProperties *uint64 `json:"minProperties,omitempty"` - Required []string `json:"required,omitempty"` - Items *Schema `json:"items,omitempty"` - Properties map[string]*Schema `json:"properties,omitempty"` - Title string `json:"title,omitempty"` - Description string `json:"description,omitempty"` - ReadOnly bool `json:"readOnly,omitempty"` - Default interface{} `json:"default,omitempty"` + Type interface{} `json:"type,omitempty"` + Enum []any `json:"enum,omitempty"` + MultipleOf *float64 `json:"multipleOf,omitempty"` + Maximum *float64 `json:"maximum,omitempty"` + Minimum *float64 `json:"minimum,omitempty"` + MaxLength *uint64 `json:"maxLength,omitempty"` + MinLength *uint64 `json:"minLength,omitempty"` + Pattern string `json:"pattern,omitempty"` + MaxItems *uint64 `json:"maxItems,omitempty"` + MinItems *uint64 `json:"minItems,omitempty"` + UniqueItems bool `json:"uniqueItems,omitempty"` + MaxProperties *uint64 `json:"maxProperties,omitempty"` + MinProperties *uint64 `json:"minProperties,omitempty"` + PatternProperties interface{} `json:"patternProperties,omitempty"` + Required []string `json:"required,omitempty"` + Items *Schema `json:"items,omitempty"` + Properties map[string]*Schema `json:"properties,omitempty"` + Title string `json:"title,omitempty"` + Description string `json:"description,omitempty"` + ReadOnly bool `json:"readOnly,omitempty"` + Default interface{} `json:"default,omitempty"` } func getKind(value string) string { @@ -156,6 +157,11 @@ func processComment(schema *Schema, comment string) (isRequired bool) { if v, err := strconv.ParseUint(value, 10, 64); err == nil { schema.MinProperties = &v } + case "patternProperties": + var jsonObject interface{} + if err := json.Unmarshal([]byte(value), &jsonObject); err == nil { + schema.PatternProperties = jsonObject + } case "required": if strings.TrimSpace(value) == "true" { isRequired = strings.TrimSpace(value) == "true" diff --git a/testdata/full.schema.json b/testdata/full.schema.json index 157870e..439a59d 100644 --- a/testdata/full.schema.json +++ b/testdata/full.schema.json @@ -11,6 +11,11 @@ "items": { "properties": { "preference": { + "patternProperties": { + "^[a-z]$": { + "type": "string" + } + }, "properties": { "matchExpressions": { "items": { diff --git a/testdata/full.yaml b/testdata/full.yaml index c407166..b0eb9c5 100644 --- a/testdata/full.yaml +++ b/testdata/full.yaml @@ -39,7 +39,7 @@ affinity: - antarctica-west1 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 - preference: + preference: # @schema patternProperties: {"^[a-z]$": {"type": "string"}} matchExpressions: - key: another-node-label-key operator: In