grafana/public/app/plugins/gen.go
Marcus Andersson 7f92f1df00
Schema: Refactor plugin code generation (#58901)
* wip

* wip

* almost there..

* wip - change so it can run.

* treelist is working.

* support CODEGEN_VERIFY env variable

* use log.fatal

* comment out old PluginTreeList code generation

* cleanup

* rename corelist package files

* fix makefile

* move pkg/codegen/pluggen.go to pkg/plugins/codegen

* copy and refactor files to pkg/plugins/codegen

* use pkg/plugins/codegen instead of pkg/codegen for core plugins code gen

* remove unneeded files

* remove unused code to resolve linting errors

* adapters first hack

* added flattener

* add back ignore build tags to go generate file

* cleaned up the code a bit.

* seems to work, needs to do some refactoring of the GoTypesJenns and TSTypesJenny.

* one more step, going to get upstream changes in this branch.

* working but need to run import tmpl in jenny_schemapath to have the proper imports.

* added header to generated files.

* added missing jenny.

* preventing plugins with multiple decls/schemas to insert multiple lines in corelist.

* fixed so we use Slot type from kindsys to detect if its group.

* adding a go jenny that only runs if the plugin has a backend.

* added version object to generated ts.

* generating the ts types with the same output as prior to this refactoring.

* removed code that is replaced by the jenny pattern.

* removed the go code that isn't used anymore.

* removed some more unused code and renamed pluggen to util_ts

* fixed linting issue.

* removed unused vars.

* use a jenny list postprocessor for header injection

* moved decl and decl_parser to pfs.

* removed the pre-pended header in the gotypes jenny since it is done in the postprocess.

* moved decl to pfs.

* removed unused template.

Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
2022-12-02 08:22:28 +01:00

92 lines
2.7 KiB
Go

//go:build ignore
// +build ignore
//go:generate go run gen.go
package main
import (
"context"
"fmt"
"log"
"os"
"path/filepath"
"strings"
"github.com/grafana/codejen"
corecodegen "github.com/grafana/grafana/pkg/codegen"
"github.com/grafana/grafana/pkg/cuectx"
"github.com/grafana/grafana/pkg/plugins/codegen"
"github.com/grafana/grafana/pkg/plugins/pfs"
)
var skipPlugins = map[string]bool{
"canvas": true,
"heatmap": true,
"candlestick": true,
"state-timeline": true,
"status-history": true,
"table": true,
"timeseries": true,
"influxdb": true, // plugin.json fails validation (defaultMatchFormat)
"mixed": true, // plugin.json fails validation (mixed)
"opentsdb": true, // plugin.json fails validation (defaultMatchFormat)
}
const sep = string(filepath.Separator)
func main() {
if len(os.Args) > 1 {
log.Fatal(fmt.Errorf("plugin thema code generator does not currently accept any arguments\n, got %q", os.Args))
}
cwd, err := os.Getwd()
if err != nil {
log.Fatal(fmt.Errorf("could not get working directory: %s", err))
}
grootp := strings.Split(cwd, sep)
groot := filepath.Join(sep, filepath.Join(grootp[:len(grootp)-3]...))
rt := cuectx.GrafanaThemaRuntime()
pluginKindGen := codejen.JennyListWithNamer(func(d *pfs.PluginDecl) string {
return d.PluginMeta.Id
})
pluginKindGen.Append(
codegen.PluginTreeListJenny(),
codegen.PluginGoTypesJenny("pkg/tsdb", adaptToPipeline(corecodegen.GoTypesJenny{})),
codegen.PluginTSTypesJenny("public/app/plugins", adaptToPipeline(corecodegen.TSTypesJenny{})),
)
pluginKindGen.AddPostprocessors(corecodegen.SlashHeaderMapper("public/app/plugins/gen.go"))
declParser := pfs.NewDeclParser(rt, skipPlugins)
decls, err := declParser.Parse(os.DirFS(cwd))
if err != nil {
log.Fatalln(fmt.Errorf("parsing plugins in dir failed %s: %s", cwd, err))
}
jfs, err := pluginKindGen.GenerateFS(decls...)
if err != nil {
log.Fatalln(fmt.Errorf("error writing files to disk: %s", err))
}
if _, set := os.LookupEnv("CODEGEN_VERIFY"); set {
if err = jfs.Verify(context.Background(), groot); err != nil {
log.Fatal(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 {
log.Fatal(fmt.Errorf("error while writing generated code to disk:\n%s", err))
}
}
func adaptToPipeline(j codejen.OneToOne[corecodegen.SchemaForGen]) codejen.OneToOne[*pfs.PluginDecl] {
return codejen.AdaptOneToOne(j, func(pd *pfs.PluginDecl) corecodegen.SchemaForGen {
return corecodegen.SchemaForGen{
Name: pd.PluginMeta.Name,
Schema: pd.Lineage.Latest(),
IsGroup: pd.Slot.IsGroup(),
}
})
}