Correctly parse multiple resources from files

Refactored how files, directories and stdin are handled. Every file must pass
through the FileVisitor and then streamed through StreamVisitor. FileVisitor
takes care of opening/closing files and StreamVisitor is parsing multiple
resources.
This commit is contained in:
Anastasis Andronidis
2015-06-14 18:39:58 +02:00
parent b3aad24d40
commit 697e07f864
5 changed files with 180 additions and 134 deletions

View File

@@ -86,9 +86,9 @@ func (b *Builder) Schema(schema validation.Schema) *Builder {
return b
}
// Filename is parameters passed via a filename argument which may be URLs, the "-" argument indicating
// STDIN, or paths to files or directories. If ContinueOnError() is set prior to this method being called,
// objects on the path that are unrecognized will be ignored (but logged at V(2)).
// FilenameParam groups input in two categories: URLs and files (files, directories, STDIN)
// If ContinueOnError() is set prior to this method, objects on the path that are not
// recognized will be ignored (but logged at V(2)).
func (b *Builder) FilenameParam(paths ...string) *Builder {
for _, s := range paths {
switch {
@@ -124,7 +124,9 @@ func (b *Builder) URL(urls ...*url.URL) *Builder {
// prior to this method being called, objects in the stream that are unrecognized
// will be ignored (but logged at V(2)).
func (b *Builder) Stdin() *Builder {
return b.Stream(os.Stdin, "STDIN")
b.stream = true
b.paths = append(b.paths, FileVisitorForSTDIN(b.mapper, b.continueOnError, b.schema))
return b
}
// Stream will read objects from the provided reader, and if an error occurs will
@@ -133,16 +135,18 @@ func (b *Builder) Stdin() *Builder {
// will be ignored (but logged at V(2)).
func (b *Builder) Stream(r io.Reader, name string) *Builder {
b.stream = true
b.paths = append(b.paths, NewStreamVisitor(r, b.mapper, b.schema, name, b.continueOnError))
b.paths = append(b.paths, NewStreamVisitor(r, b.mapper, name, b.continueOnError, b.schema))
return b
}
// Path is a set of filesystem paths that may be files containing one or more
// resources. If ContinueOnError() is set prior to this method being called,
// objects on the path that are unrecognized will be ignored (but logged at V(2)).
// Path accepts a set of paths that may be files, directories (all can containing
// one or more resources). Creates a FileVisitor for each file and then each
// FileVisitor is streaming the content to a StreamVisitor. If ContinueOnError() is set
// prior to this method being called, objects on the path that are unrecognized will be
// ignored (but logged at V(2)).
func (b *Builder) Path(paths ...string) *Builder {
for _, p := range paths {
i, err := os.Stat(p)
_, err := os.Stat(p)
if os.IsNotExist(err) {
b.errs = append(b.errs, fmt.Errorf("the path %q does not exist", p))
continue
@@ -151,26 +155,16 @@ func (b *Builder) Path(paths ...string) *Builder {
b.errs = append(b.errs, fmt.Errorf("the path %q cannot be accessed: %v", p, err))
continue
}
var visitor Visitor
if i.IsDir() {
b.dir = true
visitor = &DirectoryVisitor{
Mapper: b.mapper,
Path: p,
Extensions: []string{".json", ".yaml", ".yml"},
Recursive: false,
IgnoreErrors: b.continueOnError,
Schema: b.schema,
}
} else {
visitor = &PathVisitor{
Mapper: b.mapper,
Path: p,
IgnoreErrors: b.continueOnError,
Schema: b.schema,
}
visitors, err := ExpandPathsToFileVisitors(b.mapper, p, false, []string{".json", ".yaml", ".yml"}, b.continueOnError, b.schema)
if err != nil {
b.errs = append(b.errs, fmt.Errorf("error reading %q: %v", p, err))
}
b.paths = append(b.paths, visitor)
if len(visitors) > 1 {
b.dir = true
}
b.paths = append(b.paths, visitors...)
}
return b
}
@@ -207,8 +201,8 @@ func (b *Builder) Selector(selector labels.Selector) *Builder {
return b
}
// The namespace that these resources should be assumed to under - used by DefaultNamespace()
// and RequireNamespace()
// NamespaceParam accepts the namespace that these resources should be
// considered under from - used by DefaultNamespace() and RequireNamespace()
func (b *Builder) NamespaceParam(namespace string) *Builder {
b.namespace = namespace
return b