2024-12-04 21:50:34 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2024-12-06 14:07:05 +00:00
|
|
|
"bytes"
|
2024-12-04 21:50:34 +00:00
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"reflect"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/ghodss/yaml"
|
|
|
|
|
2024-12-06 14:07:05 +00:00
|
|
|
"github.com/databricks/cli/libs/dyn"
|
|
|
|
"github.com/databricks/cli/libs/dyn/convert"
|
|
|
|
"github.com/databricks/cli/libs/dyn/merge"
|
|
|
|
"github.com/databricks/cli/libs/dyn/yamlloader"
|
2024-12-04 21:50:34 +00:00
|
|
|
"github.com/databricks/cli/libs/jsonschema"
|
|
|
|
)
|
|
|
|
|
|
|
|
type annotation struct {
|
|
|
|
Description string `json:"description,omitempty"`
|
|
|
|
MarkdownDescription string `json:"markdown_description,omitempty"`
|
|
|
|
Title string `json:"title,omitempty"`
|
|
|
|
Default any `json:"default,omitempty"`
|
2024-12-06 14:07:05 +00:00
|
|
|
Enum []any `json:"enum,omitempty"`
|
2024-12-04 21:50:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type annotationHandler struct {
|
|
|
|
filePath string
|
|
|
|
op *openapiParser
|
|
|
|
ref map[string]annotation
|
2024-12-06 14:07:05 +00:00
|
|
|
empty map[string]annotation
|
2024-12-04 21:50:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const Placeholder = "PLACEHOLDER"
|
|
|
|
|
2024-12-06 14:07:05 +00:00
|
|
|
// Adds annotations to the JSON schema reading from the annotation files.
|
2024-12-04 21:50:34 +00:00
|
|
|
// More details https://json-schema.org/understanding-json-schema/reference/annotations
|
2024-12-06 14:07:05 +00:00
|
|
|
func newAnnotationHandler(sources []string) (*annotationHandler, error) {
|
|
|
|
prev := dyn.NilValue
|
|
|
|
for _, path := range sources {
|
|
|
|
b, err := os.ReadFile(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
generated, err := yamlloader.LoadYAML(path, bytes.NewBuffer(b))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
prev, err = merge.Merge(prev, generated)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2024-12-04 21:50:34 +00:00
|
|
|
}
|
|
|
|
|
2024-12-06 14:07:05 +00:00
|
|
|
var data map[string]annotation
|
|
|
|
|
|
|
|
err := convert.ToTyped(&data, prev)
|
2024-12-04 21:50:34 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
d := &annotationHandler{}
|
|
|
|
d.ref = data
|
2024-12-06 14:07:05 +00:00
|
|
|
d.empty = map[string]annotation{}
|
2024-12-04 21:50:34 +00:00
|
|
|
return d, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *annotationHandler) addAnnotations(typ reflect.Type, s jsonschema.Schema) jsonschema.Schema {
|
|
|
|
refPath := jsonschema.TypePath(typ)
|
|
|
|
items := map[string]*jsonschema.Schema{}
|
|
|
|
items[refPath] = &s
|
|
|
|
|
|
|
|
for k, v := range s.Properties {
|
|
|
|
itemRefPath := fmt.Sprintf("%s.%s", refPath, k)
|
|
|
|
items[itemRefPath] = v
|
|
|
|
}
|
|
|
|
|
|
|
|
for k, v := range items {
|
|
|
|
// Skipping all default types like int, string, etc.
|
|
|
|
shouldHandle := strings.HasPrefix(refPath, "github.com")
|
|
|
|
if !shouldHandle {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
item, ok := d.ref[k]
|
|
|
|
if !ok {
|
2024-12-06 14:07:05 +00:00
|
|
|
item = annotation{}
|
2024-12-04 21:50:34 +00:00
|
|
|
}
|
2024-12-06 14:07:05 +00:00
|
|
|
if item.Description == "" {
|
|
|
|
item.Description = Placeholder
|
|
|
|
d.empty[k] = item
|
|
|
|
}
|
|
|
|
if item.Description != Placeholder {
|
|
|
|
v.Description = item.Description
|
2024-12-04 21:50:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if item.Default != nil {
|
|
|
|
v.Default = item.Default
|
|
|
|
}
|
|
|
|
v.MarkdownDescription = item.MarkdownDescription
|
|
|
|
v.Title = item.Title
|
2024-12-06 14:07:05 +00:00
|
|
|
v.Enum = item.Enum
|
2024-12-04 21:50:34 +00:00
|
|
|
}
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
2024-12-06 14:07:05 +00:00
|
|
|
// Adds empty annotations with placeholders to the annotation file
|
|
|
|
func (d *annotationHandler) sync(outputPath string) error {
|
|
|
|
file, err := os.ReadFile(outputPath)
|
2024-12-04 21:50:34 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-12-06 14:07:05 +00:00
|
|
|
existing := map[string]annotation{}
|
|
|
|
err = yaml.Unmarshal(file, &existing)
|
|
|
|
|
|
|
|
for k, v := range d.empty {
|
|
|
|
existing[k] = v
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
b, err := yaml.Marshal(existing)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
err = os.WriteFile(outputPath, b, 0644)
|
2024-12-04 21:50:34 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|