mirror of https://github.com/databricks/cli.git
fixed debugTrace
This commit is contained in:
parent
1ee35c3633
commit
276ba00067
|
@ -31,11 +31,11 @@ type Item struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSchema(golangType reflect.Type) (*Schema, error) {
|
func NewSchema(golangType reflect.Type) (*Schema, error) {
|
||||||
traceSet := map[reflect.Type]struct{}{}
|
seenTypes := map[reflect.Type]struct{}{}
|
||||||
trace := list.New()
|
debugTrace := list.New()
|
||||||
rootProp, err := toProperity(golangType, traceSet, trace)
|
rootProp, err := toProperity(golangType, seenTypes, debugTrace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errWithTrace(err.Error(), debugTrace)
|
||||||
}
|
}
|
||||||
return &Schema{
|
return &Schema{
|
||||||
Type: rootProp.Type,
|
Type: rootProp.Type,
|
||||||
|
@ -46,15 +46,15 @@ func NewSchema(golangType reflect.Type) (*Schema, error) {
|
||||||
|
|
||||||
// TODO: add tests for errors being triggered
|
// TODO: add tests for errors being triggered
|
||||||
|
|
||||||
type JavascriptType int
|
type JavascriptType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Invalid JavascriptType = iota
|
Invalid JavascriptType = "invalid"
|
||||||
Boolean
|
Boolean JavascriptType = "boolean"
|
||||||
String
|
String JavascriptType = "string"
|
||||||
Number
|
Number JavascriptType = "number"
|
||||||
Object
|
Object JavascriptType = "object"
|
||||||
Array
|
Array JavascriptType = "array"
|
||||||
)
|
)
|
||||||
|
|
||||||
func javascriptType(golangType reflect.Type) (JavascriptType, error) {
|
func javascriptType(golangType reflect.Type) (JavascriptType, error) {
|
||||||
|
@ -84,13 +84,13 @@ func javascriptType(golangType reflect.Type) (JavascriptType, error) {
|
||||||
|
|
||||||
// TODO: add a simple test for this
|
// TODO: add a simple test for this
|
||||||
func errWithTrace(prefix string, trace *list.List) error {
|
func errWithTrace(prefix string, trace *list.List) error {
|
||||||
traceString := ""
|
traceString := "root"
|
||||||
curr := trace.Front()
|
curr := trace.Front()
|
||||||
for curr.Next() != nil {
|
for curr.Next() != nil {
|
||||||
traceString += " -> " + curr.Value.(reflect.Type).Name()
|
traceString += " -> " + curr.Value.(string)
|
||||||
curr = curr.Next()
|
curr = curr.Next()
|
||||||
}
|
}
|
||||||
return fmt.Errorf("[ERROR] " + prefix + " type traveral trace: " + traceString)
|
return fmt.Errorf("[ERROR] " + prefix + ". traveral trace: " + traceString)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle case of self referential pointers in structs
|
// TODO: handle case of self referential pointers in structs
|
||||||
|
@ -100,25 +100,22 @@ func errWithTrace(prefix string, trace *list.List) error {
|
||||||
|
|
||||||
// checks and errors out for cycles
|
// checks and errors out for cycles
|
||||||
// wraps the error with context
|
// wraps the error with context
|
||||||
func safeToProperty(golangType reflect.Type, traceSet map[reflect.Type]struct{}, trace *list.List) (*Property, error) {
|
func safeToProperty(golangType reflect.Type, seenTypes map[reflect.Type]struct{}, debugTrace *list.List) (*Property, error) {
|
||||||
trace.PushBack(golangType)
|
|
||||||
// detect cycles. Fail if a cycle is detected
|
// detect cycles. Fail if a cycle is detected
|
||||||
// TODO: Add references here for cycles
|
// TODO: Add references here for cycles
|
||||||
// TODO: move this check somewhere nicer
|
// TODO: move this check somewhere nicer
|
||||||
_, ok := traceSet[golangType]
|
_, ok := seenTypes[golangType]
|
||||||
if ok {
|
if ok {
|
||||||
fmt.Println("[DEBUG] traceSet: ", traceSet)
|
fmt.Println("[DEBUG] traceSet: ", seenTypes)
|
||||||
return nil, errWithTrace("cycle detected", trace)
|
return nil, fmt.Errorf("cycle detected")
|
||||||
}
|
}
|
||||||
// add current child field to history
|
// add current child field to history
|
||||||
traceSet[golangType] = struct{}{}
|
seenTypes[golangType] = struct{}{}
|
||||||
props, err := toProperity(golangType, traceSet, trace)
|
props, err := toProperity(golangType, seenTypes, debugTrace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errWithTrace(err.Error(), trace)
|
return nil, err
|
||||||
}
|
}
|
||||||
delete(traceSet, golangType)
|
delete(seenTypes, golangType)
|
||||||
back := trace.Back()
|
|
||||||
trace.Remove(back)
|
|
||||||
return props, nil
|
return props, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,11 +152,19 @@ func addStructFields(fields []reflect.StructField, golangType reflect.Type) []re
|
||||||
return fields
|
return fields
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: add ignore for -
|
||||||
|
|
||||||
// TODO: add doc string explaining numHistoryOccurances
|
// TODO: add doc string explaining numHistoryOccurances
|
||||||
func toProperity(golangType reflect.Type, traceSet map[reflect.Type]struct{}, trace *list.List) (*Property, error) {
|
func toProperity(golangType reflect.Type, seenTypes map[reflect.Type]struct{}, debugTrace *list.List) (*Property, error) {
|
||||||
// *Struct and Struct generate identical json schemas
|
// *Struct and Struct generate identical json schemas
|
||||||
|
// TODO: add test case for pointer
|
||||||
if golangType.Kind() == reflect.Pointer {
|
if golangType.Kind() == reflect.Pointer {
|
||||||
return toProperity(golangType.Elem(), traceSet, trace)
|
return toProperity(golangType.Elem(), seenTypes, debugTrace)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: add test case for interfaces
|
||||||
|
if golangType.Kind() == reflect.Interface {
|
||||||
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
rootJavascriptType, err := javascriptType(golangType)
|
rootJavascriptType, err := javascriptType(golangType)
|
||||||
|
@ -175,7 +180,7 @@ func toProperity(golangType reflect.Type, traceSet map[reflect.Type]struct{}, tr
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
elemProps, err := safeToProperty(elemGolangType, traceSet, trace)
|
elemProps, err := safeToProperty(elemGolangType, seenTypes, debugTrace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -190,9 +195,9 @@ func toProperity(golangType reflect.Type, traceSet map[reflect.Type]struct{}, tr
|
||||||
var additionalProperties *Property
|
var additionalProperties *Property
|
||||||
if golangType.Kind() == reflect.Map {
|
if golangType.Kind() == reflect.Map {
|
||||||
if golangType.Key().Kind() != reflect.String {
|
if golangType.Key().Kind() != reflect.String {
|
||||||
return nil, errWithTrace("only string keyed maps allowed", trace)
|
return nil, fmt.Errorf("only string keyed maps allowed")
|
||||||
}
|
}
|
||||||
additionalProperties, err = safeToProperty(golangType.Elem(), traceSet, trace)
|
additionalProperties, err = safeToProperty(golangType.Elem(), seenTypes, debugTrace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -208,17 +213,24 @@ func toProperity(golangType reflect.Type, traceSet map[reflect.Type]struct{}, tr
|
||||||
childJsonTag := child.Tag.Get("json")
|
childJsonTag := child.Tag.Get("json")
|
||||||
childName := strings.Split(childJsonTag, ",")[0]
|
childName := strings.Split(childJsonTag, ",")[0]
|
||||||
|
|
||||||
|
// add current field to debug trace
|
||||||
|
debugTrace.PushBack(childName)
|
||||||
|
|
||||||
// skip non json annotated fields
|
// skip non json annotated fields
|
||||||
if childName == "" {
|
if childName == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// recursively compute properties for this child field
|
// recursively compute properties for this child field
|
||||||
fieldProps, err := safeToProperty(child.Type, traceSet, trace)
|
fieldProps, err := safeToProperty(child.Type, seenTypes, debugTrace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errWithTrace(err.Error(), trace)
|
return nil, err
|
||||||
}
|
}
|
||||||
properities[childName] = fieldProps
|
properities[childName] = fieldProps
|
||||||
|
|
||||||
|
// remove current field from debug trace
|
||||||
|
back := debugTrace.Back()
|
||||||
|
debugTrace.Remove(back)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/databricks/bricks/bundle/config"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -337,3 +338,21 @@ func TestEmbeddedStructSchema(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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only for testing bundle, will be removed
|
||||||
|
func TestBundleSchema(t *testing.T) {
|
||||||
|
elem := config.Root{}
|
||||||
|
|
||||||
|
schema, err := NewSchema(reflect.TypeOf(elem))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
jsonSchema, err := json.MarshalIndent(schema, " ", " ")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
expected :=
|
||||||
|
``
|
||||||
|
|
||||||
|
t.Log("[DEBUG] actual: ", string(jsonSchema))
|
||||||
|
t.Log("[DEBUG] expected: ", expected)
|
||||||
|
assert.Equal(t, expected, string(jsonSchema))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue