mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Codegen: Render constraints in generated docs (#63196)
* Add constraints rendering * Generate docs * Fix constraint format * Add type alias * Compare numbers as strings * fixup! Compare numbers as strings * Add missing return
This commit is contained in:
@@ -60,7 +60,9 @@ func (j docsJenny) Generate(kind kindsys.Kind) (*codejen.File, error) {
|
||||
Schemas json.RawMessage
|
||||
}
|
||||
}
|
||||
err = json.Unmarshal(b, &obj)
|
||||
dec := json.NewDecoder(bytes.NewReader(b))
|
||||
dec.UseNumber()
|
||||
err = dec.Decode(&obj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal schema json: %v", err)
|
||||
}
|
||||
@@ -109,8 +111,18 @@ type templateData struct {
|
||||
|
||||
// -------------------- JSON to Markdown conversion --------------------
|
||||
// Copied from https://github.com/marcusolsson/json-schema-docs and slightly changed to fit the DocsJenny
|
||||
type constraints struct {
|
||||
Pattern string `json:"pattern"`
|
||||
Maximum json.Number `json:"maximum"`
|
||||
ExclusiveMinimum bool `json:"exclusiveMinimum"`
|
||||
Minimum json.Number `json:"minimum"`
|
||||
ExclusiveMaximum bool `json:"exclusiveMaximum"`
|
||||
MinLength uint `json:"minLength"`
|
||||
MaxLength uint `json:"maxLength"`
|
||||
}
|
||||
|
||||
type schema struct {
|
||||
constraints
|
||||
ID string `json:"$id,omitempty"`
|
||||
Ref string `json:"$ref,omitempty"`
|
||||
Schema string `json:"$schema,omitempty"`
|
||||
@@ -480,7 +492,14 @@ func makeRows(s *schema) [][]string {
|
||||
rows := make([][]string, 0, len(s.Properties))
|
||||
|
||||
for key, p := range s.Properties {
|
||||
typeStr := propTypeStr(key, p)
|
||||
alias := propTypeAlias(p)
|
||||
|
||||
var typeStr string
|
||||
if alias != "" {
|
||||
typeStr = alias
|
||||
} else {
|
||||
typeStr = propTypeStr(key, p)
|
||||
}
|
||||
|
||||
// Emphasize required properties.
|
||||
var required string
|
||||
@@ -491,7 +510,6 @@ func makeRows(s *schema) [][]string {
|
||||
}
|
||||
|
||||
var desc string
|
||||
|
||||
if p.inheritedFrom != "" {
|
||||
desc = fmt.Sprintf("*(Inherited from [%s](#%s))*", p.inheritedFrom, strings.ToLower(p.inheritedFrom))
|
||||
}
|
||||
@@ -512,6 +530,10 @@ func makeRows(s *schema) [][]string {
|
||||
desc += fmt.Sprintf(" Default: `%v`.", p.Default)
|
||||
}
|
||||
|
||||
// Render a constraint only if it's not a type alias https://cuelang.org/docs/references/spec/#predeclared-identifiers
|
||||
if alias == "" {
|
||||
desc += constraintDescr(p)
|
||||
}
|
||||
rows = append(rows, []string{fmt.Sprintf("`%s`", key), typeStr, required, formatForTable(desc)})
|
||||
}
|
||||
|
||||
@@ -528,6 +550,70 @@ func makeRows(s *schema) [][]string {
|
||||
return rows
|
||||
}
|
||||
|
||||
func propTypeAlias(prop *schema) string {
|
||||
if prop.Minimum == "" || prop.Maximum == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
min := prop.Minimum
|
||||
max := prop.Maximum
|
||||
|
||||
switch {
|
||||
case min == "0" && max == "255":
|
||||
return "uint8"
|
||||
case min == "0" && max == "65535":
|
||||
return "uint16"
|
||||
case min == "0" && max == "4294967295":
|
||||
return "uint32"
|
||||
case min == "0" && max == "18446744073709551615":
|
||||
return "uint64"
|
||||
case min == "-128" && max == "127":
|
||||
return "int8"
|
||||
case min == "-32768" && max == "32767":
|
||||
return "int16"
|
||||
case min == "-2147483648" && max == "2147483647":
|
||||
return "int32"
|
||||
case min == "-9223372036854775808" && max == "9223372036854775807":
|
||||
return "int64"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func constraintDescr(prop *schema) string {
|
||||
if prop.Minimum != "" && prop.Maximum != "" {
|
||||
var left, right string
|
||||
if prop.ExclusiveMinimum {
|
||||
left = ">" + prop.Minimum.String()
|
||||
} else {
|
||||
left = ">=" + prop.Minimum.String()
|
||||
}
|
||||
|
||||
if prop.ExclusiveMaximum {
|
||||
right = "<" + prop.Maximum.String()
|
||||
} else {
|
||||
right = "<=" + prop.Maximum.String()
|
||||
}
|
||||
return fmt.Sprintf("\nConstraint: `%s & %s`.", left, right)
|
||||
}
|
||||
|
||||
if prop.MinLength > 0 {
|
||||
left := fmt.Sprintf(">=%v", prop.MinLength)
|
||||
right := ""
|
||||
|
||||
if prop.MaxLength > 0 {
|
||||
right = fmt.Sprintf(" && <=%v", prop.MaxLength)
|
||||
}
|
||||
return fmt.Sprintf("\nConstraint: `length %s`.", left+right)
|
||||
}
|
||||
|
||||
if prop.Pattern != "" {
|
||||
return fmt.Sprintf("\nConstraint: must match `%s`.", prop.Pattern)
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func propTypeStr(propName string, propValue *schema) string {
|
||||
// If the property has AdditionalProperties, it is most likely a map type
|
||||
if propValue.AdditionalProperties != nil {
|
||||
|
||||
Reference in New Issue
Block a user