You've already forked woodpecker
mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2026-06-03 16:35:37 +02:00
Deduplicate schema linter composition errors (#6633)
This commit is contained in:
@@ -19,6 +19,7 @@ import (
|
|||||||
_ "embed"
|
_ "embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"codeberg.org/6543/go-yaml2json"
|
"codeberg.org/6543/go-yaml2json"
|
||||||
"codeberg.org/6543/xyaml"
|
"codeberg.org/6543/xyaml"
|
||||||
@@ -58,7 +59,7 @@ func Lint(r io.Reader) ([]gojsonschema.ResultError, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !result.Valid() {
|
if !result.Valid() {
|
||||||
return result.Errors(), fmt.Errorf("config not valid")
|
return filterRedundantCompositionErrors(result.Errors()), fmt.Errorf("config not valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@@ -67,3 +68,47 @@ func Lint(r io.Reader) ([]gojsonschema.ResultError, error) {
|
|||||||
func LintString(s string) ([]gojsonschema.ResultError, error) {
|
func LintString(s string) ([]gojsonschema.ResultError, error) {
|
||||||
return Lint(bytes.NewBufferString(s))
|
return Lint(bytes.NewBufferString(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func filterRedundantCompositionErrors(schemaErrors []gojsonschema.ResultError) []gojsonschema.ResultError {
|
||||||
|
filtered := make([]gojsonschema.ResultError, 0, len(schemaErrors))
|
||||||
|
for index, schemaError := range schemaErrors {
|
||||||
|
if isCompositionError(schemaError) && hasSpecificSchemaError(schemaErrors, index, schemaError.Field()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
filtered = append(filtered, schemaError)
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered
|
||||||
|
}
|
||||||
|
|
||||||
|
func isCompositionError(schemaError gojsonschema.ResultError) bool {
|
||||||
|
switch schemaError.Type() {
|
||||||
|
case "number_one_of", "number_any_of":
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasSpecificSchemaError(schemaErrors []gojsonschema.ResultError, currentIndex int, field string) bool {
|
||||||
|
for index, schemaError := range schemaErrors {
|
||||||
|
if index == currentIndex || isCompositionError(schemaError) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if isSameFieldOrChild(schemaError.Field(), field) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSameFieldOrChild(field, parent string) bool {
|
||||||
|
if parent == "(root)" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return field == parent || strings.HasPrefix(field, parent+".")
|
||||||
|
}
|
||||||
|
|||||||
@@ -147,3 +147,27 @@ func TestSchema(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSchemaFiltersRedundantCompositionErrors(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
configErrors, err := schema.LintString(`steps:
|
||||||
|
publish:
|
||||||
|
image: plugins/docker
|
||||||
|
settings:
|
||||||
|
repo: foo/bar
|
||||||
|
tags: latest
|
||||||
|
environment:
|
||||||
|
CGO: 0
|
||||||
|
`)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
descriptions := make([]string, 0, len(configErrors))
|
||||||
|
for _, configError := range configErrors {
|
||||||
|
descriptions = append(descriptions, configError.Description())
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NotContains(t, descriptions, "Must validate one and only one schema (oneOf)")
|
||||||
|
assert.NotContains(t, descriptions, "Must validate at least one schema (anyOf)")
|
||||||
|
assert.Contains(t, descriptions, "Additional property settings is not allowed")
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user