From 8745d7ef1bf527ec84b9753613d7e5b689e81a17 Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Wed, 15 Mar 2023 12:04:28 -0400 Subject: [PATCH] extract kindsys to external library (#64562) * extract kindsys * reinstate kindsys report This may end up living somewhere else (or not! who knows!), but the important part is that I don't get rid of it right now :) I hate the package layout (kindsysreport/codegen) for the main function and will take pretty much any alternative suggestion, but we can change also change it later. Note that the generated report.json is in a different location - anything using this (ops something) needs to be updated. * kindsysreport in codeowners --- .github/CODEOWNERS | 3 +- embed.go | 2 +- go.mod | 17 +- go.sum | 36 +-- kinds/constraint.cue | 2 +- kinds/gen.go | 21 +- pkg/codegen/generators.go | 2 +- pkg/codegen/jenny_basecorereg.go | 2 +- pkg/codegen/jenny_corekind.go | 2 +- pkg/codegen/jenny_crd_reg.go | 6 +- pkg/codegen/jenny_crd_types.go | 2 +- pkg/codegen/jenny_crd_yaml.go | 5 +- pkg/codegen/jenny_docs.go | 5 +- pkg/codegen/jenny_eachmajor.go | 2 +- pkg/codegen/jenny_tsveneerindex.go | 2 +- pkg/codegen/latest_jenny.go | 2 +- pkg/codegen/tmpl.go | 2 +- pkg/codegen/tmpl/core_crd_registry.tmpl | 4 +- pkg/codegen/tmpl/core_crd_types.tmpl | 2 +- pkg/codegen/tmpl/kind_core.tmpl | 6 +- pkg/codegen/tmpl/kind_registry.tmpl | 2 +- pkg/codegen/tmpl/plugin_lineage_file.tmpl | 3 +- pkg/cuectx/ctx.go | 204 +-------------- pkg/cuectx/load.go | 236 ++++++++++++++++++ pkg/kinds/dashboard/crd/dashboard_crd_gen.go | 2 +- pkg/kinds/dashboard/dashboard_kind_gen.go | 6 +- .../librarypanel/crd/librarypanel_crd_gen.go | 2 +- .../librarypanel/librarypanel_kind_gen.go | 6 +- pkg/kinds/playlist/crd/playlist_crd_gen.go | 2 +- pkg/kinds/playlist/playlist_kind_gen.go | 6 +- .../preferences/crd/preferences_crd_gen.go | 2 +- pkg/kinds/preferences/preferences_kind_gen.go | 6 +- .../crd/publicdashboard_crd_gen.go | 2 +- .../publicdashboard_kind_gen.go | 6 +- .../crd/serviceaccount_crd_gen.go | 2 +- .../serviceaccount/serviceaccount_kind_gen.go | 6 +- pkg/kinds/team/crd/team_crd_gen.go | 2 +- pkg/kinds/team/team_kind_gen.go | 6 +- pkg/kindsys/EXTENDING.md | 59 ----- pkg/kindsys/bind.go | 96 ------- pkg/kindsys/common_dataquery.cue | 38 --- pkg/kindsys/errors.go | 18 -- pkg/kindsys/k8ssys/crd.go | 154 ------------ pkg/kindsys/kind.go | 92 ------- pkg/kindsys/kindcat_composable.cue | 31 --- pkg/kindsys/kindcat_custom.cue | 15 -- pkg/kindsys/kindcats.cue | 127 ---------- pkg/kindsys/load.go | 213 ---------------- pkg/kindsys/props.go | 80 ------ pkg/kindsys/schema_interface.cue | 147 ----------- pkg/kindsys/schema_interface.go | 121 --------- pkg/kindsys/util.go | 24 -- pkg/{kindsys => }/kindsysreport/attributes.go | 0 .../codegen}/report.go | 10 +- .../codegen}/report.json | 0 pkg/{kindsys => }/kindsysreport/codeowners.go | 0 pkg/plugins/codegen/util_ts.go | 3 +- pkg/plugins/pfs/decl.go | 5 +- pkg/plugins/pfs/decl_parser.go | 2 +- pkg/plugins/pfs/grafanaplugin.cue | 2 +- pkg/plugins/pfs/pfs.go | 9 +- pkg/plugins/pfs/plugin.go | 3 +- pkg/plugins/pfs/plugin_test.go | 2 +- pkg/registry/corecrd/registry.go | 5 +- pkg/registry/corecrd/registry_gen.go | 2 +- pkg/registry/corekind/base.go | 5 +- pkg/registry/corekind/base_gen.go | 2 +- .../querydata/framing_bench_test.go | 5 +- pkg/tsdb/prometheus/querydata/request_test.go | 6 +- public/app/plugins/gen.go | 3 +- 70 files changed, 390 insertions(+), 1515 deletions(-) create mode 100644 pkg/cuectx/load.go delete mode 100644 pkg/kindsys/EXTENDING.md delete mode 100644 pkg/kindsys/bind.go delete mode 100644 pkg/kindsys/common_dataquery.cue delete mode 100644 pkg/kindsys/errors.go delete mode 100644 pkg/kindsys/k8ssys/crd.go delete mode 100644 pkg/kindsys/kind.go delete mode 100644 pkg/kindsys/kindcat_composable.cue delete mode 100644 pkg/kindsys/kindcat_custom.cue delete mode 100644 pkg/kindsys/kindcats.cue delete mode 100644 pkg/kindsys/load.go delete mode 100644 pkg/kindsys/props.go delete mode 100644 pkg/kindsys/schema_interface.cue delete mode 100644 pkg/kindsys/schema_interface.go delete mode 100644 pkg/kindsys/util.go rename pkg/{kindsys => }/kindsysreport/attributes.go (100%) rename pkg/{kindsys => kindsysreport/codegen}/report.go (98%) rename pkg/{kindsys => kindsysreport/codegen}/report.json (100%) rename pkg/{kindsys => }/kindsysreport/codeowners.go (100%) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c7c69855cc7..a66b967ba38 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -258,6 +258,7 @@ /pkg/infra/filestorage/ @grafana/grafana-app-platform-squad /pkg/util/converter/ @grafana/grafana-app-platform-squad /pkg/modules/ @grafana/grafana-app-platform-squad +/pkg/kindsysreport/ @grafana/grafana-app-platform-squad # Alerting /pkg/services/ngalert/ @grafana/alerting-squad-backend @@ -548,8 +549,6 @@ embed.go @grafana/grafana-as-code /pkg/cuectx/ @grafana/grafana-as-code /pkg/registry/ @grafana/grafana-as-code /pkg/codegen/ @grafana/grafana-as-code -/pkg/kindsys/ @grafana/grafana-as-code -/pkg/kindsys/kindcat_custom.cue @grafana/cloud-app-platform-squad /pkg/kinds/*/*_gen.go @grafana/grafana-as-code /pkg/registry/corekind/ @grafana/grafana-as-code /public/app/plugins/*gen.go @grafana/grafana-as-code diff --git a/embed.go b/embed.go index 12878a11060..570415e0034 100644 --- a/embed.go +++ b/embed.go @@ -6,5 +6,5 @@ import ( // CueSchemaFS embeds all schema-related CUE files in the Grafana project. // -//go:embed cue.mod/module.cue kinds/*.cue kinds/*/*.cue packages/grafana-schema/src/common/*.cue public/app/plugins/*/*/*.cue public/app/plugins/*/*/plugin.json pkg/kindsys/*.cue pkg/plugins/*/*.cue +//go:embed cue.mod/module.cue kinds/*.cue kinds/*/*.cue packages/grafana-schema/src/common/*.cue public/app/plugins/*/*/*.cue public/app/plugins/*/*/plugin.json pkg/plugins/*/*.cue var CueSchemaFS embed.FS diff --git a/go.mod b/go.mod index fdc268ef937..29d09128628 100644 --- a/go.mod +++ b/go.mod @@ -26,8 +26,8 @@ replace github.com/deepmap/oapi-codegen => github.com/spinillos/oapi-codegen v1. replace k8s.io/client-go => k8s.io/client-go v0.25.3 require ( - k8s.io/apiextensions-apiserver v0.25.3 - k8s.io/apimachinery v0.25.3 + k8s.io/apiextensions-apiserver v0.26.2 // indirect + k8s.io/apimachinery v0.26.2 ) require ( @@ -254,7 +254,7 @@ require ( github.com/jmoiron/sqlx v1.3.5 github.com/matryer/is v1.4.0 github.com/urfave/cli v1.22.12 - go.etcd.io/etcd/api/v3 v3.5.4 + go.etcd.io/etcd/api/v3 v3.5.5 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.37.0 go.opentelemetry.io/contrib/propagators/jaeger v1.6.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.2 @@ -268,8 +268,8 @@ require ( github.com/Masterminds/semver/v3 v3.1.1 github.com/dave/dst v0.27.2 github.com/go-jose/go-jose/v3 v3.0.0 - github.com/grafana/thema v0.0.0-20230224141623-cb20887cb028 - github.com/hmarr/codeowners v1.1.1 + github.com/grafana/kindsys v0.0.0-20230309200316-812b9884a375 + github.com/grafana/thema v0.0.0-20230302221249-6952e4a999b7 github.com/weaveworks/common v0.0.0-20230208133027-16871410fca4 github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f ) @@ -300,7 +300,6 @@ require ( github.com/drone/runner-go v1.12.0 // indirect github.com/envoyproxy/go-control-plane v0.10.3 // indirect github.com/envoyproxy/protoc-gen-validate v0.6.13 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect @@ -336,11 +335,10 @@ require ( go.starlark.net v0.0.0-20221020143700-22309ac47eac // indirect gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - k8s.io/klog/v2 v2.80.0 // indirect - k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect + k8s.io/klog/v2 v2.80.1 // indirect + k8s.io/utils v0.0.0-20221107191617-1a15be271d1d // indirect sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect ) require ( @@ -377,6 +375,7 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/google/go-github v17.0.0+incompatible github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0 // indirect + github.com/hmarr/codeowners v1.1.2 github.com/imdario/mergo v0.3.12 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect diff --git a/go.sum b/go.sum index e26c33bdc7b..98b11710089 100644 --- a/go.sum +++ b/go.sum @@ -731,8 +731,8 @@ github.com/elazarl/goproxy/ext v0.0.0-20220115173737-adb46da277ac h1:9yrT5tmn9Zc github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful/v3 v3.8.0 h1:eCZ8ulSerjdAiaNpF7GxXIE7ZCMo1moN1qX+S609eVw= github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= github.com/emicklei/proto v1.10.0 h1:pDGyFRVV5RvV+nkBK9iy3q67FBy9Xa7vwrOTE+g5aGw= github.com/emicklei/proto v1.10.0/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= @@ -776,7 +776,6 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= @@ -1277,6 +1276,8 @@ github.com/grafana/grafana-plugin-sdk-go v0.94.0/go.mod h1:3VXz4nCv6wH5SfgB3mlW3 github.com/grafana/grafana-plugin-sdk-go v0.114.0/go.mod h1:D7x3ah+1d4phNXpbnOaxa/osSaZlwh9/ZUnGGzegRbk= github.com/grafana/grafana-plugin-sdk-go v0.153.0 h1:5Z3NU/W32BsElkiqalvh6ow0Mx81GhAk94+GddIuTrQ= github.com/grafana/grafana-plugin-sdk-go v0.153.0/go.mod h1:4f/8Gf6xMwqXhOmS5U2RPmKQ2UgyA0bVteM/gxGFaCI= +github.com/grafana/kindsys v0.0.0-20230309200316-812b9884a375 h1:iWFjqAU5GjIV/HetIE/Me6VF3SRw29u5QviMVbJUVQo= +github.com/grafana/kindsys v0.0.0-20230309200316-812b9884a375/go.mod h1:213a3clTiegHfheYcLPLeEyHv/azK/fAF67OEbzuLzw= github.com/grafana/phlare/api v0.1.3 h1:mYTaE9mLsAW/uzPXlW/PQSLsZ4ojBFA+oAMfR/PDdw8= github.com/grafana/phlare/api v0.1.3/go.mod h1:29vcLwFDmZBDce2jwFIMtzvof7fzPadT8VMKw9ks7FU= github.com/grafana/prometheus-alertmanager v0.25.1-0.20230308154952-78fedf89728b h1:VQOGGGJ2lKcVPANyzIESKYhSeA0QIvUQwfA3CbrkDfA= @@ -1285,8 +1286,8 @@ github.com/grafana/saml v0.4.13-0.20230203140620-5f476db5c00a h1:aWSTt/pTOI4uGY9 github.com/grafana/saml v0.4.13-0.20230203140620-5f476db5c00a/go.mod h1:igEejV+fihTIlHXYP8zOec3V5A8y3lws5bQBFsTm4gA= github.com/grafana/sqlds/v2 v2.3.10 h1:HWKhE0vR6LoEiE+Is8CSZOgaB//D1yqb2ntkass9Fd4= github.com/grafana/sqlds/v2 v2.3.10/go.mod h1:c6ibxnxRVGxV/0YkEgvy7QpQH/lyifFyV7K/14xvdIs= -github.com/grafana/thema v0.0.0-20230224141623-cb20887cb028 h1:6DXb3CmghXpjtd0VjK1FDEjvHhNcXfYSxUcEfxyMx9w= -github.com/grafana/thema v0.0.0-20230224141623-cb20887cb028/go.mod h1:T6q1RVzq5fzVbm+QBeIsTmVzuXlMaArp4wxfLvcaMV0= +github.com/grafana/thema v0.0.0-20230302221249-6952e4a999b7 h1:XOxaBjhozlleshff3mKNdp55ul74nXJEX3wz8ckjTpc= +github.com/grafana/thema v0.0.0-20230302221249-6952e4a999b7/go.mod h1:T6q1RVzq5fzVbm+QBeIsTmVzuXlMaArp4wxfLvcaMV0= 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= @@ -1405,8 +1406,8 @@ github.com/hetznercloud/hcloud-go v1.26.2/go.mod h1:2C5uMtBiMoFr3m7lBFPf7wXTdh33 github.com/hetznercloud/hcloud-go v1.32.0/go.mod h1:XX/TQub3ge0yWR2yHWmnDVIrB+MQbda1pHxkUmDlUME= github.com/hetznercloud/hcloud-go v1.35.3 h1:WCmFAhLRooih2QHAsbCbEdpIHnshQQmrPqsr3rHE1Ow= github.com/hetznercloud/hcloud-go v1.35.3/go.mod h1:mepQwR6va27S3UQthaEPGS86jtzSY9xWL1e9dyxXpgA= -github.com/hmarr/codeowners v1.1.1 h1:a1eD22I36JYH6O/zb+R+JkJgQ3CSlbu6H9EserOojSw= -github.com/hmarr/codeowners v1.1.1/go.mod h1:+ez+YARvfVhzL1MzY0f2+D/VusjODs4iRj3tO/IxBMw= +github.com/hmarr/codeowners v1.1.2 h1:CdmLJ0e2s2aaH21+3HW1HXJyJqz+OCEiMBfD9iZb3n8= +github.com/hmarr/codeowners v1.1.2/go.mod h1:+ez+YARvfVhzL1MzY0f2+D/VusjODs4iRj3tO/IxBMw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs= @@ -2330,8 +2331,9 @@ go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/api/v3 v3.5.4 h1:OHVyt3TopwtUQ2GKdd5wu3PmmipR4FTwCqoEjSyRdIc= go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= +go.etcd.io/etcd/api/v3 v3.5.5 h1:BX4JIbQ7hl7+jL+g+2j5UAr0o1bctCm6/Ct+ArBGkf0= +go.etcd.io/etcd/api/v3 v3.5.5/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= @@ -2877,7 +2879,6 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908150016-7ac13a9a928d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -3205,10 +3206,10 @@ k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s= k8s.io/api v0.22.1/go.mod h1:bh13rkTp3F1XEaLGykbyRD2QaTTzPm0e/BMd8ptFONY= -k8s.io/api v0.25.3 h1:Q1v5UFfYe87vi5H7NU0p4RXC26PPMT8KOpr1TLQbCMQ= k8s.io/api v0.25.3/go.mod h1:o42gKscFrEVjHdQnyRenACrMtbuJsVdP+WVjqejfzmI= -k8s.io/apiextensions-apiserver v0.25.3 h1:bfI4KS31w2f9WM1KLGwnwuVlW3RSRPuIsfNF/3HzR0k= -k8s.io/apiextensions-apiserver v0.25.3/go.mod h1:ZJqwpCkxIx9itilmZek7JgfUAM0dnTsA48I4krPqRmo= +k8s.io/api v0.26.2 h1:dM3cinp3PGB6asOySalOZxEG4CZ0IAdJsrYZXE/ovGQ= +k8s.io/apiextensions-apiserver v0.26.2 h1:/yTG2B9jGY2Q70iGskMf41qTLhL9XeNN2KhI0uDgwko= +k8s.io/apiextensions-apiserver v0.26.2/go.mod h1:Y7UPgch8nph8mGCuVk0SK83LnS8Esf3n6fUBgew8SH8= k8s.io/apimachinery v0.0.0-20190809020650-423f5d784010/go.mod h1:Waf/xTS2FGRrgXCkO5FP3XxTOWh0qLf2QhL1qFZZ/R8= k8s.io/apimachinery v0.17.5/go.mod h1:ioIo1G/a+uONV7Tv+ZmCbMG1/a3kVw5YcDdncd8ugQ0= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= @@ -3216,8 +3217,9 @@ k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRp k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= -k8s.io/apimachinery v0.25.3 h1:7o9ium4uyUOM76t6aunP0nZuex7gDf8VGwkR5RcJnQc= k8s.io/apimachinery v0.25.3/go.mod h1:jaF9C/iPNM1FuLl7Zuy5b9v+n35HGSh6AQ4HYRkCqwo= +k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ= +k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= @@ -3245,23 +3247,24 @@ k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.10.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.80.0 h1:lyJt0TWMPaGoODa8B8bUuxgHS3W/m/bNr2cca3brA/g= -k8s.io/klog/v2 v2.80.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= +k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4= k8s.io/kube-openapi v0.0.0-20190722073852-5e22f3d471e6/go.mod h1:RZvgC8MSN6DjiMV6oIfEE9pDL9CYXokkfaCKZeHm3nc= k8s.io/kube-openapi v0.0.0-20200316234421-82d701f24f9d/go.mod h1:F+5wygcW0wmRTnM3cOgIqGivxkwSWIWT5YdsDbeAOaU= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= -k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA= k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20190809000727-6c36bc71fc4a/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200414100711-2df71ebbae66/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed h1:jAne/RjBTyawwAy0utX5eqigAwz/lQhTmy+Hr/Cpue4= k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20221107191617-1a15be271d1d h1:0Smp/HP1OH4Rvhe+4B8nWGERtlqAGSftbSbbmm45oFs= +k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= @@ -3282,7 +3285,6 @@ sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ih sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= xorm.io/builder v0.3.6 h1:ha28mQ2M+TFx96Hxo+iq6tQgnkC9IZkM6D8w9sKHHF8= xorm.io/builder v0.3.6/go.mod h1:LEFAPISnRzG+zxaxj2vPicRwz67BdhFreKg8yv8/TgU= diff --git a/kinds/constraint.cue b/kinds/constraint.cue index 4d1bb954cf5..2bc9f6c16c9 100644 --- a/kinds/constraint.cue +++ b/kinds/constraint.cue @@ -1,6 +1,6 @@ package kind -import "github.com/grafana/grafana/pkg/kindsys" +import "github.com/grafana/kindsys" // In each child directory, the set of .cue files with 'package kind' // must be an instance of kindsys.Core - a declaration of a core kind. diff --git a/kinds/gen.go b/kinds/gen.go index a8dae5bb021..bd6bb368c95 100644 --- a/kinds/gen.go +++ b/kinds/gen.go @@ -18,9 +18,10 @@ import ( "cuelang.org/go/cue/errors" "github.com/grafana/codejen" "github.com/grafana/cuetsy" + "github.com/grafana/kindsys" + "github.com/grafana/grafana/pkg/codegen" "github.com/grafana/grafana/pkg/cuectx" - "github.com/grafana/grafana/pkg/kindsys" ) func main() { @@ -37,13 +38,13 @@ func main() { // All the jennies that comprise the core kinds generator pipeline coreKindsGen.Append( - codegen.LatestJenny(kindsys.GoCoreKindParentPath, codegen.GoTypesJenny{}), - codegen.CoreKindJenny(kindsys.GoCoreKindParentPath, nil), - codegen.BaseCoreRegistryJenny(filepath.Join("pkg", "registry", "corekind"), kindsys.GoCoreKindParentPath), - codegen.LatestMajorsOrXJenny(kindsys.TSCoreKindParentPath, codegen.TSTypesJenny{}), + codegen.LatestJenny(cuectx.GoCoreKindParentPath, codegen.GoTypesJenny{}), + codegen.CoreKindJenny(cuectx.GoCoreKindParentPath, nil), + codegen.BaseCoreRegistryJenny(filepath.Join("pkg", "registry", "corekind"), cuectx.GoCoreKindParentPath), + codegen.LatestMajorsOrXJenny(cuectx.TSCoreKindParentPath, codegen.TSTypesJenny{}), codegen.TSVeneerIndexJenny(filepath.Join("packages", "grafana-schema", "src")), - codegen.CRDTypesJenny(kindsys.GoCoreKindParentPath), - codegen.YamlCRDJenny(kindsys.GoCoreKindParentPath), + codegen.CRDTypesJenny(cuectx.GoCoreKindParentPath), + codegen.YamlCRDJenny(cuectx.GoCoreKindParentPath), codegen.CRDKindRegistryJenny(filepath.Join("pkg", "registry", "corecrd")), codegen.DocsJenny(filepath.Join("docs", "sources", "developers", "kinds", "core")), ) @@ -61,14 +62,14 @@ func main() { rt := cuectx.GrafanaThemaRuntime() var all []kindsys.Kind - f := os.DirFS(filepath.Join(groot, kindsys.CoreDefParentPath)) + f := os.DirFS(filepath.Join(groot, cuectx.CoreDefParentPath)) kinddirs := elsedie(fs.ReadDir(f, "."))("error reading core kind fs root directory") for _, kinddir := range kinddirs { if !kinddir.IsDir() { continue } - rel := filepath.Join(kindsys.CoreDefParentPath, kinddir.Name()) - def, err := kindsys.LoadCoreKindDef(rel, rt.Context(), nil) + rel := filepath.Join(cuectx.CoreDefParentPath, kinddir.Name()) + def, err := cuectx.LoadCoreKindDef(rel, rt.Context(), nil) if err != nil { die(fmt.Errorf("%s is not a valid kind: %s", rel, errors.Details(err, nil))) } diff --git a/pkg/codegen/generators.go b/pkg/codegen/generators.go index 5bbb3a03b57..f4558c48ba7 100644 --- a/pkg/codegen/generators.go +++ b/pkg/codegen/generators.go @@ -6,7 +6,7 @@ import ( "path/filepath" "github.com/grafana/codejen" - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" "github.com/grafana/thema" ) diff --git a/pkg/codegen/jenny_basecorereg.go b/pkg/codegen/jenny_basecorereg.go index 1a685c6444e..1a19a9aca8c 100644 --- a/pkg/codegen/jenny_basecorereg.go +++ b/pkg/codegen/jenny_basecorereg.go @@ -6,7 +6,7 @@ import ( "path/filepath" "github.com/grafana/codejen" - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" ) // BaseCoreRegistryJenny generates a static registry for core kinds that diff --git a/pkg/codegen/jenny_corekind.go b/pkg/codegen/jenny_corekind.go index e2c95fa21da..b7deb36cfb5 100644 --- a/pkg/codegen/jenny_corekind.go +++ b/pkg/codegen/jenny_corekind.go @@ -6,7 +6,7 @@ import ( "path/filepath" "github.com/grafana/codejen" - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" ) // CoreKindJenny generates the implementation of [kindsys.Core] for the provided diff --git a/pkg/codegen/jenny_crd_reg.go b/pkg/codegen/jenny_crd_reg.go index 56bd409b453..fab3aa5bf1e 100644 --- a/pkg/codegen/jenny_crd_reg.go +++ b/pkg/codegen/jenny_crd_reg.go @@ -6,7 +6,9 @@ import ( "path/filepath" "github.com/grafana/codejen" - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" + + "github.com/grafana/grafana/pkg/cuectx" ) // CRDKindRegistryJenny generates a static registry of the CRD representations @@ -43,7 +45,7 @@ func (j *crdregjenny) Generate(kinds ...kindsys.Kind) (*codejen.File, error) { buf := new(bytes.Buffer) if err := tmpls.Lookup("core_crd_registry.tmpl").Execute(buf, tvars_kind_registry{ PackageName: "corecrd", - KindPackagePrefix: filepath.ToSlash(filepath.Join("github.com/grafana/grafana", kindsys.GoCoreKindParentPath)), + KindPackagePrefix: filepath.ToSlash(filepath.Join("github.com/grafana/grafana", cuectx.GoCoreKindParentPath)), Kinds: cores, }); err != nil { return nil, fmt.Errorf("failed executing core crd registry template: %w", err) diff --git a/pkg/codegen/jenny_crd_types.go b/pkg/codegen/jenny_crd_types.go index fe8945f5c8c..63cfd3e2b83 100644 --- a/pkg/codegen/jenny_crd_types.go +++ b/pkg/codegen/jenny_crd_types.go @@ -6,7 +6,7 @@ import ( "path/filepath" "github.com/grafana/codejen" - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" ) // CRDTypesJenny generates the OpenAPI CRD representation for a core diff --git a/pkg/codegen/jenny_crd_yaml.go b/pkg/codegen/jenny_crd_yaml.go index 69d8538bd9d..9abfb708d97 100644 --- a/pkg/codegen/jenny_crd_yaml.go +++ b/pkg/codegen/jenny_crd_yaml.go @@ -10,10 +10,11 @@ import ( "cuelang.org/go/encoding/openapi" cueyaml "cuelang.org/go/pkg/encoding/yaml" "github.com/grafana/codejen" - "github.com/grafana/grafana/pkg/kindsys" - "github.com/grafana/grafana/pkg/kindsys/k8ssys" + "github.com/grafana/kindsys/k8ssys" "github.com/grafana/thema" goyaml "gopkg.in/yaml.v3" + + "github.com/grafana/kindsys" ) // TODO this jenny is quite sloppy, having been quickly adapted from app-sdk. It needs love diff --git a/pkg/codegen/jenny_docs.go b/pkg/codegen/jenny_docs.go index ddf7796a948..d7f487465b5 100644 --- a/pkg/codegen/jenny_docs.go +++ b/pkg/codegen/jenny_docs.go @@ -15,11 +15,12 @@ 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/kindsys" "github.com/grafana/thema/encoding/jsonschema" "github.com/olekukonko/tablewriter" "github.com/xeipuuv/gojsonpointer" + + "github.com/grafana/grafana/pkg/components/simplejson" ) func DocsJenny(docsPath string) OneToOne { diff --git a/pkg/codegen/jenny_eachmajor.go b/pkg/codegen/jenny_eachmajor.go index a9c94425cfb..34027df9d6c 100644 --- a/pkg/codegen/jenny_eachmajor.go +++ b/pkg/codegen/jenny_eachmajor.go @@ -5,7 +5,7 @@ import ( "path/filepath" "github.com/grafana/codejen" - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" ) // LatestMajorsOrXJenny returns a jenny that repeats the input for the latest in each major version, diff --git a/pkg/codegen/jenny_tsveneerindex.go b/pkg/codegen/jenny_tsveneerindex.go index 313f0dddebc..63d9632b941 100644 --- a/pkg/codegen/jenny_tsveneerindex.go +++ b/pkg/codegen/jenny_tsveneerindex.go @@ -11,7 +11,7 @@ import ( "github.com/grafana/codejen" "github.com/grafana/cuetsy/ts" "github.com/grafana/cuetsy/ts/ast" - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" "github.com/grafana/thema" "github.com/grafana/thema/encoding/typescript" ) diff --git a/pkg/codegen/latest_jenny.go b/pkg/codegen/latest_jenny.go index d075d7b01bd..b8a0a618a0e 100644 --- a/pkg/codegen/latest_jenny.go +++ b/pkg/codegen/latest_jenny.go @@ -5,7 +5,7 @@ import ( "path/filepath" "github.com/grafana/codejen" - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" ) // LatestJenny returns a jenny that runs another jenny for only the latest diff --git a/pkg/codegen/tmpl.go b/pkg/codegen/tmpl.go index dfe43657b1b..5ea713278fd 100644 --- a/pkg/codegen/tmpl.go +++ b/pkg/codegen/tmpl.go @@ -7,7 +7,7 @@ import ( "time" "github.com/grafana/codejen" - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" ) // All the parsed templates in the tmpl subdirectory diff --git a/pkg/codegen/tmpl/core_crd_registry.tmpl b/pkg/codegen/tmpl/core_crd_registry.tmpl index a65b77378ea..f30bb443232 100644 --- a/pkg/codegen/tmpl/core_crd_registry.tmpl +++ b/pkg/codegen/tmpl/core_crd_registry.tmpl @@ -6,8 +6,8 @@ import ( {{range .Kinds }} {{ .Props.MachineName }} "{{ $.KindPackagePrefix }}/{{ .Props.MachineName }}/crd"{{end}} - "github.com/grafana/grafana/pkg/kindsys" - "github.com/grafana/grafana/pkg/kindsys/k8ssys" + "github.com/grafana/kindsys" + "github.com/grafana/kindsys/k8ssys" "github.com/grafana/grafana/pkg/registry/corekind" "gopkg.in/yaml.v3" ) diff --git a/pkg/codegen/tmpl/core_crd_types.tmpl b/pkg/codegen/tmpl/core_crd_types.tmpl index 0e6614c1853..f7d66402f82 100644 --- a/pkg/codegen/tmpl/core_crd_types.tmpl +++ b/pkg/codegen/tmpl/core_crd_types.tmpl @@ -4,7 +4,7 @@ import ( _ "embed" "github.com/grafana/grafana/pkg/kinds/{{ .Props.MachineName }}" - "github.com/grafana/grafana/pkg/kindsys/k8ssys" + "github.com/grafana/kindsys/k8ssys" ) // The CRD YAML representation of the {{ .Props.Name }} kind. diff --git a/pkg/codegen/tmpl/kind_core.tmpl b/pkg/codegen/tmpl/kind_core.tmpl index 6a4a94ed1f6..19af086e65d 100644 --- a/pkg/codegen/tmpl/kind_core.tmpl +++ b/pkg/codegen/tmpl/kind_core.tmpl @@ -1,9 +1,11 @@ package {{ .Props.MachineName }} import ( - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" "github.com/grafana/thema" "github.com/grafana/thema/vmux" + + "github.com/grafana/grafana/pkg/cuectx" ) // rootrel is the relative path from the grafana repository root to the @@ -25,7 +27,7 @@ var _ kindsys.Core = &Kind{} // TODO standard generated docs func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { - def, err := kindsys.LoadCoreKindDef(rootrel, rt.Context(), nil) + def, err := cuectx.LoadCoreKindDef(rootrel, rt.Context(), nil) if err != nil { return nil, err } diff --git a/pkg/codegen/tmpl/kind_registry.tmpl b/pkg/codegen/tmpl/kind_registry.tmpl index 40537988012..59cf5fbc0ae 100644 --- a/pkg/codegen/tmpl/kind_registry.tmpl +++ b/pkg/codegen/tmpl/kind_registry.tmpl @@ -7,7 +7,7 @@ import ( {{range .Kinds }} "{{ $.KindPackagePrefix }}/{{ .Props.MachineName }}"{{end}} "github.com/grafana/grafana/pkg/cuectx" - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" "github.com/grafana/thema" ) diff --git a/pkg/codegen/tmpl/plugin_lineage_file.tmpl b/pkg/codegen/tmpl/plugin_lineage_file.tmpl index 36b13959f80..a14f4c975be 100644 --- a/pkg/codegen/tmpl/plugin_lineage_file.tmpl +++ b/pkg/codegen/tmpl/plugin_lineage_file.tmpl @@ -7,9 +7,10 @@ import ( "path/filepath" "sync" + "github.com/grafana/thema" + "github.com/grafana/grafana/pkg/cuectx" "github.com/grafana/grafana/pkg/plugins/pfs" - "github.com/grafana/thema" ) var parseOnce sync.Once diff --git a/pkg/cuectx/ctx.go b/pkg/cuectx/ctx.go index 2d07a2c5d04..3d6f654da86 100644 --- a/pkg/cuectx/ctx.go +++ b/pkg/cuectx/ctx.go @@ -5,21 +5,27 @@ package cuectx import ( - "fmt" - "io/fs" "path/filepath" - "testing/fstest" "cuelang.org/go/cue" - "cuelang.org/go/cue/build" "cuelang.org/go/cue/cuecontext" - "github.com/grafana/grafana" "github.com/grafana/thema" - "github.com/grafana/thema/load" "github.com/grafana/thema/vmux" - "github.com/yalue/merged_fs" ) +// CoreDefParentPath is the path, relative to the repository root, where +// each child directory is expected to contain .cue files defining one +// Core kind. +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. +var GoCoreKindParentPath = filepath.Join("pkg", "kinds") + +// TSCoreKindParentPath is the path, relative to the repository root, to the directory that +// contains one directory per kind, full of generated TS kind output: types and default consts. +var TSCoreKindParentPath = filepath.Join("packages", "grafana-schema", "src", "raw") + var ctx = cuecontext.New() var rt = thema.NewRuntime(ctx) @@ -52,187 +58,3 @@ func GrafanaThemaRuntime() *thema.Runtime { func JSONtoCUE(path string, b []byte) (cue.Value, error) { return vmux.NewJSONCodec(path).Decode(ctx, b) } - -// LoadGrafanaInstancesWithThema loads CUE files containing a lineage -// representing some Grafana core model schema. It is expected to be used when -// implementing a thema.LineageFactory. -// -// This function primarily juggles paths to make CUE's loader happy. Provide the -// path from the grafana root to the directory containing the lineage.cue. The -// lineage.cue file must be the sole contents of the provided fs.FS. -// -// More details on underlying behavior can be found in the docs for github.com/grafana/thema/load.InstanceWithThema. -// -// TODO this approach is complicated and confusing, refactor to something understandable -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 { - return nil, err - } - inst, err := load.InstanceWithThema(fs, prefix) - - // Need to trick loading by creating the embedded file and - // making it look like a module in the root dir. - if err != nil { - return nil, err - } - - val := rt.Context().BuildInstance(inst) - - lin, err := thema.BindLineage(val, rt, opts...) - if err != nil { - return nil, err - } - - return lin, nil -} - -// prefixWithGrafanaCUE constructs an fs.FS that merges the provided fs.FS with -// the embedded FS containing Grafana's core CUE files, [grafana.CueSchemaFS]. -// The provided prefix should be the relative path from the grafana repository -// root to the directory root of the provided inputfs. -// -// The returned fs.FS is suitable for passing to a CUE loader, such as [load.InstanceWithThema]. -func prefixWithGrafanaCUE(prefix string, inputfs fs.FS) (fs.FS, error) { - m, err := prefixFS(prefix, inputfs) - if err != nil { - return nil, err - } - return merged_fs.NewMergedFS(m, grafana.CueSchemaFS), nil -} - -// TODO such a waste, replace with stateless impl that just transforms paths on the fly -func prefixFS(prefix string, fsys fs.FS) (fs.FS, error) { - m := make(fstest.MapFS) - - prefix = filepath.FromSlash(prefix) - err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error { - if err != nil { - return err - } - - if d.IsDir() { - return nil - } - - b, err := fs.ReadFile(fsys, filepath.ToSlash(path)) - if err != nil { - return err - } - // fstest can recognize only forward slashes. - m[filepath.ToSlash(filepath.Join(prefix, path))] = &fstest.MapFile{Data: b} - return nil - }) - return m, err -} - -// LoadGrafanaInstance wraps [load.InstanceWithThema] to load a -// [*build.Instance] corresponding to a particular path within the -// github.com/grafana/grafana CUE module. -// -// This allows resolution of imports within the grafana or thema CUE modules to -// work correctly and consistently by relying on the embedded FS at -// [grafana.CueSchemaFS] and [thema.CueFS]. -// -// relpath should be a relative path path within [grafana.CueSchemaFS] to be -// loaded. Optionally, the caller may provide an additional fs.FS via the -// overlay parameter, which will be merged with [grafana.CueSchemaFS] at -// relpath, and loaded. -// -// pkg, if non-empty, is set as the value of -// ["cuelang.org/go/cue/load".Config.Package]. If the CUE package to be loaded -// is the same as the parent directory name, it should be omitted. -// -// NOTE this function will be deprecated in favor of a more generic loader -func LoadGrafanaInstance(relpath string, pkg string, overlay fs.FS) (*build.Instance, error) { - // notes about how this crap needs to work - // - // Within grafana/grafana, need: - // - pass in an fs.FS that, in its root, contains the .cue files to load - // - has no cue.mod - // - gets prefixed with the appropriate path within grafana/grafana - // - and merged with all the other .cue files from grafana/grafana - // notes about how this crap needs to work - // - // Need a prefixing instance loader that: - // - can take multiple fs.FS, each one representing a CUE module (nesting?) - // - reconcile at most one of the provided fs with cwd - // - behavior must differ depending on whether cwd is in a cue module - // - behavior should(?) be controllable depending on - relpath = filepath.ToSlash(relpath) - - var f fs.FS = grafana.CueSchemaFS - var err error - if overlay != nil { - f, err = prefixWithGrafanaCUE(relpath, overlay) - if err != nil { - return nil, err - } - } - - if pkg != "" { - return load.InstanceWithThema(f, relpath, load.Package(pkg)) - } - return load.InstanceWithThema(f, relpath) -} - -// BuildGrafanaInstance wraps [LoadGrafanaInstance], additionally building -// the returned [*build.Instance] into a [cue.Value]. -// -// An error is returned if: -// - The underlying call to [LoadGrafanaInstance] returns an error -// - The built [cue.Value] has an error ([cue.Value.Err] returns non-nil) -// -// NOTE this function will be deprecated in favor of a more generic builder -func BuildGrafanaInstance(ctx *cue.Context, relpath string, pkg string, overlay fs.FS) (cue.Value, error) { - bi, err := LoadGrafanaInstance(relpath, pkg, overlay) - if err != nil { - return cue.Value{}, err - } - - if ctx == nil { - ctx = GrafanaCUEContext() - } - v := ctx.BuildInstance(bi) - if v.Err() != nil { - return v, fmt.Errorf("%s not a valid CUE instance: %w", relpath, v.Err()) - } - return v, nil -} - -// LoadInstanceWithGrafana loads a [*build.Instance] from .cue files -// in the provided modFS as ["cuelang.org/go/cue/load".Instances], but -// fulfilling any imports of CUE packages under: -// -// - github.com/grafana/grafana -// - github.com/grafana/thema -// -// This function is modeled after [load.InstanceWithThema]. It has the same -// signature and expectations for the modFS. -// -// Attempting to use this func to load files within the -// github.com/grafana/grafana CUE module will result in an error. Use -// [LoadGrafanaInstance] instead. -// -// NOTE This function will be deprecated in favor of a more generic loader -func LoadInstanceWithGrafana(fsys fs.FS, dir string, opts ...load.Option) (*build.Instance, error) { - if modf, err := fs.ReadFile(fsys, "cue.mod/module.cue"); err != nil { - // delegate error handling - return load.InstanceWithThema(fsys, dir, opts...) - } else if modname, err := cuecontext.New().CompileBytes(modf).LookupPath(cue.MakePath(cue.Str("module"))).String(); err != nil { - // delegate error handling - return load.InstanceWithThema(fsys, dir, opts...) - } else if modname == "github.com/grafana/grafana" { - return nil, fmt.Errorf("use cuectx.LoadGrafanaInstance to load .cue files within github.com/grafana/grafana CUE module") - } - - // TODO wasteful, doing this every time - make that stateless prefixfs! - depFS, err := prefixFS("cue.mod/pkg/github.com/grafana/grafana", grafana.CueSchemaFS) - if err != nil { - panic(err) - } - - // FIXME remove grafana from cue.mod/pkg if it exists, otherwise external thing can inject files to be loaded - return load.InstanceWithThema(merged_fs.NewMergedFS(depFS, fsys), dir, opts...) -} diff --git a/pkg/cuectx/load.go b/pkg/cuectx/load.go new file mode 100644 index 00000000000..730cea4b355 --- /dev/null +++ b/pkg/cuectx/load.go @@ -0,0 +1,236 @@ +package cuectx + +import ( + "fmt" + "io/fs" + "path/filepath" + "testing/fstest" + + "cuelang.org/go/cue" + "cuelang.org/go/cue/build" + "cuelang.org/go/cue/cuecontext" + "github.com/grafana/kindsys" + "github.com/grafana/thema" + "github.com/grafana/thema/load" + "github.com/yalue/merged_fs" + + "github.com/grafana/grafana" +) + +// LoadGrafanaInstancesWithThema loads CUE files containing a lineage +// representing some Grafana core model schema. It is expected to be used when +// implementing a thema.LineageFactory. +// +// This function primarily juggles paths to make CUE's loader happy. Provide the +// path from the grafana root to the directory containing the lineage.cue. The +// lineage.cue file must be the sole contents of the provided fs.FS. +// +// More details on underlying behavior can be found in the docs for github.com/grafana/thema/load.InstanceWithThema. +// +// TODO this approach is complicated and confusing, refactor to something understandable +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 { + return nil, err + } + inst, err := load.InstanceWithThema(fs, prefix) + + // Need to trick loading by creating the embedded file and + // making it look like a module in the root dir. + if err != nil { + return nil, err + } + + val := rt.Context().BuildInstance(inst) + + lin, err := thema.BindLineage(val, rt, opts...) + if err != nil { + return nil, err + } + + return lin, nil +} + +// prefixWithGrafanaCUE constructs an fs.FS that merges the provided fs.FS with +// the embedded FS containing Grafana's core CUE files, [grafana.CueSchemaFS]. +// The provided prefix should be the relative path from the grafana repository +// root to the directory root of the provided inputfs. +// +// The returned fs.FS is suitable for passing to a CUE loader, such as [load.InstanceWithThema]. +func prefixWithGrafanaCUE(prefix string, inputfs fs.FS) (fs.FS, error) { + m, err := prefixFS(prefix, inputfs) + if err != nil { + return nil, err + } + return merged_fs.NewMergedFS(m, grafana.CueSchemaFS), nil +} + +// TODO such a waste, replace with stateless impl that just transforms paths on the fly +func prefixFS(prefix string, fsys fs.FS) (fs.FS, error) { + m := make(fstest.MapFS) + + prefix = filepath.FromSlash(prefix) + err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + + if d.IsDir() { + return nil + } + + b, err := fs.ReadFile(fsys, filepath.ToSlash(path)) + if err != nil { + return err + } + // fstest can recognize only forward slashes. + m[filepath.ToSlash(filepath.Join(prefix, path))] = &fstest.MapFile{Data: b} + return nil + }) + return m, err +} + +// LoadGrafanaInstance wraps [load.InstanceWithThema] to load a +// [*build.Instance] corresponding to a particular path within the +// github.com/grafana/grafana CUE module. +// +// This allows resolution of imports within the grafana or thema CUE modules to +// work correctly and consistently by relying on the embedded FS at +// [grafana.CueSchemaFS] and [thema.CueFS]. +// +// relpath should be a relative path path within [grafana.CueSchemaFS] to be +// loaded. Optionally, the caller may provide an additional fs.FS via the +// overlay parameter, which will be merged with [grafana.CueSchemaFS] at +// relpath, and loaded. +// +// pkg, if non-empty, is set as the value of +// ["cuelang.org/go/cue/load".Config.Package]. If the CUE package to be loaded +// is the same as the parent directory name, it should be omitted. +// +// NOTE this function will be deprecated in favor of a more generic loader +func LoadGrafanaInstance(relpath string, pkg string, overlay fs.FS) (*build.Instance, error) { + // notes about how this crap needs to work + // + // Within grafana/grafana, need: + // - pass in an fs.FS that, in its root, contains the .cue files to load + // - has no cue.mod + // - gets prefixed with the appropriate path within grafana/grafana + // - and merged with all the other .cue files from grafana/grafana + // notes about how this crap needs to work + // + // Need a prefixing instance loader that: + // - can take multiple fs.FS, each one representing a CUE module (nesting?) + // - reconcile at most one of the provided fs with cwd + // - behavior must differ depending on whether cwd is in a cue module + // - behavior should(?) be controllable depending on + relpath = filepath.ToSlash(relpath) + + var f fs.FS = grafana.CueSchemaFS + // merge the kindsys filesystem with ours for the kind categories + f = merged_fs.NewMergedFS(kindsys.CueSchemaFS, f) + + var err error + if overlay != nil { + f, err = prefixWithGrafanaCUE(relpath, overlay) + if err != nil { + return nil, err + } + } + + if pkg != "" { + return load.InstanceWithThema(f, relpath, load.Package(pkg)) + } + return load.InstanceWithThema(f, relpath) +} + +// BuildGrafanaInstance wraps [LoadGrafanaInstance], additionally building +// the returned [*build.Instance] into a [cue.Value]. +// +// An error is returned if: +// - The underlying call to [LoadGrafanaInstance] returns an error +// - The built [cue.Value] has an error ([cue.Value.Err] returns non-nil) +// +// NOTE this function will be deprecated in favor of a more generic builder +func BuildGrafanaInstance(ctx *cue.Context, relpath string, pkg string, overlay fs.FS) (cue.Value, error) { + bi, err := LoadGrafanaInstance(relpath, pkg, overlay) + if err != nil { + return cue.Value{}, err + } + + if ctx == nil { + ctx = GrafanaCUEContext() + } + v := ctx.BuildInstance(bi) + if v.Err() != nil { + return v, fmt.Errorf("%s not a valid CUE instance: %w", relpath, v.Err()) + } + return v, nil +} + +// LoadInstanceWithGrafana loads a [*build.Instance] from .cue files +// in the provided modFS as ["cuelang.org/go/cue/load".Instances], but +// fulfilling any imports of CUE packages under: +// +// - github.com/grafana/grafana +// - github.com/grafana/thema +// +// This function is modeled after [load.InstanceWithThema]. It has the same +// signature and expectations for the modFS. +// +// Attempting to use this func to load files within the +// github.com/grafana/grafana CUE module will result in an error. Use +// [LoadGrafanaInstance] instead. +// +// NOTE This function will be deprecated in favor of a more generic loader +func LoadInstanceWithGrafana(fsys fs.FS, dir string, opts ...load.Option) (*build.Instance, error) { + if modf, err := fs.ReadFile(fsys, "cue.mod/module.cue"); err != nil { + // delegate error handling + return load.InstanceWithThema(fsys, dir, opts...) + } else if modname, err := cuecontext.New().CompileBytes(modf).LookupPath(cue.MakePath(cue.Str("module"))).String(); err != nil { + // delegate error handling + return load.InstanceWithThema(fsys, dir, opts...) + } else if modname == "github.com/grafana/grafana" { + return nil, fmt.Errorf("use cuectx.LoadGrafanaInstance to load .cue files within github.com/grafana/grafana CUE module") + } + + // TODO wasteful, doing this every time - make that stateless prefixfs! + depFS, err := prefixFS("cue.mod/pkg/github.com/grafana/grafana", grafana.CueSchemaFS) + if err != nil { + panic(err) + } + // TODO wasteful, doing this every time - make that stateless prefixfs! + kindsysFS, err := prefixFS("cue.mod/pkg/github.com/grafana/kindsys", kindsys.CueSchemaFS) + if err != nil { + panic(err) + } + + allTheFs := merged_fs.MergeMultiple(kindsysFS, depFS, fsys) + + // FIXME remove grafana from cue.mod/pkg if it exists, otherwise external thing can inject files to be loaded + return load.InstanceWithThema(allTheFs, dir, opts...) +} + +// 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. +// +// defpath is the path to the directory containing the core kind definition, +// relative to the root of the caller's repository. For example, under +// dashboards are in "kinds/dashboard". +func LoadCoreKindDef(defpath string, ctx *cue.Context, overlay fs.FS) (kindsys.Def[kindsys.CoreProperties], error) { + vk, err := BuildGrafanaInstance(ctx, defpath, "kind", overlay) + if err != nil { + return kindsys.Def[kindsys.CoreProperties]{}, err + } + + props, err := kindsys.ToKindProps[kindsys.CoreProperties](vk) + if err != nil { + return kindsys.Def[kindsys.CoreProperties]{}, err + } + + return kindsys.Def[kindsys.CoreProperties]{ + V: vk, + Properties: props, + }, nil +} diff --git a/pkg/kinds/dashboard/crd/dashboard_crd_gen.go b/pkg/kinds/dashboard/crd/dashboard_crd_gen.go index d8d1970b22b..a9a5af9730d 100644 --- a/pkg/kinds/dashboard/crd/dashboard_crd_gen.go +++ b/pkg/kinds/dashboard/crd/dashboard_crd_gen.go @@ -13,7 +13,7 @@ import ( _ "embed" "github.com/grafana/grafana/pkg/kinds/dashboard" - "github.com/grafana/grafana/pkg/kindsys/k8ssys" + "github.com/grafana/kindsys/k8ssys" ) // The CRD YAML representation of the Dashboard kind. diff --git a/pkg/kinds/dashboard/dashboard_kind_gen.go b/pkg/kinds/dashboard/dashboard_kind_gen.go index 8d0f215f4d9..65b94008504 100644 --- a/pkg/kinds/dashboard/dashboard_kind_gen.go +++ b/pkg/kinds/dashboard/dashboard_kind_gen.go @@ -10,9 +10,11 @@ package dashboard import ( - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" "github.com/grafana/thema" "github.com/grafana/thema/vmux" + + "github.com/grafana/grafana/pkg/cuectx" ) // rootrel is the relative path from the grafana repository root to the @@ -34,7 +36,7 @@ var _ kindsys.Core = &Kind{} // TODO standard generated docs func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { - def, err := kindsys.LoadCoreKindDef(rootrel, rt.Context(), nil) + def, err := cuectx.LoadCoreKindDef(rootrel, rt.Context(), nil) if err != nil { return nil, err } diff --git a/pkg/kinds/librarypanel/crd/librarypanel_crd_gen.go b/pkg/kinds/librarypanel/crd/librarypanel_crd_gen.go index 1d6975a33d6..3f538a327bf 100644 --- a/pkg/kinds/librarypanel/crd/librarypanel_crd_gen.go +++ b/pkg/kinds/librarypanel/crd/librarypanel_crd_gen.go @@ -13,7 +13,7 @@ import ( _ "embed" "github.com/grafana/grafana/pkg/kinds/librarypanel" - "github.com/grafana/grafana/pkg/kindsys/k8ssys" + "github.com/grafana/kindsys/k8ssys" ) // The CRD YAML representation of the LibraryPanel kind. diff --git a/pkg/kinds/librarypanel/librarypanel_kind_gen.go b/pkg/kinds/librarypanel/librarypanel_kind_gen.go index ce2fdf9325d..4404be4dca9 100644 --- a/pkg/kinds/librarypanel/librarypanel_kind_gen.go +++ b/pkg/kinds/librarypanel/librarypanel_kind_gen.go @@ -10,9 +10,11 @@ package librarypanel import ( - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" "github.com/grafana/thema" "github.com/grafana/thema/vmux" + + "github.com/grafana/grafana/pkg/cuectx" ) // rootrel is the relative path from the grafana repository root to the @@ -34,7 +36,7 @@ var _ kindsys.Core = &Kind{} // TODO standard generated docs func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { - def, err := kindsys.LoadCoreKindDef(rootrel, rt.Context(), nil) + def, err := cuectx.LoadCoreKindDef(rootrel, rt.Context(), nil) if err != nil { return nil, err } diff --git a/pkg/kinds/playlist/crd/playlist_crd_gen.go b/pkg/kinds/playlist/crd/playlist_crd_gen.go index fc5c93217e4..b05148c5a5a 100644 --- a/pkg/kinds/playlist/crd/playlist_crd_gen.go +++ b/pkg/kinds/playlist/crd/playlist_crd_gen.go @@ -13,7 +13,7 @@ import ( _ "embed" "github.com/grafana/grafana/pkg/kinds/playlist" - "github.com/grafana/grafana/pkg/kindsys/k8ssys" + "github.com/grafana/kindsys/k8ssys" ) // The CRD YAML representation of the Playlist kind. diff --git a/pkg/kinds/playlist/playlist_kind_gen.go b/pkg/kinds/playlist/playlist_kind_gen.go index 39a2457b28b..7d4dac3a965 100644 --- a/pkg/kinds/playlist/playlist_kind_gen.go +++ b/pkg/kinds/playlist/playlist_kind_gen.go @@ -10,9 +10,11 @@ package playlist import ( - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" "github.com/grafana/thema" "github.com/grafana/thema/vmux" + + "github.com/grafana/grafana/pkg/cuectx" ) // rootrel is the relative path from the grafana repository root to the @@ -34,7 +36,7 @@ var _ kindsys.Core = &Kind{} // TODO standard generated docs func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { - def, err := kindsys.LoadCoreKindDef(rootrel, rt.Context(), nil) + def, err := cuectx.LoadCoreKindDef(rootrel, rt.Context(), nil) if err != nil { return nil, err } diff --git a/pkg/kinds/preferences/crd/preferences_crd_gen.go b/pkg/kinds/preferences/crd/preferences_crd_gen.go index d2debdab9dd..7ccaa2380a7 100644 --- a/pkg/kinds/preferences/crd/preferences_crd_gen.go +++ b/pkg/kinds/preferences/crd/preferences_crd_gen.go @@ -13,7 +13,7 @@ import ( _ "embed" "github.com/grafana/grafana/pkg/kinds/preferences" - "github.com/grafana/grafana/pkg/kindsys/k8ssys" + "github.com/grafana/kindsys/k8ssys" ) // The CRD YAML representation of the Preferences kind. diff --git a/pkg/kinds/preferences/preferences_kind_gen.go b/pkg/kinds/preferences/preferences_kind_gen.go index fbb855fef2f..0141c1c2ae6 100644 --- a/pkg/kinds/preferences/preferences_kind_gen.go +++ b/pkg/kinds/preferences/preferences_kind_gen.go @@ -10,9 +10,11 @@ package preferences import ( - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" "github.com/grafana/thema" "github.com/grafana/thema/vmux" + + "github.com/grafana/grafana/pkg/cuectx" ) // rootrel is the relative path from the grafana repository root to the @@ -34,7 +36,7 @@ var _ kindsys.Core = &Kind{} // TODO standard generated docs func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { - def, err := kindsys.LoadCoreKindDef(rootrel, rt.Context(), nil) + def, err := cuectx.LoadCoreKindDef(rootrel, rt.Context(), nil) if err != nil { return nil, err } diff --git a/pkg/kinds/publicdashboard/crd/publicdashboard_crd_gen.go b/pkg/kinds/publicdashboard/crd/publicdashboard_crd_gen.go index b0fcbd89a33..c59e2fc1f5b 100644 --- a/pkg/kinds/publicdashboard/crd/publicdashboard_crd_gen.go +++ b/pkg/kinds/publicdashboard/crd/publicdashboard_crd_gen.go @@ -13,7 +13,7 @@ import ( _ "embed" "github.com/grafana/grafana/pkg/kinds/publicdashboard" - "github.com/grafana/grafana/pkg/kindsys/k8ssys" + "github.com/grafana/kindsys/k8ssys" ) // The CRD YAML representation of the PublicDashboard kind. diff --git a/pkg/kinds/publicdashboard/publicdashboard_kind_gen.go b/pkg/kinds/publicdashboard/publicdashboard_kind_gen.go index 40ed6542fdc..c2057b04dcd 100644 --- a/pkg/kinds/publicdashboard/publicdashboard_kind_gen.go +++ b/pkg/kinds/publicdashboard/publicdashboard_kind_gen.go @@ -10,9 +10,11 @@ package publicdashboard import ( - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" "github.com/grafana/thema" "github.com/grafana/thema/vmux" + + "github.com/grafana/grafana/pkg/cuectx" ) // rootrel is the relative path from the grafana repository root to the @@ -34,7 +36,7 @@ var _ kindsys.Core = &Kind{} // TODO standard generated docs func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { - def, err := kindsys.LoadCoreKindDef(rootrel, rt.Context(), nil) + def, err := cuectx.LoadCoreKindDef(rootrel, rt.Context(), nil) if err != nil { return nil, err } diff --git a/pkg/kinds/serviceaccount/crd/serviceaccount_crd_gen.go b/pkg/kinds/serviceaccount/crd/serviceaccount_crd_gen.go index f9ef3ae491c..33f3564a798 100644 --- a/pkg/kinds/serviceaccount/crd/serviceaccount_crd_gen.go +++ b/pkg/kinds/serviceaccount/crd/serviceaccount_crd_gen.go @@ -13,7 +13,7 @@ import ( _ "embed" "github.com/grafana/grafana/pkg/kinds/serviceaccount" - "github.com/grafana/grafana/pkg/kindsys/k8ssys" + "github.com/grafana/kindsys/k8ssys" ) // The CRD YAML representation of the ServiceAccount kind. diff --git a/pkg/kinds/serviceaccount/serviceaccount_kind_gen.go b/pkg/kinds/serviceaccount/serviceaccount_kind_gen.go index 391b7455dfa..99aca391fde 100644 --- a/pkg/kinds/serviceaccount/serviceaccount_kind_gen.go +++ b/pkg/kinds/serviceaccount/serviceaccount_kind_gen.go @@ -10,9 +10,11 @@ package serviceaccount import ( - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" "github.com/grafana/thema" "github.com/grafana/thema/vmux" + + "github.com/grafana/grafana/pkg/cuectx" ) // rootrel is the relative path from the grafana repository root to the @@ -34,7 +36,7 @@ var _ kindsys.Core = &Kind{} // TODO standard generated docs func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { - def, err := kindsys.LoadCoreKindDef(rootrel, rt.Context(), nil) + def, err := cuectx.LoadCoreKindDef(rootrel, rt.Context(), nil) if err != nil { return nil, err } diff --git a/pkg/kinds/team/crd/team_crd_gen.go b/pkg/kinds/team/crd/team_crd_gen.go index 807a87ddba8..a4f41c8d6ce 100644 --- a/pkg/kinds/team/crd/team_crd_gen.go +++ b/pkg/kinds/team/crd/team_crd_gen.go @@ -13,7 +13,7 @@ import ( _ "embed" "github.com/grafana/grafana/pkg/kinds/team" - "github.com/grafana/grafana/pkg/kindsys/k8ssys" + "github.com/grafana/kindsys/k8ssys" ) // The CRD YAML representation of the Team kind. diff --git a/pkg/kinds/team/team_kind_gen.go b/pkg/kinds/team/team_kind_gen.go index df531e7753a..6354997eaf6 100644 --- a/pkg/kinds/team/team_kind_gen.go +++ b/pkg/kinds/team/team_kind_gen.go @@ -10,9 +10,11 @@ package team import ( - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" "github.com/grafana/thema" "github.com/grafana/thema/vmux" + + "github.com/grafana/grafana/pkg/cuectx" ) // rootrel is the relative path from the grafana repository root to the @@ -34,7 +36,7 @@ var _ kindsys.Core = &Kind{} // TODO standard generated docs func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { - def, err := kindsys.LoadCoreKindDef(rootrel, rt.Context(), nil) + def, err := cuectx.LoadCoreKindDef(rootrel, rt.Context(), nil) if err != nil { return nil, err } diff --git a/pkg/kindsys/EXTENDING.md b/pkg/kindsys/EXTENDING.md deleted file mode 100644 index 6e534376699..00000000000 --- a/pkg/kindsys/EXTENDING.md +++ /dev/null @@ -1,59 +0,0 @@ -# Kind System - -This package contains Grafana's kind system, which defines the rules that govern all Grafana kind definitions, including both core and plugin kinds. It contains many contracts on which public promises of backwards compatibility are made. All changes must be considered with care. - -While this package is maintained by @grafana/grafana-as-code, contributions from others are a main goal! Any time you have the thought, "I wish this part of Grafana's codebase was consistent," rather than writing docs (that people will inevitably miss), it's worth seeing if you can express that consistency as a kindsys extension instead. - -This document is the guide to extending kindsys. But first, we have to identify kindsys's key components. - -## Elements of kindsys - -* **CUE framework** - the collection of .cue files in this directory, `pkg/kindsys`. These are schemas that define how Kinds are defined. -* **Go framework** - the Go package in this directory containing utilities for loading individual kind definitions, validating them against the CUE framework, and representing them consistently in Go. -* **Code generators** - written using the `github.com/grafana/codejen` framework, which applies the [single responsibility principle](https://en.wikipedia.org/wiki/Single-responsibility_principle) to code generation, allowing us to compose modular code generators. Each jenny - a modular generator with a single responsibility - is written as a `pkg/codegen/jenny_*.go` file. -* **Registries** - generated lists of all or a well-defined subset of kinds that can be used in code. `pkg/registries/corekind` is a registry of all core `pkg/kindsys.Interface` implementations; `packages/grafana-schema/src/index.gen.ts` is a registry of all the TypeScript types generated from the current versions of each kind's schema. -* **Kind definitions** - the definitions of individual kinds. By kind category: - * **Core** - each child directory of `kinds`. - * **Composable** - In Grafana core, `public/app/plugins/*/*/models.cue` files. - * **Custom** - No examples in Grafana core. See [operator-app-sdk](https://github.com/grafana/operator-app-sdk) (TODO that repo is private; make it public, or point to public examples). - -The above are treated as similarly to stateless libraries - a layer beneath the main Grafana frontend and backend without dependencies on it (no storage, no API, no wire, etc.). This lack of dependencies, and their Apache v2 licensing, allow their use as libraries for external tools. - -## Extending kindsys - -Extending the kind system generally involves: - -* Introducing one or more new fields into the CUE framework -* Updating the Go framework to accommodate the new fields -* Updating the kind authoring and maturity planning docs to reflect the new extension -* (possibly) Writing one or more new code generators -* (possibly) Writing/refactoring some frontend code that depends on new codegen output -* (possibly) Writing/refactoring some backend code that depends on codegen output and/or the Go kind framework -* (possibly) Tweaking all existing kinds as-needed to accommodate the new extension - -_TODO detailed guide to the above steps_ - -The above steps certainly aren't trivial. But they all come only after figuring out a way to solve the problem you want to solve in terms of the kind system and code generation in the first place. - -_TODO brief guide on how to think in codegen_ - -## Extensions not involving kind metadata - -While the main path for extending kindsys is through adding metadata, there are some other ways of extending kindsys. - -### CUE attributes - -[CUE attributes](https://cuelang.org/docs/references/spec/#attributes) provide additional information to kind tooling. They are suitable when it is necessary for a schema author to express additional information about a particular field or definition within a schema, without actually modifying the meaning of the schema. Two such known patterns are: - -* Controlling nuanced behavior of code generators for some field or type. Example: [@cuetsy](https://github.com/grafana/cuetsy#usage) attributes, which govern TS output -* Expressing some kind of structured TODO or WIP information on a field or type that can be easily analyzed and fed into other systems. Example: a kind marked at least `stable` maturity may not have any `@grafanamaturity` attributes - -In both of these cases, attributes are a tool _for the individual kind author_ to convey something to downstream consumers of kind definitions. It is essential. While attributes allow consistency in _how_ a particular task is accomplished, they leave _when_ to apply the rule up to the judgment of the kind author. - -Attributes occupy an awkward middle ground. They are more challenging to implement than standard kind framework properties, and less consistent than general codegen transformers while still imposing a cognitive burden on kind authors. They should be the last tool you reach for - but may be the only tool available when field-level schema metadata is required. - -TODO create a general pattern for self-contained attribute parser/validators to follow - -### Codegen transformers - -TODO actually write this - use `Uid`->`UID` as example diff --git a/pkg/kindsys/bind.go b/pkg/kindsys/bind.go deleted file mode 100644 index 302cedf3a94..00000000000 --- a/pkg/kindsys/bind.go +++ /dev/null @@ -1,96 +0,0 @@ -package kindsys - -import ( - "github.com/grafana/thema" -) - -// 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 -} - -func (k genericComposable) Name() string { - return k.def.Properties.Name -} - -func (k genericComposable) MachineName() string { - return k.def.Properties.MachineName -} - -func (k genericComposable) Maturity() Maturity { - return k.def.Properties.Maturity -} - -func (k genericComposable) Def() Def[ComposableProperties] { - return k.def -} - -func (k genericComposable) Lineage() thema.Lineage { - return k.lin -} - -// 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: 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/common_dataquery.cue b/pkg/kindsys/common_dataquery.cue deleted file mode 100644 index bb11488efc8..00000000000 --- a/pkg/kindsys/common_dataquery.cue +++ /dev/null @@ -1,38 +0,0 @@ -package kindsys - -// Canonically defined in pkg/kindsys/dataquery.cue FOR NOW to avoid having any external imports -// in kindsys. Code generation copies this file to the common schemas in packages/grafana-schema/src/common. -// -// NOTE make gen-cue must be run twice when updating this file - -// These are the common properties available to all queries in all datasources. -// Specific implementations will *extend* this interface, adding the required -// properties for the given context. -DataQuery: { - // A unique identifier for the query within the list of targets. - // In server side expressions, the refId is used as a variable name to identify results. - // By default, the UI will assign A->Z; however setting meaningful names may be useful. - refId: string - - // true if query is disabled (ie should not be returned to the dashboard) - // Note this does not always imply that the query should not be executed since - // the results from a hidden query may be used as the input to other queries (SSE etc) - hide?: bool - - // Specify the query flavor - // TODO make this required and give it a default - queryType?: string - - // For mixed data sources the selected datasource is on the query level. - // For non mixed scenarios this is undefined. - // TODO find a better way to do this ^ that's friendly to schema - // TODO this shouldn't be unknown but DataSourceRef | null - datasource?: _ -} @cuetsy(kind="interface") - -DataSourceRef: { - // The plugin type-id - type?: string - // Specific datasource instance - uid?: string -} @cuetsy(kind="interface") diff --git a/pkg/kindsys/errors.go b/pkg/kindsys/errors.go deleted file mode 100644 index aa6159235e8..00000000000 --- a/pkg/kindsys/errors.go +++ /dev/null @@ -1,18 +0,0 @@ -package kindsys - -import "errors" - -// TODO consider rewriting with https://github.com/cockroachdb/errors - -var ( - // ErrValueNotExist indicates that a necessary CUE value did not exist. - ErrValueNotExist = errors.New("cue value does not exist") - - // ErrValueNotAKind indicates that a provided CUE value is not any variety of - // Kind. This is almost always a user error - they oops'd and provided the - // wrong path, file, etc. - ErrValueNotAKind = errors.New("not a kind") - - // ErrInvalidCUE indicates that the CUE representing the kind is invalid. - ErrInvalidCUE = errors.New("CUE syntax error") -) diff --git a/pkg/kindsys/k8ssys/crd.go b/pkg/kindsys/k8ssys/crd.go deleted file mode 100644 index ffbe469d9c1..00000000000 --- a/pkg/kindsys/k8ssys/crd.go +++ /dev/null @@ -1,154 +0,0 @@ -package k8ssys - -import ( - "fmt" - "reflect" - - "github.com/grafana/grafana/pkg/kindsys" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - k8schema "k8s.io/apimachinery/pkg/runtime/schema" -) - -type Kind struct { - GrafanaKind kindsys.Kind - Object runtime.Object // singular type - ObjectList runtime.Object // list type - Schema apiextensionsv1.CustomResourceDefinition -} - -// TODO this could probably be done in CUE/framework -func (crd Kind) GVK() k8schema.GroupVersionKind { - // TODO custom structured - props := crd.GrafanaKind.Props().(kindsys.CoreProperties) - gvk := k8schema.GroupVersionKind{ - Group: fmt.Sprintf("%s.core.grafana.com", props.MachineName), - Kind: props.Name, - } - if props.Maturity.Less(kindsys.MaturityStable) { - gvk.Version = "v0-0alpha1" - } else { - gvk.Version = fmt.Sprintf("v%d-%d", props.CurrentVersion[0], props.CurrentVersion[1]) - } - - return gvk -} - -// CustomResourceDefinitionList is the kubernetes-API-compliant representation of a list of CustomResourceDefinitions -type CustomResourceDefinitionList struct { - ListBase[CustomResourceDefinition] -} - -// CustomResourceDefinition is the kubernetes-API-compliant representation of a Custom Resource Definition -type CustomResourceDefinition struct { - metav1.TypeMeta `json:",inline" yaml:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` - Spec CustomResourceDefinitionSpec `json:"spec"` -} - -// DeepCopyObject implements runtime.Object. -func (crd *CustomResourceDefinition) DeepCopyObject() runtime.Object { - return DeepCopyObject(crd) -} - -// CustomResourceDefinitionSpec is the body or spec of a kubernetes Custom Resource Definition -type CustomResourceDefinitionSpec struct { - Group string `json:"group" yaml:"group"` - Versions []CustomResourceDefinitionSpecVersion `json:"versions" yaml:"versions"` - Names CustomResourceDefinitionSpecNames `json:"names" yaml:"names"` - Scope string `json:"scope" yaml:"scope"` -} - -// CustomResourceDefinitionSpecVersion is the representation of a specific version of a CRD, as part of the overall spec -type CustomResourceDefinitionSpecVersion struct { - Name string `json:"name" yaml:"name"` - Served bool `json:"served" yaml:"served"` - Storage bool `json:"storage" yaml:"storage"` - Schema map[string]any `json:"schema" yaml:"schema"` - Subresources map[string]any `json:"subresources,omitempty" yaml:"subresources,omitempty"` -} - -// CustomResourceDefinitionSpecNames is the struct representing the names (kind and plural) of a kubernetes CRD -type CustomResourceDefinitionSpecNames struct { - Kind string `json:"kind" yaml:"kind"` - Plural string `json:"plural" yaml:"plural"` -} - -// Base is a struct which describes a basic CRD, and implements runtime.Object. -// SpecType should be the struct that represents the spec in the definition. -// It cannot be used on its own, as the name of the CRD in kubernetes must exactly match the name of struct. -// Instead, this struct can be used as a component of a new named struct, for examples: -// -// type MyCustomResource struct { -// crd.Base[MyCustomResourceSpec] -// } -type Base[SpecType any] struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - Spec SpecType `json:"spec"` -} - -// DeepCopyObject is implemented for Base so it will implement runtime.Object. -// DeepCopyObject here just calls crd.DeepCopyObject on itself. -func (b *Base[T]) DeepCopyObject() runtime.Object { - return DeepCopyObject(b) -} - -// ListBase is a struct which describes a list of CRDs, and implements runtime.Object. -// ItemType should be the CRD type being listed (NOT the model). -// It cannot be used on its own, as the struct name must exactly match `List`. -// Instead, this struct can be used as a component of a new named struct, for examples: -// -// type MyCustomResourceList struct { -// crd.Base[MyCustomResource] -// } -type ListBase[ItemType any] struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata"` - Items []ItemType `json:"items"` -} - -// DeepCopyObject is implemented for Base so it will implement runtime.Object. -// DeepCopyObject here just calls crd.DeepCopyObject on itself. -func (b *ListBase[T]) DeepCopyObject() runtime.Object { - return DeepCopyObject(b) -} - -// BaseStatus extends Base by including a Status subresource. -// This should be used if your kubernetes CRD includes the status subresource and you want to be able to view/modify it. -// Usage is identical to Base -type BaseStatus[SpecType, StatusType any] struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - Spec SpecType `json:"spec"` - Status StatusType `json:"status"` -} - -// DeepCopyObject is implemented for Base so it will implement runtime.Object. -// DeepCopyObject here just calls crd.DeepCopyObject on itself. -func (b *BaseStatus[T, S]) DeepCopyObject() runtime.Object { - return DeepCopyObject(b) -} - -// DeepCopyObject is an implementation of the receiver method required for implementing runtime.Object. -// It should be used in your own runtime.Object implementations if you do not wish to implement custom behavior. -// Example: -// -// func (c *CustomObject) DeepCopyObject() runtime.Object { -// return crd.DeepCopyObject(c) -// } -func DeepCopyObject(in any) runtime.Object { - val := reflect.ValueOf(in).Elem() - - cpy := reflect.New(val.Type()) - cpy.Elem().Set(val) - - // Using the , for the type conversion ensures that it doesn't panic if it can't be converted - if obj, ok := cpy.Interface().(runtime.Object); ok { - return obj - } - - // TODO: better return than nil? - return nil -} diff --git a/pkg/kindsys/kind.go b/pkg/kindsys/kind.go deleted file mode 100644 index 71479a2a021..00000000000 --- a/pkg/kindsys/kind.go +++ /dev/null @@ -1,92 +0,0 @@ -package kindsys - -import ( - "fmt" - - "github.com/grafana/thema" -) - -// TODO docs -type Maturity string - -const ( - MaturityMerged Maturity = "merged" - MaturityExperimental Maturity = "experimental" - MaturityStable Maturity = "stable" - MaturityMature Maturity = "mature" -) - -func maturityIdx(m Maturity) int { - // icky to do this globally, this is effectively setting a default - if string(m) == "" { - m = MaturityMerged - } - - for i, ms := range maturityOrder { - if m == ms { - return i - } - } - panic(fmt.Sprintf("unknown maturity milestone %s", m)) -} - -var maturityOrder = []Maturity{ - MaturityMerged, - MaturityExperimental, - MaturityStable, - MaturityMature, -} - -func (m Maturity) Less(om Maturity) bool { - return maturityIdx(m) < maturityIdx(om) -} - -func (m Maturity) String() string { - return string(m) -} - -// Kind describes a Grafana kind object: a Go representation of the definition of -// one of Grafana's categories of kinds. -type Kind interface { - // Props returns a [kindsys.SomeKindProps], representing the properties - // of the kind as declared in the .cue source. The underlying type is - // determined by the category of kind. - // - // This method is largely for convenience, as all actual kind categories are - // expected to implement one of the other interfaces, each of which contain - // a Def() method through which these same properties are accessible. - Props() SomeKindProperties - - // TODO docs - Lineage() thema.Lineage - - // TODO remove, unnecessary with Props() - Name() string - - // TODO remove, unnecessary with Props() - MachineName() string - - // TODO remove, unnecessary with Props() - Maturity() Maturity // TODO unclear if we want maturity for raw kinds -} - -type Core interface { - Kind - - // TODO docs - Def() Def[CoreProperties] -} - -type Custom interface { - Kind - - // TODO docs - Def() Def[CustomProperties] -} - -type Composable interface { - Kind - - // TODO docs - Def() Def[ComposableProperties] -} diff --git a/pkg/kindsys/kindcat_composable.cue b/pkg/kindsys/kindcat_composable.cue deleted file mode 100644 index bbd5b893076..00000000000 --- a/pkg/kindsys/kindcat_composable.cue +++ /dev/null @@ -1,31 +0,0 @@ -package kindsys - -// Composable is a category of kind that provides schema elements for -// composition into Core and Custom kinds. Grafana plugins -// provide composable kinds; for example, a datasource plugin provides one to -// describe the structure of its queries, which is then composed into dashboards -// and alerting rules. -// -// Each Composable is an implementation of exactly one Slot, a shared meta-schema -// defined by Grafana itself that constrains the shape of schemas defined in -// that ComposableKind. -Composable: S={ - _sharedKind - - // schemaInterface is the name of the Grafana schema interface implemented by - // this Composable kind. The set is open to ensure forward compatibility of - // Grafana and tooling with any additional schema interfaces that may be added. - schemaInterface: string - // TODO is it worth doing something like below, given that we have to keep this set open for forward compatibility? -// schemaInterface: or([ for k, _ in schemaInterfaces {k}, string]) - - let schif = schemaInterfaces[S.schemaInterface] - - // lineage is the Thema lineage containing all the schemas that have existed for this kind. - // The name of the lineage is constrained to the name of the schema interface being implemented. -// FIXME cuetsy currently gets confused by all the unifications - maybe openapi too. Do something like the following after thema separates joinSchema/constraint expression -// lineage: { joinSchema: schif.interface } -// lineage: { joinSchema: (schif.interface | *{}) } - - lineageIsGroup: schif.group -} diff --git a/pkg/kindsys/kindcat_custom.cue b/pkg/kindsys/kindcat_custom.cue deleted file mode 100644 index 9644df48bb1..00000000000 --- a/pkg/kindsys/kindcat_custom.cue +++ /dev/null @@ -1,15 +0,0 @@ -package kindsys - -// Custom specifies the kind category for plugin-defined arbitrary types. -// Custom kinds have the same purpose as Core kinds, differing only in -// that they are defined by external plugins rather than in Grafana core. As such, -// this specification is kept closely aligned with the Core kind. -// -// Grafana provides Kubernetes apiserver-shaped HTTP APIs for interacting with custom -// kinds - the same API patterns (and clients) used to interact with k8s CustomResources. -Custom: S={ - _sharedKind - - lineage: { name: S.machineName } - lineageIsGroup: false -} diff --git a/pkg/kindsys/kindcats.cue b/pkg/kindsys/kindcats.cue deleted file mode 100644 index 2eb4d2d1986..00000000000 --- a/pkg/kindsys/kindcats.cue +++ /dev/null @@ -1,127 +0,0 @@ -package kindsys - -import ( - "strings" - - "github.com/grafana/thema" -) - -// A Kind is a specification for a type of object that Grafana knows -// how to work with. Each kind definition contains a schema, and some -// declarative metadata and constraints. -// -// An instance of a kind is called a resource. Resources are a sequence of -// bytes - for example, a JSON file or HTTP request body - that conforms -// to the schemas and other constraints defined in a Kind. -// -// Once Grafana has determined a given byte sequence to be an -// instance of a known Kind, kind-specific behaviors can be applied, -// requests can be routed, events can be triggered, etc. -// -// Grafana's kinds are similar to Kubernetes CustomResourceDefinitions. -// Grafana provides a standard mechanism for representing its kinds as CRDs. -// -// There are three categories of kinds: Core, Custom, and Composable. -Kind: Composable | Core | Custom - -// properties shared between all kind categories. -_sharedKind: { - // name is the canonical name of a Kind, as expressed in PascalCase. - // - // To ensure names are generally portable and amenable for consumption - // in various mechanical tasks, name largely follows the relatively - // strict DNS label naming standard as defined in RFC 1123: - // - Contain at most 63 characters - // - Contain only lowercase alphanumeric characters or '-' - // - Start with an uppercase alphabetic character - // - End with an alphanumeric character - name: =~"^([A-Z][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])$" - - // machineName is the case-normalized (lowercase) version of [name]. This - // version of the name is preferred for use in most mechanical contexts, - // as case normalization ensures that case-insensitive and case-sensitive - // checks will never disagree on uniqueness. - // - // In addition to lowercase normalization, dashes are transformed to underscores. - machineName: strings.ToLower(strings.Replace(name, "-", "_", -1)) - - // pluralName is the pluralized form of name. Defaults to name + "s". - pluralName: =~"^([A-Z][a-zA-Z0-9-]{0,61}[a-zA-Z])$" | *(name + "s") - - // pluralMachineName is the pluralized form of [machineName]. The same case - // normalization and dash transformation is applied to [pluralName] as [machineName] - // applies to [name]. - pluralMachineName: strings.ToLower(strings.Replace(pluralName, "-", "_", -1)) - - // lineageIsGroup indicates whether the lineage in this kind is "grouped". In a - // grouped lineage, each top-level field in the schema specifies a discrete - // object that is expected to exist in the wild - // - // This value of this field is set by the kindsys framework. It cannot be changed - // in the definition of any individual kind. - // - // This is likely to eventually become a first-class property in Thema: - // https://github.com/grafana/thema/issues/62 - lineageIsGroup: bool - - // lineage is the Thema lineage containing all the schemas that have existed for this kind. - lineage: thema.#Lineage - - // currentVersion is computed to be the syntactic version number of the latest - // schema in lineage. - currentVersion: thema.#SyntacticVersion & (thema.#LatestVersion & {lin: lineage}).out - - maturity: Maturity - - // The kind system itself is not mature enough yet for any single - // kind to advance beyond "experimental" - // TODO allow more maturity stages once system is ready https://github.com/orgs/grafana/projects/133/views/8 - maturity: *"merged" | "experimental" -} - -// properties shared by all kinds that represent a complete object from root (i.e., not composable) -_rootKind: { - // description is a brief narrative description of the nature and purpose of the kind. - // The contents of this field is shown to end users. Prefer clear, concise wording - // with minimal jargon. - description: nonEmptyString -} - -// Maturity indicates the how far a given kind definition is in its initial -// journey. Mature kinds still evolve, but with guarantees about compatibility. -Maturity: "merged" | "experimental" | "stable" | "mature" - -// Core specifies the kind category for core-defined arbitrary types. -// Familiar types and functional resources in Grafana, such as dashboards and -// and datasources, are represented as core kinds. -Core: S=close({ - _sharedKind - _rootKind - - lineage: { name: S.machineName } - lineageIsGroup: false - - // crd contains properties specific to converting this kind to a Kubernetes CRD. - crd: { - // group is used as the CRD group name in the GVK. - group: "\(S.machineName).core.grafana.com" - - // scope determines whether resources of this kind exist globally ("Cluster") or - // within Kubernetes namespaces. - scope: "Cluster" | *"Namespaced" - - // dummySchema determines whether a dummy OpenAPI schema - where the schema is - // simply an empty, open object - should be generated for the kind. - // - // It is a goal that this option eventually be force dto false. Only set to - // true when Grafana's code generators produce OpenAPI that is rejected by - // Kubernetes' CRD validation. - dummySchema: bool | *false - - // deepCopy determines whether a generic implementation of copying should be - // generated, or a passthrough call to a Go function. - // deepCopy: *"generic" | "passthrough" - } -}) - -nonEmptyString: string & strings.MinRunes(1) diff --git a/pkg/kindsys/load.go b/pkg/kindsys/load.go deleted file mode 100644 index b82c3971c6d..00000000000 --- a/pkg/kindsys/load.go +++ /dev/null @@ -1,213 +0,0 @@ -package kindsys - -import ( - "fmt" - "io/fs" - "path/filepath" - "sync" - - "cuelang.org/go/cue" - "cuelang.org/go/cue/errors" - "github.com/grafana/grafana/pkg/cuectx" - "github.com/grafana/thema" -) - -// CoreDefParentPath is the path, relative to the repository root, where -// each child directory is expected to contain .cue files defining one -// Core kind. -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. -var GoCoreKindParentPath = filepath.Join("pkg", "kinds") - -// TSCoreKindParentPath is the path, relative to the repository root, to the directory that -// contains one directory per kind, full of generated TS kind output: types and default consts. -var TSCoreKindParentPath = filepath.Join("packages", "grafana-schema", "src", "raw") - -var defaultFramework cue.Value -var fwOnce sync.Once - -func init() { - loadpFrameworkOnce() -} - -func loadpFrameworkOnce() { - fwOnce.Do(func() { - var err error - defaultFramework, err = doLoadFrameworkCUE(cuectx.GrafanaCUEContext()) - if err != nil { - panic(err) - } - }) -} - -func doLoadFrameworkCUE(ctx *cue.Context) (cue.Value, error) { - v, err := cuectx.BuildGrafanaInstance(ctx, filepath.Join("pkg", "kindsys"), "kindsys", nil) - if err != nil { - return v, err - } - - if err = v.Validate(cue.Concrete(false), cue.All()); err != nil { - return cue.Value{}, fmt.Errorf("kindsys framework loaded cue.Value has err: %w", err) - } - - return v, nil -} - -// CUEFramework returns a cue.Value representing all the kind framework -// raw CUE files. -// -// For low-level use in constructing other types and APIs, while still letting -// us define all the frameworky CUE bits in a single package. Other Go types -// make the constructs in the returned cue.Value easy to use. -// -// Calling this with a nil [cue.Context] (the singleton returned from -// [cuectx.GrafanaCUEContext] is used) will memoize certain CUE operations. -// Prefer passing nil unless a different cue.Context is specifically required. -func CUEFramework(ctx *cue.Context) cue.Value { - if ctx == nil || ctx == cuectx.GrafanaCUEContext() { - // Ensure framework is loaded, even if this func is called - // from an init() somewhere. - loadpFrameworkOnce() - return defaultFramework - } - // Error guaranteed to be nil here because erroring would have caused init() to panic - v, _ := doLoadFrameworkCUE(ctx) // nolint:errcheck - return v -} - -// ToKindProps takes a cue.Value expected to represent a kind of the category -// specified by the type parameter and populates the Go type from the cue.Value. -func ToKindProps[T KindProperties](v cue.Value) (T, error) { - props := new(T) - if !v.Exists() { - return *props, ErrValueNotExist - } - - fw := CUEFramework(v.Context()) - var kdef cue.Value - - anyprops := any(*props).(SomeKindProperties) - switch anyprops.(type) { - case CoreProperties: - kdef = fw.LookupPath(cue.MakePath(cue.Str("Core"))) - case CustomProperties: - kdef = fw.LookupPath(cue.MakePath(cue.Str("Custom"))) - case ComposableProperties: - kdef = fw.LookupPath(cue.MakePath(cue.Str("Composable"))) - default: - // unreachable so long as all the possibilities in KindProperties have switch branches - panic("unreachable") - } - - item := v.Unify(kdef) - if item.Err() != nil { - return *props, errors.Wrap(errors.Promote(ErrValueNotAKind, ""), item.Err()) - } - - if err := item.Decode(props); err != nil { - // Should only be reachable if CUE and Go framework types have diverged - panic(errors.Details(err, nil)) - } - - return *props, nil -} - -// SomeDef represents a single kind definition, having been loaded and -// validated by a func such as [LoadCoreKindDef]. -// -// The underlying type of the Properties field indicates the category of kind. -type SomeDef struct { - // V is the cue.Value containing the entire Kind definition. - V cue.Value - // Properties contains the kind's declarative non-schema properties. - Properties SomeKindProperties -} - -// BindKindLineage binds the lineage for the kind definition. -// -// For kinds with a corresponding Go type, it is left to the caller to associate -// that Go type with the lineage returned from this function by a call to -// [thema.BindType]. -func (def SomeDef) BindKindLineage(rt *thema.Runtime, opts ...thema.BindOption) (thema.Lineage, error) { - if rt == nil { - rt = cuectx.GrafanaThemaRuntime() - } - return thema.BindLineage(def.V.LookupPath(cue.MakePath(cue.Str("lineage"))), rt, opts...) -} - -// IsCore indicates whether the represented kind is a core kind. -func (def SomeDef) IsCore() bool { - _, is := def.Properties.(CoreProperties) - return is -} - -// IsCustom indicates whether the represented kind is a custom kind. -func (def SomeDef) IsCustom() bool { - _, is := def.Properties.(CustomProperties) - return is -} - -// IsComposable indicates whether the represented kind is a composable kind. -func (def SomeDef) IsComposable() bool { - _, is := def.Properties.(ComposableProperties) - return is -} - -// 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 - // Properties contains the kind's declarative non-schema properties. - Properties T -} - -// Some converts the typed Def to the equivalent typeless SomeDef. -func (def Def[T]) Some() SomeDef { - return SomeDef{ - V: def.V, - Properties: any(def.Properties).(SomeKindProperties), - } -} - -// 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. -// -// declpath is the path to the directory containing the core kind definition, -// relative to the grafana/grafana root. For example, dashboards are in -// "kinds/dashboard". -// -// The .cue file bytes containing the core kind definition will be retrieved -// from the central embedded FS, [grafana.CueSchemaFS]. If desired (e.g. for -// testing), an optional fs.FS may be provided via the overlay parameter, which -// will be merged over [grafana.CueSchemaFS]. But in typical circumstances, -// overlay can and should be nil. -// -// 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 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 { - return none, err - } - - props, err := ToKindProps[CoreProperties](vk) - if err != nil { - return none, err - } - - return Def[CoreProperties]{ - V: vk, - Properties: props, - }, nil -} diff --git a/pkg/kindsys/props.go b/pkg/kindsys/props.go deleted file mode 100644 index a314fcc46cf..00000000000 --- a/pkg/kindsys/props.go +++ /dev/null @@ -1,80 +0,0 @@ -package kindsys - -import "github.com/grafana/thema" - -// CommonProperties contains the metadata common to all categories of kinds. -type CommonProperties struct { - Name string `json:"name"` - PluralName string `json:"pluralName"` - MachineName string `json:"machineName"` - PluralMachineName string `json:"pluralMachineName"` - LineageIsGroup bool `json:"lineageIsGroup"` - Maturity Maturity `json:"maturity"` - Description string `json:"description,omitempty"` -} - -// CoreProperties represents the static properties in the definition of a -// Core kind that are representable with basic Go types. This -// excludes Thema schemas. -// -// When .cue file(s) containing a Core definition is loaded through the standard -// [LoadCoreKindDef], func, it is fully validated and populated according to all -// rules specified in CUE for Core kinds. -type CoreProperties struct { - CommonProperties - CurrentVersion thema.SyntacticVersion `json:"currentVersion"` - CRD struct { - Group string `json:"group"` - Scope string `json:"scope"` - DummySchema bool `json:"dummySchema"` - } `json:"crd"` -} - -func (m CoreProperties) _private() {} -func (m CoreProperties) Common() CommonProperties { - return m.CommonProperties -} - -// CustomProperties represents the static properties in the definition of a -// Custom kind that are representable with basic Go types. This -// excludes Thema schemas. -type CustomProperties struct { - CommonProperties - CurrentVersion thema.SyntacticVersion `json:"currentVersion"` -} - -func (m CustomProperties) _private() {} -func (m CustomProperties) Common() CommonProperties { - return m.CommonProperties -} - -// ComposableProperties represents the static properties in the definition of a -// Composable kind that are representable with basic Go types. This -// excludes Thema schemas. -type ComposableProperties struct { - CommonProperties - CurrentVersion thema.SyntacticVersion `json:"currentVersion"` - SchemaInterface string `json:"schemaInterface"` -} - -func (m ComposableProperties) _private() {} -func (m ComposableProperties) Common() CommonProperties { - return m.CommonProperties -} - -// SomeKindProperties is an interface type to abstract over the different kind -// property struct types: [CoreProperties], [CustomProperties], -// [ComposableProperties]. -// -// It is the traditional interface counterpart to the generic type constraint -// KindProperties. -type SomeKindProperties interface { - _private() - Common() CommonProperties -} - -// KindProperties is a type parameter that comprises the base possible set of -// kind metadata configurations. -type KindProperties interface { - CoreProperties | CustomProperties | ComposableProperties -} diff --git a/pkg/kindsys/schema_interface.cue b/pkg/kindsys/schema_interface.cue deleted file mode 100644 index a2811b7dfe7..00000000000 --- a/pkg/kindsys/schema_interface.cue +++ /dev/null @@ -1,147 +0,0 @@ -package kindsys - -// The schema interfaces defined in this file are meta-schemas. They are shared -// contracts between the producers (composable kinds, defined in Grafana -// plugins) and consumers (core and custom Grafana kinds) of composable schemas. -// -// This contract is similar to an interface in most programming languages: -// producer and consumer implementations depend only on the schema interface -// definition, rather than the details of any particular implementation. This -// allows producers and consumers to be loosely coupled, while keeping an -// explicit contract for composition of sub-schemas from producers into the -// consumer schemas that want to use them. -// -// Schema interfaces allow schema composition to be broken down into a series of -// simple "what," "which," and "how" questions: -// -// - "What" is the subschema to be composed? -// - "How" should subschema(s) be composed into another schema to produce a unified result schema? -// - "Which" subset of known composable subschemas ("whats") should be provided in composition ("how")? -// -// On the producer side, Grafana plugin authors may provide Thema lineages -// within Composable kinds declared in .cue files adjacent to their -// plugin.json, following a pattern (see -// github.com/grafana/grafana/pkg/plugins/pfs.GrafanaPlugin.composableKinds) -// corresponding to the name of the schema interface. Each such definition is -// an answer to "what." -// -// On the consumer side, any core or custom kind author can choose to define a -// standard Thema composition slot in its contained lineage that uses one of -// these schema interfaces as its meta-schema. The slot specification in Thema -// answers "how", for that kind. -// -// Composable kinds declared by a plugin are parsed and validated by Grafana's -// plugin system when a plugin is installed. This gives each Grafana instance a -// set of all known Composable kinds ("whats"), which can be narrowed into the -// subsets ("which") that each known Core or Custom can consume. These subsets -// are injected dynamically into the consumers, resulting in the final schema. -// -// For example, in the Thema lineage for the dashboard core kind: -// - There is a slot named `panelcfg` -// - It is constrained to accept only Thema lineages following the `panelcfg` schema interface -// - The composition logic specifies that the `panelcfg.PanelOptions` from each lineage provided -// to the dashboard lineage be one possibility for `panels[].options` -// -// (TODO actual implementation is pending https://github.com/grafana/thema/issue/8) -// -// Thus, the dashboard schema used for validation by any particular Grafana instance -// can tell the user if a particular dashboard with a `timeseries` panel has invalid -// values for `panels[].options`, even though neither the dashboard core kind, nor the -// the timeseries composable kind, are directly aware of (import) each other. - -// A SchemaInterface defines a single Grafana schema interface. -SchemaInterface: { - // name is the unique identifier of the schema interface. - // - // Often used to provide namespacing of schema interface implementations - // in places where implementations must be enumerated, such as: - // - In-memory indexes in the Grafana backend - // - Documentation URLs - // - Parent directory paths or names in generated code - name: string & =~"^[A-Z][A-Za-z]{1,19}$" - - // interface is the body of the SchemaInterface - the actual meta-schema that - // forms the shared contract between consumers (core & custom kind lineages) - // and producers (composable kind lineages). - interface: {} - - // pluginTypes is a list of plugin types that are expected to produce composable - // kinds following this interface. - // - // Note that Grafana's plugin architecture intentionally does not enforce this. - // The worst that a violation (impl expected and absent, or impl present and not expected) - // will currently produce is a warning. - // - // TODO this relies on information in pkg/plugins/plugindef, awkward having it here - pluginTypes: [...string] - - // Whether lineages implementing this are considered "grouped" or not. Generally - // this refers to whether an e.g. JSON object is ever expected to exist that - // corresponds to the whole schema, or to top-level fields within the schema. - // - // TODO see https://github.com/grafana/thema/issues/62 - // - // The main effect is whether code generation should produce one type that represents - // the root schema for lineages, or only produce types for each of the top-level fields - // within the schema. - group: bool | *true -} - -// alias the exported type because DataQuery is shadowed by the schema interface -// name where we need to use the type -let dq = DataQuery - -// The canonical list of all Grafana schema interfaces. -schemaInterfaces: [N=string]: SchemaInterface & { name: N } -schemaInterfaces: { - PanelCfg: { - interface: { - // Defines plugin-specific options for a panel that should be persisted. Required, - // though a panel without any options may specify an empty struct. - // - // Currently mapped to #Panel.options within the dashboard schema. - PanelOptions: {} - - // Plugin-specific custom field properties. Optional. - // - // Currently mapped to #Panel.fieldConfig.defaults.custom within the dashboard schema. - PanelFieldConfig?: {} - } - - pluginTypes: ["panel"] - - // grouped b/c separate non-cross-referring elements always occur together in larger structure (panel) - group: true - } - - // The DataQuery schema interface specifies how (datasource) plugins are expected to define - // the shape of their queries. - // - // It is expected that plugins may support multiple logically distinct query types within - // their single DataQuery composable kind. Implementations are generally free to model - // this as they please, with understanding that Grafana systems will look to the queryType - // field as a discriminator - each distinct value will be assumed, where possible, to - // identify a distinct type of query supported by the plugin. - DataQuery: { - interface: { - dq - } - - pluginTypes: ["datasource"] - group: false - } - - DataSourceCfg: { - interface: { - // Normal datasource configuration options. - Options: {} - // Sensitive datasource configuration options that require encryption. - SecureOptions: {} - } - - pluginTypes: ["datasource"] - - // group b/c separate, non-cross-referring elements have diff runtime representation due to encryption - group: true - } -} diff --git a/pkg/kindsys/schema_interface.go b/pkg/kindsys/schema_interface.go deleted file mode 100644 index f9093ec022e..00000000000 --- a/pkg/kindsys/schema_interface.go +++ /dev/null @@ -1,121 +0,0 @@ -package kindsys - -import ( - "fmt" - "sync" - - "cuelang.org/go/cue" - "github.com/grafana/grafana/pkg/cuectx" -) - -// SchemaInterface represents one of Grafana's named schema interfaces. -// -// Canonical definition of schema interfaces is done in CUE. Instances of -// this type simply represent that information in Go. -// TODO link to framework docs -type SchemaInterface struct { - name string - group bool - raw cue.Value - plugins []string -} - -// Name returns the name of the SchemaInterface. -// -// The name is also used as the path at which a SchemaInterface lineage is defined in a -// plugin models.cue file. -func (s SchemaInterface) Name() string { - return s.name -} - -// Contract returns the cue.Value representing the meta-schema that is the -// contract between core/custom kinds that consume schemas that are instances -// of the SchemaInterface contract, and composable kinds that produce such schemas. -func (s SchemaInterface) Contract() cue.Value { - return s.raw.LookupPath(ip) -} - -var ip = cue.ParsePath("interface") - -// Should indicates whether the given plugin type is expected (but not required) -// to produce a composable kind that implements this SchemaInterface. -func (s SchemaInterface) Should(plugintype string) bool { - pt := plugintype - for _, t := range s.plugins { - if pt == t { - return true - } - } - return false -} - -// 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 SchemaInterface) IsGroup() bool { - return s.group -} - -func FindSchemaInterface(name string) (SchemaInterface, error) { - sl, has := SchemaInterfaces(nil)[name] - if !has { - return SchemaInterface{}, fmt.Errorf("unsupported slot: %s", name) - } - return sl, nil -} - -var defaultIfaces map[string]SchemaInterface -var onceIfaces sync.Once - -// SchemaInterfaces returns a map of all [SchemaInterface]s defined by -// Grafana's kindsys framework. -// -// All calling code within grafana/grafana is expected to use Grafana's -// singleton [cue.Context], returned from [cuectx.GrafanaCUEContext]. If nil is -// passed, the singleton will be used. This is a reasonable default for external -// code, as well. -// -// TODO link to framework docs -func SchemaInterfaces(ctx *cue.Context) map[string]SchemaInterface { - if ctx == nil || ctx == cuectx.GrafanaCUEContext() { - // Ensure framework is loaded, even if this func is called - // from an init() somewhere. - onceIfaces.Do(func() { - defaultIfaces = doSchemaInterfaces(nil) - }) - return defaultIfaces - } - - return doSchemaInterfaces(ctx) -} - -func doSchemaInterfaces(ctx *cue.Context) map[string]SchemaInterface { - fw := CUEFramework(ctx) - - defs := fw.LookupPath(cue.ParsePath("schemaInterfaces")) - if !defs.Exists() { - panic("schemaInterfaces key does not exist in kindsys framework") - } - type typ struct { - Name string `json:"name"` - PluginTypes []string `json:"pluginTypes"` - Group bool `json:"group"` - } - - ifaces := make(map[string]SchemaInterface) - iter, _ := defs.Fields() //nolint:errcheck - for iter.Next() { - k := iter.Selector().String() - v := &typ{} - _ = iter.Value().Decode(&v) //nolint:errcheck,gosec - ifaces[k] = SchemaInterface{ - name: v.Name, - plugins: v.PluginTypes, - group: v.Group, - raw: iter.Value(), - } - } - - return ifaces -} diff --git a/pkg/kindsys/util.go b/pkg/kindsys/util.go deleted file mode 100644 index b7d03085e79..00000000000 --- a/pkg/kindsys/util.go +++ /dev/null @@ -1,24 +0,0 @@ -package kindsys - -// Ptr returns a pointer to a value of an arbitrary type. -// -// This function is provided to compensate for Grafana's Go code generation that -// represents optional fields using pointers. -// -// Pointers are the only technically [correct, non-ambiguous] way of -// representing an optional field in Go's type system. However, Go does not -// allow taking the address of certain primitive types inline. That is, -// this is invalid Go code: -// -// var str *string -// str = &"colorless green ideas sleep furiously" -// -// This func allows making such declarations in a single line: -// -// var str *string -// str = kindsys.Ptr("colorless green ideas sleep furiously") -// -// [correct, non-ambiguous]: https://github.com/grafana/grok/issues/1 -func Ptr[T any](v T) *T { - return &v -} diff --git a/pkg/kindsys/kindsysreport/attributes.go b/pkg/kindsysreport/attributes.go similarity index 100% rename from pkg/kindsys/kindsysreport/attributes.go rename to pkg/kindsysreport/attributes.go diff --git a/pkg/kindsys/report.go b/pkg/kindsysreport/codegen/report.go similarity index 98% rename from pkg/kindsys/report.go rename to pkg/kindsysreport/codegen/report.go index 4cc691e03db..0d199d8696b 100644 --- a/pkg/kindsys/report.go +++ b/pkg/kindsysreport/codegen/report.go @@ -17,14 +17,14 @@ import ( "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/kindsys" + "github.com/grafana/thema" + + "github.com/grafana/grafana/pkg/kindsysreport" "github.com/grafana/grafana/pkg/plugins/pfs/corelist" "github.com/grafana/grafana/pkg/plugins/plugindef" "github.com/grafana/grafana/pkg/registry/corekind" - "github.com/grafana/thema" ) const ( @@ -187,7 +187,7 @@ func buildKindStateReport() *KindStateReport { r := emptyKindStateReport() b := corekind.NewBase(nil) - groot := filepath.Join(elsedie(os.Getwd())("cannot get cwd"), "..", "..") + groot := filepath.Join(elsedie(os.Getwd())("cannot get cwd"), "..", "..", "..") of := elsedie(kindsysreport.NewCodeOwnersFinder(groot))("cannot parse .github/codeowners") seen := make(map[string]bool) diff --git a/pkg/kindsys/report.json b/pkg/kindsysreport/codegen/report.json similarity index 100% rename from pkg/kindsys/report.json rename to pkg/kindsysreport/codegen/report.json diff --git a/pkg/kindsys/kindsysreport/codeowners.go b/pkg/kindsysreport/codeowners.go similarity index 100% rename from pkg/kindsys/kindsysreport/codeowners.go rename to pkg/kindsysreport/codeowners.go diff --git a/pkg/plugins/codegen/util_ts.go b/pkg/plugins/codegen/util_ts.go index dbc2fb0d2ef..0e2ddd65667 100644 --- a/pkg/plugins/codegen/util_ts.go +++ b/pkg/plugins/codegen/util_ts.go @@ -7,6 +7,7 @@ import ( "cuelang.org/go/cue/ast" tsast "github.com/grafana/cuetsy/ts/ast" + "github.com/grafana/grafana/pkg/plugins/pfs" ) @@ -16,7 +17,7 @@ import ( var importMap = map[string]string{ "github.com/grafana/thema": "", - "github.com/grafana/grafana/pkg/kindsys": "", + "github.com/grafana/kindsys": "", "github.com/grafana/grafana/pkg/plugins/pfs": "", "github.com/grafana/grafana/packages/grafana-schema/src/common": "@grafana/schema", } diff --git a/pkg/plugins/pfs/decl.go b/pkg/plugins/pfs/decl.go index cfad1a4d262..37a3916d904 100644 --- a/pkg/plugins/pfs/decl.go +++ b/pkg/plugins/pfs/decl.go @@ -2,9 +2,10 @@ package pfs import ( "cuelang.org/go/cue/ast" - "github.com/grafana/grafana/pkg/kindsys" - "github.com/grafana/grafana/pkg/plugins/plugindef" + "github.com/grafana/kindsys" "github.com/grafana/thema" + + "github.com/grafana/grafana/pkg/plugins/plugindef" ) type PluginDecl struct { diff --git a/pkg/plugins/pfs/decl_parser.go b/pkg/plugins/pfs/decl_parser.go index fa9f72ac1eb..bc344f813cf 100644 --- a/pkg/plugins/pfs/decl_parser.go +++ b/pkg/plugins/pfs/decl_parser.go @@ -7,7 +7,7 @@ import ( "path/filepath" "sort" - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" "github.com/grafana/thema" ) diff --git a/pkg/plugins/pfs/grafanaplugin.cue b/pkg/plugins/pfs/grafanaplugin.cue index fa839bb1a5c..6adb68555a1 100644 --- a/pkg/plugins/pfs/grafanaplugin.cue +++ b/pkg/plugins/pfs/grafanaplugin.cue @@ -1,7 +1,7 @@ package pfs import ( - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" ) // GrafanaPlugin specifies what plugins may declare in .cue files in a diff --git a/pkg/plugins/pfs/pfs.go b/pkg/plugins/pfs/pfs.go index f6b4116e249..98dc59f0563 100644 --- a/pkg/plugins/pfs/pfs.go +++ b/pkg/plugins/pfs/pfs.go @@ -15,13 +15,14 @@ import ( "cuelang.org/go/cue/errors" "cuelang.org/go/cue/parser" "cuelang.org/go/cue/token" - "github.com/grafana/grafana/pkg/cuectx" - "github.com/grafana/grafana/pkg/kindsys" - "github.com/grafana/grafana/pkg/plugins/plugindef" + "github.com/grafana/kindsys" "github.com/grafana/thema" "github.com/grafana/thema/load" "github.com/grafana/thema/vmux" "github.com/yalue/merged_fs" + + "github.com/grafana/grafana/pkg/cuectx" + "github.com/grafana/grafana/pkg/plugins/plugindef" ) // PackageName is the name of the CUE package that Grafana will load when @@ -57,7 +58,7 @@ func loadGP(ctx *cue.Context) cue.Value { func PermittedCUEImports() []string { return []string{ "github.com/grafana/thema", - "github.com/grafana/grafana/pkg/kindsys", + "github.com/grafana/kindsys", "github.com/grafana/grafana/pkg/plugins/pfs", "github.com/grafana/grafana/packages/grafana-schema/src/common", } diff --git a/pkg/plugins/pfs/plugin.go b/pkg/plugins/pfs/plugin.go index c3ed63b3d75..e5b95dae398 100644 --- a/pkg/plugins/pfs/plugin.go +++ b/pkg/plugins/pfs/plugin.go @@ -2,7 +2,8 @@ package pfs import ( "cuelang.org/go/cue/ast" - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" + "github.com/grafana/grafana/pkg/plugins/plugindef" ) diff --git a/pkg/plugins/pfs/plugin_test.go b/pkg/plugins/pfs/plugin_test.go index c75f2a220c1..99330b241f0 100644 --- a/pkg/plugins/pfs/plugin_test.go +++ b/pkg/plugins/pfs/plugin_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" ) // This is a brick-dumb test that just ensures known schema interfaces are being diff --git a/pkg/registry/corecrd/registry.go b/pkg/registry/corecrd/registry.go index 8c81e72c1b3..fa160c057e0 100644 --- a/pkg/registry/corecrd/registry.go +++ b/pkg/registry/corecrd/registry.go @@ -1,9 +1,10 @@ package corecrd import ( - "github.com/grafana/grafana/pkg/kindsys/k8ssys" - "github.com/grafana/grafana/pkg/registry/corekind" + "github.com/grafana/kindsys/k8ssys" "github.com/grafana/thema" + + "github.com/grafana/grafana/pkg/registry/corekind" ) // New constructs a new [Registry]. diff --git a/pkg/registry/corecrd/registry_gen.go b/pkg/registry/corecrd/registry_gen.go index b7dd1d07a17..0b07d7a910f 100644 --- a/pkg/registry/corecrd/registry_gen.go +++ b/pkg/registry/corecrd/registry_gen.go @@ -20,8 +20,8 @@ import ( publicdashboard "github.com/grafana/grafana/pkg/kinds/publicdashboard/crd" serviceaccount "github.com/grafana/grafana/pkg/kinds/serviceaccount/crd" team "github.com/grafana/grafana/pkg/kinds/team/crd" - "github.com/grafana/grafana/pkg/kindsys/k8ssys" "github.com/grafana/grafana/pkg/registry/corekind" + "github.com/grafana/kindsys/k8ssys" "gopkg.in/yaml.v3" ) diff --git a/pkg/registry/corekind/base.go b/pkg/registry/corekind/base.go index cb0fd331df6..3da8ee5a1c5 100644 --- a/pkg/registry/corekind/base.go +++ b/pkg/registry/corekind/base.go @@ -4,9 +4,10 @@ import ( "sync" "github.com/google/wire" - "github.com/grafana/grafana/pkg/cuectx" - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" "github.com/grafana/thema" + + "github.com/grafana/grafana/pkg/cuectx" ) // KindSet contains all of the wire-style providers related to kinds. diff --git a/pkg/registry/corekind/base_gen.go b/pkg/registry/corekind/base_gen.go index 9a2e2b605e8..e8b620703e0 100644 --- a/pkg/registry/corekind/base_gen.go +++ b/pkg/registry/corekind/base_gen.go @@ -19,7 +19,7 @@ import ( "github.com/grafana/grafana/pkg/kinds/publicdashboard" "github.com/grafana/grafana/pkg/kinds/serviceaccount" "github.com/grafana/grafana/pkg/kinds/team" - "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/kindsys" "github.com/grafana/thema" ) diff --git a/pkg/tsdb/prometheus/querydata/framing_bench_test.go b/pkg/tsdb/prometheus/querydata/framing_bench_test.go index 798b8f5c519..d754cd7d77d 100644 --- a/pkg/tsdb/prometheus/querydata/framing_bench_test.go +++ b/pkg/tsdb/prometheus/querydata/framing_bench_test.go @@ -15,10 +15,11 @@ import ( "time" "github.com/grafana/grafana-plugin-sdk-go/backend" - "github.com/grafana/grafana/pkg/kindsys" - "github.com/grafana/grafana/pkg/tsdb/prometheus/kinds/dataquery" + "github.com/grafana/kindsys" "github.com/stretchr/testify/require" + "github.com/grafana/grafana/pkg/tsdb/prometheus/kinds/dataquery" + "github.com/grafana/grafana/pkg/tsdb/prometheus/models" ) diff --git a/pkg/tsdb/prometheus/querydata/request_test.go b/pkg/tsdb/prometheus/querydata/request_test.go index d3f6238098b..3e218851e7b 100644 --- a/pkg/tsdb/prometheus/querydata/request_test.go +++ b/pkg/tsdb/prometheus/querydata/request_test.go @@ -14,15 +14,17 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" "github.com/grafana/grafana-plugin-sdk-go/data" - "github.com/grafana/grafana/pkg/tsdb/prometheus/kinds/dataquery" apiv1 "github.com/prometheus/client_golang/api/prometheus/v1" p "github.com/prometheus/common/model" "github.com/stretchr/testify/require" + "github.com/grafana/grafana/pkg/tsdb/prometheus/kinds/dataquery" + + "github.com/grafana/kindsys" + "github.com/grafana/grafana/pkg/infra/httpclient" "github.com/grafana/grafana/pkg/infra/log/logtest" "github.com/grafana/grafana/pkg/infra/tracing" - "github.com/grafana/grafana/pkg/kindsys" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/tsdb/prometheus/client" "github.com/grafana/grafana/pkg/tsdb/prometheus/models" diff --git a/public/app/plugins/gen.go b/public/app/plugins/gen.go index 4c45b1f8705..2db944dbf6e 100644 --- a/public/app/plugins/gen.go +++ b/public/app/plugins/gen.go @@ -14,9 +14,10 @@ import ( "strings" "github.com/grafana/codejen" + "github.com/grafana/kindsys" + 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" )