Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion pkg/analysis/passes/metadatavalid/metadatavalid.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@ package metadatavalid

import (
"bytes"
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
"strings"

"github.com/hashicorp/go-version"
"github.com/xeipuuv/gojsonschema"

"github.com/grafana/plugin-validator/pkg/analysis"
"github.com/grafana/plugin-validator/pkg/analysis/passes/archive"
"github.com/grafana/plugin-validator/pkg/analysis/passes/metadata"
"github.com/grafana/plugin-validator/pkg/analysis/passes/metadataschema"
"github.com/grafana/plugin-validator/pkg/logme"
)

var (
Expand Down Expand Up @@ -84,6 +88,27 @@ func run(pass *analysis.Pass) (interface{}, error) {
case err == nil:
break
}

pluginJsonBytes, err := os.ReadFile(metadataPath)
if err != nil {
// log the error and continue with schema validation
logme.ErrorF("failed to read plugin.json in metadatavalid check: %q", err)
}
if pluginJsonBytes != nil {
var data metadata.Metadata
if err := json.Unmarshal(pluginJsonBytes, &data); err == nil {
_, err = version.NewConstraint(data.Dependencies.GrafanaDependency)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to confirm: with this change we will validate both that the GrafanaDependency is valid according to the regex in the schema + actual semver library used by Grafana's backend?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will use hashicorp/semver to validate the constraint. Schema validation for grafanaDependency will be ignored.

if err != nil {
pass.ReportResult(
pass.AnalyzerName,
invalidMetadata,
fmt.Sprintf("plugin.json: Dependencies.grafanaDependency field has invalid or empty version constraint: %q", data.Dependencies.GrafanaDependency),
"The plugin.json file is not following the schema. Please refer to the documentation for more information. https://grafana.com/docs/grafana/latest/developers/plugins/metadata/#grafanadependency",
)
}
}
}

schemaLoader := gojsonschema.NewReferenceLoader("file:///" + schemaPath)
documentLoader := gojsonschema.NewReferenceLoader("file:///" + metadataPath)

Expand All @@ -92,15 +117,22 @@ func run(pass *analysis.Pass) (interface{}, error) {
return nil, err
}

errLen := len(result.Errors())
for _, desc := range result.Errors() {
// we validate grafanaDependency at line 91-100,
// so we ignore the error from schema validation
if strings.Contains(desc.Field(), "grafanaDependency") || strings.Contains(desc.Description(), "grafanaDependency") {
errLen -= 1
continue
}
pass.ReportResult(
pass.AnalyzerName,
invalidMetadata,
fmt.Sprintf("plugin.json: %s: %s", desc.Field(), desc.Description()),
"The plugin.json file is not following the schema. Please refer to the documentation for more information. https://grafana.com/docs/grafana/latest/developers/plugins/metadata/",
)
}
if len(result.Errors()) == 0 && validMetadata.ReportAll {
if errLen == 0 && validMetadata.ReportAll {
pass.ReportResult(pass.AnalyzerName, validMetadata, "plugin.json: metadata is valid", "")
}

Expand Down
26 changes: 26 additions & 0 deletions pkg/analysis/passes/metadatavalid/metadatavalid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,32 @@ func TestMetadataInvalid(t *testing.T) {
)
}

func TestGrafanaDependencyInvalid(t *testing.T) {
var interceptor testpassinterceptor.TestPassInterceptor
pass := &analysis.Pass{
RootDir: filepath.Join("./"),
ResultOf: map[*analysis.Analyzer]interface{}{
archive.Analyzer: filepath.Join("testdata", "invalid", "grafana-dep"),
metadataschema.Analyzer: getSchema(),
},
Report: interceptor.ReportInterceptor(),
}

_, err := Analyzer.Run(pass)
require.NoError(t, err)
require.Len(t, interceptor.Diagnostics, 2)
require.Equal(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: validate that the schema is not reporting grafanaDependency as it used to be.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now the new error message is checked in the main_test.go

t,
"plugin.json: Dependencies.grafanaDependency field has invalid or empty version constraint: \">=invalid\"",
interceptor.Diagnostics[0].Title,
)
require.Equal(
t,
"plugin.json: (root): Additional property invalid is not allowed",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need this validation here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is to check combination of schema and grafanaDependency.

interceptor.Diagnostics[1].Title,
)
}

func getSchema() []byte {
if len(schemaContent) > 0 {
return schemaContent
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"type": "panel",
"name": "Clock",
"id": "grafana-clock-panel",
"skipDataQuery": true,
"invalid": "invalid",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can remove this, we want to test the grafanaDependency, there are tests already for invalid schema fields.

"info": {
"description": "Clock panel for grafana",
"author": {
"name": "Grafana Labs",
"url": "https://grafana.com"
},
"keywords": [
"clock",
"panel"
],
"logos": {
"small": "img/clock.svg",
"large": "img/clock.svg"
},
"links": [
{
"name": "Project site",
"url": "https://github.com/grafana/clock-panel"
},
{
"name": "MIT License",
"url": "https://github.com/grafana/clock-panel/blob/master/LICENSE"
}
],
"screenshots": [
{
"name": "Showcase",
"path": "img/screenshot-showcase.png"
},
{
"name": "Options",
"path": "img/screenshot-clock-options.png"
}
],
"version": "%VERSION%",
"updated": "%TODAY%"
},
"dependencies": {
"grafanaDependency": ">=invalid",
"plugins": []
}
}
12 changes: 6 additions & 6 deletions pkg/cmd/plugincheck2/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,8 @@ func TestIntegration(t *testing.T) {
"metadatavalid": {
{
Severity: "error",
Title: "plugin.json: dependencies: grafanaDependency is required",
Detail: "The plugin.json file is not following the schema. Please refer to the documentation for more information. https://grafana.com/docs/grafana/latest/developers/plugins/metadata/",
Title: "plugin.json: Dependencies.grafanaDependency field has invalid or empty version constraint: \"\"",
Detail: "The plugin.json file is not following the schema. Please refer to the documentation for more information. https://grafana.com/docs/grafana/latest/developers/plugins/metadata/#grafanadependency",
Name: "invalid-metadata",
},
},
Expand Down Expand Up @@ -317,8 +317,8 @@ func TestIntegration(t *testing.T) {
"metadatavalid": {
{
Severity: "error",
Title: "plugin.json: dependencies: grafanaDependency is required",
Detail: "The plugin.json file is not following the schema. Please refer to the documentation for more information. https://grafana.com/docs/grafana/latest/developers/plugins/metadata/",
Title: "plugin.json: Dependencies.grafanaDependency field has invalid or empty version constraint: \"\"",
Detail: "The plugin.json file is not following the schema. Please refer to the documentation for more information. https://grafana.com/docs/grafana/latest/developers/plugins/metadata/#grafanadependency",
Name: "invalid-metadata",
},
},
Expand All @@ -336,8 +336,8 @@ func TestIntegration(t *testing.T) {
"metadatavalid": {
{
Severity: "warning",
Title: "plugin.json: dependencies: grafanaDependency is required",
Detail: "The plugin.json file is not following the schema. Please refer to the documentation for more information. https://grafana.com/docs/grafana/latest/developers/plugins/metadata/",
Title: "plugin.json: Dependencies.grafanaDependency field has invalid or empty version constraint: \"\"",
Detail: "The plugin.json file is not following the schema. Please refer to the documentation for more information. https://grafana.com/docs/grafana/latest/developers/plugins/metadata/#grafanadependency",
Name: "invalid-metadata",
},
},
Expand Down
1 change: 1 addition & 0 deletions pkg/runner/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ var tests = []struct {
"plugin.json: plugin id should follow the format org-name-type",
"LLM review skipped due to errors in metadatavalid",
"Code diff skipped due to errors in metadatavalid",
"plugin.json: Dependencies.grafanaDependency field has invalid or empty version constraint: \"\"",
}},
}

Expand Down
Loading