mirror of
https://github.com/grafana/grafana.git
synced 2025-08-02 04:31:36 +08:00
Core: Remove thema and kindsys dependencies (#84499)
* 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
This commit is contained in:
130
pkg/codegen/generators/utils.go
Normal file
130
pkg/codegen/generators/utils.go
Normal file
@ -0,0 +1,130 @@
|
||||
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()
|
||||
}
|
Reference in New Issue
Block a user