mirror of
https://github.com/grafana/grafana.git
synced 2026-07-30 08:18:10 -05:00
Chore: Hacky first pass on generating composable kinds within grafana/schema (#64723)
* Super hacky first pass on gen types * First sketchy pass at generated compo kinds in TS, grok-style * Merge fix * Create jenny for MajorsOrX for plugins * Re-generate files with imports * Delete invalid generated file * Fix cue * Update go.mod * Update schemas * Fix go-imports * Regenerate cue files --------- Co-authored-by: spinillos <selenepinillos@gmail.com>
This commit is contained in:
@@ -34,6 +34,11 @@ func (j *lmox) JennyName() string {
|
||||
}
|
||||
|
||||
func (j *lmox) Generate(kind kindsys.Kind) (codejen.Files, error) {
|
||||
// TODO remove this once codejen catches nils https://github.com/grafana/codejen/issues/5
|
||||
if kind == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
comm := kind.Props().Common()
|
||||
sfg := SchemaForGen{
|
||||
Name: comm.Name,
|
||||
|
||||
@@ -2,8 +2,10 @@ package codegen
|
||||
|
||||
import (
|
||||
"github.com/grafana/codejen"
|
||||
"github.com/grafana/cuetsy"
|
||||
"github.com/grafana/cuetsy/ts"
|
||||
"github.com/grafana/cuetsy/ts/ast"
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
"github.com/grafana/thema/encoding/typescript"
|
||||
)
|
||||
|
||||
@@ -25,6 +27,10 @@ func (j TSResourceJenny) Generate(sfg SchemaForGen) (*codejen.File, error) {
|
||||
f, err := typescript.GenerateTypes(sfg.Schema, &typescript.TypeConfig{
|
||||
RootName: sfg.Name,
|
||||
Group: sfg.IsGroup,
|
||||
CuetsyConfig: &cuetsy.Config{
|
||||
Export: true,
|
||||
ImportMapper: cuectx.MapCUEImportToTS,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -2,6 +2,8 @@ package codegen
|
||||
|
||||
import (
|
||||
"github.com/grafana/codejen"
|
||||
"github.com/grafana/cuetsy"
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
"github.com/grafana/thema/encoding/typescript"
|
||||
)
|
||||
|
||||
@@ -21,6 +23,10 @@ func (j TSTypesJenny) JennyName() string {
|
||||
func (j TSTypesJenny) Generate(sfg SchemaForGen) (*codejen.File, error) {
|
||||
// TODO allow using name instead of machine name in thema generator
|
||||
f, err := typescript.GenerateTypes(sfg.Schema, &typescript.TypeConfig{
|
||||
CuetsyConfig: &cuetsy.Config{
|
||||
Export: true,
|
||||
ImportMapper: cuectx.MapCUEImportToTS,
|
||||
},
|
||||
RootName: sfg.Name,
|
||||
Group: sfg.IsGroup,
|
||||
})
|
||||
|
||||
@@ -9,8 +9,10 @@ import (
|
||||
"cuelang.org/go/cue"
|
||||
"cuelang.org/go/cue/errors"
|
||||
"github.com/grafana/codejen"
|
||||
"github.com/grafana/cuetsy"
|
||||
"github.com/grafana/cuetsy/ts"
|
||||
"github.com/grafana/cuetsy/ts/ast"
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
"github.com/grafana/kindsys"
|
||||
"github.com/grafana/thema"
|
||||
"github.com/grafana/thema/encoding/typescript"
|
||||
@@ -44,6 +46,9 @@ func (gen *genTSVeneerIndex) Generate(kinds ...kindsys.Kind) (*codejen.File, err
|
||||
for _, def := range kinds {
|
||||
sch := def.Lineage().Latest()
|
||||
f, err := typescript.GenerateTypes(sch, &typescript.TypeConfig{
|
||||
CuetsyConfig: &cuetsy.Config{
|
||||
ImportMapper: cuectx.MapCUEImportToTS,
|
||||
},
|
||||
RootName: def.Props().Common().Name,
|
||||
Group: def.Props().Common().LineageIsGroup,
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package codegen
|
||||
package cuectx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -7,23 +7,20 @@ import (
|
||||
|
||||
"cuelang.org/go/cue/ast"
|
||||
tsast "github.com/grafana/cuetsy/ts/ast"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins/pfs"
|
||||
)
|
||||
|
||||
// CUE import paths, mapped to corresponding TS import paths. An empty value
|
||||
// indicates the import path should be dropped in the conversion to TS. Imports
|
||||
// not present in the list are not not allowed, and code generation will fail.
|
||||
// not present in the list are not allowed, and code generation will fail.
|
||||
var importMap = map[string]string{
|
||||
"github.com/grafana/thema": "",
|
||||
|
||||
"github.com/grafana/thema": "",
|
||||
"github.com/grafana/kindsys": "",
|
||||
"github.com/grafana/grafana/pkg/plugins/pfs": "",
|
||||
"github.com/grafana/grafana/packages/grafana-schema/src/common": "@grafana/schema",
|
||||
}
|
||||
|
||||
func init() {
|
||||
allow := pfs.PermittedCUEImports()
|
||||
allow := PermittedCUEImports()
|
||||
strsl := make([]string, 0, len(importMap))
|
||||
for p := range importMap {
|
||||
strsl = append(strsl, p)
|
||||
@@ -36,13 +33,24 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
// mapCUEImportToTS maps the provided CUE import path to the corresponding
|
||||
// PermittedCUEImports returns the list of import paths that may be imported in
|
||||
// Grafana kind definitions.
|
||||
func PermittedCUEImports() []string {
|
||||
return []string{
|
||||
"github.com/grafana/thema",
|
||||
"github.com/grafana/kindsys",
|
||||
"github.com/grafana/grafana/pkg/plugins/pfs",
|
||||
"github.com/grafana/grafana/packages/grafana-schema/src/common",
|
||||
}
|
||||
}
|
||||
|
||||
// MapCUEImportToTS maps the provided CUE import path to the corresponding
|
||||
// TypeScript import path in generated code.
|
||||
//
|
||||
// Providing an import path that is not allowed results in an error. If a nil
|
||||
// error and empty string are returned, the import path should be dropped in
|
||||
// generated code.
|
||||
func mapCUEImportToTS(path string) (string, error) {
|
||||
func MapCUEImportToTS(path string) (string, error) {
|
||||
i, has := importMap[path]
|
||||
if !has {
|
||||
return "", fmt.Errorf("import %q in models.cue is not allowed", path)
|
||||
@@ -50,10 +58,14 @@ func mapCUEImportToTS(path string) (string, error) {
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// TODO convert this to use cuetsy ts types, once import * form is supported
|
||||
func convertImport(im *ast.ImportSpec) (tsast.ImportSpec, error) {
|
||||
// ConvertImport converts a CUE import statement, represented in its AST form,
|
||||
// to the corresponding TS import, if the CUE import is allowed.
|
||||
//
|
||||
// Some CUE imports are allowed but have no corresponding TS import - the CUE
|
||||
// types from that package are expected to be inlined.
|
||||
func ConvertImport(im *ast.ImportSpec) (tsast.ImportSpec, error) {
|
||||
tsim := tsast.ImportSpec{}
|
||||
pkg, err := mapCUEImportToTS(strings.Trim(im.Path.Value, "\""))
|
||||
pkg, err := MapCUEImportToTS(strings.Trim(im.Path.Value, "\""))
|
||||
if err != nil || pkg == "" {
|
||||
// err should be unreachable if paths has been verified already
|
||||
// Empty string mapping means skip it
|
||||
@@ -0,0 +1,72 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/grafana/codejen"
|
||||
tsast "github.com/grafana/cuetsy/ts/ast"
|
||||
corecodegen "github.com/grafana/grafana/pkg/codegen"
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
"github.com/grafana/grafana/pkg/plugins/pfs"
|
||||
"github.com/grafana/kindsys"
|
||||
"github.com/grafana/thema"
|
||||
)
|
||||
|
||||
func PluginTSEachMajor(rt *thema.Runtime) codejen.OneToMany[*pfs.PluginDecl] {
|
||||
latestMajorsOrX := corecodegen.LatestMajorsOrXJenny(filepath.Join("packages", "grafana-schema", "src", "raw", "composable"), false, corecodegen.TSTypesJenny{})
|
||||
return &pleJenny{
|
||||
inner: kinds2pd(rt, latestMajorsOrX),
|
||||
}
|
||||
}
|
||||
|
||||
type pleJenny struct {
|
||||
inner codejen.OneToMany[*pfs.PluginDecl]
|
||||
}
|
||||
|
||||
func (*pleJenny) JennyName() string {
|
||||
return "PluginEachMajorJenny"
|
||||
}
|
||||
|
||||
func (j *pleJenny) Generate(decl *pfs.PluginDecl) (codejen.Files, error) {
|
||||
if !decl.HasSchema() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
jf, err := j.inner.Generate(decl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
files := make(codejen.Files, len(jf))
|
||||
for i, file := range jf {
|
||||
tsf := &tsast.File{}
|
||||
for _, im := range decl.Imports {
|
||||
if tsim, err := cuectx.ConvertImport(im); err != nil {
|
||||
return nil, err
|
||||
} else if tsim.From.Value != "" {
|
||||
tsf.Imports = append(tsf.Imports, tsim)
|
||||
}
|
||||
}
|
||||
|
||||
tsf.Nodes = append(tsf.Nodes, tsast.Raw{
|
||||
Data: string(file.Data),
|
||||
})
|
||||
|
||||
data := []byte(tsf.String())
|
||||
data = data[:len(data)-1] // remove the additional line break added by the inner jenny
|
||||
|
||||
files[i] = *codejen.NewFile(file.RelativePath, data, append(file.From, j)...)
|
||||
}
|
||||
|
||||
return files, nil
|
||||
}
|
||||
|
||||
func kinds2pd(rt *thema.Runtime, j codejen.OneToMany[kindsys.Kind]) codejen.OneToMany[*pfs.PluginDecl] {
|
||||
return codejen.AdaptOneToMany(j, func(pd *pfs.PluginDecl) kindsys.Kind {
|
||||
kd, err := kindsys.BindComposable(rt, pd.KindDecl)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return kd
|
||||
})
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/grafana/codejen"
|
||||
tsast "github.com/grafana/cuetsy/ts/ast"
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
"github.com/grafana/grafana/pkg/plugins/pfs"
|
||||
)
|
||||
|
||||
@@ -34,7 +35,7 @@ func (j *ptsJenny) Generate(decl *pfs.PluginDecl) (*codejen.File, error) {
|
||||
tsf := &tsast.File{}
|
||||
|
||||
for _, im := range decl.Imports {
|
||||
if tsim, err := convertImport(im); err != nil {
|
||||
if tsim, err := cuectx.ConvertImport(im); err != nil {
|
||||
return nil, err
|
||||
} else if tsim.From.Value != "" {
|
||||
tsf.Imports = append(tsf.Imports, tsim)
|
||||
|
||||
+1
-10
@@ -53,16 +53,7 @@ func loadGP(ctx *cue.Context) cue.Value {
|
||||
|
||||
// PermittedCUEImports returns the list of import paths that may be used in a
|
||||
// plugin's grafanaplugin cue package.
|
||||
//
|
||||
// TODO probably move this into kindsys
|
||||
func PermittedCUEImports() []string {
|
||||
return []string{
|
||||
"github.com/grafana/thema",
|
||||
"github.com/grafana/kindsys",
|
||||
"github.com/grafana/grafana/pkg/plugins/pfs",
|
||||
"github.com/grafana/grafana/packages/grafana-schema/src/common",
|
||||
}
|
||||
}
|
||||
var PermittedCUEImports = cuectx.PermittedCUEImports
|
||||
|
||||
func importAllowed(path string) bool {
|
||||
for _, p := range PermittedCUEImports() {
|
||||
|
||||
Reference in New Issue
Block a user