Switch to new interfaces

This commit is contained in:
Alex Yatskov 2021-04-11 19:13:59 -07:00
parent a197b40f61
commit 4ff3c32c4b
7 changed files with 55 additions and 60 deletions

View File

@ -1,4 +1,4 @@
Copyright 2015-2019 Alex Yatskov
Copyright 2015-2021 Alex Yatskov
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in

View File

@ -75,7 +75,7 @@ func (cache *cache) buildCachePath(context *Context, outputPath string, inputFil
hasher.Write(uintBuff)
hasher.Write([]byte(outputPath))
sort.Sort(FilesByPath(inputFiles))
sort.Sort(filesByPath(inputFiles))
for _, inputFile := range inputFiles {
fileHash, err := inputFile.hash()
if err != nil {

View File

@ -17,7 +17,9 @@ type Context struct {
plugin Plugin
hash uint32
fileFilters []Filter
filtersExternal filterStack
filtersInternal filterStack
inputFiles chan *File
outputFiles chan *File
}
@ -74,14 +76,17 @@ func (context *Context) RetrieveCachedFile(outputPath string, inputFiles ...*Fil
return context.goldsmith.retrieveFile(context, outputPath, inputFiles)
}
// Specify internal filter(s) that exclude files from being processed.
func (context *Context) Filter(filters ...Filter) *Context {
context.filtersInternal = filters
return context
}
func (context *Context) step() {
defer close(context.outputFiles)
var err error
var filter Filter
if initializer, ok := context.plugin.(Initializer); ok {
filter, err = initializer.Initialize(context)
if err != nil {
if err := initializer.Initialize(context); err != nil {
context.goldsmith.fault(context.plugin.Name(), nil, err)
return
}
@ -96,26 +101,7 @@ func (context *Context) step() {
go func() {
defer wg.Done()
for inputFile := range context.inputFiles {
var fileFilters []Filter
fileFilters = append(fileFilters, context.fileFilters...)
if filter != nil {
fileFilters = append(fileFilters, filter)
}
var accept bool
if processor != nil {
for _, fileFilter := range fileFilters {
if accept, err = fileFilter.Accept(inputFile); err != nil {
context.goldsmith.fault(fileFilter.Name(), inputFile, err)
return
}
if !accept {
break
}
}
}
if accept {
if processor != nil && context.filtersInternal.accept(inputFile) && context.filtersExternal.accept(inputFile) {
if _, err := inputFile.Seek(0, os.SEEK_SET); err != nil {
context.goldsmith.fault("core", inputFile, err)
}

33
file.go
View File

@ -186,17 +186,17 @@ func (file *File) hash() (uint32, error) {
return file.hashValue, nil
}
type FilesByPath []*File
type filesByPath []*File
func (file FilesByPath) Len() int {
func (file filesByPath) Len() int {
return len(file)
}
func (file FilesByPath) Swap(i, j int) {
func (file filesByPath) Swap(i, j int) {
file[i], file[j] = file[j], file[i]
}
func (file FilesByPath) Less(i, j int) bool {
func (file filesByPath) Less(i, j int) bool {
return strings.Compare(file[i].Path(), file[j].Path()) < 0
}
@ -227,3 +227,28 @@ func scanDir(rootDir string, infos chan fileInfo) {
return err
})
}
type filterStack []Filter
func (filters *filterStack) accept(file *File) bool {
for _, filter := range *filters {
if !filter.Accept(file) {
return false
}
}
return true
}
func (filters *filterStack) push(filter Filter) {
*filters = append(*filters, filter)
}
func (filters *filterStack) pop() {
count := len(*filters)
if count == 0 {
panic("attempted to pop empty filter stack")
}
*filters = (*filters)[:count-1]
}

View File

@ -18,11 +18,11 @@ type Goldsmith struct {
contexts []*Context
contextHasher hash.Hash32
fileRefs map[string]bool
fileFilters []Filter
fileCache *cache
fileRefs map[string]bool
fileCache *cache
clean bool
filters filterStack
clean bool
errors []error
mutex sync.Mutex
@ -63,7 +63,7 @@ func (goldsmith *Goldsmith) Chain(plugin Plugin) *Goldsmith {
outputFiles: make(chan *File),
}
context.fileFilters = append(context.fileFilters, goldsmith.fileFilters...)
context.filtersExternal = append(context.filtersExternal, goldsmith.filters...)
if len(goldsmith.contexts) > 0 {
context.inputFiles = goldsmith.contexts[len(goldsmith.contexts)-1].outputFiles
@ -75,18 +75,13 @@ func (goldsmith *Goldsmith) Chain(plugin Plugin) *Goldsmith {
// FilterPush pushes a filter instance on the chain's filter stack.
func (goldsmith *Goldsmith) FilterPush(filter Filter) *Goldsmith {
goldsmith.fileFilters = append(goldsmith.fileFilters, filter)
goldsmith.filters.push(filter)
return goldsmith
}
// FilterPop pops a filter instance from the chain's filter stack.
func (goldsmith *Goldsmith) FilterPop() *Goldsmith {
count := len(goldsmith.fileFilters)
if count == 0 {
panic("attempted to pop empty filter stack")
}
goldsmith.fileFilters = goldsmith.fileFilters[:count-1]
goldsmith.filters.pop()
return goldsmith
}
@ -99,21 +94,10 @@ func (goldsmith *Goldsmith) End(targetDir string) []error {
}
context := goldsmith.contexts[len(goldsmith.contexts)-1]
export:
for file := range context.outputFiles {
for _, fileFilter := range goldsmith.fileFilters {
accept, err := fileFilter.Accept(file)
if err != nil {
goldsmith.fault(fileFilter.Name(), file, err)
continue export
}
if !accept {
continue export
}
if goldsmith.filters.accept(file) {
goldsmith.exportFile(file)
}
goldsmith.exportFile(file)
}
if goldsmith.clean {

View File

@ -9,7 +9,7 @@ type Plugin interface {
// Initializer is used to optionally initialize a plugin and to specify a
// filter to be used for determining which files will be processed.
type Initializer interface {
Initialize(context *Context) (Filter, error)
Initialize(context *Context) error
}
// Processor allows for optional processing of files passing through a plugin.
@ -26,5 +26,5 @@ type Finalizer interface {
// Filter is used to determine which files should continue in the chain.
type Filter interface {
Name() string
Accept(file *File) (bool, error)
Accept(file *File) bool
}

View File

@ -10,7 +10,7 @@ func (*loader) Name() string {
return "loader"
}
func (*loader) Initialize(ctx *Context) (Filter, error) {
func (*loader) Initialize(ctx *Context) error {
infos := make(chan fileInfo)
go scanDir(ctx.goldsmith.sourceDir, infos)
@ -32,5 +32,5 @@ func (*loader) Initialize(ctx *Context) (Filter, error) {
ctx.DispatchFile(file)
}
return nil, nil
return nil
}