From 4ff3c32c4bde4d428b18e4a09700684f8f3eb2c5 Mon Sep 17 00:00:00 2001 From: Alex Yatskov Date: Sun, 11 Apr 2021 19:13:59 -0700 Subject: [PATCH] Switch to new interfaces --- LICENSE | 2 +- cache.go | 2 +- context.go | 36 +++++++++++------------------------- file.go | 33 +++++++++++++++++++++++++++++---- goldsmith.go | 34 +++++++++------------------------- interface.go | 4 ++-- loader.go | 4 ++-- 7 files changed, 55 insertions(+), 60 deletions(-) diff --git a/LICENSE b/LICENSE index 197ac83..db7e050 100644 --- a/LICENSE +++ b/LICENSE @@ -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 diff --git a/cache.go b/cache.go index 77c337f..8004f43 100644 --- a/cache.go +++ b/cache.go @@ -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 { diff --git a/context.go b/context.go index e48075e..3d260ea 100644 --- a/context.go +++ b/context.go @@ -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) } diff --git a/file.go b/file.go index 8e57ed4..46c517f 100644 --- a/file.go +++ b/file.go @@ -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] +} diff --git a/goldsmith.go b/goldsmith.go index 9d50663..bad1dca 100644 --- a/goldsmith.go +++ b/goldsmith.go @@ -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 { diff --git a/interface.go b/interface.go index 9a88004..c0671f0 100644 --- a/interface.go +++ b/interface.go @@ -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 } diff --git a/loader.go b/loader.go index ef95410..478a399 100644 --- a/loader.go +++ b/loader.go @@ -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 }