Configurable extensions for template parser

This commit is contained in:
Katrina Verey
2022-04-21 18:28:13 -04:00
parent 9d5491c2e2
commit bcae65770a
5 changed files with 42 additions and 10 deletions

View File

@@ -13,9 +13,9 @@ import (
) )
type parser struct { type parser struct {
fs iofs.FS fs iofs.FS
paths []string paths []string
extension string extensions []string
} }
type contentProcessor func(content []byte, name string) error type contentProcessor func(content []byte, name string) error
@@ -51,8 +51,8 @@ func (l parser) readPath(path string, processContent contentProcessor) error {
} }
// Path is a file -- check extension and read it // Path is a file -- check extension and read it
if !strings.HasSuffix(path, l.extension) { if err := checkExtension(path, l.extensions); err != nil {
return errors.Errorf("file %s did not have required extension %s", path, l.extension) return err
} }
b, err := ioutil.ReadAll(f) b, err := ioutil.ReadAll(f)
if err != nil { if err != nil {
@@ -61,6 +61,15 @@ func (l parser) readPath(path string, processContent contentProcessor) error {
return processContent(b, path) return processContent(b, path)
} }
func checkExtension(path string, extensions []string) error {
for _, ext := range extensions {
if strings.HasSuffix(path, ext) {
return nil
}
}
return errors.Errorf("file %s does not have any of permitted extensions %s", path, extensions)
}
func (l parser) readDir(dir iofs.ReadDirFile, dirname string, processContent contentProcessor) error { func (l parser) readDir(dir iofs.ReadDirFile, dirname string, processContent contentProcessor) error {
entries, err := dir.ReadDir(0) entries, err := dir.ReadDir(0)
if err != nil { if err != nil {
@@ -68,7 +77,7 @@ func (l parser) readDir(dir iofs.ReadDirFile, dirname string, processContent con
} }
for _, entry := range entries { for _, entry := range entries {
if entry.IsDir() || !strings.HasSuffix(entry.Name(), l.extension) { if err := checkExtension(entry.Name(), l.extensions); err != nil || entry.IsDir() {
continue continue
} }
// Note: using filepath.Join will break Windows, because io/fs.FS implementations require slashes on all OS. // Note: using filepath.Join will break Windows, because io/fs.FS implementations require slashes on all OS.

View File

@@ -56,7 +56,7 @@ func SchemaStrings(data ...string) framework.SchemaParser {
// AdditionalSchemas: parser.SchemaFiles("path/to/crd-schemas", "path/to/special-schema.json), // AdditionalSchemas: parser.SchemaFiles("path/to/crd-schemas", "path/to/special-schema.json),
// } // }
func SchemaFiles(paths ...string) SchemaParser { func SchemaFiles(paths ...string) SchemaParser {
return SchemaParser{parser{paths: paths, extension: SchemaExtension}} return SchemaParser{parser{paths: paths, extensions: []string{SchemaExtension}}}
} }
// SchemaParser is a framework.SchemaParser that can parse files or directories containing openapi schemas. // SchemaParser is a framework.SchemaParser that can parse files or directories containing openapi schemas.

View File

@@ -52,7 +52,7 @@ func TestSchemaFiles(t *testing.T) {
{ {
name: "rejects non-.template.yaml files", name: "rejects non-.template.yaml files",
paths: []string{"testdata/ignore.yaml"}, paths: []string{"testdata/ignore.yaml"},
wantErr: "file testdata/ignore.yaml did not have required extension .json", wantErr: "file testdata/ignore.yaml does not have any of permitted extensions [.json]",
}, },
} }
for _, tt := range tests { for _, tt := range tests {

View File

@@ -61,7 +61,7 @@ func TemplateStrings(data ...string) framework.TemplateParser {
// }}, // }},
// } // }
func TemplateFiles(paths ...string) TemplateParser { func TemplateFiles(paths ...string) TemplateParser {
return TemplateParser{parser{paths: paths, extension: TemplateExtension}} return TemplateParser{parser{paths: paths, extensions: []string{TemplateExtension}}}
} }
// TemplateParser is a framework.TemplateParser that can parse files or directories containing Go templated YAML. // TemplateParser is a framework.TemplateParser that can parse files or directories containing Go templated YAML.
@@ -95,3 +95,9 @@ func (l TemplateParser) FromFS(fs iofs.FS) TemplateParser {
l.parser.fs = fs l.parser.fs = fs
return l return l
} }
// WithExtensions allows you to replace the extension the parser accept on the input files.
func (l TemplateParser) WithExtensions(ext ...string) TemplateParser {
l.parser.extensions = ext
return l
}

View File

@@ -81,7 +81,7 @@ func TestTemplateFiles(t *testing.T) {
{ {
name: "rejects non-.template.yaml files", name: "rejects non-.template.yaml files",
paths: []string{"testdata/ignore.yaml"}, paths: []string{"testdata/ignore.yaml"},
wantErr: "file testdata/ignore.yaml did not have required extension .template.yaml", wantErr: "file testdata/ignore.yaml does not have any of permitted extensions [.template.yaml]",
}, },
} }
for _, tt := range tests { for _, tt := range tests {
@@ -114,6 +114,23 @@ func TestTemplateFiles(t *testing.T) {
} }
} }
func TestTemplateParser_WithExtensions(t *testing.T) {
p := parser.TemplateFiles("testdata").WithExtensions(".json")
templates, err := p.Parse()
require.NoError(t, err)
require.Len(t, templates, 2)
p = p.WithExtensions(".yaml")
templates, err = p.Parse()
require.NoError(t, err)
require.Len(t, templates, 3)
p = p.WithExtensions(".yaml", ".json")
templates, err = p.Parse()
require.NoError(t, err)
require.Len(t, templates, 5)
}
func TestTemplateStrings(t *testing.T) { func TestTemplateStrings(t *testing.T) {
tests := []struct { tests := []struct {
name string name string