diff --git a/README.md b/README.md index d493b294..26c2424c 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,13 @@ How many deployments have you done that needed to be rolled back due to a missin ### Where can you use this tool? * In a CI/CD pipeline as a quality gate * On your desktop to validate configuration files as you write them -* As a library in your existing go tools +* As a library within your existing go code ### What types of files are supported? * XML * JSON * YAML +* TOML ## Getting Started Binaries and a container on Dockerhub will eventually be available but for now the project must be built on an environment that has golang 1.17+ installed. diff --git a/cmd/validator/validator.go b/cmd/validator/validator.go index 0a205ca2..afb622d9 100644 --- a/cmd/validator/validator.go +++ b/cmd/validator/validator.go @@ -2,6 +2,7 @@ package main import ( "flag" + "fmt" "github.com/Boeing/config-file-validator/pkg/cli" "log" "os" @@ -21,7 +22,7 @@ func getFlags() (*string, *string, int) { exit := 0 if *searchPathPtr == "" { - log.Println("Missing required Parameter. Showing help: ") + fmt.Println("Missing required Parameter. Showing help: ") flag.PrintDefaults() exit = 1 return nil, nil, exit diff --git a/go.mod b/go.mod index eb397182..6fa8e7c0 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/fatih/color v1.13.0 // indirect github.com/mattn/go-colorable v0.1.9 // indirect github.com/mattn/go-isatty v0.0.14 // indirect + github.com/pelletier/go-toml/v2 v2.0.6 // indirect golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect -) \ No newline at end of file +) diff --git a/go.sum b/go.sum index 2afe6e55..0c916345 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U= @@ -5,10 +7,20 @@ github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= +github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/filetype/file_type.go b/pkg/filetype/file_type.go index 6748a7a9..e6a61427 100644 --- a/pkg/filetype/file_type.go +++ b/pkg/filetype/file_type.go @@ -25,7 +25,7 @@ var JsonFileType = FileType{ // Instance of the FileType object to // represent a YAML file var YamlFileType = FileType{ - "json", + "yaml", []string{"yml", "yaml"}, validator.YamlValidator{}, } @@ -38,10 +38,19 @@ var XmlFileType = FileType{ validator.XmlValidator{}, } +// Instance of FileType object to +// represent a Toml file +var TomlFileType = FileType{ + "toml", + []string{"toml"}, + validator.TomlValidator{}, +} + // An array of files types that are supported // by the validator var FileTypes = []FileType{ JsonFileType, YamlFileType, XmlFileType, + TomlFileType, } diff --git a/pkg/finder/fsfinder.go b/pkg/finder/fsfinder.go index 3266f1f7..af2d6da3 100644 --- a/pkg/finder/fsfinder.go +++ b/pkg/finder/fsfinder.go @@ -21,11 +21,10 @@ func (fsf FileSystemFinder) Find(pathRoot string, fileTypes []filetype.FileType, return nil, err } - err := filepath.Walk(pathRoot, func(path string, fileInfo fs.FileInfo, err error) error { + err := filepath.WalkDir(pathRoot, func(path string, dirEntry fs.DirEntry, err error) error { // determine if directory is in the excludeDirs list for _, dir := range excludeDirs { - if fileInfo.IsDir() && fileInfo.Name() == dir { - //log.Info("Skipping directory") + if dirEntry.IsDir() && dirEntry.Name() == dir { err := filepath.SkipDir if err != nil { return err @@ -33,7 +32,7 @@ func (fsf FileSystemFinder) Find(pathRoot string, fileTypes []filetype.FileType, } } - if !fileInfo.IsDir() { + if !dirEntry.IsDir() { walkFileExtension := filepath.Ext(path) for _, fileType := range fileTypes { @@ -42,7 +41,7 @@ func (fsf FileSystemFinder) Find(pathRoot string, fileTypes []filetype.FileType, // so it needs to be prepended to the FileType extension // in order to match if ("." + extension) == walkFileExtension { - fileMetadata := FileMetadata{fileInfo.Name(), path, fileType} + fileMetadata := FileMetadata{dirEntry.Name(), path, fileType} matchingFiles = append(matchingFiles, fileMetadata) } } diff --git a/pkg/validator/toml.go b/pkg/validator/toml.go new file mode 100644 index 00000000..05beb252 --- /dev/null +++ b/pkg/validator/toml.go @@ -0,0 +1,20 @@ +package validator + +import ( + "errors" + "fmt" + "github.com/pelletier/go-toml/v2" +) + +type TomlValidator struct{} + +func (tv TomlValidator) Validate(b []byte) (bool, error) { + var output interface{} + err := toml.Unmarshal(b, &output) + var derr *toml.DecodeError + if errors.As(err, &derr) { + row, col := derr.Position() + return false, fmt.Errorf("Error at line %v column %v: %v", row, col, err) + } + return true, nil +} diff --git a/pkg/validator/validator_test.go b/pkg/validator/validator_test.go index ada1ac3a..53725d59 100644 --- a/pkg/validator/validator_test.go +++ b/pkg/validator/validator_test.go @@ -16,6 +16,8 @@ var testData = []struct { {"invalidYaml", []byte("a: b\nc: d:::::::::::::::"), false, YamlValidator{}}, {"validXml", []byte("\n"), true, XmlValidator{}}, {"invalidXml", []byte("