From 5b70ab57d8778bdb5d1e34a50fd898deab8a6642 Mon Sep 17 00:00:00 2001 From: Aleksandar Stojanov Date: Wed, 21 Feb 2024 08:55:45 +0100 Subject: [PATCH] add readOnly field to schema from comments closes [#32](https://github.com/losisin/helm-values-schema-json/issues/32) Signed-off-by: Aleksandar Stojanov --- docs/README.md | 19 +++++++++++++++++++ pkg/parser.go | 6 ++++++ pkg/parser_test.go | 16 ++++++++++++---- pkg/schema.go | 7 ++++++- pkg/schema_test.go | 4 ++-- testdata/full.schema.json | 1 + testdata/full.yaml | 2 +- 7 files changed, 47 insertions(+), 8 deletions(-) diff --git a/docs/README.md b/docs/README.md index fcdbcbf..617faac 100644 --- a/docs/README.md +++ b/docs/README.md @@ -383,3 +383,22 @@ fullnameOverride: bar # @schema title: My title "type": "string" }, ``` + +### readOnly + +```yaml +image: + tag: latest # @schema readOnly: true +``` + +```json +"image": { + "properties": { + "tag": { + "readOnly": true, + "type": "string" + } + }, + "type": "object" +} +``` diff --git a/pkg/parser.go b/pkg/parser.go index 700d90d..815bdc0 100644 --- a/pkg/parser.go +++ b/pkg/parser.go @@ -53,6 +53,9 @@ func mergeSchemas(dest, src *Schema) *Schema { if src.Title != "" { dest.Title = src.Title } + if src.ReadOnly { + dest.ReadOnly = src.ReadOnly + } // Merge 'enum' field (assuming that maintaining order doesn't matter) dest.Enum = append(dest.Enum, src.Enum...) @@ -143,6 +146,9 @@ func convertSchemaToMapRec(schema *Schema, visited map[uintptr]bool) (map[string if schema.Title != "" { schemaMap["title"] = schema.Title } + if schema.ReadOnly { + schemaMap["readOnly"] = schema.ReadOnly + } // Arrays if len(schema.Required) > 0 { diff --git a/pkg/parser_test.go b/pkg/parser_test.go index 1098d03..cbc9a27 100644 --- a/pkg/parser_test.go +++ b/pkg/parser_test.go @@ -21,7 +21,7 @@ func schemasEqual(a, b *Schema) bool { return a == b } // Compare simple fields - if a.Type != b.Type || a.Pattern != b.Pattern || a.UniqueItems != b.UniqueItems || a.Title != b.Title { + if a.Type != b.Type || a.Pattern != b.Pattern || a.UniqueItems != b.UniqueItems || a.Title != b.Title || a.ReadOnly != b.ReadOnly { return false } // Compare pointer fields @@ -138,9 +138,9 @@ func TestMergeSchemas(t *testing.T) { }, { name: "string properties", - dest: &Schema{Type: "string", Pattern: "^abc", Title: "My Title", MinLength: uint64Ptr(1), MaxLength: uint64Ptr(10)}, - src: &Schema{Type: "string", Pattern: "^abc", Title: "My Title", MinLength: uint64Ptr(1), MaxLength: uint64Ptr(10)}, - want: &Schema{Type: "string", Pattern: "^abc", Title: "My Title", MinLength: uint64Ptr(1), MaxLength: uint64Ptr(10)}, + dest: &Schema{Type: "string", Pattern: "^abc", MinLength: uint64Ptr(1), MaxLength: uint64Ptr(10)}, + src: &Schema{Type: "string", Pattern: "^abc", MinLength: uint64Ptr(1), MaxLength: uint64Ptr(10)}, + want: &Schema{Type: "string", Pattern: "^abc", MinLength: uint64Ptr(1), MaxLength: uint64Ptr(10)}, }, { name: "array properties", @@ -154,6 +154,12 @@ func TestMergeSchemas(t *testing.T) { src: &Schema{Type: "object", MinProperties: uint64Ptr(1), MaxProperties: uint64Ptr(10)}, want: &Schema{Type: "object", MinProperties: uint64Ptr(1), MaxProperties: uint64Ptr(10)}, }, + { + name: "meta-data properties", + dest: &Schema{Type: "object", Title: "My Title", ReadOnly: true}, + src: &Schema{Type: "object", Title: "My Title", ReadOnly: true}, + want: &Schema{Type: "object", Title: "My Title", ReadOnly: true}, + }, } for _, tt := range tests { @@ -211,6 +217,7 @@ func TestConvertSchemaToMap(t *testing.T) { MinItems: uint64Ptr(1), MaxItems: uint64Ptr(2), UniqueItems: true, + ReadOnly: true, }, want: map[string]interface{}{ "type": "array", @@ -222,6 +229,7 @@ func TestConvertSchemaToMap(t *testing.T) { "minItems": uint64(1), "maxItems": uint64(2), "uniqueItems": true, + "readOnly": true, }, }, { diff --git a/pkg/schema.go b/pkg/schema.go index 4ebc9a8..20cb4a5 100644 --- a/pkg/schema.go +++ b/pkg/schema.go @@ -11,7 +11,6 @@ import ( type Schema struct { Type interface{} `json:"type,omitempty"` Enum []any `json:"enum,omitempty"` - Title string `json:"title,omitempty"` MultipleOf *float64 `json:"multipleOf,omitempty"` Maximum *float64 `json:"maximum,omitempty"` Minimum *float64 `json:"minimum,omitempty"` @@ -26,6 +25,8 @@ type Schema struct { Required []string `json:"required,omitempty"` Items *Schema `json:"items,omitempty"` Properties map[string]*Schema `json:"properties,omitempty"` + Title string `json:"title,omitempty"` + ReadOnly bool `json:"readOnly,omitempty"` } func getKind(value string) string { @@ -160,6 +161,10 @@ func processComment(schema *Schema, comment string) (isRequired bool) { schema.Type = processList(value, true) case "title": schema.Title = value + case "readOnly": + if v, err := strconv.ParseBool(value); err == nil { + schema.ReadOnly = v + } } } } diff --git a/pkg/schema_test.go b/pkg/schema_test.go index f725a3d..25f5ac6 100644 --- a/pkg/schema_test.go +++ b/pkg/schema_test.go @@ -276,8 +276,8 @@ func TestProcessComment(t *testing.T) { { name: "Set enum", schema: &Schema{}, - comment: "# @schema enum:[one, two, null]", - expectedSchema: &Schema{Enum: []any{"one", "two", nil}}, + comment: "# @schema enum:[one, two, null];readOnly:true", + expectedSchema: &Schema{Enum: []any{"one", "two", nil}, ReadOnly: true}, expectedRequired: false, }, { diff --git a/testdata/full.schema.json b/testdata/full.schema.json index 7f27075..f34abfd 100644 --- a/testdata/full.schema.json +++ b/testdata/full.schema.json @@ -102,6 +102,7 @@ "type": "string" }, "tag": { + "readOnly": true, "type": "string" } }, diff --git a/testdata/full.yaml b/testdata/full.yaml index 7789fb8..de5d193 100644 --- a/testdata/full.yaml +++ b/testdata/full.yaml @@ -1,7 +1,7 @@ # Required image: repository: nginx # @schema required: true - tag: latest + tag: latest # @schema readOnly: true pullPolicy: Always nameOverride: foo # @schema required: true