mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
* 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>
122 lines
3.5 KiB
Go
122 lines
3.5 KiB
Go
package kindsys
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"cuelang.org/go/cue"
|
|
)
|
|
|
|
// Slot represents one of Grafana's named slot definitions.
|
|
// TODO link to framework docs
|
|
type Slot struct {
|
|
name string
|
|
raw cue.Value
|
|
plugins map[string]bool
|
|
}
|
|
|
|
// Name returns the name of the Slot.
|
|
//
|
|
// The name is also used as the path at which a Slot lineage is defined in a
|
|
// plugin models.cue file.
|
|
func (s Slot) Name() string {
|
|
return s.name
|
|
}
|
|
|
|
// MetaSchema returns the meta-schema that is the contract between core or
|
|
// custom kinds that compose the meta-schema, and the plugin-declared composable
|
|
// kinds that implement the meta-schema.
|
|
func (s Slot) MetaSchema() cue.Value {
|
|
return s.raw
|
|
}
|
|
|
|
// ForPluginType indicates whether for this Slot, plugins of the given type may
|
|
// provide a slot implementation (first return value), and for those types that
|
|
// may, whether they must produce one (second return value).
|
|
//
|
|
// Expected values here are those in the set of
|
|
// ["github.com/grafana/grafana/pkg/plugins/plugindef".Type], though passing
|
|
// a string not in that set will harmlessly return {false, false}. That type is
|
|
// not used here to avoid import cycles.
|
|
//
|
|
// Note that, at least for now, plugins are not required to provide any slot
|
|
// implementations, and do so by simply not containing any .cue files in the
|
|
// "grafanaplugin" package. Consequently, the "must" return value is best
|
|
// understood as, "IF a plugin provides a *.cue files, it MUST contain an
|
|
// implementation of this slot."
|
|
func (s Slot) ForPluginType(plugintype string) (may, must bool) {
|
|
must, may = s.plugins[plugintype]
|
|
return
|
|
}
|
|
|
|
// IsGroup indicates whether the slot specifies a group lineage - one in which
|
|
// each top-level key represents a distinct schema for objects that are expected
|
|
// to exist in the wild, but objects corresponding to the root of the schema are not
|
|
// expected to exist.
|
|
func (s Slot) IsGroup() bool {
|
|
// TODO rely on first-class Thema properties for this, one they exist - https://github.com/grafana/thema/issues/62
|
|
switch s.name {
|
|
case "Panel", "DSOptions":
|
|
return true
|
|
case "Query":
|
|
return false
|
|
default:
|
|
panic("unreachable - unknown slot name " + s.name)
|
|
}
|
|
}
|
|
|
|
func FindSlot(name string) (*Slot, error) {
|
|
sl, has := AllSlots(nil)[name]
|
|
if !has {
|
|
return nil, fmt.Errorf("unsupported slot: %s", name)
|
|
}
|
|
return sl, nil
|
|
}
|
|
|
|
// AllSlots returns a map of all [Slot]s defined in the Grafana kindsys
|
|
// framework.
|
|
//
|
|
// TODO cache this for core context
|
|
func AllSlots(ctx *cue.Context) map[string]*Slot {
|
|
fw := CUEFramework(ctx)
|
|
slots := make(map[string]*Slot)
|
|
|
|
// Ignore err, can only happen if we change structure of fw files, and all we'd
|
|
// do is panic and that's what the next line will do anyway. Same for similar ignored
|
|
// errors later in this func
|
|
iter, _ := fw.LookupPath(cue.ParsePath("pluginTypeMetaSchema")).Fields(cue.Optional(true))
|
|
type nameopt struct {
|
|
name string
|
|
req bool
|
|
}
|
|
plugslots := make(map[string][]nameopt)
|
|
for iter.Next() {
|
|
plugin := iter.Selector().String()
|
|
iiter, _ := iter.Value().Fields(cue.Optional(true))
|
|
for iiter.Next() {
|
|
slotname := iiter.Selector().String()
|
|
plugslots[slotname] = append(plugslots[slotname], nameopt{
|
|
name: plugin,
|
|
req: !iiter.IsOptional(),
|
|
})
|
|
}
|
|
}
|
|
|
|
iter, _ = fw.LookupPath(cue.ParsePath("slots")).Fields(cue.Optional(true))
|
|
for iter.Next() {
|
|
n := iter.Selector().String()
|
|
sl := Slot{
|
|
name: n,
|
|
raw: iter.Value(),
|
|
plugins: make(map[string]bool),
|
|
}
|
|
|
|
for _, no := range plugslots[n] {
|
|
sl.plugins[no.name] = no.req
|
|
}
|
|
|
|
slots[n] = &sl
|
|
}
|
|
|
|
return slots
|
|
}
|