Update API to support filters

This commit is contained in:
Alex Yatskov 2018-01-07 15:42:32 -08:00
parent b03a37b208
commit ab65be1361
4 changed files with 57 additions and 32 deletions

View File

@ -26,23 +26,21 @@ import (
"os" "os"
"runtime" "runtime"
"sync" "sync"
"github.com/bmatcuk/doublestar"
) )
type context struct { type context struct {
gs *goldsmith gs *goldsmith
plug Plugin plug Plugin
filters []string filters []Filter
input, output chan *file input, output chan *file
} }
func (ctx *context) chain() { func (ctx *context) chain() {
defer close(ctx.output) defer close(ctx.output)
var filters []string
if initializer, ok := ctx.plug.(Initializer); ok {
var err error var err error
var filters []Filter
if initializer, ok := ctx.plug.(Initializer); ok {
filters, err = initializer.Initialize(ctx) filters, err = initializer.Initialize(ctx)
if err != nil { if err != nil {
ctx.gs.fault(ctx.plug.Name(), nil, err) ctx.gs.fault(ctx.plug.Name(), nil, err)
@ -60,20 +58,16 @@ func (ctx *context) chain() {
defer wg.Done() defer wg.Done()
for f := range ctx.input { for f := range ctx.input {
accept := processor != nil accept := processor != nil
matcher := func(patterns []string) { for _, filter := range append(ctx.filters, filters...) {
if accept && len(patterns) > 0 { if accept, err = filter.Accept(ctx, f); err != nil {
accept = false ctx.gs.fault(filter.Name(), f, err)
for _, pattern := range patterns { return
if match, _ := doublestar.PathMatch(pattern, f.Path()); match { }
accept = true
if !accept {
break break
} }
} }
}
}
matcher(filters)
matcher(ctx.filters)
if accept { if accept {
if _, err := f.Seek(0, os.SEEK_SET); err != nil { if _, err := f.Seek(0, os.SEEK_SET); err != nil {

38
core.go
View File

@ -33,18 +33,15 @@ type goldsmith struct {
contexts []*context contexts []*context
refs map[string]bool refs map[string]bool
complete bool complete bool
filters []Filter
errors []error errors []error
errorMtx sync.Mutex errorMtx sync.Mutex
} }
func (gs *goldsmith) pushContext(plug Plugin, filters []string) *context { func (gs *goldsmith) pushContext(plug Plugin) *context {
ctx := &context{ ctx := &context{gs: gs, plug: plug, output: make(chan *file)}
gs: gs, ctx.filters = append(ctx.filters, gs.filters...)
plug: plug,
filters: filters,
output: make(chan *file),
}
if len(gs.contexts) > 0 { if len(gs.contexts) > 0 {
ctx.input = gs.contexts[len(gs.contexts)-1].output ctx.input = gs.contexts[len(gs.contexts)-1].output
@ -102,12 +99,35 @@ func (gs *goldsmith) fault(name string, f *file, err error) {
// Goldsmith Implementation // Goldsmith Implementation
// //
func (gs *goldsmith) Chain(p Plugin, filters ...string) Goldsmith { func (gs *goldsmith) Chain(p Plugin) Goldsmith {
if gs.complete { if gs.complete {
panic("attempted reuse of goldsmith instance") panic("attempted reuse of goldsmith instance")
} }
gs.pushContext(p, filters) gs.pushContext(p)
return gs
}
func (gs *goldsmith) FilterPush(f Filter) Goldsmith {
if gs.complete {
panic("attempted reuse of goldsmith instance")
}
gs.filters = append(gs.filters, f)
return gs
}
func (gs *goldsmith) FilterPop() Goldsmith {
if gs.complete {
panic("attempted reuse of goldsmith instance")
}
count := len(gs.filters)
if count == 0 {
panic("attempted to pop empty filter stack")
}
gs.filters = gs.filters[:count-1]
return gs return gs
} }

View File

@ -32,13 +32,15 @@ import (
) )
type Goldsmith interface { type Goldsmith interface {
Chain(p Plugin, filters ...string) Goldsmith Chain(p Plugin) Goldsmith
FilterPush(f Filter) Goldsmith
FilterPop() Goldsmith
End(dstDir string) []error End(dstDir string) []error
} }
func Begin(srcDir string, filters ...string) Goldsmith { func Begin(srcDir string) Goldsmith {
gs := &goldsmith{srcDir: srcDir, refs: make(map[string]bool)} gs := &goldsmith{srcDir: srcDir, refs: make(map[string]bool)}
gs.Chain(new(loader), filters...) gs.Chain(new(loader))
return gs return gs
} }
@ -113,7 +115,7 @@ func (e Error) Error() string {
} }
type Initializer interface { type Initializer interface {
Initialize(ctx Context) ([]string, error) Initialize(ctx Context) ([]Filter, error)
} }
type Processor interface { type Processor interface {
@ -124,6 +126,15 @@ type Finalizer interface {
Finalize(ctx Context) error Finalize(ctx Context) error
} }
type Plugin interface { type Component interface {
Name() string Name() string
} }
type Filter interface {
Component
Accept(ctx Context, f File) (bool, error)
}
type Plugin interface {
Component
}

View File

@ -30,7 +30,7 @@ func (*loader) Name() string {
return "loader" return "loader"
} }
func (*loader) Initialize(ctx Context) ([]string, error) { func (*loader) Initialize(ctx Context) ([]Filter, error) {
infos := make(chan fileInfo) infos := make(chan fileInfo)
go scanDir(ctx.SrcDir(), infos) go scanDir(ctx.SrcDir(), infos)