mirror of https://github.com/databricks/cli.git
fix: More ducmentation + tests
This commit is contained in:
parent
d27282c3a4
commit
13181fc5a7
|
@ -87,13 +87,13 @@ func buildAttributeTable(m *markdownRenderer, attributes []attributeNode) *markd
|
|||
|
||||
func formatDescription(a attributeNode) string {
|
||||
s := strings.ReplaceAll(a.Description, "\n", " ")
|
||||
if a.Reference != "" {
|
||||
if a.Link != "" {
|
||||
if strings.HasSuffix(s, ".") {
|
||||
s += " "
|
||||
} else if s != "" {
|
||||
s += ". "
|
||||
}
|
||||
s += fmt.Sprintf("See [_](#%s).", a.Reference)
|
||||
s += fmt.Sprintf("See [_](#%s).", a.Link)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ type attributeNode struct {
|
|||
Title string
|
||||
Type string
|
||||
Description string
|
||||
Reference string
|
||||
Link string
|
||||
}
|
||||
|
||||
type rootProp struct {
|
||||
|
@ -61,6 +61,7 @@ func buildNodes(s jsonschema.Schema, refs map[string]*jsonschema.Schema, ownFiel
|
|||
continue
|
||||
}
|
||||
visited[k] = true
|
||||
|
||||
v = resolveRefs(v, refs)
|
||||
node := rootNode{
|
||||
Title: k,
|
||||
|
@ -70,37 +71,56 @@ func buildNodes(s jsonschema.Schema, refs map[string]*jsonschema.Schema, ownFiel
|
|||
Type: getHumanReadableType(v.Type),
|
||||
}
|
||||
|
||||
node.Attributes = getAttributes(v.Properties, refs, ownFields, k, item.circular)
|
||||
if !item.circular {
|
||||
rootProps = append(rootProps, extractNodes(k, v.Properties, refs, ownFields)...)
|
||||
hasProperties := len(v.Properties) > 0
|
||||
if hasProperties {
|
||||
node.Attributes = getAttributes(v.Properties, refs, ownFields, k, item.circular)
|
||||
}
|
||||
|
||||
additionalProps, ok := v.AdditionalProperties.(*jsonschema.Schema)
|
||||
if ok {
|
||||
objectKeyType := resolveRefs(additionalProps, refs)
|
||||
d := getDescription(objectKeyType, true)
|
||||
mapValueType := getMapValueType(v, refs)
|
||||
if mapValueType != nil {
|
||||
d := getDescription(mapValueType, true)
|
||||
if d != "" {
|
||||
node.Description = d
|
||||
}
|
||||
if len(node.Example) == 0 {
|
||||
node.Example = getExample(objectKeyType)
|
||||
}
|
||||
prefix := k + ".<name>"
|
||||
node.ObjectKeyAttributes = getAttributes(objectKeyType.Properties, refs, ownFields, prefix, item.circular)
|
||||
if !item.circular {
|
||||
rootProps = append(rootProps, extractNodes(prefix, objectKeyType.Properties, refs, ownFields)...)
|
||||
if node.Example == "" {
|
||||
node.Example = getExample(mapValueType)
|
||||
}
|
||||
node.ObjectKeyAttributes = getAttributes(mapValueType.Properties, refs, ownFields, getMapKeyPrefix(k), item.circular)
|
||||
}
|
||||
|
||||
if v.Items != nil {
|
||||
arrayItemType := resolveRefs(v.Items, refs)
|
||||
arrayItemType := resolveRefs(v.Items, refs)
|
||||
if arrayItemType != nil {
|
||||
node.ArrayItemAttributes = getAttributes(arrayItemType.Properties, refs, ownFields, k, item.circular)
|
||||
if !item.circular {
|
||||
rootProps = append(rootProps, extractNodes(k, arrayItemType.Properties, refs, ownFields)...)
|
||||
}
|
||||
}
|
||||
|
||||
nodes = append(nodes, node)
|
||||
|
||||
// Whether we should add new root props from the children of the current JSON-schema node to include their definitions to this document
|
||||
shouldAddNewProps := !item.circular
|
||||
if shouldAddNewProps {
|
||||
newProps := []rootProp{}
|
||||
// Adds node with definition for the properties. Example:
|
||||
// bundle:
|
||||
// prop-name: <value>
|
||||
if hasProperties {
|
||||
newProps = append(newProps, extractNodes(k, v.Properties, refs, ownFields)...)
|
||||
}
|
||||
|
||||
// Adds node with definition for the type of array item. Example:
|
||||
// permissions:
|
||||
// - <item>
|
||||
if arrayItemType != nil {
|
||||
newProps = append(newProps, extractNodes(k, arrayItemType.Properties, refs, ownFields)...)
|
||||
}
|
||||
// Adds node with definition for the type of the Map value. Example:
|
||||
// targets:
|
||||
// <key>: <value>
|
||||
if mapValueType != nil {
|
||||
newProps = append(newProps, extractNodes(getMapKeyPrefix(k), mapValueType.Properties, refs, ownFields)...)
|
||||
}
|
||||
|
||||
rootProps = append(rootProps, newProps...)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Slice(nodes, func(i, j int) bool {
|
||||
|
@ -109,6 +129,18 @@ func buildNodes(s jsonschema.Schema, refs map[string]*jsonschema.Schema, ownFiel
|
|||
return nodes
|
||||
}
|
||||
|
||||
func getMapValueType(v *jsonschema.Schema, refs map[string]*jsonschema.Schema) *jsonschema.Schema {
|
||||
additionalProps, ok := v.AdditionalProperties.(*jsonschema.Schema)
|
||||
if ok {
|
||||
return resolveRefs(additionalProps, refs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getMapKeyPrefix(s string) string {
|
||||
return s + ".<name>"
|
||||
}
|
||||
|
||||
func removePluralForm(s string) string {
|
||||
if strings.HasSuffix(s, "s") {
|
||||
return strings.TrimSuffix(s, "s")
|
||||
|
@ -143,7 +175,7 @@ func getAttributes(props, refs map[string]*jsonschema.Schema, ownFields map[stri
|
|||
Title: k,
|
||||
Type: typeString,
|
||||
Description: getDescription(v, true),
|
||||
Reference: reference,
|
||||
Link: reference,
|
||||
})
|
||||
}
|
||||
sort.Slice(attributes, func(i, j int) bool {
|
||||
|
@ -172,7 +204,7 @@ func shouldExtract(ref string, ownFields map[string]bool) bool {
|
|||
func extractNodes(prefix string, props, refs map[string]*jsonschema.Schema, ownFields map[string]bool) []rootProp {
|
||||
nodes := []rootProp{}
|
||||
for k, v := range props {
|
||||
if !shouldExtract(*v.Reference, ownFields) {
|
||||
if v.Reference != nil && !shouldExtract(*v.Reference, ownFields) {
|
||||
continue
|
||||
}
|
||||
v = resolveRefs(v, refs)
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/databricks/cli/libs/jsonschema"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestBuildNodes_ChildExpansion(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
schema jsonschema.Schema
|
||||
refs map[string]*jsonschema.Schema
|
||||
ownFields map[string]bool
|
||||
wantNodes []rootNode
|
||||
}{
|
||||
{
|
||||
name: "array expansion",
|
||||
schema: jsonschema.Schema{
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
"list": {
|
||||
Type: "array",
|
||||
Items: &jsonschema.Schema{
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
"listSub": {Reference: strPtr("#/$defs/github.com/listSub")},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
refs: map[string]*jsonschema.Schema{
|
||||
"github.com/listSub": {Type: "array", Items: &jsonschema.Schema{Type: "object", Properties: map[string]*jsonschema.Schema{"subField": {Type: "string"}}}},
|
||||
},
|
||||
ownFields: map[string]bool{"github.com/listSub": true},
|
||||
wantNodes: []rootNode{
|
||||
{
|
||||
Title: "list",
|
||||
TopLevel: true,
|
||||
Type: "Sequence",
|
||||
ArrayItemAttributes: []attributeNode{
|
||||
{Title: "listSub", Type: "Sequence", Link: "list.listSub"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Title: "list.listSub",
|
||||
Type: "Sequence",
|
||||
ArrayItemAttributes: []attributeNode{
|
||||
{Title: "subField", Type: "String"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "map expansion",
|
||||
schema: jsonschema.Schema{
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
"myMap": {
|
||||
Type: "object",
|
||||
AdditionalProperties: &jsonschema.Schema{
|
||||
Reference: strPtr("#/$defs/github.com/myMap"),
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
"mapSub": {Type: "object", Reference: strPtr("#/$defs/github.com/mapSub")},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
refs: map[string]*jsonschema.Schema{
|
||||
"github.com/myMap": {
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
"mapSub": {Type: "boolean", Reference: strPtr("#/$defs/github.com/mapSub")},
|
||||
},
|
||||
},
|
||||
"github.com/mapSub": {
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
"deepSub": {Type: "boolean"},
|
||||
},
|
||||
},
|
||||
},
|
||||
ownFields: map[string]bool{
|
||||
"github.com/myMap": true,
|
||||
"github.com/mapSub": true,
|
||||
},
|
||||
wantNodes: []rootNode{
|
||||
{
|
||||
Title: "myMap",
|
||||
TopLevel: true,
|
||||
Type: "Map",
|
||||
ObjectKeyAttributes: []attributeNode{
|
||||
{Title: "mapSub", Type: "Map", Link: "myMap.<name>.mapSub"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Title: "myMap.<name>.mapSub",
|
||||
Type: "Map",
|
||||
Attributes: []attributeNode{
|
||||
{Title: "deepSub", Type: "Boolean"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := buildNodes(tt.schema, tt.refs, tt.ownFields)
|
||||
assert.Equal(t, tt.wantNodes, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func strPtr(s string) *string {
|
||||
return &s
|
||||
}
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/databricks/cli/libs/jsonschema"
|
||||
)
|
||||
|
||||
func isReferenceType(v *jsonschema.Schema, refs map[string]*jsonschema.Schema, customFields map[string]bool) bool {
|
||||
func isReferenceType(v *jsonschema.Schema, refs map[string]*jsonschema.Schema, ownFields map[string]bool) bool {
|
||||
if v.Type != "object" && v.Type != "array" {
|
||||
return false
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ func isReferenceType(v *jsonschema.Schema, refs map[string]*jsonschema.Schema, c
|
|||
}
|
||||
}
|
||||
props := resolveAdditionalProperties(v)
|
||||
if !isInOwnFields(props, customFields) {
|
||||
if !isInOwnFields(props, ownFields) {
|
||||
return false
|
||||
}
|
||||
if props != nil {
|
||||
|
@ -32,9 +32,9 @@ func isReferenceType(v *jsonschema.Schema, refs map[string]*jsonschema.Schema, c
|
|||
return false
|
||||
}
|
||||
|
||||
func isInOwnFields(node *jsonschema.Schema, customFields map[string]bool) bool {
|
||||
func isInOwnFields(node *jsonschema.Schema, ownFields map[string]bool) bool {
|
||||
if node != nil && node.Reference != nil {
|
||||
return customFields[getRefType(node)]
|
||||
return ownFields[getRefType(node)]
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -51,8 +51,11 @@ func resolveAdditionalProperties(v *jsonschema.Schema) *jsonschema.Schema {
|
|||
}
|
||||
|
||||
func resolveRefs(s *jsonschema.Schema, schemas map[string]*jsonschema.Schema) *jsonschema.Schema {
|
||||
node := s
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
node := s
|
||||
description := s.Description
|
||||
markdownDescription := s.MarkdownDescription
|
||||
examples := s.Examples
|
||||
|
@ -62,6 +65,7 @@ func resolveRefs(s *jsonschema.Schema, schemas map[string]*jsonschema.Schema) *j
|
|||
newNode, ok := schemas[ref]
|
||||
if !ok {
|
||||
log.Printf("schema %s not found", ref)
|
||||
break
|
||||
}
|
||||
|
||||
if description == "" {
|
||||
|
|
Loading…
Reference in New Issue