diff --git a/goldsmith.go b/goldsmith.go index 0248821..cbd8456 100644 --- a/goldsmith.go +++ b/goldsmith.go @@ -27,6 +27,7 @@ import ( "path" "path/filepath" "sync" + "sync/atomic" ) type stage struct { @@ -40,16 +41,7 @@ type goldsmith struct { stages []*stage refs map[string]bool mtx sync.Mutex -} - -func New(srcDir, dstDir string) Goldsmith { - gs := &goldsmith{ - srcDir: srcDir, - dstDir: dstDir, - } - - gs.queueFiles() - return gs + count int32 } func (gs *goldsmith) queueFiles() { @@ -67,7 +59,7 @@ func (gs *goldsmith) queueFiles() { panic(err) } - file := s.NewFile(relPath) + file := NewFile(relPath) var f *os.File if f, file.Err = os.Open(path); file.Err == nil { @@ -123,6 +115,11 @@ func (gs *goldsmith) cleanupFiles() { } func (gs *goldsmith) exportFile(file *File) { + defer func() { + file.Buff.Reset() + gs.decFiles() + }() + if file.Err != nil { return } @@ -141,6 +138,34 @@ func (gs *goldsmith) exportFile(file *File) { } } +func (gs *goldsmith) refFile(path string) { + gs.mtx.Lock() + defer gs.mtx.Unlock() + + if gs.refs == nil { + gs.refs = make(map[string]bool) + } + + path = cleanPath(path) + + for { + gs.refs[path] = true + if path == "." { + break + } + + path = filepath.Dir(path) + } +} + +func (gs *goldsmith) incFiles() { + atomic.AddInt32(&gs.count, 1) +} + +func (gs *goldsmith) decFiles() { + atomic.AddInt32(&gs.count, -1) +} + func (gs *goldsmith) newStage() *stage { s := &stage{ gs: gs, @@ -187,26 +212,6 @@ func (gs *goldsmith) chain(s *stage, p Plugin) { } } -func (gs *goldsmith) refFile(path string) { - gs.mtx.Lock() - defer gs.mtx.Unlock() - - if gs.refs == nil { - gs.refs = make(map[string]bool) - } - - path = cleanPath(path) - - for { - gs.refs[path] = true - if path == "." { - break - } - - path = filepath.Dir(path) - } -} - func (gs *goldsmith) Chain(p Plugin) Goldsmith { go gs.chain(gs.newStage(), p) return gs @@ -218,7 +223,6 @@ func (gs *goldsmith) Complete() ([]*File, []error) { var files []*File for file := range s.output { gs.exportFile(file) - file.Buff.Reset() files = append(files, file) } diff --git a/stage.go b/stage.go index 868f8cf..e55c0ab 100644 --- a/stage.go +++ b/stage.go @@ -22,19 +22,15 @@ package goldsmith -func (s *stage) NewFile(path string) *File { - file := &File{ - Path: cleanPath(path), - Meta: make(map[string]interface{}), - } - s.output <- file - return file -} - func (s *stage) RefFile(path string) { s.gs.refFile(path) } +func (s *stage) AddFile(file *File) { + s.gs.incFiles() + s.output <- file +} + func (s *stage) SrcDir() string { return s.gs.srcDir } diff --git a/types.go b/types.go index a664758..3d7b6a6 100644 --- a/types.go +++ b/types.go @@ -29,6 +29,34 @@ type Goldsmith interface { Complete() ([]*File, []error) } +func New(srcDir, dstDir string) Goldsmith { + gs := &goldsmith{srcDir: srcDir, dstDir: dstDir} + gs.queueFiles() + return gs +} + +type File struct { + Path string + Meta map[string]interface{} + Buff bytes.Buffer + Err error +} + +func NewFile(path string) *File { + return &File{ + Path: cleanPath(path), + Meta: make(map[string]interface{}), + } +} + +type Context interface { + SrcDir() string + DstDir() string + + AddFile(file *File) + RefFile(path string) +} + type Plugin interface{} type Initializer interface { @@ -42,22 +70,3 @@ type Finalizer interface { type Processor interface { Process(ctx Context, file *File) bool } - -type Chainer interface { - Chain(ctx Context, input, output chan *File) -} - -type File struct { - Path string - Meta map[string]interface{} - Buff bytes.Buffer - Err error -} - -type Context interface { - SrcDir() string - DstDir() string - - NewFile(path string) *File - RefFile(path string) -}