diff --git a/pkg/kindsys/kindsysreport/kindsysreport.go b/pkg/kindsys/kindsysreport/kindsysreport.go new file mode 100644 index 0000000000000..c51a4b3df740a --- /dev/null +++ b/pkg/kindsys/kindsysreport/kindsysreport.go @@ -0,0 +1,74 @@ +package kindsysreport + +import ( + "cuelang.org/go/cue" +) + +type AttributeWalker struct { + seen map[cue.Value]bool + count map[string]int +} + +func (w *AttributeWalker) Count(sch cue.Value, attrs ...string) map[string]int { + w.seen = make(map[cue.Value]bool) + w.count = make(map[string]int) + + for _, attr := range attrs { + w.count[attr] = 0 + } + + w.walk(cue.MakePath(), sch) + return w.count +} + +func (w *AttributeWalker) walk(p cue.Path, v cue.Value) { + if w.seen[v] { + return + } + + w.seen[v] = true + + for attr := range w.count { + if found := v.Attribute(attr); found.Err() == nil { + w.count[attr]++ + } + } + + // nolint: exhaustive + switch v.Kind() { + case cue.StructKind: + // If current cue.Value is a reference to another + // definition, we don't want to traverse its fields + // individually, because we'll do so for the actual def. + if v != cue.Dereference(v) { + return + } + + iter, err := v.Fields(cue.All()) + if err != nil { + panic(err) + } + + for iter.Next() { + w.walk(appendPath(p, iter.Selector()), iter.Value()) + } + if lv := v.LookupPath(cue.MakePath(cue.AnyString)); lv.Exists() { + w.walk(appendPath(p, cue.AnyString), lv) + } + case cue.ListKind: + list, err := v.List() + if err != nil { + panic(err) + } + for i := 0; list.Next(); i++ { + w.walk(appendPath(p, cue.Index(i)), list.Value()) + } + if lv := v.LookupPath(cue.MakePath(cue.AnyIndex)); lv.Exists() { + w.walk(appendPath(p, cue.AnyString), lv) + } + } +} + +func appendPath(p cue.Path, sel cue.Selector) cue.Path { + return cue.MakePath(append(p.Selectors(), sel)...) +} diff --git a/pkg/kindsys/report.go b/pkg/kindsys/report.go index cd565cfa0d232..70a955d46043f 100644 --- a/pkg/kindsys/report.go +++ b/pkg/kindsys/report.go @@ -15,8 +15,11 @@ import ( "sort" "strings" + "cuelang.org/go/cue" + "github.com/grafana/codejen" "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/grafana/pkg/kindsys/kindsysreport" "github.com/grafana/grafana/pkg/plugins/pfs/corelist" "github.com/grafana/grafana/pkg/plugins/plugindef" "github.com/grafana/grafana/pkg/registry/corekind" @@ -82,8 +85,9 @@ type KindLinks struct { type Kind struct { kindsys.SomeKindProperties - Category string - Links KindLinks + Category string + Links KindLinks + GrafanaMaturityCount int } // MarshalJSON is overwritten to marshal @@ -100,6 +104,7 @@ func (k Kind) MarshalJSON() ([]byte, error) { } m["category"] = k.Category + m["grafanaMaturityCount"] = k.GrafanaMaturityCount m["links"] = map[string]string{} for _, ref := range []string{"Schema", "Go", "Ts", "Docs"} { @@ -177,13 +182,14 @@ func buildKindStateReport() *KindStateReport { seen := make(map[string]bool) for _, k := range b.All() { seen[k.Props().Common().Name] = true - k.Lineage() + lin := k.Lineage() switch k.Props().(type) { case kindsys.CoreProperties: r.add(Kind{ - SomeKindProperties: k.Props(), - Category: "core", - Links: buildCoreLinks(k.Lineage(), k.Decl().Properties), + SomeKindProperties: k.Props(), + Category: "core", + Links: buildCoreLinks(lin, k.Decl().Properties), + GrafanaMaturityCount: grafanaMaturityAttrCount(lin.Latest().Underlying()), }) } } @@ -212,9 +218,10 @@ func buildKindStateReport() *KindStateReport { for _, si := range all { if ck, has := pp.ComposableKinds[si.Name()]; has { r.add(Kind{ - SomeKindProperties: ck.Props(), - Category: "composable", - Links: buildComposableLinks(pp.Properties, ck.Decl().Properties), + SomeKindProperties: ck.Props(), + Category: "composable", + Links: buildComposableLinks(pp.Properties, ck.Decl().Properties), + GrafanaMaturityCount: grafanaMaturityAttrCount(ck.Lineage().Latest().Underlying()), }) } else if may := si.Should(string(pp.Properties.Type)); may { n := plugindef.DerivePascalName(pp.Properties) + si.Name() @@ -306,6 +313,12 @@ func buildComposableLinks(pp plugindef.PluginDef, cp kindsys.ComposablePropertie } } +func grafanaMaturityAttrCount(sch cue.Value) int { + const attr = "grafanamaturity" + aw := new(kindsysreport.AttributeWalker) + return aw.Count(sch, attr)[attr] +} + func machinize(s string) string { return strings.Map(func(r rune) rune { switch { diff --git a/pkg/kindsys/report.json b/pkg/kindsys/report.json index b7d2378d7dd0d..5878ac71d90f8 100644 --- a/pkg/kindsys/report.json +++ b/pkg/kindsys/report.json @@ -6,6 +6,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -26,6 +27,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -46,6 +48,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -66,6 +69,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -86,6 +90,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "https:/grafana.com/docs/grafana/next/developers/kinds/composable/annotationslistpanelcfg/schema-reference", @@ -106,6 +111,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -125,6 +131,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -145,6 +152,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -165,6 +173,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "https:/grafana.com/docs/grafana/next/developers/kinds/composable/barchartpanelcfg/schema-reference", @@ -185,6 +194,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "https:/grafana.com/docs/grafana/next/developers/kinds/composable/bargaugepanelcfg/schema-reference", @@ -205,6 +215,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -225,6 +236,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -245,6 +257,7 @@ 0, 0 ], + "grafanaMaturityCount": 144, "lineageIsGroup": false, "links": { "docs": "https:/grafana.com/docs/grafana/next/developers/kinds/core/dashboard/schema-reference", @@ -264,6 +277,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -284,6 +298,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -304,6 +319,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "https:/grafana.com/docs/grafana/next/developers/kinds/composable/dashboardlistpanelcfg/schema-reference", @@ -324,6 +340,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -343,6 +360,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -363,6 +381,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -383,6 +402,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -403,6 +423,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -423,6 +444,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -442,6 +464,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "https:/grafana.com/docs/grafana/next/developers/kinds/composable/gaugepanelcfg/schema-reference", @@ -462,6 +485,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -482,6 +506,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -502,6 +527,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -522,6 +548,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -542,6 +569,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -562,6 +590,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -582,6 +611,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -602,6 +632,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -622,6 +653,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -642,6 +674,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "https:/grafana.com/docs/grafana/next/developers/kinds/composable/histogrampanelcfg/schema-reference", @@ -662,6 +695,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -682,6 +716,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -702,6 +737,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -722,6 +758,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -742,6 +779,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -762,6 +800,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -782,6 +821,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -802,6 +842,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -822,6 +863,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -842,6 +884,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -862,6 +905,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -882,6 +926,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "https:/grafana.com/docs/grafana/next/developers/kinds/composable/newspanelcfg/schema-reference", @@ -902,6 +947,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -922,6 +968,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -942,6 +989,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -962,6 +1010,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -982,6 +1031,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -1002,6 +1052,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "https:/grafana.com/docs/grafana/next/developers/kinds/composable/piechartpanelcfg/schema-reference", @@ -1022,6 +1073,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "https:/grafana.com/docs/grafana/next/developers/kinds/core/playlist/schema-reference", @@ -1041,6 +1093,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -1061,6 +1114,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -1081,6 +1135,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -1101,6 +1156,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -1121,6 +1177,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -1140,6 +1197,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -1159,6 +1217,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -1178,6 +1237,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "https:/grafana.com/docs/grafana/next/developers/kinds/composable/statpanelcfg/schema-reference", @@ -1198,6 +1258,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -1218,6 +1279,7 @@ 0, 0 ], + "grafanaMaturityCount": 7, "lineageIsGroup": false, "links": { "docs": "https:/grafana.com/docs/grafana/next/developers/kinds/core/team/schema-reference", @@ -1237,6 +1299,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -1257,6 +1320,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -1277,6 +1341,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -1297,6 +1362,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -1317,6 +1383,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "https:/grafana.com/docs/grafana/next/developers/kinds/composable/textpanelcfg/schema-reference", @@ -1337,6 +1404,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -1356,6 +1424,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -1376,6 +1445,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -1395,6 +1465,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -1415,6 +1486,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a", @@ -1435,6 +1507,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": false, "links": { "docs": "n/a", @@ -1455,6 +1528,7 @@ 0, 0 ], + "grafanaMaturityCount": 0, "lineageIsGroup": true, "links": { "docs": "n/a",