mirror of https://github.com/databricks/cli.git
Allow including fields with ignored tags in the bundle schema output
This commit is contained in:
parent
d8a64e6617
commit
0b222358ca
|
@ -52,7 +52,7 @@ func UpdateBundleDescriptions(openapiSpecPath string) (*Docs, error) {
|
||||||
// Generate schema from the embedded descriptions, and convert it back to docs.
|
// Generate schema from the embedded descriptions, and convert it back to docs.
|
||||||
// This creates empty descriptions for any properties that were missing in the
|
// This creates empty descriptions for any properties that were missing in the
|
||||||
// embedded descriptions.
|
// embedded descriptions.
|
||||||
schema, err := New(reflect.TypeOf(config.Root{}), embedded)
|
schema, err := New(reflect.TypeOf(config.Root{}), embedded, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ func UpdateBundleDescriptions(openapiSpecPath string) (*Docs, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resourceSchema, err := New(reflect.TypeOf(config.Resources{}), resourcesDocs)
|
resourceSchema, err := New(reflect.TypeOf(config.Resources{}), resourcesDocs, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"container/list"
|
"container/list"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/jsonschema"
|
"github.com/databricks/cli/libs/jsonschema"
|
||||||
|
@ -42,9 +43,9 @@ const deprecatedTag = "deprecated"
|
||||||
//
|
//
|
||||||
// - []MyStruct -> {type: object, properties: {}, additionalProperties: false}
|
// - []MyStruct -> {type: object, properties: {}, additionalProperties: false}
|
||||||
// for details visit: https://json-schema.org/understanding-json-schema/reference/object.html#properties
|
// for details visit: https://json-schema.org/understanding-json-schema/reference/object.html#properties
|
||||||
func New(golangType reflect.Type, docs *Docs) (*jsonschema.Schema, error) {
|
func New(golangType reflect.Type, docs *Docs, includeTags []string) (*jsonschema.Schema, error) {
|
||||||
tracker := newTracker()
|
tracker := newTracker()
|
||||||
schema, err := safeToSchema(golangType, docs, "", tracker)
|
schema, err := safeToSchema(golangType, docs, "", tracker, includeTags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, tracker.errWithTrace(err.Error(), "root")
|
return nil, tracker.errWithTrace(err.Error(), "root")
|
||||||
}
|
}
|
||||||
|
@ -91,7 +92,7 @@ func jsonSchemaType(golangType reflect.Type) (jsonschema.Type, error) {
|
||||||
// like array, map or no json tags
|
// like array, map or no json tags
|
||||||
//
|
//
|
||||||
// - tracker: Keeps track of types / traceIds seen during recursive traversal
|
// - tracker: Keeps track of types / traceIds seen during recursive traversal
|
||||||
func safeToSchema(golangType reflect.Type, docs *Docs, traceId string, tracker *tracker) (*jsonschema.Schema, error) {
|
func safeToSchema(golangType reflect.Type, docs *Docs, traceId string, tracker *tracker, includeTags []string) (*jsonschema.Schema, error) {
|
||||||
// WE ERROR OUT IF THERE ARE CYCLES IN THE JSON SCHEMA
|
// WE ERROR OUT IF THERE ARE CYCLES IN THE JSON SCHEMA
|
||||||
// There are mechanisms to deal with cycles though recursive identifiers in json
|
// There are mechanisms to deal with cycles though recursive identifiers in json
|
||||||
// schema. However if we use them, we would need to make sure we are able to detect
|
// schema. However if we use them, we would need to make sure we are able to detect
|
||||||
|
@ -104,7 +105,7 @@ func safeToSchema(golangType reflect.Type, docs *Docs, traceId string, tracker *
|
||||||
}
|
}
|
||||||
|
|
||||||
tracker.push(golangType, traceId)
|
tracker.push(golangType, traceId)
|
||||||
props, err := toSchema(golangType, docs, tracker)
|
props, err := toSchema(golangType, docs, tracker, includeTags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -144,10 +145,10 @@ func getStructFields(golangType reflect.Type) []reflect.StructField {
|
||||||
return fields
|
return fields
|
||||||
}
|
}
|
||||||
|
|
||||||
func toSchema(golangType reflect.Type, docs *Docs, tracker *tracker) (*jsonschema.Schema, error) {
|
func toSchema(golangType reflect.Type, docs *Docs, tracker *tracker, includeTags []string) (*jsonschema.Schema, error) {
|
||||||
// *Struct and Struct generate identical json schemas
|
// *Struct and Struct generate identical json schemas
|
||||||
if golangType.Kind() == reflect.Pointer {
|
if golangType.Kind() == reflect.Pointer {
|
||||||
return safeToSchema(golangType.Elem(), docs, "", tracker)
|
return safeToSchema(golangType.Elem(), docs, "", tracker, includeTags)
|
||||||
}
|
}
|
||||||
if golangType.Kind() == reflect.Interface {
|
if golangType.Kind() == reflect.Interface {
|
||||||
return &jsonschema.Schema{}, nil
|
return &jsonschema.Schema{}, nil
|
||||||
|
@ -174,7 +175,7 @@ func toSchema(golangType reflect.Type, docs *Docs, tracker *tracker) (*jsonschem
|
||||||
if docs != nil {
|
if docs != nil {
|
||||||
childDocs = docs.Items
|
childDocs = docs.Items
|
||||||
}
|
}
|
||||||
elemProps, err := safeToSchema(elemGolangType, childDocs, "", tracker)
|
elemProps, err := safeToSchema(elemGolangType, childDocs, "", tracker, includeTags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -196,7 +197,7 @@ func toSchema(golangType reflect.Type, docs *Docs, tracker *tracker) (*jsonschem
|
||||||
if docs != nil {
|
if docs != nil {
|
||||||
childDocs = docs.AdditionalProperties
|
childDocs = docs.AdditionalProperties
|
||||||
}
|
}
|
||||||
jsonSchema.AdditionalProperties, err = safeToSchema(golangType.Elem(), childDocs, "", tracker)
|
jsonSchema.AdditionalProperties, err = safeToSchema(golangType.Elem(), childDocs, "", tracker, includeTags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -211,7 +212,7 @@ func toSchema(golangType reflect.Type, docs *Docs, tracker *tracker) (*jsonschem
|
||||||
bundleTag := child.Tag.Get("bundle")
|
bundleTag := child.Tag.Get("bundle")
|
||||||
// Fields marked as "readonly", "internal" or "deprecated" are skipped
|
// Fields marked as "readonly", "internal" or "deprecated" are skipped
|
||||||
// while generating the schema
|
// while generating the schema
|
||||||
if bundleTag == readonlyTag || bundleTag == internalTag || bundleTag == deprecatedTag {
|
if (bundleTag == readonlyTag || bundleTag == internalTag || bundleTag == deprecatedTag) && !slices.Contains(includeTags, bundleTag) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +247,7 @@ func toSchema(golangType reflect.Type, docs *Docs, tracker *tracker) (*jsonschem
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute Schema.Properties for the child recursively
|
// compute Schema.Properties for the child recursively
|
||||||
fieldProps, err := safeToSchema(child.Type, childDocs, childName, tracker)
|
fieldProps, err := safeToSchema(child.Type, childDocs, childName, tracker, includeTags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ func TestIntSchema(t *testing.T) {
|
||||||
"type": "number"
|
"type": "number"
|
||||||
}`
|
}`
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elemInt), nil)
|
schema, err := New(reflect.TypeOf(elemInt), nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -36,7 +36,7 @@ func TestBooleanSchema(t *testing.T) {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
}`
|
}`
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -55,7 +55,7 @@ func TestStringSchema(t *testing.T) {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}`
|
}`
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -90,7 +90,7 @@ func TestStructOfPrimitivesSchema(t *testing.T) {
|
||||||
|
|
||||||
elem := Foo{}
|
elem := Foo{}
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -183,7 +183,7 @@ func TestStructOfStructsSchema(t *testing.T) {
|
||||||
|
|
||||||
elem := MyStruct{}
|
elem := MyStruct{}
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -241,7 +241,7 @@ func TestStructOfMapsSchema(t *testing.T) {
|
||||||
|
|
||||||
elem := Foo{}
|
elem := Foo{}
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -289,7 +289,7 @@ func TestStructOfSliceSchema(t *testing.T) {
|
||||||
|
|
||||||
elem := Foo{}
|
elem := Foo{}
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -329,7 +329,7 @@ func TestStructOfSliceSchema(t *testing.T) {
|
||||||
func TestMapOfPrimitivesSchema(t *testing.T) {
|
func TestMapOfPrimitivesSchema(t *testing.T) {
|
||||||
var elem map[string]int
|
var elem map[string]int
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -355,7 +355,7 @@ func TestMapOfStructSchema(t *testing.T) {
|
||||||
|
|
||||||
var elem map[string]Foo
|
var elem map[string]Foo
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -386,7 +386,7 @@ func TestMapOfStructSchema(t *testing.T) {
|
||||||
func TestMapOfMapSchema(t *testing.T) {
|
func TestMapOfMapSchema(t *testing.T) {
|
||||||
var elem map[string]map[string]int
|
var elem map[string]map[string]int
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -411,7 +411,7 @@ func TestMapOfMapSchema(t *testing.T) {
|
||||||
func TestMapOfSliceSchema(t *testing.T) {
|
func TestMapOfSliceSchema(t *testing.T) {
|
||||||
var elem map[string][]string
|
var elem map[string][]string
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -436,7 +436,7 @@ func TestMapOfSliceSchema(t *testing.T) {
|
||||||
func TestSliceOfPrimitivesSchema(t *testing.T) {
|
func TestSliceOfPrimitivesSchema(t *testing.T) {
|
||||||
var elem []float32
|
var elem []float32
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -458,7 +458,7 @@ func TestSliceOfPrimitivesSchema(t *testing.T) {
|
||||||
func TestSliceOfSliceSchema(t *testing.T) {
|
func TestSliceOfSliceSchema(t *testing.T) {
|
||||||
var elem [][]string
|
var elem [][]string
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -483,7 +483,7 @@ func TestSliceOfSliceSchema(t *testing.T) {
|
||||||
func TestSliceOfMapSchema(t *testing.T) {
|
func TestSliceOfMapSchema(t *testing.T) {
|
||||||
var elem []map[string]int
|
var elem []map[string]int
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -512,7 +512,7 @@ func TestSliceOfStructSchema(t *testing.T) {
|
||||||
|
|
||||||
var elem []Foo
|
var elem []Foo
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -564,7 +564,7 @@ func TestEmbeddedStructSchema(t *testing.T) {
|
||||||
|
|
||||||
elem := Story{}
|
elem := Story{}
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -683,7 +683,7 @@ func TestNonAnnotatedFieldsAreSkipped(t *testing.T) {
|
||||||
|
|
||||||
elem := MyStruct{}
|
elem := MyStruct{}
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -717,7 +717,7 @@ func TestDashFieldsAreSkipped(t *testing.T) {
|
||||||
|
|
||||||
elem := MyStruct{}
|
elem := MyStruct{}
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -759,7 +759,7 @@ func TestPointerInStructSchema(t *testing.T) {
|
||||||
|
|
||||||
elem := Foo{}
|
elem := Foo{}
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -846,7 +846,7 @@ func TestGenericSchema(t *testing.T) {
|
||||||
|
|
||||||
elem := Story{}
|
elem := Story{}
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -1017,7 +1017,7 @@ func TestFieldsWithoutOmitEmptyAreRequired(t *testing.T) {
|
||||||
|
|
||||||
elem := MyStruct{}
|
elem := MyStruct{}
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -1091,7 +1091,7 @@ func TestDocIngestionForObject(t *testing.T) {
|
||||||
|
|
||||||
elem := Root{}
|
elem := Root{}
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), docs)
|
schema, err := New(reflect.TypeOf(elem), docs, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -1167,7 +1167,7 @@ func TestDocIngestionForSlice(t *testing.T) {
|
||||||
|
|
||||||
elem := Root{}
|
elem := Root{}
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), docs)
|
schema, err := New(reflect.TypeOf(elem), docs, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -1250,7 +1250,7 @@ func TestDocIngestionForMap(t *testing.T) {
|
||||||
|
|
||||||
elem := Root{}
|
elem := Root{}
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), docs)
|
schema, err := New(reflect.TypeOf(elem), docs, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -1312,7 +1312,7 @@ func TestDocIngestionForTopLevelPrimitive(t *testing.T) {
|
||||||
|
|
||||||
elem := Root{}
|
elem := Root{}
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), docs)
|
schema, err := New(reflect.TypeOf(elem), docs, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -1345,7 +1345,7 @@ func TestErrorOnMapWithoutStringKey(t *testing.T) {
|
||||||
Bar map[int]string `json:"bar"`
|
Bar map[int]string `json:"bar"`
|
||||||
}
|
}
|
||||||
elem := Foo{}
|
elem := Foo{}
|
||||||
_, err := New(reflect.TypeOf(elem), nil)
|
_, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.ErrorContains(t, err, "only strings map keys are valid. key type: int")
|
assert.ErrorContains(t, err, "only strings map keys are valid. key type: int")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1355,7 +1355,7 @@ func TestErrorIfStructRefersToItself(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
elem := Foo{}
|
elem := Foo{}
|
||||||
_, err := New(reflect.TypeOf(elem), nil)
|
_, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.ErrorContains(t, err, "cycle detected. traversal trace: root -> my_foo")
|
assert.ErrorContains(t, err, "cycle detected. traversal trace: root -> my_foo")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1372,7 +1372,7 @@ func TestErrorIfStructHasLoop(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
elem := Apple{}
|
elem := Apple{}
|
||||||
_, err := New(reflect.TypeOf(elem), nil)
|
_, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.ErrorContains(t, err, "cycle detected. traversal trace: root -> my_mango -> my_guava -> my_papaya -> my_apple")
|
assert.ErrorContains(t, err, "cycle detected. traversal trace: root -> my_mango -> my_guava -> my_papaya -> my_apple")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1384,7 +1384,7 @@ func TestInterfaceGeneratesEmptySchema(t *testing.T) {
|
||||||
|
|
||||||
elem := Foo{}
|
elem := Foo{}
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -1425,7 +1425,7 @@ func TestBundleReadOnlytag(t *testing.T) {
|
||||||
|
|
||||||
elem := Foo{}
|
elem := Foo{}
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -1477,7 +1477,7 @@ func TestBundleInternalTag(t *testing.T) {
|
||||||
|
|
||||||
elem := Foo{}
|
elem := Foo{}
|
||||||
|
|
||||||
schema, err := New(reflect.TypeOf(elem), nil)
|
schema, err := New(reflect.TypeOf(elem), nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
@ -1514,3 +1514,118 @@ func TestBundleInternalTag(t *testing.T) {
|
||||||
t.Log("[DEBUG] expected: ", expected)
|
t.Log("[DEBUG] expected: ", expected)
|
||||||
assert.Equal(t, expected, string(jsonSchema))
|
assert.Equal(t, expected, string(jsonSchema))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBundleSingleIncludeTag(t *testing.T) {
|
||||||
|
type Pokemon struct {
|
||||||
|
Pikachu string `json:"pikachu" bundle:"internal"`
|
||||||
|
Raichu string `json:"raichu"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Foo struct {
|
||||||
|
Pokemon *Pokemon `json:"pokemon"`
|
||||||
|
Apple int `json:"apple"`
|
||||||
|
Banana int `json:"banana,omitempty" bundle:"readonly"`
|
||||||
|
Mango string `json:"mango" bundle:"internal"`
|
||||||
|
}
|
||||||
|
|
||||||
|
elem := Foo{}
|
||||||
|
|
||||||
|
schema, err := New(reflect.TypeOf(elem), nil, []string{"readonly"})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
expected :=
|
||||||
|
`{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"apple": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"banana": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"pokemon": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"raichu": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": [
|
||||||
|
"raichu"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": [
|
||||||
|
"pokemon",
|
||||||
|
"apple"
|
||||||
|
]
|
||||||
|
}`
|
||||||
|
|
||||||
|
t.Log("[DEBUG] actual: ", string(jsonSchema))
|
||||||
|
t.Log("[DEBUG] expected: ", expected)
|
||||||
|
assert.Equal(t, expected, string(jsonSchema))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBundleMultipleIncludeTag(t *testing.T) {
|
||||||
|
type Pokemon struct {
|
||||||
|
Pikachu string `json:"pikachu" bundle:"deprecated"`
|
||||||
|
Raichu string `json:"raichu"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Foo struct {
|
||||||
|
Pokemon *Pokemon `json:"pokemon"`
|
||||||
|
Apple int `json:"apple"`
|
||||||
|
Banana int `json:"banana,omitempty" bundle:"readonly"`
|
||||||
|
Mango string `json:"mango,omitempty" bundle:"internal"`
|
||||||
|
}
|
||||||
|
|
||||||
|
elem := Foo{}
|
||||||
|
|
||||||
|
schema, err := New(reflect.TypeOf(elem), nil, []string{"readonly", "internal"})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
expected :=
|
||||||
|
`{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"apple": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"banana": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"mango": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"pokemon": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"raichu": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": [
|
||||||
|
"raichu"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": [
|
||||||
|
"pokemon",
|
||||||
|
"apple"
|
||||||
|
]
|
||||||
|
}`
|
||||||
|
|
||||||
|
t.Log("[DEBUG] actual: ", string(jsonSchema))
|
||||||
|
t.Log("[DEBUG] expected: ", expected)
|
||||||
|
assert.Equal(t, expected, string(jsonSchema))
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@ func newSchemaCommand() *cobra.Command {
|
||||||
Use: "schema",
|
Use: "schema",
|
||||||
Short: "Generate JSON Schema for bundle configuration",
|
Short: "Generate JSON Schema for bundle configuration",
|
||||||
}
|
}
|
||||||
|
var includeTags []string
|
||||||
|
cmd.Flags().StringSliceVar(&includeTags, "include-tags", []string{}, "Also include fields with these tags.")
|
||||||
|
|
||||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||||
// Load embedded schema descriptions.
|
// Load embedded schema descriptions.
|
||||||
|
@ -23,7 +25,7 @@ func newSchemaCommand() *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the JSON schema from the bundle configuration struct in Go.
|
// Generate the JSON schema from the bundle configuration struct in Go.
|
||||||
schema, err := schema.New(reflect.TypeOf(config.Root{}), docs)
|
schema, err := schema.New(reflect.TypeOf(config.Root{}), docs, includeTags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue