diff --git a/kinds/gen.go b/kinds/gen.go index 930a157d2ca..4cf85e53624 100644 --- a/kinds/gen.go +++ b/kinds/gen.go @@ -31,8 +31,8 @@ func main() { // Core kinds composite code generator. Produces all generated code in // grafana/grafana that derives from core kinds. - coreKindsGen := codejen.JennyListWithNamer(func(def *codegen.DefForGen) string { - return def.Properties.Common().MachineName + coreKindsGen := codejen.JennyListWithNamer(func(def kindsys.Kind) string { + return def.Props().Common().MachineName }) // All the jennies that comprise the core kinds generator pipeline @@ -56,28 +56,28 @@ func main() { groot := filepath.Dir(cwd) rt := cuectx.GrafanaThemaRuntime() - var all []*codegen.DefForGen + var all []kindsys.Kind - f := os.DirFS(filepath.Join(groot, kindsys.CoreDeclParentPath)) + f := os.DirFS(filepath.Join(groot, kindsys.CoreDefParentPath)) kinddirs := elsedie(fs.ReadDir(f, "."))("error reading core kind fs root directory") - for _, ent := range kinddirs { - if !ent.IsDir() { + for _, kinddir := range kinddirs { + if !kinddir.IsDir() { continue } - rel := filepath.Join(kindsys.CoreDeclParentPath, ent.Name()) - decl, err := kindsys.LoadCoreKind(rel, rt.Context(), nil) + rel := filepath.Join(kindsys.CoreDefParentPath, kinddir.Name()) + def, err := kindsys.LoadCoreKindDef(rel, rt.Context(), nil) if err != nil { die(fmt.Errorf("%s is not a valid kind: %s", rel, errors.Details(err, nil))) } - if decl.Properties.MachineName != ent.Name() { - die(fmt.Errorf("%s: kind's machine name (%s) must equal parent dir name (%s)", rel, decl.Properties.Name, ent.Name())) + 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(codegen.ForGen(rt, decl.Some()))(rel)) + all = append(all, elsedie(kindsys.BindCore(rt, def))(rel)) } sort.Slice(all, func(i, j int) bool { - return nameFor(all[i].Properties) < nameFor(all[j].Properties) + return nameFor(all[i].Props()) < nameFor(all[j].Props()) }) jfs, err := coreKindsGen.GenerateFS(all...) diff --git a/pkg/codegen/generators.go b/pkg/codegen/generators.go index 2b5e48b61ca..02e2f21f6f1 100644 --- a/pkg/codegen/generators.go +++ b/pkg/codegen/generators.go @@ -10,45 +10,20 @@ import ( "github.com/grafana/thema" ) -type OneToOne codejen.OneToOne[*DefForGen] -type OneToMany codejen.OneToMany[*DefForGen] -type ManyToOne codejen.ManyToOne[*DefForGen] -type ManyToMany codejen.ManyToMany[*DefForGen] +type OneToOne codejen.OneToOne[kindsys.Kind] +type OneToMany codejen.OneToMany[kindsys.Kind] +type ManyToOne codejen.ManyToOne[kindsys.Kind] +type ManyToMany codejen.ManyToMany[kindsys.Kind] -// ForGen is a codejen input transformer that converts a pure kindsys.SomeDef into -// a DefForGen by binding its contained lineage. -func ForGen(rt *thema.Runtime, def kindsys.SomeDef) (*DefForGen, error) { - lin, err := def.BindKindLineage(rt) - if err != nil { - return nil, err - } - - return &DefForGen{ - SomeDef: def, - lin: lin, - }, nil -} - -// DefForGen wraps [kindsys.SomeDef] to provide trivial caching of -// the lineage declared by the kind (nil for raw kinds). -// TODO this type is unneeded - kindsys.Kind is sufficient. -type DefForGen struct { - kindsys.SomeDef - lin thema.Lineage -} - -// Lineage returns the [thema.Lineage] for the underlying [kindsys.SomeDef]. -func (def *DefForGen) Lineage() thema.Lineage { - return def.lin -} - -// ForLatestSchema returns a [SchemaForGen] for the latest schema in this -// DefForGen's lineage. -func (def *DefForGen) ForLatestSchema() SchemaForGen { - comm := def.Properties.Common() +// ForLatestSchema returns a [SchemaForGen] for the latest schema in the +// provided [kindsys.Kind]'s lineage. +// +// TODO this will be replaced by thema-native constructs +func ForLatestSchema(k kindsys.Kind) SchemaForGen { + comm := k.Props().Common() return SchemaForGen{ Name: comm.Name, - Schema: def.Lineage().Latest(), + Schema: k.Lineage().Latest(), IsGroup: comm.LineageIsGroup, } } @@ -81,6 +56,8 @@ func SlashHeaderMapper(maingen string) codejen.FileMapper { // SchemaForGen is an intermediate values type for jennies that holds both a thema.Schema, // and values relevant to generating the schema that should properly, eventually, be in // thema itself. +// +// TODO this will be replaced by thema-native constructs type SchemaForGen struct { // The PascalCase name of the schematized type. Name string diff --git a/pkg/codegen/jenny_basecorereg.go b/pkg/codegen/jenny_basecorereg.go index 4be4722881a..99522ca060b 100644 --- a/pkg/codegen/jenny_basecorereg.go +++ b/pkg/codegen/jenny_basecorereg.go @@ -6,10 +6,11 @@ import ( "path/filepath" "github.com/grafana/codejen" + "github.com/grafana/grafana/pkg/kindsys" ) // BaseCoreRegistryJenny generates a static registry for core kinds that -// only initializes their [kindsys.Interface]. No slot kinds are composed. +// only initializes their [kindsys.Kind]. No slot kinds are composed. // // Path should be the relative path to the directory that will contain the // generated registry. kindrelroot should be the repo-root-relative path to the @@ -31,12 +32,12 @@ func (gen *genBaseRegistry) JennyName() string { return "BaseCoreRegistryJenny" } -func (gen *genBaseRegistry) Generate(defs ...*DefForGen) (*codejen.File, error) { +func (gen *genBaseRegistry) Generate(kinds ...kindsys.Kind) (*codejen.File, error) { buf := new(bytes.Buffer) if err := tmpls.Lookup("kind_registry.tmpl").Execute(buf, tvars_kind_registry{ PackageName: filepath.Base(gen.path), KindPackagePrefix: filepath.ToSlash(filepath.Join("github.com/grafana/grafana", gen.kindrelroot)), - Kinds: defs, + Kinds: kinds, }); err != nil { return nil, fmt.Errorf("failed executing kind registry template: %w", err) } diff --git a/pkg/codegen/jenny_corekind.go b/pkg/codegen/jenny_corekind.go index 575ef4fdf11..e2c95fa21da 100644 --- a/pkg/codegen/jenny_corekind.go +++ b/pkg/codegen/jenny_corekind.go @@ -6,6 +6,7 @@ import ( "path/filepath" "github.com/grafana/codejen" + "github.com/grafana/grafana/pkg/kindsys" ) // CoreKindJenny generates the implementation of [kindsys.Core] for the provided @@ -20,8 +21,8 @@ func CoreKindJenny(gokindsdir string, cfg *CoreKindJennyConfig) OneToOne { cfg = new(CoreKindJennyConfig) } if cfg.GenDirName == nil { - cfg.GenDirName = func(def *DefForGen) string { - return def.Properties.Common().MachineName + cfg.GenDirName = func(def kindsys.Kind) string { + return def.Props().Common().MachineName } } @@ -35,7 +36,7 @@ func CoreKindJenny(gokindsdir string, cfg *CoreKindJennyConfig) OneToOne { type CoreKindJennyConfig struct { // GenDirName returns the name of the directory in which the file should be // generated. Defaults to DefForGen.Lineage().Name() if nil. - GenDirName func(*DefForGen) string + GenDirName func(kindsys.Kind) string } type coreKindJenny struct { @@ -49,14 +50,14 @@ func (gen *coreKindJenny) JennyName() string { return "CoreKindJenny" } -func (gen *coreKindJenny) Generate(def *DefForGen) (*codejen.File, error) { - if !def.IsCore() { +func (gen *coreKindJenny) Generate(kind kindsys.Kind) (*codejen.File, error) { + if _, is := kind.(kindsys.Core); !is { return nil, nil } - path := filepath.Join(gen.gokindsdir, gen.cfg.GenDirName(def), def.Properties.Common().MachineName+"_kind_gen.go") + path := filepath.Join(gen.gokindsdir, gen.cfg.GenDirName(kind), kind.Props().Common().MachineName+"_kind_gen.go") buf := new(bytes.Buffer) - if err := tmpls.Lookup("kind_core.tmpl").Execute(buf, def); err != nil { + if err := tmpls.Lookup("kind_core.tmpl").Execute(buf, kind); err != nil { return nil, fmt.Errorf("failed executing kind_core template for %s: %w", path, err) } b, err := postprocessGoFile(genGoFile{ diff --git a/pkg/codegen/jenny_docs.go b/pkg/codegen/jenny_docs.go index d163e6f895b..6718bd67d77 100644 --- a/pkg/codegen/jenny_docs.go +++ b/pkg/codegen/jenny_docs.go @@ -15,6 +15,7 @@ import ( "cuelang.org/go/cue/cuecontext" "github.com/grafana/codejen" "github.com/grafana/grafana/pkg/components/simplejson" + "github.com/grafana/grafana/pkg/kindsys" "github.com/grafana/thema/encoding/jsonschema" "github.com/olekukonko/tablewriter" "github.com/xeipuuv/gojsonpointer" @@ -34,8 +35,13 @@ func (j docsJenny) JennyName() string { return "DocsJenny" } -func (j docsJenny) Generate(def *DefForGen) (*codejen.File, error) { - f, err := jsonschema.GenerateSchema(def.Lineage().Latest()) +func (j docsJenny) Generate(kind kindsys.Kind) (*codejen.File, error) { + // TODO remove this once codejen catches nils https://github.com/grafana/codejen/issues/5 + if kind == nil { + return nil, nil + } + + f, err := jsonschema.GenerateSchema(kind.Lineage().Latest()) if err != nil { return nil, fmt.Errorf("failed to generate json representation for the schema: %v", err) } @@ -61,10 +67,10 @@ func (j docsJenny) Generate(def *DefForGen) (*codejen.File, error) { // fixes the references between the types within a json after making components.schema. the root of the json kindJsonStr := strings.Replace(string(obj.Components.Schemas), "#/components/schemas/", "#/", -1) - kindProps := def.Properties.Common() + kindProps := kind.Props().Common() data := templateData{ KindName: kindProps.Name, - KindVersion: def.Lineage().Latest().Version().String(), + KindVersion: kind.Lineage().Latest().Version().String(), KindMaturity: string(kindProps.Maturity), Markdown: "{{ .Markdown 1 }}", } diff --git a/pkg/codegen/jenny_eachmajor.go b/pkg/codegen/jenny_eachmajor.go index bd46a66fe94..ba06bf84016 100644 --- a/pkg/codegen/jenny_eachmajor.go +++ b/pkg/codegen/jenny_eachmajor.go @@ -29,8 +29,8 @@ func (j *lmox) JennyName() string { return "LatestMajorsOrXJenny" } -func (j *lmox) Generate(def *DefForGen) (codejen.Files, error) { - comm := def.Properties.Common() +func (j *lmox) Generate(kind kindsys.Kind) (codejen.Files, error) { + comm := kind.Props().Common() sfg := SchemaForGen{ Name: comm.Name, IsGroup: comm.LineageIsGroup, @@ -39,7 +39,7 @@ func (j *lmox) Generate(def *DefForGen) (codejen.Files, error) { do := func(sfg SchemaForGen, infix string) (codejen.Files, error) { f, err := j.inner.Generate(sfg) if err != nil { - return nil, fmt.Errorf("%s jenny failed on %s schema for %s: %w", j.inner.JennyName(), sfg.Schema.Version(), def.Properties.Common().Name, err) + return nil, fmt.Errorf("%s jenny failed on %s schema for %s: %w", j.inner.JennyName(), sfg.Schema.Version(), kind.Props().Common().Name, err) } if f == nil || !f.Exists() { return nil, nil @@ -51,12 +51,12 @@ func (j *lmox) Generate(def *DefForGen) (codejen.Files, error) { } if comm.Maturity.Less(kindsys.MaturityStable) { - sfg.Schema = def.Lineage().Latest() + sfg.Schema = kind.Lineage().Latest() return do(sfg, "x") } var fl codejen.Files - for sch := def.Lineage().First(); sch != nil; sch = sch.Successor() { + for sch := kind.Lineage().First(); sch != nil; sch = sch.Successor() { sfg.Schema = sch.LatestInMajor() files, err := do(sfg, fmt.Sprintf("v%v", sch.Version()[0])) if err != nil { diff --git a/pkg/codegen/jenny_tsveneerindex.go b/pkg/codegen/jenny_tsveneerindex.go index ccf1d5d3dbc..313f0dddebc 100644 --- a/pkg/codegen/jenny_tsveneerindex.go +++ b/pkg/codegen/jenny_tsveneerindex.go @@ -39,20 +39,20 @@ func (gen *genTSVeneerIndex) JennyName() string { return "TSVeneerIndexJenny" } -func (gen *genTSVeneerIndex) Generate(decls ...*DefForGen) (*codejen.File, error) { +func (gen *genTSVeneerIndex) Generate(kinds ...kindsys.Kind) (*codejen.File, error) { tsf := new(ast.File) - for _, def := range decls { + for _, def := range kinds { sch := def.Lineage().Latest() f, err := typescript.GenerateTypes(sch, &typescript.TypeConfig{ - RootName: def.Properties.Common().Name, - Group: def.Properties.Common().LineageIsGroup, + RootName: def.Props().Common().Name, + Group: def.Props().Common().LineageIsGroup, }) if err != nil { - return nil, fmt.Errorf("%s: %w", def.Properties.Common().Name, err) + return nil, fmt.Errorf("%s: %w", def.Props().Common().Name, err) } elems, err := gen.extractTSIndexVeneerElements(def, f) if err != nil { - return nil, fmt.Errorf("%s: %w", def.Properties.Common().Name, err) + return nil, fmt.Errorf("%s: %w", def.Props().Common().Name, err) } tsf.Nodes = append(tsf.Nodes, elems...) } @@ -60,9 +60,9 @@ func (gen *genTSVeneerIndex) Generate(decls ...*DefForGen) (*codejen.File, error return codejen.NewFile(filepath.Join(gen.dir, "index.gen.ts"), []byte(tsf.String()), gen), nil } -func (gen *genTSVeneerIndex) extractTSIndexVeneerElements(def *DefForGen, tf *ast.File) ([]ast.Decl, error) { +func (gen *genTSVeneerIndex) extractTSIndexVeneerElements(def kindsys.Kind, tf *ast.File) ([]ast.Decl, error) { lin := def.Lineage() - comm := def.Properties.Common() + comm := def.Props().Common() // Check the root, then walk the tree rootv := lin.Latest().Underlying() @@ -139,7 +139,7 @@ func (gen *genTSVeneerIndex) extractTSIndexVeneerElements(def *DefForGen, tf *as } vpath := fmt.Sprintf("v%v", thema.LatestVersion(lin)[0]) - if def.Properties.Common().Maturity.Less(kindsys.MaturityStable) { + if def.Props().Common().Maturity.Less(kindsys.MaturityStable) { vpath = "x" } diff --git a/pkg/codegen/latest_jenny.go b/pkg/codegen/latest_jenny.go index 9947559b393..d075d7b01bd 100644 --- a/pkg/codegen/latest_jenny.go +++ b/pkg/codegen/latest_jenny.go @@ -5,6 +5,7 @@ import ( "path/filepath" "github.com/grafana/codejen" + "github.com/grafana/grafana/pkg/kindsys" ) // LatestJenny returns a jenny that runs another jenny for only the latest @@ -31,17 +32,17 @@ func (j *latestj) JennyName() string { return "LatestJenny" } -func (j *latestj) Generate(def *DefForGen) (*codejen.File, error) { - comm := def.Properties.Common() +func (j *latestj) Generate(kind kindsys.Kind) (*codejen.File, error) { + comm := kind.Props().Common() sfg := SchemaForGen{ Name: comm.Name, - Schema: def.Lineage().Latest(), + Schema: kind.Lineage().Latest(), IsGroup: comm.LineageIsGroup, } f, err := j.inner.Generate(sfg) if err != nil { - return nil, fmt.Errorf("%s jenny failed on %s schema for %s: %w", j.inner.JennyName(), sfg.Schema.Version(), def.Properties.Common().Name, err) + return nil, fmt.Errorf("%s jenny failed on %s schema for %s: %w", j.inner.JennyName(), sfg.Schema.Version(), kind.Props().Common().Name, err) } if f == nil || !f.Exists() { return nil, nil diff --git a/pkg/codegen/tmpl.go b/pkg/codegen/tmpl.go index d0b5071dd70..7ca6f1b797a 100644 --- a/pkg/codegen/tmpl.go +++ b/pkg/codegen/tmpl.go @@ -7,6 +7,7 @@ import ( "time" "github.com/grafana/codejen" + "github.com/grafana/grafana/pkg/kindsys" ) // All the parsed templates in the tmpl subdirectory @@ -40,7 +41,7 @@ type ( // Header tvars_autogen_header PackageName string KindPackagePrefix string - Kinds []*DefForGen + Kinds []kindsys.Kind } tvars_coremodel_imports struct { PackageName string diff --git a/pkg/codegen/tmpl/kind_core.tmpl b/pkg/codegen/tmpl/kind_core.tmpl index 1ffb689e385..6a4a94ed1f6 100644 --- a/pkg/codegen/tmpl/kind_core.tmpl +++ b/pkg/codegen/tmpl/kind_core.tmpl @@ -1,4 +1,4 @@ -package {{ .Properties.MachineName }} +package {{ .Props.MachineName }} import ( "github.com/grafana/grafana/pkg/kindsys" @@ -10,95 +10,59 @@ import ( // directory containing the .cue files in which this kind is defined. Necessary // for runtime errors related to the definition and/or lineage to provide // a real path to the correct .cue file. -const rootrel string = "kinds/{{ .Properties.MachineName }}" +const rootrel string = "kinds/{{ .Props.MachineName }}" // TODO standard generated docs type Kind struct { - lin thema.ConvergentLineage[*{{ .Properties.Name }}] + kindsys.Core + lin thema.ConvergentLineage[*{{ .Props.Name }}] jcodec vmux.Codec - valmux vmux.ValueMux[*{{ .Properties.Name }}] - def kindsys.Def[kindsys.CoreProperties] + valmux vmux.ValueMux[*{{ .Props.Name }}] } -// type guard +// type guard - ensure generated Kind type satisfies the kindsys.Core interface var _ kindsys.Core = &Kind{} // TODO standard generated docs func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { - def, err := kindsys.LoadCoreKind(rootrel, rt.Context(), nil) - if err != nil { - return nil, err - } - k := &Kind{ - def: def, - } - - lin, err := def.Some().BindKindLineage(rt, opts...) + def, err := kindsys.LoadCoreKindDef(rootrel, rt.Context(), nil) if err != nil { return nil, err } + k := &Kind{} + k.Core, err = kindsys.BindCore(rt, def, opts...) + if err != nil { + return nil, err + } // Get the thema.Schema that the meta says is in the current version (which // codegen ensures is always the latest) - cursch := thema.SchemaP(lin, k.def.Properties.CurrentVersion) - tsch, err := thema.BindType[*{{ .Properties.Name }}](cursch, &{{ .Properties.Name }}{}) + cursch := thema.SchemaP(k.Core.Lineage(), def.Properties.CurrentVersion) + tsch, err := thema.BindType[*{{ .Props.Name }}](cursch, &{{ .Props.Name }}{}) if err != nil { // Should be unreachable, modulo bugs in the Thema->Go code generator return nil, err } - k.jcodec = vmux.NewJSONCodec("{{ .Properties.MachineName }}.json") + k.jcodec = vmux.NewJSONCodec("{{ .Props.MachineName }}.json") k.lin = tsch.ConvergentLineage() k.valmux = vmux.NewValueMux(k.lin.TypedSchema(), k.jcodec) return k, nil } -// TODO standard generated docs -func (k *Kind) Name() string { - return "{{ .Properties.MachineName }}" -} - -// TODO standard generated docs -func (k *Kind) MachineName() string { - return "{{ .Properties.MachineName }}" -} - -// TODO standard generated docs -func (k *Kind) Lineage() thema.Lineage { - return k.lin -} - -// TODO standard generated docs -func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*{{ .Properties.Name }}] { +// ConvergentLineage returns the same [thema.Lineage] as Lineage, but bound (see [thema.BindType]) +// to the the {{ .Props.Name }} type generated from the current schema, v{{ .Props.CurrentVersion }}. +func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*{{ .Props.Name }}] { return k.lin } // JSONValueMux is a version multiplexer that maps a []byte containing JSON data -// at any schematized dashboard version to an instance of {{ .Properties.Name }}. +// at any schematized dashboard version to an instance of {{ .Props.Name }}. // // Validation and translation errors emitted from this func will identify the // input bytes as "dashboard.json". // // This is a thin wrapper around Thema's [vmux.ValueMux]. -func (k *Kind) JSONValueMux(b []byte) (*{{ .Properties.Name }}, thema.TranslationLacunas, error) { +func (k *Kind) JSONValueMux(b []byte) (*{{ .Props.Name }}, thema.TranslationLacunas, error) { return k.valmux(b) } - -// TODO standard generated docs -func (k *Kind) Maturity() kindsys.Maturity { - return k.def.Properties.Maturity -} - -// Def returns the [kindsys.Def] containing both CUE and Go representations of the -// {{ .Properties.MachineName }} declaration in .cue files. -func (k *Kind) Def() kindsys.Def[kindsys.CoreProperties] { - return k.def -} - -// Props returns a [kindsys.SomeKindProps], with underlying type [kindsys.CoreProperties], -// representing the static properties declared in the {{ .Properties.MachineName }} kind. -// -// This method is identical to calling Def().Props. It is provided to satisfy [kindsys.Interface]. -func (k *Kind) Props() kindsys.SomeKindProperties { - return k.def.Properties -} diff --git a/pkg/codegen/tmpl/kind_registry.tmpl b/pkg/codegen/tmpl/kind_registry.tmpl index 11a86de2e59..40537988012 100644 --- a/pkg/codegen/tmpl/kind_registry.tmpl +++ b/pkg/codegen/tmpl/kind_registry.tmpl @@ -5,38 +5,43 @@ import ( "sync" {{range .Kinds }} - "{{ $.KindPackagePrefix }}/{{ .Properties.MachineName }}"{{end}} + "{{ $.KindPackagePrefix }}/{{ .Props.MachineName }}"{{end}} "github.com/grafana/grafana/pkg/cuectx" "github.com/grafana/grafana/pkg/kindsys" "github.com/grafana/thema" ) -// Base is a registry of kindsys.Interface. It provides two modes for accessing -// kinds: individually via literal named methods, or as a slice returned from -// an All*() method. +// Base is a registry of all Grafana core kinds. It is designed for use both inside +// of Grafana itself, and for import by external Go programs wanting to work with Grafana's +// kind system. +// +// The registry provides two modes for accessing core kinds: +// * Per-kind methods, which return the kind-specific type, e.g. Dashboard() returns [dashboard.Dashboard]. +// * All(), which returns a slice of [kindsys.Core]. // // Prefer the individual named methods for use cases where the particular kind(s) that // are needed are known to the caller. For example, a dashboard linter can know that it // specifically wants the dashboard kind. // -// Prefer All*() methods when performing operations generically across all kinds. -// For example, a validation HTTP middleware for any kind-schematized object type. +// Prefer All() when performing operations generically across all kinds. For example, +// a generic HTTP middleware for validating request bodies expected to contain some +// kind-schematized type. type Base struct { all []kindsys.Core {{- range .Kinds }} - {{ .Properties.MachineName }} *{{ .Properties.MachineName }}.Kind{{end}} + {{ .Props.MachineName }} *{{ .Props.MachineName }}.Kind{{end}} } // type guards var ( {{- range .Kinds }} - _ kindsys.Core = &{{ .Properties.MachineName }}.Kind{}{{end}} + _ kindsys.Core = &{{ .Props.MachineName }}.Kind{}{{end}} ) {{range .Kinds }} -// {{ .Properties.Name }} returns the [kindsys.Interface] implementation for the {{ .Properties.MachineName }} kind. -func (b *Base) {{ .Properties.Name }}() *{{ .Properties.MachineName }}.Kind { - return b.{{ .Properties.MachineName }} +// {{ .Props.Name }} returns the [kindsys.Interface] implementation for the {{ .Props.MachineName }} kind. +func (b *Base) {{ .Props.Name }}() *{{ .Props.MachineName }}.Kind { + return b.{{ .Props.MachineName }} } {{end}} @@ -45,11 +50,11 @@ func doNewBase(rt *thema.Runtime) *Base { reg := &Base{} {{range .Kinds }} - reg.{{ .Properties.MachineName }}, err = {{ .Properties.MachineName }}.NewKind(rt) + reg.{{ .Props.MachineName }}, err = {{ .Props.MachineName }}.NewKind(rt) if err != nil { - panic(fmt.Sprintf("error while initializing the {{ .Properties.MachineName }} Kind: %s", err)) + panic(fmt.Sprintf("error while initializing the {{ .Props.MachineName }} Kind: %s", err)) } - reg.all = append(reg.all, reg.{{ .Properties.MachineName }}) + reg.all = append(reg.all, reg.{{ .Props.MachineName }}) {{end}} return reg diff --git a/pkg/kinds/dashboard/dashboard_kind_gen.go b/pkg/kinds/dashboard/dashboard_kind_gen.go index a77fd521dc7..8d0f215f4d9 100644 --- a/pkg/kinds/dashboard/dashboard_kind_gen.go +++ b/pkg/kinds/dashboard/dashboard_kind_gen.go @@ -23,33 +23,30 @@ const rootrel string = "kinds/dashboard" // TODO standard generated docs type Kind struct { + kindsys.Core lin thema.ConvergentLineage[*Dashboard] jcodec vmux.Codec valmux vmux.ValueMux[*Dashboard] - def kindsys.Def[kindsys.CoreProperties] } -// type guard +// type guard - ensure generated Kind type satisfies the kindsys.Core interface var _ kindsys.Core = &Kind{} // TODO standard generated docs func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { - def, err := kindsys.LoadCoreKind(rootrel, rt.Context(), nil) - if err != nil { - return nil, err - } - k := &Kind{ - def: def, - } - - lin, err := def.Some().BindKindLineage(rt, opts...) + def, err := kindsys.LoadCoreKindDef(rootrel, rt.Context(), nil) if err != nil { return nil, err } + k := &Kind{} + k.Core, err = kindsys.BindCore(rt, def, opts...) + if err != nil { + return nil, err + } // Get the thema.Schema that the meta says is in the current version (which // codegen ensures is always the latest) - cursch := thema.SchemaP(lin, k.def.Properties.CurrentVersion) + cursch := thema.SchemaP(k.Core.Lineage(), def.Properties.CurrentVersion) tsch, err := thema.BindType[*Dashboard](cursch, &Dashboard{}) if err != nil { // Should be unreachable, modulo bugs in the Thema->Go code generator @@ -62,22 +59,8 @@ func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { return k, nil } -// TODO standard generated docs -func (k *Kind) Name() string { - return "dashboard" -} - -// TODO standard generated docs -func (k *Kind) MachineName() string { - return "dashboard" -} - -// TODO standard generated docs -func (k *Kind) Lineage() thema.Lineage { - return k.lin -} - -// TODO standard generated docs +// ConvergentLineage returns the same [thema.Lineage] as Lineage, but bound (see [thema.BindType]) +// to the the Dashboard type generated from the current schema, v0.0. func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Dashboard] { return k.lin } @@ -92,22 +75,3 @@ func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Dashboard] { func (k *Kind) JSONValueMux(b []byte) (*Dashboard, thema.TranslationLacunas, error) { return k.valmux(b) } - -// TODO standard generated docs -func (k *Kind) Maturity() kindsys.Maturity { - return k.def.Properties.Maturity -} - -// Def returns the [kindsys.Def] containing both CUE and Go representations of the -// dashboard declaration in .cue files. -func (k *Kind) Def() kindsys.Def[kindsys.CoreProperties] { - return k.def -} - -// Props returns a [kindsys.SomeKindProps], with underlying type [kindsys.CoreProperties], -// representing the static properties declared in the dashboard kind. -// -// This method is identical to calling Def().Props. It is provided to satisfy [kindsys.Interface]. -func (k *Kind) Props() kindsys.SomeKindProperties { - return k.def.Properties -} diff --git a/pkg/kinds/librarypanel/librarypanel_kind_gen.go b/pkg/kinds/librarypanel/librarypanel_kind_gen.go index c5d24146c73..ce2fdf9325d 100644 --- a/pkg/kinds/librarypanel/librarypanel_kind_gen.go +++ b/pkg/kinds/librarypanel/librarypanel_kind_gen.go @@ -23,33 +23,30 @@ const rootrel string = "kinds/librarypanel" // TODO standard generated docs type Kind struct { + kindsys.Core lin thema.ConvergentLineage[*LibraryPanel] jcodec vmux.Codec valmux vmux.ValueMux[*LibraryPanel] - def kindsys.Def[kindsys.CoreProperties] } -// type guard +// type guard - ensure generated Kind type satisfies the kindsys.Core interface var _ kindsys.Core = &Kind{} // TODO standard generated docs func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { - def, err := kindsys.LoadCoreKind(rootrel, rt.Context(), nil) - if err != nil { - return nil, err - } - k := &Kind{ - def: def, - } - - lin, err := def.Some().BindKindLineage(rt, opts...) + def, err := kindsys.LoadCoreKindDef(rootrel, rt.Context(), nil) if err != nil { return nil, err } + k := &Kind{} + k.Core, err = kindsys.BindCore(rt, def, opts...) + if err != nil { + return nil, err + } // Get the thema.Schema that the meta says is in the current version (which // codegen ensures is always the latest) - cursch := thema.SchemaP(lin, k.def.Properties.CurrentVersion) + cursch := thema.SchemaP(k.Core.Lineage(), def.Properties.CurrentVersion) tsch, err := thema.BindType[*LibraryPanel](cursch, &LibraryPanel{}) if err != nil { // Should be unreachable, modulo bugs in the Thema->Go code generator @@ -62,22 +59,8 @@ func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { return k, nil } -// TODO standard generated docs -func (k *Kind) Name() string { - return "librarypanel" -} - -// TODO standard generated docs -func (k *Kind) MachineName() string { - return "librarypanel" -} - -// TODO standard generated docs -func (k *Kind) Lineage() thema.Lineage { - return k.lin -} - -// TODO standard generated docs +// ConvergentLineage returns the same [thema.Lineage] as Lineage, but bound (see [thema.BindType]) +// to the the LibraryPanel type generated from the current schema, v0.0. func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*LibraryPanel] { return k.lin } @@ -92,22 +75,3 @@ func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*LibraryPanel] { func (k *Kind) JSONValueMux(b []byte) (*LibraryPanel, thema.TranslationLacunas, error) { return k.valmux(b) } - -// TODO standard generated docs -func (k *Kind) Maturity() kindsys.Maturity { - return k.def.Properties.Maturity -} - -// Def returns the [kindsys.Def] containing both CUE and Go representations of the -// librarypanel declaration in .cue files. -func (k *Kind) Def() kindsys.Def[kindsys.CoreProperties] { - return k.def -} - -// Props returns a [kindsys.SomeKindProps], with underlying type [kindsys.CoreProperties], -// representing the static properties declared in the librarypanel kind. -// -// This method is identical to calling Def().Props. It is provided to satisfy [kindsys.Interface]. -func (k *Kind) Props() kindsys.SomeKindProperties { - return k.def.Properties -} diff --git a/pkg/kinds/playlist/playlist_kind_gen.go b/pkg/kinds/playlist/playlist_kind_gen.go index 34ecf687be9..39a2457b28b 100644 --- a/pkg/kinds/playlist/playlist_kind_gen.go +++ b/pkg/kinds/playlist/playlist_kind_gen.go @@ -23,33 +23,30 @@ const rootrel string = "kinds/playlist" // TODO standard generated docs type Kind struct { + kindsys.Core lin thema.ConvergentLineage[*Playlist] jcodec vmux.Codec valmux vmux.ValueMux[*Playlist] - def kindsys.Def[kindsys.CoreProperties] } -// type guard +// type guard - ensure generated Kind type satisfies the kindsys.Core interface var _ kindsys.Core = &Kind{} // TODO standard generated docs func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { - def, err := kindsys.LoadCoreKind(rootrel, rt.Context(), nil) - if err != nil { - return nil, err - } - k := &Kind{ - def: def, - } - - lin, err := def.Some().BindKindLineage(rt, opts...) + def, err := kindsys.LoadCoreKindDef(rootrel, rt.Context(), nil) if err != nil { return nil, err } + k := &Kind{} + k.Core, err = kindsys.BindCore(rt, def, opts...) + if err != nil { + return nil, err + } // Get the thema.Schema that the meta says is in the current version (which // codegen ensures is always the latest) - cursch := thema.SchemaP(lin, k.def.Properties.CurrentVersion) + cursch := thema.SchemaP(k.Core.Lineage(), def.Properties.CurrentVersion) tsch, err := thema.BindType[*Playlist](cursch, &Playlist{}) if err != nil { // Should be unreachable, modulo bugs in the Thema->Go code generator @@ -62,22 +59,8 @@ func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { return k, nil } -// TODO standard generated docs -func (k *Kind) Name() string { - return "playlist" -} - -// TODO standard generated docs -func (k *Kind) MachineName() string { - return "playlist" -} - -// TODO standard generated docs -func (k *Kind) Lineage() thema.Lineage { - return k.lin -} - -// TODO standard generated docs +// ConvergentLineage returns the same [thema.Lineage] as Lineage, but bound (see [thema.BindType]) +// to the the Playlist type generated from the current schema, v0.0. func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Playlist] { return k.lin } @@ -92,22 +75,3 @@ func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Playlist] { func (k *Kind) JSONValueMux(b []byte) (*Playlist, thema.TranslationLacunas, error) { return k.valmux(b) } - -// TODO standard generated docs -func (k *Kind) Maturity() kindsys.Maturity { - return k.def.Properties.Maturity -} - -// Def returns the [kindsys.Def] containing both CUE and Go representations of the -// playlist declaration in .cue files. -func (k *Kind) Def() kindsys.Def[kindsys.CoreProperties] { - return k.def -} - -// Props returns a [kindsys.SomeKindProps], with underlying type [kindsys.CoreProperties], -// representing the static properties declared in the playlist kind. -// -// This method is identical to calling Def().Props. It is provided to satisfy [kindsys.Interface]. -func (k *Kind) Props() kindsys.SomeKindProperties { - return k.def.Properties -} diff --git a/pkg/kinds/preferences/preferences_kind_gen.go b/pkg/kinds/preferences/preferences_kind_gen.go index 43cd677757b..fbb855fef2f 100644 --- a/pkg/kinds/preferences/preferences_kind_gen.go +++ b/pkg/kinds/preferences/preferences_kind_gen.go @@ -23,33 +23,30 @@ const rootrel string = "kinds/preferences" // TODO standard generated docs type Kind struct { + kindsys.Core lin thema.ConvergentLineage[*Preferences] jcodec vmux.Codec valmux vmux.ValueMux[*Preferences] - def kindsys.Def[kindsys.CoreProperties] } -// type guard +// type guard - ensure generated Kind type satisfies the kindsys.Core interface var _ kindsys.Core = &Kind{} // TODO standard generated docs func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { - def, err := kindsys.LoadCoreKind(rootrel, rt.Context(), nil) - if err != nil { - return nil, err - } - k := &Kind{ - def: def, - } - - lin, err := def.Some().BindKindLineage(rt, opts...) + def, err := kindsys.LoadCoreKindDef(rootrel, rt.Context(), nil) if err != nil { return nil, err } + k := &Kind{} + k.Core, err = kindsys.BindCore(rt, def, opts...) + if err != nil { + return nil, err + } // Get the thema.Schema that the meta says is in the current version (which // codegen ensures is always the latest) - cursch := thema.SchemaP(lin, k.def.Properties.CurrentVersion) + cursch := thema.SchemaP(k.Core.Lineage(), def.Properties.CurrentVersion) tsch, err := thema.BindType[*Preferences](cursch, &Preferences{}) if err != nil { // Should be unreachable, modulo bugs in the Thema->Go code generator @@ -62,22 +59,8 @@ func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { return k, nil } -// TODO standard generated docs -func (k *Kind) Name() string { - return "preferences" -} - -// TODO standard generated docs -func (k *Kind) MachineName() string { - return "preferences" -} - -// TODO standard generated docs -func (k *Kind) Lineage() thema.Lineage { - return k.lin -} - -// TODO standard generated docs +// ConvergentLineage returns the same [thema.Lineage] as Lineage, but bound (see [thema.BindType]) +// to the the Preferences type generated from the current schema, v0.0. func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Preferences] { return k.lin } @@ -92,22 +75,3 @@ func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Preferences] { func (k *Kind) JSONValueMux(b []byte) (*Preferences, thema.TranslationLacunas, error) { return k.valmux(b) } - -// TODO standard generated docs -func (k *Kind) Maturity() kindsys.Maturity { - return k.def.Properties.Maturity -} - -// Def returns the [kindsys.Def] containing both CUE and Go representations of the -// preferences declaration in .cue files. -func (k *Kind) Def() kindsys.Def[kindsys.CoreProperties] { - return k.def -} - -// Props returns a [kindsys.SomeKindProps], with underlying type [kindsys.CoreProperties], -// representing the static properties declared in the preferences kind. -// -// This method is identical to calling Def().Props. It is provided to satisfy [kindsys.Interface]. -func (k *Kind) Props() kindsys.SomeKindProperties { - return k.def.Properties -} diff --git a/pkg/kinds/publicdashboard/publicdashboard_kind_gen.go b/pkg/kinds/publicdashboard/publicdashboard_kind_gen.go index cf4d833dffc..40ed6542fdc 100644 --- a/pkg/kinds/publicdashboard/publicdashboard_kind_gen.go +++ b/pkg/kinds/publicdashboard/publicdashboard_kind_gen.go @@ -23,33 +23,30 @@ const rootrel string = "kinds/publicdashboard" // TODO standard generated docs type Kind struct { + kindsys.Core lin thema.ConvergentLineage[*PublicDashboard] jcodec vmux.Codec valmux vmux.ValueMux[*PublicDashboard] - def kindsys.Def[kindsys.CoreProperties] } -// type guard +// type guard - ensure generated Kind type satisfies the kindsys.Core interface var _ kindsys.Core = &Kind{} // TODO standard generated docs func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { - def, err := kindsys.LoadCoreKind(rootrel, rt.Context(), nil) - if err != nil { - return nil, err - } - k := &Kind{ - def: def, - } - - lin, err := def.Some().BindKindLineage(rt, opts...) + def, err := kindsys.LoadCoreKindDef(rootrel, rt.Context(), nil) if err != nil { return nil, err } + k := &Kind{} + k.Core, err = kindsys.BindCore(rt, def, opts...) + if err != nil { + return nil, err + } // Get the thema.Schema that the meta says is in the current version (which // codegen ensures is always the latest) - cursch := thema.SchemaP(lin, k.def.Properties.CurrentVersion) + cursch := thema.SchemaP(k.Core.Lineage(), def.Properties.CurrentVersion) tsch, err := thema.BindType[*PublicDashboard](cursch, &PublicDashboard{}) if err != nil { // Should be unreachable, modulo bugs in the Thema->Go code generator @@ -62,22 +59,8 @@ func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { return k, nil } -// TODO standard generated docs -func (k *Kind) Name() string { - return "publicdashboard" -} - -// TODO standard generated docs -func (k *Kind) MachineName() string { - return "publicdashboard" -} - -// TODO standard generated docs -func (k *Kind) Lineage() thema.Lineage { - return k.lin -} - -// TODO standard generated docs +// ConvergentLineage returns the same [thema.Lineage] as Lineage, but bound (see [thema.BindType]) +// to the the PublicDashboard type generated from the current schema, v0.0. func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*PublicDashboard] { return k.lin } @@ -92,22 +75,3 @@ func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*PublicDashboard] { func (k *Kind) JSONValueMux(b []byte) (*PublicDashboard, thema.TranslationLacunas, error) { return k.valmux(b) } - -// TODO standard generated docs -func (k *Kind) Maturity() kindsys.Maturity { - return k.def.Properties.Maturity -} - -// Def returns the [kindsys.Def] containing both CUE and Go representations of the -// publicdashboard declaration in .cue files. -func (k *Kind) Def() kindsys.Def[kindsys.CoreProperties] { - return k.def -} - -// Props returns a [kindsys.SomeKindProps], with underlying type [kindsys.CoreProperties], -// representing the static properties declared in the publicdashboard kind. -// -// This method is identical to calling Def().Props. It is provided to satisfy [kindsys.Interface]. -func (k *Kind) Props() kindsys.SomeKindProperties { - return k.def.Properties -} diff --git a/pkg/kinds/serviceaccount/serviceaccount_kind_gen.go b/pkg/kinds/serviceaccount/serviceaccount_kind_gen.go index ee9237e3b18..391b7455dfa 100644 --- a/pkg/kinds/serviceaccount/serviceaccount_kind_gen.go +++ b/pkg/kinds/serviceaccount/serviceaccount_kind_gen.go @@ -23,33 +23,30 @@ const rootrel string = "kinds/serviceaccount" // TODO standard generated docs type Kind struct { + kindsys.Core lin thema.ConvergentLineage[*ServiceAccount] jcodec vmux.Codec valmux vmux.ValueMux[*ServiceAccount] - def kindsys.Def[kindsys.CoreProperties] } -// type guard +// type guard - ensure generated Kind type satisfies the kindsys.Core interface var _ kindsys.Core = &Kind{} // TODO standard generated docs func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { - def, err := kindsys.LoadCoreKind(rootrel, rt.Context(), nil) - if err != nil { - return nil, err - } - k := &Kind{ - def: def, - } - - lin, err := def.Some().BindKindLineage(rt, opts...) + def, err := kindsys.LoadCoreKindDef(rootrel, rt.Context(), nil) if err != nil { return nil, err } + k := &Kind{} + k.Core, err = kindsys.BindCore(rt, def, opts...) + if err != nil { + return nil, err + } // Get the thema.Schema that the meta says is in the current version (which // codegen ensures is always the latest) - cursch := thema.SchemaP(lin, k.def.Properties.CurrentVersion) + cursch := thema.SchemaP(k.Core.Lineage(), def.Properties.CurrentVersion) tsch, err := thema.BindType[*ServiceAccount](cursch, &ServiceAccount{}) if err != nil { // Should be unreachable, modulo bugs in the Thema->Go code generator @@ -62,22 +59,8 @@ func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { return k, nil } -// TODO standard generated docs -func (k *Kind) Name() string { - return "serviceaccount" -} - -// TODO standard generated docs -func (k *Kind) MachineName() string { - return "serviceaccount" -} - -// TODO standard generated docs -func (k *Kind) Lineage() thema.Lineage { - return k.lin -} - -// TODO standard generated docs +// ConvergentLineage returns the same [thema.Lineage] as Lineage, but bound (see [thema.BindType]) +// to the the ServiceAccount type generated from the current schema, v0.0. func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*ServiceAccount] { return k.lin } @@ -92,22 +75,3 @@ func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*ServiceAccount] { func (k *Kind) JSONValueMux(b []byte) (*ServiceAccount, thema.TranslationLacunas, error) { return k.valmux(b) } - -// TODO standard generated docs -func (k *Kind) Maturity() kindsys.Maturity { - return k.def.Properties.Maturity -} - -// Def returns the [kindsys.Def] containing both CUE and Go representations of the -// serviceaccount declaration in .cue files. -func (k *Kind) Def() kindsys.Def[kindsys.CoreProperties] { - return k.def -} - -// Props returns a [kindsys.SomeKindProps], with underlying type [kindsys.CoreProperties], -// representing the static properties declared in the serviceaccount kind. -// -// This method is identical to calling Def().Props. It is provided to satisfy [kindsys.Interface]. -func (k *Kind) Props() kindsys.SomeKindProperties { - return k.def.Properties -} diff --git a/pkg/kinds/team/team_kind_gen.go b/pkg/kinds/team/team_kind_gen.go index 0fed5765bc3..df531e7753a 100644 --- a/pkg/kinds/team/team_kind_gen.go +++ b/pkg/kinds/team/team_kind_gen.go @@ -23,33 +23,30 @@ const rootrel string = "kinds/team" // TODO standard generated docs type Kind struct { + kindsys.Core lin thema.ConvergentLineage[*Team] jcodec vmux.Codec valmux vmux.ValueMux[*Team] - def kindsys.Def[kindsys.CoreProperties] } -// type guard +// type guard - ensure generated Kind type satisfies the kindsys.Core interface var _ kindsys.Core = &Kind{} // TODO standard generated docs func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { - def, err := kindsys.LoadCoreKind(rootrel, rt.Context(), nil) - if err != nil { - return nil, err - } - k := &Kind{ - def: def, - } - - lin, err := def.Some().BindKindLineage(rt, opts...) + def, err := kindsys.LoadCoreKindDef(rootrel, rt.Context(), nil) if err != nil { return nil, err } + k := &Kind{} + k.Core, err = kindsys.BindCore(rt, def, opts...) + if err != nil { + return nil, err + } // Get the thema.Schema that the meta says is in the current version (which // codegen ensures is always the latest) - cursch := thema.SchemaP(lin, k.def.Properties.CurrentVersion) + cursch := thema.SchemaP(k.Core.Lineage(), def.Properties.CurrentVersion) tsch, err := thema.BindType[*Team](cursch, &Team{}) if err != nil { // Should be unreachable, modulo bugs in the Thema->Go code generator @@ -62,22 +59,8 @@ func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { return k, nil } -// TODO standard generated docs -func (k *Kind) Name() string { - return "team" -} - -// TODO standard generated docs -func (k *Kind) MachineName() string { - return "team" -} - -// TODO standard generated docs -func (k *Kind) Lineage() thema.Lineage { - return k.lin -} - -// TODO standard generated docs +// ConvergentLineage returns the same [thema.Lineage] as Lineage, but bound (see [thema.BindType]) +// to the the Team type generated from the current schema, v0.0. func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Team] { return k.lin } @@ -92,22 +75,3 @@ func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Team] { func (k *Kind) JSONValueMux(b []byte) (*Team, thema.TranslationLacunas, error) { return k.valmux(b) } - -// TODO standard generated docs -func (k *Kind) Maturity() kindsys.Maturity { - return k.def.Properties.Maturity -} - -// Def returns the [kindsys.Def] containing both CUE and Go representations of the -// team declaration in .cue files. -func (k *Kind) Def() kindsys.Def[kindsys.CoreProperties] { - return k.def -} - -// Props returns a [kindsys.SomeKindProps], with underlying type [kindsys.CoreProperties], -// representing the static properties declared in the team kind. -// -// This method is identical to calling Def().Props. It is provided to satisfy [kindsys.Interface]. -func (k *Kind) Props() kindsys.SomeKindProperties { - return k.def.Properties -} diff --git a/pkg/kindsys/bind.go b/pkg/kindsys/bind.go index 848867b4771..302cedf3a94 100644 --- a/pkg/kindsys/bind.go +++ b/pkg/kindsys/bind.go @@ -4,13 +4,15 @@ import ( "github.com/grafana/thema" ) -var _ Composable = genericComposable{} - +// genericComposable is a general representation of a parsed and validated +// Composable kind. type genericComposable struct { def Def[ComposableProperties] lin thema.Lineage } +var _ Composable = genericComposable{} + func (k genericComposable) Props() SomeKindProperties { return k.def.Properties } @@ -35,14 +37,60 @@ func (k genericComposable) Lineage() thema.Lineage { return k.lin } -func BindComposable(rt *thema.Runtime, decl Def[ComposableProperties], opts ...thema.BindOption) (Composable, error) { - lin, err := decl.Some().BindKindLineage(rt, opts...) +// TODO docs +func BindComposable(rt *thema.Runtime, def Def[ComposableProperties], opts ...thema.BindOption) (Composable, error) { + lin, err := def.Some().BindKindLineage(rt, opts...) if err != nil { return nil, err } return genericComposable{ - def: decl, + def: def, + lin: lin, + }, nil +} + +// genericCore is a general representation of a parsed and validated Core kind. +type genericCore struct { + def Def[CoreProperties] + lin thema.Lineage +} + +var _ Core = genericCore{} + +func (k genericCore) Props() SomeKindProperties { + return k.def.Properties +} + +func (k genericCore) Name() string { + return k.def.Properties.Name +} + +func (k genericCore) MachineName() string { + return k.def.Properties.MachineName +} + +func (k genericCore) Maturity() Maturity { + return k.def.Properties.Maturity +} + +func (k genericCore) Def() Def[CoreProperties] { + return k.def +} + +func (k genericCore) Lineage() thema.Lineage { + return k.lin +} + +// TODO docs +func BindCore(rt *thema.Runtime, def Def[CoreProperties], opts ...thema.BindOption) (Core, error) { + lin, err := def.Some().BindKindLineage(rt, opts...) + if err != nil { + return nil, err + } + + return genericCore{ + def: def, lin: lin, }, nil } diff --git a/pkg/kindsys/load.go b/pkg/kindsys/load.go index ab6413aa93a..b82c3971c6d 100644 --- a/pkg/kindsys/load.go +++ b/pkg/kindsys/load.go @@ -12,10 +12,10 @@ import ( "github.com/grafana/thema" ) -// CoreDeclParentPath is the path, relative to the repository root, where +// CoreDefParentPath is the path, relative to the repository root, where // each child directory is expected to contain .cue files defining one // Core kind. -var CoreDeclParentPath = "kinds" +var CoreDefParentPath = "kinds" // GoCoreKindParentPath is the path, relative to the repository root, to the directory // containing one directory per kind, full of generated Go kind output: types and bindings. @@ -115,7 +115,7 @@ func ToKindProps[T KindProperties](v cue.Value) (T, error) { } // SomeDef represents a single kind definition, having been loaded and -// validated by a func such as [LoadCoreKind]. +// validated by a func such as [LoadCoreKindDef]. // // The underlying type of the Properties field indicates the category of kind. type SomeDef struct { @@ -155,10 +155,13 @@ func (def SomeDef) IsComposable() bool { return is } -// Def represents a single kind definition, having been loaded -// and validated by a func such as [LoadCoreKind]. +// Def represents a single kind definition, having been loaded and validated by +// a func such as [LoadCoreKindDef]. // // Its type parameter indicates the category of kind. +// +// Thema lineages in the contained definition have not yet necessarily been +// validated. type Def[T KindProperties] struct { // V is the cue.Value containing the entire Kind definition. V cue.Value @@ -174,7 +177,7 @@ func (def Def[T]) Some() SomeDef { } } -// LoadCoreKind loads and validates a core kind definition of the kind category +// LoadCoreKindDef loads and validates a core kind definition of the kind category // indicated by the type parameter. On success, it returns a [Def] which // contains the entire contents of the kind definition. // @@ -191,7 +194,7 @@ func (def Def[T]) Some() SomeDef { // This is a low-level function, primarily intended for use in code generation. // For representations of core kinds that are useful in Go programs at runtime, // see ["github.com/grafana/grafana/pkg/registry/corekind"]. -func LoadCoreKind(defpath string, ctx *cue.Context, overlay fs.FS) (Def[CoreProperties], error) { +func LoadCoreKindDef(defpath string, ctx *cue.Context, overlay fs.FS) (Def[CoreProperties], error) { none := Def[CoreProperties]{} vk, err := cuectx.BuildGrafanaInstance(ctx, defpath, "kind", overlay) if err != nil { diff --git a/pkg/kindsys/props.go b/pkg/kindsys/props.go index 9cd507db447..91e12adacfb 100644 --- a/pkg/kindsys/props.go +++ b/pkg/kindsys/props.go @@ -18,7 +18,7 @@ type CommonProperties struct { // excludes Thema schemas. // // When .cue file(s) containing a Core definition is loaded through the standard -// [LoadCoreKind], func, it is fully validated and populated according to all +// [LoadCoreKindDef], func, it is fully validated and populated according to all // rules specified in CUE for Core kinds. type CoreProperties struct { CommonProperties diff --git a/pkg/kindsys/report.go b/pkg/kindsys/report.go index 00703a6b91c..4cc691e03db 100644 --- a/pkg/kindsys/report.go +++ b/pkg/kindsys/report.go @@ -194,17 +194,14 @@ func buildKindStateReport() *KindStateReport { for _, k := range b.All() { seen[k.Props().Common().Name] = true lin := k.Lineage() - switch k.Props().(type) { - case kindsys.CoreProperties: - links := buildCoreLinks(lin, k.Def().Properties) - r.add(Kind{ - SomeKindProperties: k.Props(), - Category: "core", - Links: links, - GrafanaMaturityCount: grafanaMaturityAttrCount(lin.Latest().Underlying()), - CodeOwners: findCodeOwners(of, links), - }) - } + links := buildCoreLinks(lin, k.Def().Properties) + r.add(Kind{ + SomeKindProperties: k.Props(), + Category: "core", + Links: links, + GrafanaMaturityCount: grafanaMaturityAttrCount(lin.Latest().Underlying()), + CodeOwners: findCodeOwners(of, links), + }) } for _, kn := range plannedCoreKinds { diff --git a/pkg/plugins/codegen/jenny_plugindocs.go b/pkg/plugins/codegen/jenny_plugindocs.go deleted file mode 100644 index 7db376dbc49..00000000000 --- a/pkg/plugins/codegen/jenny_plugindocs.go +++ /dev/null @@ -1,28 +0,0 @@ -package codegen - -import ( - "github.com/grafana/codejen" - "github.com/grafana/grafana/pkg/plugins/pfs" -) - -func PluginDocsJenny(inner codejen.OneToOne[*pfs.PluginDecl]) codejen.OneToOne[*pfs.PluginDecl] { - return &docsJenny{ - inner: inner, - } -} - -type docsJenny struct { - inner codejen.OneToOne[*pfs.PluginDecl] -} - -func (j *docsJenny) JennyName() string { - return "PluginDocsJenny" -} - -func (j *docsJenny) Generate(decl *pfs.PluginDecl) (*codejen.File, error) { - if !decl.HasSchema() { - return nil, nil - } - - return j.inner.Generate(decl) -} diff --git a/pkg/registry/corekind/base_gen.go b/pkg/registry/corekind/base_gen.go index 99d00e9c0d0..9a2e2b605e8 100644 --- a/pkg/registry/corekind/base_gen.go +++ b/pkg/registry/corekind/base_gen.go @@ -23,16 +23,21 @@ import ( "github.com/grafana/thema" ) -// Base is a registry of kindsys.Interface. It provides two modes for accessing -// kinds: individually via literal named methods, or as a slice returned from -// an All*() method. +// Base is a registry of all Grafana core kinds. It is designed for use both inside +// of Grafana itself, and for import by external Go programs wanting to work with Grafana's +// kind system. +// +// The registry provides two modes for accessing core kinds: +// - Per-kind methods, which return the kind-specific type, e.g. Dashboard() returns [dashboard.Dashboard]. +// - All(), which returns a slice of [kindsys.Core]. // // Prefer the individual named methods for use cases where the particular kind(s) that // are needed are known to the caller. For example, a dashboard linter can know that it // specifically wants the dashboard kind. // -// Prefer All*() methods when performing operations generically across all kinds. -// For example, a validation HTTP middleware for any kind-schematized object type. +// Prefer All() when performing operations generically across all kinds. For example, +// a generic HTTP middleware for validating request bodies expected to contain some +// kind-schematized type. type Base struct { all []kindsys.Core dashboard *dashboard.Kind diff --git a/public/app/plugins/gen.go b/public/app/plugins/gen.go index 3497d286437..83a67330f29 100644 --- a/public/app/plugins/gen.go +++ b/public/app/plugins/gen.go @@ -16,6 +16,7 @@ import ( "github.com/grafana/codejen" corecodegen "github.com/grafana/grafana/pkg/codegen" "github.com/grafana/grafana/pkg/cuectx" + "github.com/grafana/grafana/pkg/kindsys" "github.com/grafana/grafana/pkg/plugins/codegen" "github.com/grafana/grafana/pkg/plugins/pfs" ) @@ -54,9 +55,9 @@ func main() { codegen.PluginTreeListJenny(), codegen.PluginGoTypesJenny("pkg/tsdb"), codegen.PluginTSTypesJenny("public/app/plugins", adaptToPipeline(corecodegen.TSTypesJenny{})), - codegen.PluginDocsJenny(toDeclForGen(corecodegen.DocsJenny( + kind2pd(corecodegen.DocsJenny( filepath.Join("docs", "sources", "developers", "kinds", "composable"), - ))), + )), ) pluginKindGen.AddPostprocessors(corecodegen.SlashHeaderMapper("public/app/plugins/gen.go")) @@ -91,11 +92,11 @@ func adaptToPipeline(j codejen.OneToOne[corecodegen.SchemaForGen]) codejen.OneTo }) } -func toDeclForGen(j codejen.OneToOne[*corecodegen.DefForGen]) codejen.OneToOne[*pfs.PluginDecl] { - return codejen.AdaptOneToOne(j, func(pd *pfs.PluginDecl) *corecodegen.DefForGen { - kd, err := corecodegen.ForGen(pd.Lineage.Runtime(), pd.KindDecl.Some()) +func kind2pd(j codejen.OneToOne[kindsys.Kind]) codejen.OneToOne[*pfs.PluginDecl] { + return codejen.AdaptOneToOne(j, func(pd *pfs.PluginDecl) kindsys.Kind { + kd, err := kindsys.BindComposable(nil, pd.KindDecl) if err != nil { - panic("should be unreachable") + return nil } return kd })