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

38
core.go
View File

@ -33,18 +33,15 @@ type goldsmith struct {
contexts []*context
refs map[string]bool
complete bool
filters []Filter
errors []error
errorMtx sync.Mutex
}
func (gs *goldsmith) pushContext(plug Plugin, filters []string) *context {
ctx := &context{
gs: gs,
plug: plug,
filters: filters,
output: make(chan *file),
}
func (gs *goldsmith) pushContext(plug Plugin) *context {
ctx := &context{gs: gs, plug: plug, output: make(chan *file)}
ctx.filters = append(ctx.filters, gs.filters...)
if len(gs.contexts) > 0 {
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
//
func (gs *goldsmith) Chain(p Plugin, filters ...string) Goldsmith {
func (gs *goldsmith) Chain(p Plugin) Goldsmith {
if gs.complete {
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
}

View File

@ -32,13 +32,15 @@ import (
)
type Goldsmith interface {
Chain(p Plugin, filters ...string) Goldsmith
Chain(p Plugin) Goldsmith
FilterPush(f Filter) Goldsmith
FilterPop() Goldsmith
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.Chain(new(loader), filters...)
gs.Chain(new(loader))
return gs
}
@ -113,7 +115,7 @@ func (e Error) Error() string {
}
type Initializer interface {
Initialize(ctx Context) ([]string, error)
Initialize(ctx Context) ([]Filter, error)
}
type Processor interface {
@ -124,6 +126,15 @@ type Finalizer interface {
Finalize(ctx Context) error
}
type Plugin interface {
type Component interface {
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"
}
func (*loader) Initialize(ctx Context) ([]string, error) {
func (*loader) Initialize(ctx Context) ([]Filter, error) {
infos := make(chan fileInfo)
go scanDir(ctx.SrcDir(), infos)