mirror of
https://github.com/grafana/grafana.git
synced 2025-01-10 08:03:58 -06:00
473898e47c
* Move some thema code inside grafana * Use new codegen instead of thema for core kinds * Replace TS generator * Use new generator for go types * Remove thema from oapi generator * Remove thema from generators * Don't use kindsys/thema for core kinds * Remove kindsys/thema from plugins * Remove last thema related * Remove most of cuectx and move utils_ts into codegen. It also deletes wire dependency * Merge plugins generators * Delete thema dependency 🎉 * Fix CODEOWNERS * Fix package name * Fix TS output names * More path fixes * Fix mod codeowners * Use original plugin's name * Remove kindsys dependency 🎉 * Modify oapi schema and create an apply function to fix elasticsearch errors * cue.mod was deleted by mistake * Fix TS panels * sort imports * Fixing elasticsearch output * Downgrade oapi-codegen library * Update output ts files * More fixes * Restore old elasticsearch generated file and skip its generation. Remove core imports into plugins * More lint fixes * Add codeowners * restore embed.go file * Fix embed.go
131 lines
2.9 KiB
Go
131 lines
2.9 KiB
Go
package generators
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"cuelang.org/go/cue"
|
|
"cuelang.org/go/cue/ast"
|
|
"cuelang.org/go/cue/token"
|
|
)
|
|
|
|
// sanitizeLabelString strips characters from a string that are not allowed for
|
|
// use in a CUE label.
|
|
func sanitizeLabelString(s string) string {
|
|
return strings.Map(func(r rune) rune {
|
|
switch {
|
|
case r >= 'a' && r <= 'z':
|
|
fallthrough
|
|
case r >= 'A' && r <= 'Z':
|
|
fallthrough
|
|
case r >= '0' && r <= '9':
|
|
fallthrough
|
|
case r == '_':
|
|
return r
|
|
default:
|
|
return -1
|
|
}
|
|
}, s)
|
|
}
|
|
|
|
// trimPathPrefix strips the provided prefix from the provided path, if the
|
|
// prefix exists.
|
|
//
|
|
// If path and prefix are equivalent, and there is at least one additional
|
|
// selector in the provided path.
|
|
func trimPathPrefix(path, prefix cue.Path) cue.Path {
|
|
sels, psels := path.Selectors(), prefix.Selectors()
|
|
if len(sels) == 1 {
|
|
return path
|
|
}
|
|
var i int
|
|
for ; i < len(psels) && i < len(sels); i++ {
|
|
if !selEq(psels[i], sels[i]) {
|
|
break
|
|
}
|
|
}
|
|
return cue.MakePath(sels[i:]...)
|
|
}
|
|
|
|
// selEq indicates whether two selectors are equivalent. Selectors are equivalent if
|
|
// they are either exactly equal, or if they are equal ignoring path optionality.
|
|
func selEq(s1, s2 cue.Selector) bool {
|
|
return s1 == s2 || s1.Optional() == s2.Optional()
|
|
}
|
|
|
|
// getFieldByLabel returns the ast.Field with a given label from a struct-ish input.
|
|
func getFieldByLabel(n ast.Node, label string) (*ast.Field, error) {
|
|
var d []ast.Decl
|
|
switch x := n.(type) {
|
|
case *ast.File:
|
|
d = x.Decls
|
|
case *ast.StructLit:
|
|
d = x.Elts
|
|
default:
|
|
return nil, fmt.Errorf("not an *ast.File or *ast.StructLit")
|
|
}
|
|
|
|
for _, el := range d {
|
|
if isFieldWithLabel(el, label) {
|
|
return el.(*ast.Field), nil
|
|
}
|
|
}
|
|
|
|
return nil, fmt.Errorf("no field with label %q", label)
|
|
}
|
|
|
|
func isFieldWithLabel(n ast.Node, label string) bool {
|
|
if x, is := n.(*ast.Field); is {
|
|
if l, is := x.Label.(*ast.BasicLit); is {
|
|
return strEq(l, label)
|
|
}
|
|
if l, is := x.Label.(*ast.Ident); is {
|
|
return identStrEq(l, label)
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func strEq(lit *ast.BasicLit, str string) bool {
|
|
if lit.Kind != token.STRING {
|
|
return false
|
|
}
|
|
ls, _ := strconv.Unquote(lit.Value)
|
|
return str == ls || str == lit.Value
|
|
}
|
|
|
|
func identStrEq(id *ast.Ident, str string) bool {
|
|
if str == id.Name {
|
|
return true
|
|
}
|
|
ls, _ := strconv.Unquote(id.Name)
|
|
return str == ls
|
|
}
|
|
|
|
// pathHasPrefix tests whether the [cue.Path] p begins with prefix.
|
|
func pathHasPrefix(p, prefix cue.Path) bool {
|
|
ps, pres := p.Selectors(), prefix.Selectors()
|
|
if len(pres) > len(ps) {
|
|
return false
|
|
}
|
|
return pathsAreEq(ps[:len(pres)], pres)
|
|
}
|
|
|
|
func pathsAreEq(p1s, p2s []cue.Selector) bool {
|
|
if len(p1s) != len(p2s) {
|
|
return false
|
|
}
|
|
for i := 0; i < len(p2s); i++ {
|
|
if !selEq(p2s[i], p1s[i]) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func getSchemaName(v cue.Value) (string, error) {
|
|
nameValue := v.LookupPath(cue.ParsePath("name"))
|
|
return nameValue.String()
|
|
}
|