From e5a6547a9487d1c62a80200c386d51755748ae9e Mon Sep 17 00:00:00 2001 From: sam boyer Date: Tue, 11 Oct 2022 04:45:07 -0400 Subject: [PATCH] coremodels: Update to latest Thema with generics (#56602) * Update thema to latest * Deal with s/Library/*Runtime/ * Commit new, working results of codegen --- go.mod | 2 +- go.sum | 2 + pkg/cmd/grafana-cli/runner/wire.go | 4 +- pkg/codegen/coremodel.go | 8 +- pkg/codegen/pluggen.go | 8 +- pkg/codegen/tmpl/addenda.tmpl | 8 +- pkg/codegen/tmpl/coremodel_registry.tmpl | 4 +- pkg/codegen/tmpl/plugin_lineage_binding.tmpl | 4 +- pkg/codegen/tmpl/plugin_lineage_file.tmpl | 12 +-- pkg/codegen/tmpl/plugin_registry.tmpl | 8 +- pkg/codegen/tmpl/plugin_registry_ref.tmpl | 4 +- pkg/coremodel/dashboard/dashboard_gen.go | 8 +- pkg/coremodel/dashboard/dashboards_test.go | 2 +- pkg/coremodel/playlist/playlist_gen.go | 8 +- pkg/coremodel/pluginmeta/pluginmeta_gen.go | 8 +- pkg/cuectx/ctx.go | 36 ++++---- pkg/framework/coremodel/gen.go | 6 +- pkg/framework/coremodel/helpers.go | 81 +---------------- pkg/framework/coremodel/registry/provide.go | 23 ++--- .../coremodel/registry/registry_gen.go | 8 +- pkg/plugins/pfs/corelist/loadlist_gen.go | 90 +++++++++---------- pkg/plugins/pfs/corelist/new.go | 8 +- pkg/plugins/pfs/pfs.go | 66 +++++++------- pkg/plugins/pfs/pfs_test.go | 4 +- pkg/server/wire.go | 4 +- public/app/plugins/gen.go | 2 +- 26 files changed, 171 insertions(+), 247 deletions(-) diff --git a/go.mod b/go.mod index 627e3066a5e..c85c85cf24b 100644 --- a/go.mod +++ b/go.mod @@ -58,7 +58,7 @@ require ( github.com/grafana/grafana-aws-sdk v0.11.0 github.com/grafana/grafana-azure-sdk-go v1.3.1 github.com/grafana/grafana-plugin-sdk-go v0.139.0 - github.com/grafana/thema v0.0.0-20220817114012-ebeee841c104 + github.com/grafana/thema v0.0.0-20220929145912-2c7c4a7bb20b github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/hashicorp/go-hclog v1.0.0 github.com/hashicorp/go-plugin v1.4.3 diff --git a/go.sum b/go.sum index 11da489ed75..4b17d89735d 100644 --- a/go.sum +++ b/go.sum @@ -1380,6 +1380,8 @@ github.com/grafana/saml v0.4.9-0.20220727151557-61cd9c9353fc h1:1PY8n+rXuBNr3r1J github.com/grafana/saml v0.4.9-0.20220727151557-61cd9c9353fc/go.mod h1:9Zh6dWPtB3MSzTRt8fIFH60Z351QQ+s7hCU3J/tTlA4= github.com/grafana/thema v0.0.0-20220817114012-ebeee841c104 h1:dYpwFYIChrMfpq3wDa/ZBxAbUGSW5NYmYBeSezhaoao= github.com/grafana/thema v0.0.0-20220817114012-ebeee841c104/go.mod h1:fCV1rqv6XRQg2GfIQ7pU9zdxd5fLRcEBCnrDVwlK+ZY= +github.com/grafana/thema v0.0.0-20220929145912-2c7c4a7bb20b h1:OEGzlaj04LE6Eq7aGMOh0bCplGW5rXNeSSSwgamPBEY= +github.com/grafana/thema v0.0.0-20220929145912-2c7c4a7bb20b/go.mod h1:i3/NX50sNrwsPSAQAj56ckjQTb4biaYG/6y+zyKgpb0= github.com/grafana/xorm v0.8.3-0.20220614223926-2fcda7565af6 h1:I9dh1MXGX0wGyxdV/Sl7+ugnki4Dfsy8lv2s5Yf887o= github.com/grafana/xorm v0.8.3-0.20220614223926-2fcda7565af6/go.mod h1:ZkJLEYLoVyg7amJK/5r779bHyzs2AU8f8VMiP6BM7uY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= diff --git a/pkg/cmd/grafana-cli/runner/wire.go b/pkg/cmd/grafana-cli/runner/wire.go index beb7f785203..e75e0ee0594 100644 --- a/pkg/cmd/grafana-cli/runner/wire.go +++ b/pkg/cmd/grafana-cli/runner/wire.go @@ -301,8 +301,8 @@ var wireSet = wire.NewSet( authproxy.ProvideAuthProxy, statscollector.ProvideService, cmreg.CoremodelSet, - cuectx.ProvideCUEContext, - cuectx.ProvideThemaLibrary, + cuectx.GrafanaCUEContext, + cuectx.GrafanaThemaRuntime, csrf.ProvideCSRFFilter, ossaccesscontrol.ProvideTeamPermissions, wire.Bind(new(accesscontrol.TeamPermissionsService), new(*ossaccesscontrol.TeamPermissionsService)), diff --git a/pkg/codegen/coremodel.go b/pkg/codegen/coremodel.go index d70ae77d33e..cfdc78e1e30 100644 --- a/pkg/codegen/coremodel.go +++ b/pkg/codegen/coremodel.go @@ -50,7 +50,7 @@ type CoremodelDeclaration struct { // This loading approach is intended primarily for use with code generators, or // other use cases external to grafana-server backend. For code within // grafana-server, prefer lineage loaders provided in e.g. pkg/coremodel/*. -func ExtractLineage(path string, lib thema.Library) (*CoremodelDeclaration, error) { +func ExtractLineage(path string, rt *thema.Runtime) (*CoremodelDeclaration, error) { if !filepath.IsAbs(path) { return nil, fmt.Errorf("must provide an absolute path, got %q", path) } @@ -99,7 +99,7 @@ func ExtractLineage(path string, lib thema.Library) (*CoremodelDeclaration, erro panic(err) } ec.RelativePath = filepath.ToSlash(ec.RelativePath) - ec.Lineage, err = cuectx.LoadGrafanaInstancesWithThema(filepath.Dir(ec.RelativePath), fs, lib) + ec.Lineage, err = cuectx.LoadGrafanaInstancesWithThema(filepath.Dir(ec.RelativePath), fs, rt) if err != nil { return ec, err } @@ -156,7 +156,7 @@ func (cd *CoremodelDeclaration) PathVersion() string { // The provided path must be a directory. Generated code files will be written // to that path. The final element of the path must match the Lineage.Name(). func (cd *CoremodelDeclaration) GenerateGoCoremodel(path string) (WriteDiffer, error) { - lin, lib := cd.Lineage, cd.Lineage.Library() + lin, rt := cd.Lineage, cd.Lineage.Runtime() _, name := filepath.Split(path) if name != lin.Name() { return nil, fmt.Errorf("lineage name %q must match final element of path, got %q", lin.Name(), path) @@ -168,7 +168,7 @@ func (cd *CoremodelDeclaration) GenerateGoCoremodel(path string) (WriteDiffer, e return nil, fmt.Errorf("thema openapi generation failed: %w", err) } - str, err := yaml.Marshal(lib.Context().BuildFile(f)) + str, err := yaml.Marshal(rt.Context().BuildFile(f)) if err != nil { return nil, fmt.Errorf("cue-yaml marshaling failed: %w", err) } diff --git a/pkg/codegen/pluggen.go b/pkg/codegen/pluggen.go index 1f6c8bba4c6..55bc8d9e775 100644 --- a/pkg/codegen/pluggen.go +++ b/pkg/codegen/pluggen.go @@ -63,7 +63,7 @@ func MapCUEImportToTS(path string) (string, error) { // Errors returned from [pfs.ParsePluginFS] are placed in the option map. Only // filesystem traversal and read errors will result in a non-nil second return // value. -func ExtractPluginTrees(parent fs.FS, lib thema.Library) (map[string]PluginTreeOrErr, error) { +func ExtractPluginTrees(parent fs.FS, rt *thema.Runtime) (map[string]PluginTreeOrErr, error) { ents, err := fs.ReadDir(parent, ".") if err != nil { return nil, fmt.Errorf("error reading fs root directory: %w", err) @@ -78,7 +78,7 @@ func ExtractPluginTrees(parent fs.FS, lib thema.Library) (map[string]PluginTreeO } var either PluginTreeOrErr - if ptree, err := pfs.ParsePluginFS(sub, lib); err == nil { + if ptree, err := pfs.ParsePluginFS(sub, rt); err == nil { either.Tree = (*PluginTree)(ptree) } else { either.Err = err @@ -235,7 +235,7 @@ func genGoTypes(plug pfs.PluginInfo, path, subpath, prefix string) (WriteDiffer, wd := NewWriteDiffer() for slotname, lin := range plug.SlotImplementations() { lowslot := strings.ToLower(slotname) - lib := lin.Library() + rt := lin.Runtime() sch := thema.SchemaP(lin, thema.LatestVersion(lin)) // FIXME gotta hack this out of thema in order to deal with our custom imports :scream: @@ -244,7 +244,7 @@ func genGoTypes(plug pfs.PluginInfo, path, subpath, prefix string) (WriteDiffer, return nil, fmt.Errorf("thema openapi generation failed: %w", err) } - str, err := yaml.Marshal(lib.Context().BuildFile(f)) + str, err := yaml.Marshal(rt.Context().BuildFile(f)) if err != nil { return nil, fmt.Errorf("cue-yaml marshaling failed: %w", err) } diff --git a/pkg/codegen/tmpl/addenda.tmpl b/pkg/codegen/tmpl/addenda.tmpl index e8b99ae2f8b..dc7533b8ea7 100644 --- a/pkg/codegen/tmpl/addenda.tmpl +++ b/pkg/codegen/tmpl/addenda.tmpl @@ -18,8 +18,8 @@ var currentVersion = thema.SV({{ .LatestSeqv }}, {{ .LatestSchv }}) {{- if .IsComposed }}// // This is the base variant of the schema. It does not include any composed // plugin schemas.{{ end }} -func Lineage(lib thema.Library, opts ...thema.BindOption) (thema.Lineage, error) { - return cuectx.LoadGrafanaInstancesWithThema(filepath.Join("pkg", "coremodel", "{{ .Name }}"), cueFS, lib, opts...) +func Lineage(rt *thema.Runtime, opts ...thema.BindOption) (thema.Lineage, error) { + return cuectx.LoadGrafanaInstancesWithThema(filepath.Join("pkg", "coremodel", "{{ .Name }}"), cueFS, rt, opts...) } var _ thema.LineageFactory = Lineage @@ -52,8 +52,8 @@ func (c *Coremodel) GoType() interface{} { // Note that this function does not cache, and initially loading a Thema lineage // can be expensive. As such, the Grafana backend should prefer to access this // coremodel through a registry (pkg/framework/coremodel/registry), which does cache. -func New(lib thema.Library) (*Coremodel, error) { - lin, err := Lineage(lib) +func New(rt *thema.Runtime) (*Coremodel, error) { + lin, err := Lineage(rt) if err != nil { return nil, err } diff --git a/pkg/codegen/tmpl/coremodel_registry.tmpl b/pkg/codegen/tmpl/coremodel_registry.tmpl index 07c4bc27197..04efd5bb3c3 100644 --- a/pkg/codegen/tmpl/coremodel_registry.tmpl +++ b/pkg/codegen/tmpl/coremodel_registry.tmpl @@ -42,12 +42,12 @@ func (b *Base) {{ .TitleName }}() *{{ .Name }}.Coremodel { } {{end}} -func doProvideBase(lib thema.Library) *Base { +func doProvideBase(rt *thema.Runtime) *Base { var err error reg := &Base{} {{range .Coremodels }} - reg.{{ .Name }}, err = {{ .Name }}.New(lib) + reg.{{ .Name }}, err = {{ .Name }}.New(rt) if err != nil { panic(fmt.Sprintf("error while initializing {{ .Name }} coremodel: %s", err)) } diff --git a/pkg/codegen/tmpl/plugin_lineage_binding.tmpl b/pkg/codegen/tmpl/plugin_lineage_binding.tmpl index 41f9b6bbfc8..e3d66a9f1ac 100644 --- a/pkg/codegen/tmpl/plugin_lineage_binding.tmpl +++ b/pkg/codegen/tmpl/plugin_lineage_binding.tmpl @@ -7,6 +7,6 @@ var currentVersion{{ .SlotName }} = thema.SV({{ .LatestSeqv }}, {{ .LatestSchv } // {{ .SlotName }}Lineage returns the Thema lineage for the {{ .PluginID }} {{ .PluginType }} plugin's // {{ .SlotName }} ["github.com/grafana/grafana/pkg/framework/coremodel".Slot] implementation. -func {{ .SlotName }}Lineage(lib thema.Library, opts ...thema.BindOption) (thema.Lineage, error) { - return cuectx.LoadGrafanaInstancesWithThema(filepath.Join("public", "app", "{{ .Name }}"), cueFS, lib, opts...) +func {{ .SlotName }}Lineage(rt *thema.Runtime, opts ...thema.BindOption) (thema.Lineage, error) { + return cuectx.LoadGrafanaInstancesWithThema(filepath.Join("public", "app", "{{ .Name }}"), cueFS, rt, opts...) } diff --git a/pkg/codegen/tmpl/plugin_lineage_file.tmpl b/pkg/codegen/tmpl/plugin_lineage_file.tmpl index 5212a0b503f..36b13959f80 100644 --- a/pkg/codegen/tmpl/plugin_lineage_file.tmpl +++ b/pkg/codegen/tmpl/plugin_lineage_file.tmpl @@ -19,14 +19,14 @@ var ptree *pfs.Tree var plugFS embed.FS // PluginTree returns the plugin tree representing the statically analyzable contents of the {{ .PluginID }} plugin. -func PluginTree(lib *thema.Library) *pfs.Tree { +func PluginTree(rt *thema.Runtime) *pfs.Tree { var err error - if lib == nil { + if rt == nil || rt == cuectx.GrafanaThemaRuntime() { parseOnce.Do(func() { - ptree, err = pfs.ParsePluginFS(plugFS, cuectx.ProvideThemaLibrary()) + ptree, err = pfs.ParsePluginFS(plugFS, cuectx.GrafanaThemaRuntime()) }) } else { - ptree, err = pfs.ParsePluginFS(plugFS, cuectx.ProvideThemaLibrary()) + ptree, err = pfs.ParsePluginFS(plugFS, rt) } if err != nil { @@ -40,8 +40,8 @@ func PluginTree(lib *thema.Library) *pfs.Tree { {{ $pluginfo := . }}{{ range $slot := .SlotImpls }} // {{ .SlotName }}Lineage returns the Thema lineage for the {{ $pluginfo.PluginID }} {{ $pluginfo.PluginType }} plugin's // {{ .SlotName }} ["github.com/grafana/grafana/pkg/framework/coremodel".Slot] implementation. -func {{ .SlotName }}Lineage(lib *thema.Library, opts ...thema.BindOption) (thema.Lineage, error) { - t := PluginTree(lib) +func {{ .SlotName }}Lineage(rt *thema.Runtime, opts ...thema.BindOption) (thema.Lineage, error) { + t := PluginTree(rt) lin, has := t.RootPlugin().SlotImplementations()["{{ .SlotName }}"] if !has { panic("unreachable: lineage for {{ .SlotName }} does not exist, but code is only generated for existing lineages") diff --git a/pkg/codegen/tmpl/plugin_registry.tmpl b/pkg/codegen/tmpl/plugin_registry.tmpl index 4983a8a285e..38854645c6a 100644 --- a/pkg/codegen/tmpl/plugin_registry.tmpl +++ b/pkg/codegen/tmpl/plugin_registry.tmpl @@ -10,22 +10,22 @@ import ( "github.com/grafana/thema" ) -func makeTreeOrPanic(path string, pkgname string, lib thema.Library) *pfs.Tree { +func makeTreeOrPanic(path string, pkgname string, rt *thema.Runtime) *pfs.Tree { sub, err := fs.Sub(grafana.CueSchemaFS, path) if err != nil { panic("could not create fs sub to " + path) } - tree, err := pfs.ParsePluginFS(sub, lib) + tree, err := pfs.ParsePluginFS(sub, rt) if err != nil { panic(fmt.Sprintf("error parsing plugin metadata for %s: %s", pkgname, err)) } return tree } -func coreTreeList(lib thema.Library) pfs.TreeList{ +func coreTreeList(rt *thema.Runtime) pfs.TreeList{ return pfs.TreeList{ {{- range .Plugins }} - makeTreeOrPanic("{{ .Path }}", "{{ .PkgName }}", lib), + makeTreeOrPanic("{{ .Path }}", "{{ .PkgName }}", rt), {{- end }} } } diff --git a/pkg/codegen/tmpl/plugin_registry_ref.tmpl b/pkg/codegen/tmpl/plugin_registry_ref.tmpl index b4a9be5ffc7..68ef98cbded 100644 --- a/pkg/codegen/tmpl/plugin_registry_ref.tmpl +++ b/pkg/codegen/tmpl/plugin_registry_ref.tmpl @@ -8,8 +8,8 @@ import ( {{ if .NoAlias }}{{ .PkgName }} {{end}}"{{ .Path }}"{{ end }} ) -func coreTreeLoaders() []func(*thema.Library) *pfs.Tree{ - return []func(*thema.Library) *pfs.Tree{ +func coreTreeLoaders() []func(*thema.Runtime) *pfs.Tree{ + return []func(*thema.Runtime) *pfs.Tree{ {{- range .Plugins }} {{ .PkgName }}.PluginTree,{{ end }} } diff --git a/pkg/coremodel/dashboard/dashboard_gen.go b/pkg/coremodel/dashboard/dashboard_gen.go index 22ee2662100..97080a48a1b 100644 --- a/pkg/coremodel/dashboard/dashboard_gen.go +++ b/pkg/coremodel/dashboard/dashboard_gen.go @@ -1018,8 +1018,8 @@ var currentVersion = thema.SV(0, 0) // The lineage is the canonical specification of the current dashboard schema, // all prior schema versions, and the mappings that allow migration between // schema versions. -func Lineage(lib thema.Library, opts ...thema.BindOption) (thema.Lineage, error) { - return cuectx.LoadGrafanaInstancesWithThema(filepath.Join("pkg", "coremodel", "dashboard"), cueFS, lib, opts...) +func Lineage(rt *thema.Runtime, opts ...thema.BindOption) (thema.Lineage, error) { + return cuectx.LoadGrafanaInstancesWithThema(filepath.Join("pkg", "coremodel", "dashboard"), cueFS, rt, opts...) } var _ thema.LineageFactory = Lineage @@ -1052,8 +1052,8 @@ func (c *Coremodel) GoType() interface{} { // Note that this function does not cache, and initially loading a Thema lineage // can be expensive. As such, the Grafana backend should prefer to access this // coremodel through a registry (pkg/framework/coremodel/registry), which does cache. -func New(lib thema.Library) (*Coremodel, error) { - lin, err := Lineage(lib) +func New(rt *thema.Runtime) (*Coremodel, error) { + lin, err := Lineage(rt) if err != nil { return nil, err } diff --git a/pkg/coremodel/dashboard/dashboards_test.go b/pkg/coremodel/dashboard/dashboards_test.go index f1563bebcd8..ba4fa4a7fc4 100644 --- a/pkg/coremodel/dashboard/dashboards_test.go +++ b/pkg/coremodel/dashboard/dashboards_test.go @@ -22,7 +22,7 @@ func TestDevenvDashboardValidity(t *testing.T) { m, err := themaTestableDashboards(os.DirFS(path)) require.NoError(t, err) - cm, err := dashboard.New(cuectx.ProvideThemaLibrary()) + cm, err := dashboard.New(cuectx.GrafanaThemaRuntime()) require.NoError(t, err) for path, b := range m { diff --git a/pkg/coremodel/playlist/playlist_gen.go b/pkg/coremodel/playlist/playlist_gen.go index c33b65311b9..79502c2b80e 100644 --- a/pkg/coremodel/playlist/playlist_gen.go +++ b/pkg/coremodel/playlist/playlist_gen.go @@ -90,8 +90,8 @@ var currentVersion = thema.SV(0, 0) // The lineage is the canonical specification of the current playlist schema, // all prior schema versions, and the mappings that allow migration between // schema versions. -func Lineage(lib thema.Library, opts ...thema.BindOption) (thema.Lineage, error) { - return cuectx.LoadGrafanaInstancesWithThema(filepath.Join("pkg", "coremodel", "playlist"), cueFS, lib, opts...) +func Lineage(rt *thema.Runtime, opts ...thema.BindOption) (thema.Lineage, error) { + return cuectx.LoadGrafanaInstancesWithThema(filepath.Join("pkg", "coremodel", "playlist"), cueFS, rt, opts...) } var _ thema.LineageFactory = Lineage @@ -124,8 +124,8 @@ func (c *Coremodel) GoType() interface{} { // Note that this function does not cache, and initially loading a Thema lineage // can be expensive. As such, the Grafana backend should prefer to access this // coremodel through a registry (pkg/framework/coremodel/registry), which does cache. -func New(lib thema.Library) (*Coremodel, error) { - lin, err := Lineage(lib) +func New(rt *thema.Runtime) (*Coremodel, error) { + lin, err := Lineage(rt) if err != nil { return nil, err } diff --git a/pkg/coremodel/pluginmeta/pluginmeta_gen.go b/pkg/coremodel/pluginmeta/pluginmeta_gen.go index 5fe83adee33..3dbcf883f15 100644 --- a/pkg/coremodel/pluginmeta/pluginmeta_gen.go +++ b/pkg/coremodel/pluginmeta/pluginmeta_gen.go @@ -560,8 +560,8 @@ var currentVersion = thema.SV(0, 0) // The lineage is the canonical specification of the current pluginmeta schema, // all prior schema versions, and the mappings that allow migration between // schema versions. -func Lineage(lib thema.Library, opts ...thema.BindOption) (thema.Lineage, error) { - return cuectx.LoadGrafanaInstancesWithThema(filepath.Join("pkg", "coremodel", "pluginmeta"), cueFS, lib, opts...) +func Lineage(rt *thema.Runtime, opts ...thema.BindOption) (thema.Lineage, error) { + return cuectx.LoadGrafanaInstancesWithThema(filepath.Join("pkg", "coremodel", "pluginmeta"), cueFS, rt, opts...) } var _ thema.LineageFactory = Lineage @@ -594,8 +594,8 @@ func (c *Coremodel) GoType() interface{} { // Note that this function does not cache, and initially loading a Thema lineage // can be expensive. As such, the Grafana backend should prefer to access this // coremodel through a registry (pkg/framework/coremodel/registry), which does cache. -func New(lib thema.Library) (*Coremodel, error) { - lin, err := Lineage(lib) +func New(rt *thema.Runtime) (*Coremodel, error) { + lin, err := Lineage(rt) if err != nil { return nil, err } diff --git a/pkg/cuectx/ctx.go b/pkg/cuectx/ctx.go index 5b1e065784d..d2865caf2ab 100644 --- a/pkg/cuectx/ctx.go +++ b/pkg/cuectx/ctx.go @@ -1,6 +1,6 @@ -// Package cuectx provides a single, central CUE context (runtime) and Thema -// library that can be used uniformly across Grafana, and related helper -// functions for loading Thema lineages. +// Package cuectx provides a single, central ["cuelang.org/go/cue".Context] and +// ["github.com/grafana/thema".Runtime] that can be used uniformly across +// Grafana, and related helper functions for loading Thema lineages. package cuectx @@ -12,21 +12,27 @@ import ( "cuelang.org/go/cue" "cuelang.org/go/cue/cuecontext" "github.com/grafana/thema" - "github.com/grafana/thema/kernel" "github.com/grafana/thema/load" + "github.com/grafana/thema/vmux" ) var ctx = cuecontext.New() -var lib = thema.NewLibrary(ctx) +var rt = thema.NewRuntime(ctx) -// ProvideCUEContext is a wire service provider of a central cue.Context. -func ProvideCUEContext() *cue.Context { +// GrafanaCUEContext returns Grafana's singleton instance of [cue.Context]. +// +// All code within grafana/grafana that needs a *cue.Context should get it +// from this function, when one was not otherwise provided. +func GrafanaCUEContext() *cue.Context { return ctx } -// ProvideThemaLibrary is a wire service provider of a central thema.Library. -func ProvideThemaLibrary() thema.Library { - return lib +// GrafanaThemaRuntime returns Grafana's singleton instance of [thema.Runtime]. +// +// All code within grafana/grafana that needs a *thema.Runtime should get it +// from this function, when one was not otherwise provided. +func GrafanaThemaRuntime() *thema.Runtime { + return rt } // JSONtoCUE attempts to decode the given []byte into a cue.Value, relying on @@ -37,10 +43,10 @@ func ProvideThemaLibrary() thema.Library { // returned cue.Value. // // This is a convenience function for one-off JSON decoding. It's wasteful to -// call it repeatedly. Most use cases use cases should probably prefer making +// call it repeatedly. Most use cases should probably prefer making // their own Thema/CUE decoders. func JSONtoCUE(path string, b []byte) (cue.Value, error) { - return kernel.NewJSONDecoder(path)(ctx, b) + return vmux.NewJSONEndec(path).Decode(ctx, b) } // LoadGrafanaInstancesWithThema loads CUE files containing a lineage @@ -54,7 +60,7 @@ func JSONtoCUE(path string, b []byte) (cue.Value, error) { // More details on underlying behavior can be found in the docs for github.com/grafana/thema/load.InstancesWithThema. // // TODO this approach is complicated and confusing, refactor to something understandable -func LoadGrafanaInstancesWithThema(path string, cueFS fs.FS, lib thema.Library, opts ...thema.BindOption) (thema.Lineage, error) { +func LoadGrafanaInstancesWithThema(path string, cueFS fs.FS, rt *thema.Runtime, opts ...thema.BindOption) (thema.Lineage, error) { prefix := filepath.FromSlash(path) fs, err := prefixWithGrafanaCUE(prefix, cueFS) if err != nil { @@ -68,9 +74,9 @@ func LoadGrafanaInstancesWithThema(path string, cueFS fs.FS, lib thema.Library, return nil, err } - val := lib.Context().BuildInstance(inst) + val := rt.Context().BuildInstance(inst) - lin, err := thema.BindLineage(val, lib, opts...) + lin, err := thema.BindLineage(val, rt, opts...) if err != nil { return nil, err } diff --git a/pkg/framework/coremodel/gen.go b/pkg/framework/coremodel/gen.go index 06e5723df35..c56b5983353 100644 --- a/pkg/framework/coremodel/gen.go +++ b/pkg/framework/coremodel/gen.go @@ -20,11 +20,10 @@ import ( "github.com/grafana/cuetsy/ts" "github.com/grafana/cuetsy/ts/ast" gcgen "github.com/grafana/grafana/pkg/codegen" + "github.com/grafana/grafana/pkg/cuectx" "github.com/grafana/thema" ) -var lib = thema.NewLibrary(cuecontext.New()) - const sep = string(filepath.Separator) var tsroot, cmroot, groot string @@ -46,6 +45,7 @@ func init() { // Generate Go and Typescript implementations for all coremodels, and populate the // coremodel static registry. func main() { + rt := cuectx.GrafanaThemaRuntime() if len(os.Args) > 1 { fmt.Fprintf(os.Stderr, "coremodel code generator does not currently accept any arguments\n, got %q", os.Args) os.Exit(1) @@ -60,7 +60,7 @@ func main() { var lins []*gcgen.CoremodelDeclaration for _, item := range items { if item.IsDir() { - lin, err := gcgen.ExtractLineage(filepath.Join(cmroot, item.Name(), "coremodel.cue"), lib) + lin, err := gcgen.ExtractLineage(filepath.Join(cmroot, item.Name(), "coremodel.cue"), rt) if err != nil { fmt.Fprintf(os.Stderr, "could not process coremodel dir %s: %s\n", filepath.Join(cmroot, item.Name()), err) os.Exit(1) diff --git a/pkg/framework/coremodel/helpers.go b/pkg/framework/coremodel/helpers.go index 20d111edba2..e7b47a2951c 100644 --- a/pkg/framework/coremodel/helpers.go +++ b/pkg/framework/coremodel/helpers.go @@ -9,7 +9,6 @@ import ( "cuelang.org/go/cue" "cuelang.org/go/cue/load" - "github.com/grafana/thema/kernel" tload "github.com/grafana/thema/load" "github.com/grafana/grafana/pkg/cuectx" @@ -24,7 +23,7 @@ var defaultFramework cue.Value func init() { var err error - defaultFramework, err = doLoadFrameworkCUE(cuectx.ProvideCUEContext()) + defaultFramework, err = doLoadFrameworkCUE(cuectx.GrafanaCUEContext()) if err != nil { panic(err) } @@ -106,81 +105,3 @@ func CUEFrameworkWithContext(ctx *cue.Context) cue.Value { v, _ := doLoadFrameworkCUE(ctx) // nolint:errcheck return v } - -// Mux takes a coremodel and returns a Thema version muxer that, given a byte -// slice containing any version of schema for that coremodel, will translate it -// to the Interface.CurrentSchema() version, and optionally decode it onto the -// Interface.GoType(). -// -// By default, JSON decoding will be used, and the filename given to any input -// bytes (shown in errors, which may be user-facing) will be -// ".", e.g. dashboard.json. -func Mux(cm Interface, opts ...MuxOption) kernel.InputKernel { - c := &muxConfig{} - for _, opt := range opts { - opt(c) - } - - cfg := kernel.InputKernelConfig{ - Typ: cm.GoType(), - Lineage: cm.Lineage(), - To: cm.CurrentSchema().Version(), - } - - switch c.decodetyp { - case "", "json": // json by default - if c.filename == "" { - c.filename = fmt.Sprintf("%s.json", cm.Lineage().Name()) - } - cfg.Loader = kernel.NewJSONDecoder(c.filename) - case "yaml": - if c.filename == "" { - c.filename = fmt.Sprintf("%s.yaml", cm.Lineage().Name()) - } - cfg.Loader = kernel.NewYAMLDecoder(c.filename) - default: - panic("") - } - - mux, err := kernel.NewInputKernel(cfg) - if err != nil { - // Barring a fundamental bug in Thema's schema->Go type assignability checker or - // a direct attempt by a Grafana dev to get around the invariants of coremodel codegen, - // this should be unreachable. (And even the latter case should be caught elsewhere - // by tests). - panic(err) - } - return mux -} - -// A MuxOption defines options that may be specified only at initial -// construction of a Lineage via BindLineage. -type MuxOption muxOption - -// Internal representation of MuxOption. -type muxOption func(c *muxConfig) - -type muxConfig struct { - filename string - decodetyp string -} - -// YAML indicates that the resulting Mux should look for YAML in input bytes, -// rather than the default JSON. -func YAML() MuxOption { - return func(c *muxConfig) { - c.decodetyp = "yaml" - } -} - -// Filename specifies the filename that is given to input bytes passing through -// the mux. -// -// The filename has no impact on mux behavior, but is used in user-facing error -// output, such as schema validation failures. Thus, it is recommended to pick a -// name that will make sense in the context a user is expected to see the error. -func Filename(name string) MuxOption { - return func(c *muxConfig) { - c.filename = name - } -} diff --git a/pkg/framework/coremodel/registry/provide.go b/pkg/framework/coremodel/registry/provide.go index 7e56ca7482b..9b71925ddad 100644 --- a/pkg/framework/coremodel/registry/provide.go +++ b/pkg/framework/coremodel/registry/provide.go @@ -17,19 +17,20 @@ var CoremodelSet = wire.NewSet( // NewBase provides a registry of all coremodels, without any composition of // plugin-defined schemas. // -// The returned registry will use the default Grafana thema.Library, defined in -// pkg/cuectx. If you need control over the thema.Library used by the coremodel -// lineages, use NewBaseWithLib instead. +// The returned registry will use Grafana's singleton [thema.Runtime], +// returned from [cuectx.GrafanaThemaRuntime]. func NewBase() *Base { return provideBase(nil) } -// NewBaseWithLib is the same as NewBase, but allows control over the -// thema.Library used to initialize the underlying coremodels. +// NewBaseWithRuntime is the same as NewBase, but allows control over the +// [thema.Runtime] used to initialize the underlying coremodels. // // Prefer NewBase unless you absolutely need this control. -func NewBaseWithLib(lib thema.Library) *Base { - return provideBase(&lib) +// +// TODO it's OK to export this if it's ever actually needed +func NewBaseWithRuntime(rt *thema.Runtime) *Base { + return provideBase(rt) } var ( @@ -37,15 +38,15 @@ var ( defaultBase *Base ) -func provideBase(lib *thema.Library) *Base { - if lib == nil { +func provideBase(rt *thema.Runtime) *Base { + if rt == nil { baseOnce.Do(func() { - defaultBase = doProvideBase(cuectx.ProvideThemaLibrary()) + defaultBase = doProvideBase(cuectx.GrafanaThemaRuntime()) }) return defaultBase } - return doProvideBase(*lib) + return doProvideBase(rt) } // All returns a slice of all registered coremodels. diff --git a/pkg/framework/coremodel/registry/registry_gen.go b/pkg/framework/coremodel/registry/registry_gen.go index 74ac7b9d88d..7daa559cb58 100644 --- a/pkg/framework/coremodel/registry/registry_gen.go +++ b/pkg/framework/coremodel/registry/registry_gen.go @@ -57,23 +57,23 @@ func (b *Base) Pluginmeta() *pluginmeta.Coremodel { return b.pluginmeta } -func doProvideBase(lib thema.Library) *Base { +func doProvideBase(rt *thema.Runtime) *Base { var err error reg := &Base{} - reg.dashboard, err = dashboard.New(lib) + reg.dashboard, err = dashboard.New(rt) if err != nil { panic(fmt.Sprintf("error while initializing dashboard coremodel: %s", err)) } reg.all = append(reg.all, reg.dashboard) - reg.playlist, err = playlist.New(lib) + reg.playlist, err = playlist.New(rt) if err != nil { panic(fmt.Sprintf("error while initializing playlist coremodel: %s", err)) } reg.all = append(reg.all, reg.playlist) - reg.pluginmeta, err = pluginmeta.New(lib) + reg.pluginmeta, err = pluginmeta.New(rt) if err != nil { panic(fmt.Sprintf("error while initializing pluginmeta coremodel: %s", err)) } diff --git a/pkg/plugins/pfs/corelist/loadlist_gen.go b/pkg/plugins/pfs/corelist/loadlist_gen.go index 7348eb903ba..91f85772a57 100644 --- a/pkg/plugins/pfs/corelist/loadlist_gen.go +++ b/pkg/plugins/pfs/corelist/loadlist_gen.go @@ -27,61 +27,61 @@ import ( "github.com/grafana/thema" ) -func makeTreeOrPanic(path string, pkgname string, lib thema.Library) *pfs.Tree { +func makeTreeOrPanic(path string, pkgname string, rt *thema.Runtime) *pfs.Tree { sub, err := fs.Sub(grafana.CueSchemaFS, path) if err != nil { panic("could not create fs sub to " + path) } - tree, err := pfs.ParsePluginFS(sub, lib) + tree, err := pfs.ParsePluginFS(sub, rt) if err != nil { panic(fmt.Sprintf("error parsing plugin metadata for %s: %s", pkgname, err)) } return tree } -func coreTreeList(lib thema.Library) pfs.TreeList { +func coreTreeList(rt *thema.Runtime) pfs.TreeList { return pfs.TreeList{ - makeTreeOrPanic("public/app/plugins/datasource/alertmanager", "alertmanager", lib), - makeTreeOrPanic("public/app/plugins/datasource/cloud-monitoring", "stackdriver", lib), - makeTreeOrPanic("public/app/plugins/datasource/cloudwatch", "cloudwatch", lib), - makeTreeOrPanic("public/app/plugins/datasource/dashboard", "dashboard", lib), - makeTreeOrPanic("public/app/plugins/datasource/elasticsearch", "elasticsearch", lib), - makeTreeOrPanic("public/app/plugins/datasource/grafana", "grafana", lib), - makeTreeOrPanic("public/app/plugins/datasource/grafana-azure-monitor-datasource", "grafana_azure_monitor_datasource", lib), - makeTreeOrPanic("public/app/plugins/datasource/graphite", "graphite", lib), - makeTreeOrPanic("public/app/plugins/datasource/jaeger", "jaeger", lib), - makeTreeOrPanic("public/app/plugins/datasource/loki", "loki", lib), - makeTreeOrPanic("public/app/plugins/datasource/mssql", "mssql", lib), - makeTreeOrPanic("public/app/plugins/datasource/mysql", "mysql", lib), - makeTreeOrPanic("public/app/plugins/datasource/postgres", "postgres", lib), - makeTreeOrPanic("public/app/plugins/datasource/prometheus", "prometheus", lib), - makeTreeOrPanic("public/app/plugins/datasource/tempo", "tempo", lib), - makeTreeOrPanic("public/app/plugins/datasource/testdata", "testdata", lib), - makeTreeOrPanic("public/app/plugins/datasource/zipkin", "zipkin", lib), - makeTreeOrPanic("public/app/plugins/panel/alertGroups", "alertGroups", lib), - makeTreeOrPanic("public/app/plugins/panel/alertlist", "alertlist", lib), - makeTreeOrPanic("public/app/plugins/panel/annolist", "annolist", lib), - makeTreeOrPanic("public/app/plugins/panel/barchart", "barchart", lib), - makeTreeOrPanic("public/app/plugins/panel/bargauge", "bargauge", lib), - makeTreeOrPanic("public/app/plugins/panel/dashlist", "dashlist", lib), - makeTreeOrPanic("public/app/plugins/panel/debug", "debug", lib), - makeTreeOrPanic("public/app/plugins/panel/flamegraph", "flamegraph", lib), - makeTreeOrPanic("public/app/plugins/panel/gauge", "gauge", lib), - makeTreeOrPanic("public/app/plugins/panel/geomap", "geomap", lib), - makeTreeOrPanic("public/app/plugins/panel/gettingstarted", "gettingstarted", lib), - makeTreeOrPanic("public/app/plugins/panel/graph", "graph", lib), - makeTreeOrPanic("public/app/plugins/panel/histogram", "histogram", lib), - makeTreeOrPanic("public/app/plugins/panel/icon", "icon", lib), - makeTreeOrPanic("public/app/plugins/panel/live", "live", lib), - makeTreeOrPanic("public/app/plugins/panel/logs", "logs", lib), - makeTreeOrPanic("public/app/plugins/panel/news", "news", lib), - makeTreeOrPanic("public/app/plugins/panel/nodeGraph", "nodeGraph", lib), - makeTreeOrPanic("public/app/plugins/panel/piechart", "piechart", lib), - makeTreeOrPanic("public/app/plugins/panel/stat", "stat", lib), - makeTreeOrPanic("public/app/plugins/panel/table-old", "table_old", lib), - makeTreeOrPanic("public/app/plugins/panel/text", "text", lib), - makeTreeOrPanic("public/app/plugins/panel/traces", "traces", lib), - makeTreeOrPanic("public/app/plugins/panel/welcome", "welcome", lib), - makeTreeOrPanic("public/app/plugins/panel/xychart", "xychart", lib), + makeTreeOrPanic("public/app/plugins/datasource/alertmanager", "alertmanager", rt), + makeTreeOrPanic("public/app/plugins/datasource/cloud-monitoring", "stackdriver", rt), + makeTreeOrPanic("public/app/plugins/datasource/cloudwatch", "cloudwatch", rt), + makeTreeOrPanic("public/app/plugins/datasource/dashboard", "dashboard", rt), + makeTreeOrPanic("public/app/plugins/datasource/elasticsearch", "elasticsearch", rt), + makeTreeOrPanic("public/app/plugins/datasource/grafana", "grafana", rt), + makeTreeOrPanic("public/app/plugins/datasource/grafana-azure-monitor-datasource", "grafana_azure_monitor_datasource", rt), + makeTreeOrPanic("public/app/plugins/datasource/graphite", "graphite", rt), + makeTreeOrPanic("public/app/plugins/datasource/jaeger", "jaeger", rt), + makeTreeOrPanic("public/app/plugins/datasource/loki", "loki", rt), + makeTreeOrPanic("public/app/plugins/datasource/mssql", "mssql", rt), + makeTreeOrPanic("public/app/plugins/datasource/mysql", "mysql", rt), + makeTreeOrPanic("public/app/plugins/datasource/postgres", "postgres", rt), + makeTreeOrPanic("public/app/plugins/datasource/prometheus", "prometheus", rt), + makeTreeOrPanic("public/app/plugins/datasource/tempo", "tempo", rt), + makeTreeOrPanic("public/app/plugins/datasource/testdata", "testdata", rt), + makeTreeOrPanic("public/app/plugins/datasource/zipkin", "zipkin", rt), + makeTreeOrPanic("public/app/plugins/panel/alertGroups", "alertGroups", rt), + makeTreeOrPanic("public/app/plugins/panel/alertlist", "alertlist", rt), + makeTreeOrPanic("public/app/plugins/panel/annolist", "annolist", rt), + makeTreeOrPanic("public/app/plugins/panel/barchart", "barchart", rt), + makeTreeOrPanic("public/app/plugins/panel/bargauge", "bargauge", rt), + makeTreeOrPanic("public/app/plugins/panel/dashlist", "dashlist", rt), + makeTreeOrPanic("public/app/plugins/panel/debug", "debug", rt), + makeTreeOrPanic("public/app/plugins/panel/flamegraph", "flamegraph", rt), + makeTreeOrPanic("public/app/plugins/panel/gauge", "gauge", rt), + makeTreeOrPanic("public/app/plugins/panel/geomap", "geomap", rt), + makeTreeOrPanic("public/app/plugins/panel/gettingstarted", "gettingstarted", rt), + makeTreeOrPanic("public/app/plugins/panel/graph", "graph", rt), + makeTreeOrPanic("public/app/plugins/panel/histogram", "histogram", rt), + makeTreeOrPanic("public/app/plugins/panel/icon", "icon", rt), + makeTreeOrPanic("public/app/plugins/panel/live", "live", rt), + makeTreeOrPanic("public/app/plugins/panel/logs", "logs", rt), + makeTreeOrPanic("public/app/plugins/panel/news", "news", rt), + makeTreeOrPanic("public/app/plugins/panel/nodeGraph", "nodeGraph", rt), + makeTreeOrPanic("public/app/plugins/panel/piechart", "piechart", rt), + makeTreeOrPanic("public/app/plugins/panel/stat", "stat", rt), + makeTreeOrPanic("public/app/plugins/panel/table-old", "table_old", rt), + makeTreeOrPanic("public/app/plugins/panel/text", "text", rt), + makeTreeOrPanic("public/app/plugins/panel/traces", "traces", rt), + makeTreeOrPanic("public/app/plugins/panel/welcome", "welcome", rt), + makeTreeOrPanic("public/app/plugins/panel/xychart", "xychart", rt), } } diff --git a/pkg/plugins/pfs/corelist/new.go b/pkg/plugins/pfs/corelist/new.go index 1ac92961078..bbc6aa50a32 100644 --- a/pkg/plugins/pfs/corelist/new.go +++ b/pkg/plugins/pfs/corelist/new.go @@ -15,16 +15,16 @@ var coreOnce sync.Once // in the current version of Grafana. // // Go code within the grafana codebase should only ever call this with nil. -func New(lib *thema.Library) pfs.TreeList { +func New(rt *thema.Runtime) pfs.TreeList { var tl pfs.TreeList - if lib == nil { + if rt == nil { coreOnce.Do(func() { - coreTrees = coreTreeList(cuectx.ProvideThemaLibrary()) + coreTrees = coreTreeList(cuectx.GrafanaThemaRuntime()) }) tl = make(pfs.TreeList, len(coreTrees)) copy(tl, coreTrees) } else { - return coreTreeList(*lib) + return coreTreeList(rt) } return tl } diff --git a/pkg/plugins/pfs/pfs.go b/pkg/plugins/pfs/pfs.go index dd1fe0543b7..d176c7dff3e 100644 --- a/pkg/plugins/pfs/pfs.go +++ b/pkg/plugins/pfs/pfs.go @@ -13,11 +13,11 @@ import ( "cuelang.org/go/cue/parser" "github.com/grafana/grafana" "github.com/grafana/grafana/pkg/coremodel/pluginmeta" + "github.com/grafana/grafana/pkg/cuectx" "github.com/grafana/grafana/pkg/framework/coremodel" - "github.com/grafana/grafana/pkg/framework/coremodel/registry" "github.com/grafana/thema" - "github.com/grafana/thema/kernel" "github.com/grafana/thema/load" + "github.com/grafana/thema/vmux" "github.com/yalue/merged_fs" ) @@ -51,11 +51,9 @@ type slotandname struct { var allslots []slotandname -var plugmux kernel.InputKernel - // TODO re-enable after go1.18 -// var tsch thema.TypedSchema[pluginmeta.Model] -// var plugmux vmux.ValueMux[pluginmeta.Model] +var tsch thema.TypedSchema[*pluginmeta.Model] +var plugmux vmux.ValueMux[*pluginmeta.Model] func init() { var all []string @@ -78,13 +76,6 @@ func init() { var muxonce sync.Once -func loadMux() kernel.InputKernel { - muxonce.Do(func() { - plugmux = coremodel.Mux(registry.NewBase().Pluginmeta(), coremodel.Filename("plugin.json")) - }) - return plugmux -} - // This used to be in init(), but that creates a risk for codegen. // // thema.BindType ensures that Go type and Thema schema are aligned. If we were @@ -102,19 +93,22 @@ func loadMux() kernel.InputKernel { // called as needed to get our muxer, and internally relies on a sync.Once to avoid // repeated processing of thema.BindType. // TODO mux loading is easily generalizable in pkg/f/coremodel, shouldn't need one-off -// TODO switch to this generic signature after go1.18 -// func loadMux() (thema.TypedSchema[pluginmeta.Model], vmux.ValueMux[pluginmeta.Model]) { -// muxonce.Do(func() { -// var err error -// var t pluginmeta.Model -// tsch, err = thema.BindType[pluginmeta.Model](pm.CurrentSchema(), t) -// if err != nil { -// panic(err) -// } -// plugmux = vmux.NewValueMux(tsch, vmux.NewJSONEndec("plugin.json")) -// }) -// return tsch, plugmux -// } +func loadMux() (thema.TypedSchema[*pluginmeta.Model], vmux.ValueMux[*pluginmeta.Model]) { + muxonce.Do(func() { + var err error + t := new(pluginmeta.Model) + pm, err := pluginmeta.New(cuectx.GrafanaThemaRuntime()) + if err != nil { + panic(err) + } + tsch, err = thema.BindType[*pluginmeta.Model](pm.CurrentSchema(), t) + if err != nil { + panic(err) + } + plugmux = vmux.NewValueMux(tsch, vmux.NewJSONEndec("plugin.json")) + }) + return tsch, plugmux +} // Tree represents the contents of a plugin filesystem tree. type Tree struct { @@ -190,13 +184,12 @@ func (pi PluginInfo) Meta() pluginmeta.Model { // It does not descend into subdirectories to search for additional plugin.json // files. // TODO no descent is ok for core plugins, but won't cut it in general -func ParsePluginFS(f fs.FS, lib thema.Library) (*Tree, error) { +func ParsePluginFS(f fs.FS, rt *thema.Runtime) (*Tree, error) { if f == nil { return nil, ErrEmptyFS } - // _, mux := loadMux() - mux := loadMux() - ctx := lib.Context() + _, mux := loadMux() + ctx := rt.Context() b, err := fs.ReadFile(f, "plugin.json") if err != nil { @@ -216,13 +209,14 @@ func ParsePluginFS(f fs.FS, lib thema.Library) (*Tree, error) { // Pass the raw bytes into the muxer, get the populated Model type out that we want. // TODO stop ignoring second return. (for now, lacunas are a WIP and can't occur until there's >1 schema in the pluginmeta lineage) - metaany, _, err := mux.Converge(b) + // metaany, _, err := mux(b) + pmeta, _, err := mux(b) if err != nil { // TODO more nuanced error handling by class of Thema failure // return nil, fmt.Errorf("plugin.json was invalid: %w", err) return nil, ewrap(err, ErrInvalidRootFile) } - r.meta = *metaany.(*pluginmeta.Model) + r.meta = *pmeta if modbyt, err := fs.ReadFile(f, "models.cue"); err == nil { // TODO introduce layered CUE dependency-injecting loader @@ -260,7 +254,7 @@ func ParsePluginFS(f fs.FS, lib thema.Library) (*Tree, error) { } for _, s := range allslots { iv := val.LookupPath(cue.ParsePath(s.slot.Name())) - lin, err := bindSlotLineage(iv, s.slot, r.meta, lib) + lin, err := bindSlotLineage(iv, s.slot, r.meta, rt) if lin != nil { r.slotimpls[s.slot.Name()] = lin } @@ -273,7 +267,7 @@ func ParsePluginFS(f fs.FS, lib thema.Library) (*Tree, error) { return tree, nil } -func bindSlotLineage(v cue.Value, s *coremodel.Slot, meta pluginmeta.Model, lib thema.Library, opts ...thema.BindOption) (thema.Lineage, error) { +func bindSlotLineage(v cue.Value, s *coremodel.Slot, meta pluginmeta.Model, rt *thema.Runtime, opts ...thema.BindOption) (thema.Lineage, error) { accept, required := s.ForPluginType(string(meta.Type)) exists := v.Exists() @@ -292,8 +286,8 @@ func bindSlotLineage(v cue.Value, s *coremodel.Slot, meta pluginmeta.Model, lib } // TODO make this opt real in thema, then uncomment to enforce joinSchema - // lin, err := thema.BindLineage(iv, lib, thema.SatisfiesJoinSchema(s.MetaSchema())) - lin, err := thema.BindLineage(v, lib, opts...) + // lin, err := thema.BindLineage(iv, rt, thema.SatisfiesJoinSchema(s.MetaSchema())) + lin, err := thema.BindLineage(v, rt, opts...) if err != nil { return nil, ewrap(fmt.Errorf("%s: invalid thema lineage for slot %s: %w", meta.Id, s.Name(), err), ErrInvalidLineage) } diff --git a/pkg/plugins/pfs/pfs_test.go b/pkg/plugins/pfs/pfs_test.go index ad92138ba3e..ad8ec6438b3 100644 --- a/pkg/plugins/pfs/pfs_test.go +++ b/pkg/plugins/pfs/pfs_test.go @@ -157,7 +157,7 @@ func TestParseTreeTestdata(t *testing.T) { tab[ent.Name()] = tst } - lib := cuectx.ProvideThemaLibrary() + lib := cuectx.GrafanaThemaRuntime() for name, otst := range tab { tst := otst // otherwise var is shadowed within func by looping t.Run(name, func(t *testing.T) { @@ -256,7 +256,7 @@ func TestParseTreeZips(t *testing.T) { tab[ent.Name()] = tst } - lib := cuectx.ProvideThemaLibrary() + lib := cuectx.GrafanaThemaRuntime() for name, otst := range tab { tst := otst // otherwise var is shadowed within func by looping t.Run(name, func(t *testing.T) { diff --git a/pkg/server/wire.go b/pkg/server/wire.go index 05052db1405..72a99b04320 100644 --- a/pkg/server/wire.go +++ b/pkg/server/wire.go @@ -330,8 +330,8 @@ var wireBasicSet = wire.NewSet( authproxy.ProvideAuthProxy, statscollector.ProvideService, cmreg.CoremodelSet, - cuectx.ProvideCUEContext, - cuectx.ProvideThemaLibrary, + cuectx.GrafanaCUEContext, + cuectx.GrafanaThemaRuntime, csrf.ProvideCSRFFilter, ossaccesscontrol.ProvideTeamPermissions, wire.Bind(new(accesscontrol.TeamPermissionsService), new(*ossaccesscontrol.TeamPermissionsService)), diff --git a/public/app/plugins/gen.go b/public/app/plugins/gen.go index 6cbc14861c0..cbb28c1ee53 100644 --- a/public/app/plugins/gen.go +++ b/public/app/plugins/gen.go @@ -48,7 +48,7 @@ func main() { groot := filepath.Join(sep, filepath.Join(grootp[:len(grootp)-3]...)) wd := codegen.NewWriteDiffer() - lib := cuectx.ProvideThemaLibrary() + lib := cuectx.GrafanaThemaRuntime() type ptreepath struct { Path string