Skip to content

Commit

Permalink
Merge pull request #232 from hasheddan/anno-reader
Browse files Browse the repository at this point in the history
Support AnnotatedReaders in package parser
  • Loading branch information
hasheddan authored Dec 8, 2020
2 parents 57ef784 + 2d0e327 commit 479dbc8
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 3 deletions.
39 changes: 37 additions & 2 deletions pkg/parser/fsreader.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ import (
"github.com/spf13/afero"
)

var _ AnnotatedReadCloser = &FsReadCloser{}

// FsReadCloserAnnotation annotates data for an FsReadCloser.
type FsReadCloserAnnotation struct {
path string
position int
}

// FsReadCloser implements io.ReadCloser for an Afero filesystem.
type FsReadCloser struct {
fs afero.Fs
Expand All @@ -32,6 +40,7 @@ type FsReadCloser struct {
index int
position int
writeBreak bool
wroteBreak bool
}

// A FilterFn filters files when the FsReadCloser walks the filesystem.
Expand All @@ -56,6 +65,13 @@ func SkipDirs() FilterFn {
}
}

// SkipEmpty skips empty files.
func SkipEmpty() FilterFn {
return func(path string, info os.FileInfo) (bool, error) {
return info.Size() == 0, nil
}
}

// SkipNotYAML skips files that do not have YAML extension.
func SkipNotYAML() FilterFn {
return func(path string, info os.FileInfo) (bool, error) {
Expand Down Expand Up @@ -94,24 +110,29 @@ func NewFsReadCloser(fs afero.Fs, dir string, fns ...FilterFn) (*FsReadCloser, e
index: 0,
position: 0,
writeBreak: false,
wroteBreak: false,
}, err
}

func (r *FsReadCloser) Read(p []byte) (n int, err error) {
if r.wroteBreak {
r.index++
r.position = 0
r.wroteBreak = false
}
if r.index == len(r.paths) {
return 0, io.EOF
}
if r.writeBreak {
n = copy(p, "\n---\n")
r.writeBreak = false
r.wroteBreak = true
return n, nil
}
b, err := afero.ReadFile(r.fs, r.paths[r.index])
n = copy(p, b[r.position:])
r.position += n
if err == io.EOF || n == 0 {
r.position = 0
r.index++
r.writeBreak = true
err = nil
}
Expand All @@ -122,3 +143,17 @@ func (r *FsReadCloser) Read(p []byte) (n int, err error) {
func (r *FsReadCloser) Close() error {
return nil
}

// Annotate returns additional about the data currently being read.
func (r *FsReadCloser) Annotate() interface{} {
// Index will be out of bounds if we error after the final file has been
// read.
index := r.index
if index == len(r.paths) {
index--
}
return FsReadCloserAnnotation{
path: r.paths[index],
position: r.position,
}
}
12 changes: 12 additions & 0 deletions pkg/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ package parser
import (
"bufio"
"context"
"fmt"
"io"
"io/ioutil"
"strings"

"github.com/pkg/errors"
"github.com/spf13/afero"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand All @@ -31,6 +33,13 @@ import (
"k8s.io/client-go/kubernetes"
)

// AnnotatedReadCloser is a wrapper around io.ReadCloser that allows
// implementations to supply additional information about data that is read.
type AnnotatedReadCloser interface {
io.ReadCloser
Annotate() interface{}
}

// ObjectCreaterTyper know how to create and determine the type of objects.
type ObjectCreaterTyper interface {
runtime.ObjectCreater
Expand Down Expand Up @@ -105,6 +114,9 @@ func (p *PackageParser) Parse(ctx context.Context, reader io.ReadCloser) (*Packa
if err != nil {
o, _, err := do.Decode(bytes, nil, nil)
if err != nil {
if anno, ok := reader.(AnnotatedReadCloser); ok {
return pkg, errors.Wrap(err, fmt.Sprintf("%+v", anno.Annotate()))
}
return pkg, err
}
pkg.objects = append(pkg.objects, o)
Expand Down
2 changes: 1 addition & 1 deletion pkg/parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func TestParser(t *testing.T) {
"FsBackendSkip": {
reason: "should skip empty files and files without yaml extension",
parser: New(metaScheme, objScheme),
backend: NewFsBackend(emptyFs, FsDir("."), FsFilters(SkipDirs(), SkipNotYAML())),
backend: NewFsBackend(emptyFs, FsDir("."), FsFilters(SkipDirs(), SkipEmpty(), SkipNotYAML())),
pkg: NewPackage(),
},
}
Expand Down

0 comments on commit 479dbc8

Please sign in to comment.