mirror of
https://github.com/grafana/grafana.git
synced 2024-11-27 11:20:27 -06:00
ca1f79b9ba
Co-authored-by: sam boyer <sdboyer@grafana.com>
185 lines
5.3 KiB
Go
185 lines
5.3 KiB
Go
//go:build ignore
|
|
// +build ignore
|
|
|
|
//go:generate go run gen.go
|
|
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"sort"
|
|
"strings"
|
|
|
|
"cuelang.org/go/cue/errors"
|
|
"github.com/grafana/codejen"
|
|
"github.com/grafana/cuetsy"
|
|
"github.com/grafana/kindsys"
|
|
|
|
"github.com/grafana/grafana/pkg/codegen"
|
|
"github.com/grafana/grafana/pkg/cuectx"
|
|
)
|
|
|
|
func main() {
|
|
if len(os.Args) > 1 {
|
|
fmt.Fprintf(os.Stderr, "plugin thema code generator does not currently accept any arguments\n, got %q", os.Args)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Core kinds composite code generator. Produces all generated code in
|
|
// grafana/grafana that derives from core kinds.
|
|
coreKindsGen := codejen.JennyListWithNamer(func(def kindsys.Kind) string {
|
|
return def.Props().Common().MachineName
|
|
})
|
|
|
|
// All the jennies that comprise the core kinds generator pipeline
|
|
coreKindsGen.Append(
|
|
&codegen.ResourceGoTypesJenny{},
|
|
&codegen.SubresourceGoTypesJenny{},
|
|
codegen.CoreKindJenny(cuectx.GoCoreKindParentPath, nil),
|
|
codegen.BaseCoreRegistryJenny(filepath.Join("pkg", "registry", "corekind"), cuectx.GoCoreKindParentPath),
|
|
codegen.LatestMajorsOrXJenny(
|
|
cuectx.TSCoreKindParentPath,
|
|
true, // forcing group so that we ignore the top level resource (for now)
|
|
codegen.TSResourceJenny{}),
|
|
codegen.TSVeneerIndexJenny(filepath.Join("packages", "grafana-schema", "src")),
|
|
codegen.DocsJenny(filepath.Join("docs", "sources", "developers", "kinds", "core")),
|
|
)
|
|
|
|
header := codegen.SlashHeaderMapper("kinds/gen.go")
|
|
coreKindsGen.AddPostprocessors(header)
|
|
|
|
cwd, err := os.Getwd()
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "could not get working directory: %s", err)
|
|
os.Exit(1)
|
|
}
|
|
groot := filepath.Dir(cwd)
|
|
|
|
rt := cuectx.GrafanaThemaRuntime()
|
|
var all []kindsys.Kind
|
|
|
|
f := os.DirFS(filepath.Join(groot, cuectx.CoreDefParentPath))
|
|
kinddirs := elsedie(fs.ReadDir(f, "."))("error reading core kind fs root directory")
|
|
for _, kinddir := range kinddirs {
|
|
if !kinddir.IsDir() {
|
|
continue
|
|
}
|
|
rel := filepath.Join(cuectx.CoreDefParentPath, kinddir.Name())
|
|
def, err := cuectx.LoadCoreKindDef(rel, rt.Context(), nil)
|
|
if err != nil {
|
|
die(fmt.Errorf("%s is not a valid kind: %s", rel, errors.Details(err, nil)))
|
|
}
|
|
if def.Properties.MachineName != kinddir.Name() {
|
|
die(fmt.Errorf("%s: kind's machine name (%s) must equal parent dir name (%s)", rel, def.Properties.Name, kinddir.Name()))
|
|
}
|
|
|
|
all = append(all, elsedie(kindsys.BindCore(rt, def))(rel))
|
|
}
|
|
|
|
sort.Slice(all, func(i, j int) bool {
|
|
return nameFor(all[i].Props()) < nameFor(all[j].Props())
|
|
})
|
|
|
|
jfs, err := coreKindsGen.GenerateFS(all...)
|
|
if err != nil {
|
|
die(fmt.Errorf("core kinddirs codegen failed: %w", err))
|
|
}
|
|
|
|
commfsys := elsedie(genCommon(filepath.Join(groot, "pkg", "kindsys")))("common schemas failed")
|
|
commfsys = elsedie(commfsys.Map(header))("failed gen header on common fsys")
|
|
if err = jfs.Merge(commfsys); err != nil {
|
|
die(err)
|
|
}
|
|
|
|
if _, set := os.LookupEnv("CODEGEN_VERIFY"); set {
|
|
if err = jfs.Verify(context.Background(), groot); err != nil {
|
|
die(fmt.Errorf("generated code is out of sync with inputs:\n%s\nrun `make gen-cue` to regenerate", err))
|
|
}
|
|
} else if err = jfs.Write(context.Background(), groot); err != nil {
|
|
die(fmt.Errorf("error while writing generated code to disk:\n%s", err))
|
|
}
|
|
}
|
|
|
|
func nameFor(m kindsys.SomeKindProperties) string {
|
|
switch x := m.(type) {
|
|
case kindsys.CoreProperties:
|
|
return x.Name
|
|
case kindsys.CustomProperties:
|
|
return x.Name
|
|
case kindsys.ComposableProperties:
|
|
return x.Name
|
|
default:
|
|
// unreachable so long as all the possibilities in KindProperties have switch branches
|
|
panic("unreachable")
|
|
}
|
|
}
|
|
|
|
type dummyCommonJenny struct{}
|
|
|
|
func genCommon(kp string) (*codejen.FS, error) {
|
|
fsys := codejen.NewFS()
|
|
|
|
// kp := filepath.Join("pkg", "kindsys")
|
|
path := filepath.Join("packages", "grafana-schema", "src", "common")
|
|
// Grab all the common_* files from kindsys and load them in
|
|
dfsys := os.DirFS(kp)
|
|
matches := elsedie(fs.Glob(dfsys, "common_*.cue"))("could not glob kindsys cue files")
|
|
for _, fname := range matches {
|
|
fpath := filepath.Join(path, strings.TrimPrefix(fname, "common_"))
|
|
fpath = fpath[:len(fpath)-4] + "_gen.cue"
|
|
data := elsedie(fs.ReadFile(dfsys, fname))("error reading " + fname)
|
|
_ = fsys.Add(*codejen.NewFile(fpath, data, dummyCommonJenny{}))
|
|
}
|
|
fsys = elsedie(fsys.Map(packageMapper))("failed remapping fs")
|
|
|
|
v, err := cuectx.BuildGrafanaInstance(nil, path, "", nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
b := elsedie(cuetsy.Generate(v, cuetsy.Config{
|
|
Export: true,
|
|
}))("failed to generate common schema TS")
|
|
|
|
_ = fsys.Add(*codejen.NewFile(filepath.Join(path, "common.gen.ts"), b, dummyCommonJenny{}))
|
|
return fsys, nil
|
|
}
|
|
|
|
func (j dummyCommonJenny) JennyName() string {
|
|
return "CommonSchemaJenny"
|
|
}
|
|
|
|
func (j dummyCommonJenny) Generate(dummy any) ([]codejen.File, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
var pkgReplace = regexp.MustCompile("^package kindsys")
|
|
|
|
func packageMapper(f codejen.File) (codejen.File, error) {
|
|
f.Data = pkgReplace.ReplaceAllLiteral(f.Data, []byte("package common"))
|
|
return f, nil
|
|
}
|
|
|
|
func elsedie[T any](t T, err error) func(msg string) T {
|
|
if err != nil {
|
|
return func(msg string) T {
|
|
fmt.Fprintf(os.Stderr, "%s: %s\n", msg, err)
|
|
os.Exit(1)
|
|
return t
|
|
}
|
|
}
|
|
return func(msg string) T {
|
|
return t
|
|
}
|
|
}
|
|
|
|
func die(err error) {
|
|
fmt.Fprint(os.Stderr, err, "\n")
|
|
os.Exit(1)
|
|
}
|