Kindsys: Unify plugins, pfs with kind framework (#61192)

* New pfs impl

* Reached codegen parity with old system

* Update all models.cue inputs

* Rename all models.cue files

* Remove unused prefixfs

* Changes Queries->DataQuery schema interface

* Recodegen

* All tests passing, nearly good now

* Add SchemaInterface to kindsys props

* Add pascal name deriver

* Relocate plugin cue files again

* Clarify use of injected fields

* Remove unnecessary aliasing

* Move DataQuery into mudball

* Allow forcing ExpandReferences on go type generation

* Move DataQuery def into kindsys, add generator to copy it to common

* Fix copy generator to replace package name correctly

* Fix duplicate type, test failure

* Fix linting issues
This commit is contained in:
sam boyer
2023-01-20 09:41:35 +00:00
committed by GitHub
parent 6a7cbeae6c
commit 3b3059c9ce
91 changed files with 2192 additions and 1870 deletions
+43
View File
@@ -0,0 +1,43 @@
package plugindef
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestDerivePascal(t *testing.T) {
table := []struct {
id, name, out string
}{
{
name: "-- Grafana --",
out: "Grafana",
},
{
name: "A weird/Thing",
out: "AWeirdThing",
},
{
name: "/",
out: "Empty",
},
{
name: "some really Long thing WHY would38883 anyone do this i don't know but hey It seems like it this is just going on and",
out: "SomeReallyLongThingWHYWouldAnyoneDoThisIDonTKnowButHeyItSeemsLi",
},
}
for _, row := range table {
if row.id == "" {
row.id = "default-empty-panel"
}
pd := PluginDef{
Id: row.id,
Name: row.name,
}
require.Equal(t, row.out, DerivePascalName(pd))
}
}
+13
View File
@@ -2,6 +2,7 @@ package plugindef
import (
"strings"
"regexp"
"github.com/grafana/thema"
)
@@ -34,6 +35,18 @@ seqs: [
// the UI.
name: string
// FIXME there appears to be a bug in thema that prevents this from working. Maybe it'd
// help to refer to it with an alias, but thema can't support using current list syntax.
// syntax (fixed by grafana/thema#82). Either way, for now, pascalName gets populated in Go.
let sani = (strings.ToTitle(regexp.ReplaceAllLiteral("[^a-zA-Z]+", name, "")))
// The PascalCase name for the plugin. Used for creating machine-friendly
// identifiers, typically in code generation.
//
// If not provided, defaults to name, but title-cased and sanitized (only
// alphabetical characters allowed).
pascalName: string & =~"^([A-Z][a-zA-Z]{1,62})$" | *sani
// Plugin category used on the Add data source page.
category?: "tsdb" | "logging" | "cloud" | "tracing" | "sql" | "enterprise" | "profiling" | "other"
+39 -4
View File
@@ -1,6 +1,7 @@
package plugindef
import (
"strings"
"sync"
"cuelang.org/go/cue/build"
@@ -10,10 +11,6 @@ import (
//go:generate go run gen.go
// PkgName is the name of the CUE package that Grafana will load when looking
// for kind declarations by a Grafana plugin.
const PkgName = "grafanaplugin"
func loadInstanceForplugindef() (*build.Instance, error) {
return cuectx.LoadGrafanaInstance("pkg/plugins/plugindef", "", nil)
}
@@ -36,3 +33,41 @@ func Lineage(rt *thema.Runtime, opts ...thema.BindOption) (thema.ConvergentLinea
}
return doLineage(rt, opts...)
}
// DerivePascalName derives a PascalCase name from a PluginDef.
//
// This function does not mutate the input PluginDef; as such, it ignores
// whether there exists any value for PluginDef.PascalName.
//
// FIXME this should be removable once CUE logic for it works/unmarshals correctly.
func DerivePascalName(pd PluginDef) string {
sani := func(s string) string {
ret := strings.Title(strings.Map(func(r rune) rune {
switch {
case r >= 'a' && r <= 'z':
return r
case r >= 'A' && r <= 'Z':
return r
default:
return -1
}
}, strings.Title(strings.Map(func(r rune) rune {
switch r {
case '-', '_':
return ' '
default:
return r
}
}, s))))
if len(ret) > 63 {
return ret[:63]
}
return ret
}
fromname := sani(pd.Name)
if len(fromname) != 0 {
return fromname
}
return sani(strings.Split(pd.Id, "-")[1])
}
@@ -432,6 +432,13 @@ type PluginDef struct {
// the UI.
Name string `json:"name"`
// The PascalCase name for the plugin. Used for creating machine-friendly
// identifiers, typically in code generation.
//
// If not provided, defaults to name, but title-cased and sanitized (only
// alphabetical characters allowed).
PascalName string `json:"pascalName"`
// Initialize plugin on startup. By default, the plugin
// initializes on first use.
Preload *bool `json:"preload,omitempty"`