Skip to content

Commit

Permalink
Add support for loading directories
Browse files Browse the repository at this point in the history
Add new function `LoadDirectory` to load files in a directory as documents
in an InputFile struct.

Add reference to the InputFile to the Path struct.

Add function to create a description of the path root.

Simplify buffer and print code where possible.
  • Loading branch information
HeavyWombat committed Mar 19, 2021
1 parent 8029068 commit f169745
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 34 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/BurntSushi/toml v0.3.1
github.com/gonvenience/bunt v1.3.2
github.com/gonvenience/neat v1.3.6
github.com/gonvenience/text v1.0.6
github.com/gonvenience/wrap v1.1.0
github.com/gorilla/mux v1.8.0
github.com/onsi/ginkgo v1.15.2
Expand Down
15 changes: 4 additions & 11 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/gonvenience/bunt v1.1.3/go.mod h1:hZ898ZprNWgaVlq4s1ivsJu3AY+3wrlJadF5Gp7Yq2c=
github.com/gonvenience/bunt v1.3.1 h1:64ziExF14bk0kVkYmAhoIXvXedw8hvWjouqLv/behjo=
github.com/gonvenience/bunt v1.3.1/go.mod h1:G+d3dJBxxOqV2oca96psgAnPABVC9QptEifjVqPu+mo=
github.com/gonvenience/neat v1.3.5 h1:IUbsj/WF1pjAlsI2L1Gn9mY+FaGfmiG6Kp4vmO6r2oQ=
github.com/gonvenience/neat v1.3.5/go.mod h1:BS9YqdxIL7HScL1tSF3VBzCtXXOq18xKq3H8l96T+LI=
github.com/gonvenience/bunt v1.3.2 h1:gDiyTDfPf87fCtIbFzvENrmlnDZYbENdhhRW2kun/tw=
github.com/gonvenience/bunt v1.3.2/go.mod h1:oTOZqb1TVL1KqZm57zUCJCiwUliNfY8+d3QndOVqxpg=
github.com/gonvenience/neat v1.3.6 h1:IS6kT53mBYnKXramPhWjNtOIh201aC+gB4wXg3kDnrQ=
github.com/gonvenience/neat v1.3.6/go.mod h1:wv0eXmvwFfpuS5bpf2fIofXQvf8W7HTdSzKfGCYbIe8=
github.com/gonvenience/term v1.0.0 h1:joCB/j0Ngmdakd3muuLgAGPMf7DNKdoe708c1I6RiBs=
github.com/gonvenience/term v1.0.0/go.mod h1:wohD4Iqso9Eol7qc2VnNhSFFhZxok5PvO7pZhdrAn4E=
github.com/gonvenience/term v1.0.1 h1:8bg2O0ox0Ss64nnUxW5AXlSHhllc8dTOSKuKu6uoGpw=
github.com/gonvenience/term v1.0.1/go.mod h1:TrQEhxBNE/ng5kTV+S0OvQowTDJSfhlBeZbcOmTR6qI=
github.com/gonvenience/text v1.0.6 h1:9JH9fz0BL0NX4uKmjLuVcsBKiniPa+XLpf8KH9so44U=
github.com/gonvenience/text v1.0.6/go.mod h1:9U5WbkT/5wR5+aNMR4HucamY+HgVMEn+UbF78XHmUio=
github.com/gonvenience/wrap v1.1.0 h1:d8gEZrXS/zg4BC1q0U4nHpPIh5k6muKpQ1+rQFBwpYc=
github.com/gonvenience/wrap v1.1.0/go.mod h1:L47Cm1sK1G8QmFAYQfkHcF/sQ1IBJUa0u4sjqiLqPdM=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
Expand All @@ -35,11 +35,9 @@ github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3 h1:BXxTozrOU8zgC5dkpn3J6NTRdoP+hjok/e+ACr4Hibk=
github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3/go.mod h1:x1uk6vxTiVuNt6S5R2UYgdhpj3oKojXvOXauHZ7dEnI=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936 h1:kw1v0NlnN+GZcU8Ma8CLF2Zzgjfx95gs3/GN3vYAPpo=
github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
Expand All @@ -51,15 +49,13 @@ github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg=
github.com/onsi/ginkgo v1.15.1 h1:DsXNrKujDlkMS9Rsxmd+Fg7S6Kc5lhE+qX8tY6laOxc=
github.com/onsi/ginkgo v1.15.1/go.mod h1:Dd6YFfwBW84ETqqtL0CPyPXillHgY6XhQH3uuCCTr/o=
github.com/onsi/ginkgo v1.15.2 h1:l77YT15o814C2qVL47NOyjV/6RbaP7kKdrvZnxQ3Org=
github.com/onsi/ginkgo v1.15.2/go.mod h1:Dd6YFfwBW84ETqqtL0CPyPXillHgY6XhQH3uuCCTr/o=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ=
github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug=
github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg=
Expand All @@ -70,7 +66,6 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand Down Expand Up @@ -124,10 +119,8 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
80 changes: 57 additions & 23 deletions input.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ import (
"net/url"
"os"
"path/filepath"
"sort"
"strings"

toml "github.com/BurntSushi/toml"
"github.com/BurntSushi/toml"
"github.com/gonvenience/bunt"
"github.com/gonvenience/text"
"github.com/gonvenience/wrap"
ordered "github.com/virtuald/go-ordered-json"
yamlv3 "gopkg.in/yaml.v3"
Expand All @@ -51,11 +53,14 @@ type DecoderProxy struct {
ordered *ordered.Decoder
}

// InputFile represents the actual input file (either local, or fetched remotely) that needs to be processed. It can contain multiple documents, where a document is a map or a list of things.
// InputFile represents the actual input file (local, or fetched remotely) that
// needs to be processed. It can contain multiple documents, where a document
// is a map or a list of things.
type InputFile struct {
Location string
Note string
Documents []*yamlv3.Node
Names []string
}

// NewDecoderProxy creates a new decoder proxy which either works in ordered
Expand Down Expand Up @@ -91,45 +96,36 @@ func HumanReadableLocationInformation(inputFile InputFile) string {

// Add additional note if it is set
if inputFile.Note != "" {
buf.WriteString(", ")
buf.WriteString(bunt.Sprintf("Orange{%s}", inputFile.Note))
bunt.Fprintf(&buf, ", Orange{%s}", inputFile.Note)
}

// Add an information about how many documents are in the provided input file
if documents := len(inputFile.Documents); documents > 1 {
var str string
if documents == 1 {
str = "document"
} else {
str = "documents"
}

buf.WriteString(", ")
buf.WriteString(bunt.Sprintf("Aquamarine{*%s*}", str))
bunt.Fprintf(&buf, ", Aquamarine{*%s*}", text.Plural(documents, "document"))
}

return buf.String()
}

// HumanReadableLocation returns a human readable location with proper coloring
func HumanReadableLocation(location string) string {
var buf bytes.Buffer

if IsStdin(location) {
bunt.Fprint(&buf, "_*stdin*_")
return bunt.Sprint("_*stdin*_")
}

} else if _, err := os.Stat(location); err == nil {
if _, err := os.Stat(location); err == nil {
if abs, err := filepath.Abs(location); err == nil {
buf.WriteString(bunt.Style(abs, bunt.Bold()))
} else {
buf.WriteString(bunt.Style(location, bunt.Bold()))
location = abs
}

} else if _, err := url.ParseRequestURI(location); err == nil {
buf.WriteString(bunt.Sprintf("CornflowerBlue{~%s~}", location))
return bunt.Sprintf("*%s*", location)
}

return buf.String()
if _, err := url.ParseRequestURI(location); err == nil {
return bunt.Sprintf("CornflowerBlue{~%s~}", location)
}

return location
}

// LoadFiles concurrently loads two files from the provided locations
Expand Down Expand Up @@ -168,6 +164,10 @@ func LoadFiles(locationA string, locationB string) (InputFile, InputFile, error)
// LoadFile processes the provided input location to load it as one of the
// supported document formats, or plain text if nothing else works.
func LoadFile(location string) (InputFile, error) {
if info, err := os.Stat(location); err == nil && info.IsDir() {
return LoadDirectory(location)
}

var (
documents []*yamlv3.Node
data []byte
Expand All @@ -188,6 +188,40 @@ func LoadFile(location string) (InputFile, error) {
}, nil
}

// LoadDirectory reads the provided location as a directory and processes all
// files in the directory as documents
func LoadDirectory(location string) (InputFile, error) {
files, err := ioutil.ReadDir(location)
if err != nil {
return InputFile{}, wrap.Errorf(err, "failed to read files in directory %s", location)
}

sort.Slice(files, func(i, j int) bool {
return strings.Compare(files[i].Name(), files[j].Name()) < 0
})

var result = InputFile{
Location: location,
}

for _, file := range files {
bytes, err := getBytesFromLocation(filepath.Join(location, file.Name()))
if err != nil {
return InputFile{}, err
}

docs, err := LoadDocuments(bytes)
if err != nil {
return InputFile{}, err
}

result.Documents = append(result.Documents, docs...)
result.Names = append(result.Names, file.Name())
}

return result, nil
}

// LoadDocuments reads the provided input data slice as a YAML, JSON, or TOML
// file with potential multiple documents. It only acts as a dispatcher and
// depending on the input will either use `LoadTOMLDocuments`,
Expand Down
14 changes: 14 additions & 0 deletions path.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const (
// For example, `sizing.api.count` points to the key `sizing` of the root
// element and in there to the key `api` and so on and so forth.
type Path struct {
Root *InputFile
DocumentIdx int
PathElements []PathElement
}
Expand Down Expand Up @@ -106,13 +107,26 @@ func (path *Path) ToDotStyle() string {
return strings.Join(sections, ".")
}

// RootDescription returns a description of the root level of this path, which
// could be the number of the respective document inside a YAML or if available
// the name of the document
func (path *Path) RootDescription() string {
if path.Root != nil && path.DocumentIdx < len(path.Root.Names) {
return path.Root.Names[path.DocumentIdx]
}

// Note: human style counting that starts with 1
return fmt.Sprintf("document #%d", path.DocumentIdx+1)
}

// NewPathWithPathElement returns a new path based on a given path adding a new
// path element.
func NewPathWithPathElement(path Path, pathElement PathElement) Path {
result := make([]PathElement, len(path.PathElements))
copy(result, path.PathElements)

return Path{
Root: path.Root,
DocumentIdx: path.DocumentIdx,
PathElements: append(result, pathElement)}
}
Expand Down

0 comments on commit f169745

Please sign in to comment.