golangci-lint/test/configuration_file_test.go
2024-03-18 13:25:52 +01:00

116 lines
2.5 KiB
Go

package test
import (
"errors"
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"
"testing"
"github.com/santhosh-tekuri/jsonschema/v5"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
)
func Test_validateTestConfigurationFiles(t *testing.T) {
err := validateTestConfigurationFiles("../jsonschema/golangci.next.jsonschema.json", ".")
require.NoError(t, err)
}
func validateTestConfigurationFiles(schemaPath, targetDir string) error {
schema, err := loadSchema(filepath.FromSlash(schemaPath))
if err != nil {
return fmt.Errorf("load schema: %w", err)
}
yamlFiles, err := findConfigurationFiles(filepath.FromSlash(targetDir))
if err != nil {
return fmt.Errorf("find configuration files: %w", err)
}
var errAll error
for _, filename := range yamlFiles {
// internal tests
if filename == filepath.FromSlash("testdata/withconfig/.golangci.yml") {
continue
}
m, err := decodeYamlFile(filename)
if err != nil {
return err
}
err = schema.Validate(m)
if err != nil {
abs, _ := filepath.Abs(filename)
errAll = errors.Join(errAll, fmt.Errorf("%s: %w", abs, err))
}
}
return errAll
}
func loadSchema(schemaPath string) (*jsonschema.Schema, error) {
compiler := jsonschema.NewCompiler()
compiler.Draft = jsonschema.Draft7
schemaFile, err := os.Open(schemaPath)
if err != nil {
return nil, fmt.Errorf("open schema file: %w", err)
}
defer func() { _ = schemaFile.Close() }()
err = compiler.AddResource(filepath.Base(schemaPath), schemaFile)
if err != nil {
return nil, fmt.Errorf("add schema resource: %w", err)
}
schema, err := compiler.Compile(filepath.Base(schemaPath))
if err != nil {
return nil, fmt.Errorf("compile schema: %w", err)
}
return schema, nil
}
func findConfigurationFiles(targetDir string) ([]string, error) {
var yamlFiles []string
err := filepath.WalkDir(targetDir, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if !d.IsDir() && (strings.EqualFold(filepath.Ext(d.Name()), ".yml") || strings.EqualFold(filepath.Ext(d.Name()), ".yaml")) {
yamlFiles = append(yamlFiles, path)
}
return nil
})
if err != nil {
return nil, fmt.Errorf("walk dir: %w", err)
}
return yamlFiles, nil
}
func decodeYamlFile(filename string) (any, error) {
yamlFile, err := os.Open(filename)
if err != nil {
return nil, fmt.Errorf("[%s] file open: %w", filename, err)
}
defer func() { _ = yamlFile.Close() }()
var m any
err = yaml.NewDecoder(yamlFile).Decode(&m)
if err != nil {
return nil, fmt.Errorf("[%s] yaml decode: %w", filename, err)
}
return m, nil
}