Better file scanning

This commit is contained in:
Alex Yatskov 2015-11-02 18:07:34 +09:00
parent 57769c218c
commit 7de3c3d37b
2 changed files with 61 additions and 8 deletions

View File

@ -28,8 +28,6 @@ import (
"path" "path"
"path/filepath" "path/filepath"
"sync" "sync"
"github.com/bmatcuk/doublestar"
) )
type stage struct { type stage struct {
@ -40,26 +38,32 @@ type goldsmith struct {
srcDir, dstDir string srcDir, dstDir string
stages []stage stages []stage
files chan *File files chan *File
refs map[string]bool
err error err error
} }
func New(srcDir, dstDir string) Goldsmith { func New(srcDir, dstDir string) Goldsmith {
gs := &goldsmith{srcDir: srcDir, dstDir: dstDir} gs := &goldsmith{
srcDir: srcDir,
dstDir: dstDir,
refs: make(map[string]bool),
}
gs.scan() gs.scan()
return gs return gs
} }
func (gs *goldsmith) scan() { func (gs *goldsmith) scan() {
matches, err := doublestar.Glob(filepath.Join(gs.srcDir, "**")) fileMatches, _, err := scanDir(gs.srcDir)
if err != nil { if err != nil {
gs.err = err gs.err = err
return return
} }
s := stage{nil, make(chan *File, len(matches))} s := stage{nil, make(chan *File, len(fileMatches))}
defer close(s.output) defer close(s.output)
for _, match := range matches { for _, match := range fileMatches {
relPath, err := filepath.Rel(gs.srcDir, match) relPath, err := filepath.Rel(gs.srcDir, match)
if err != nil { if err != nil {
panic(err) panic(err)
@ -83,6 +87,29 @@ func (gs *goldsmith) scan() {
gs.stages = append(gs.stages, s) gs.stages = append(gs.stages, s)
} }
func (gs *goldsmith) clean() {
fileMatches, _, err := scanDir(gs.dstDir)
if err != nil {
gs.err = err
return
}
for _, path := range fileMatches {
relPath, err := filepath.Rel(gs.dstDir, path)
if err != nil {
gs.err = err
return
}
if contained, _ := gs.refs[relPath]; !contained {
if err := os.Remove(path); err != nil {
gs.err = err
return
}
}
}
}
func (gs *goldsmith) makeStage() stage { func (gs *goldsmith) makeStage() stage {
s := stage{ s := stage{
gs.stages[len(gs.stages)-1].output, gs.stages[len(gs.stages)-1].output,
@ -165,7 +192,10 @@ func (gs *goldsmith) Complete() ([]*File, error) {
var f *os.File var f *os.File
if f, file.Err = os.Create(absPath); file.Err == nil { if f, file.Err = os.Create(absPath); file.Err == nil {
_, file.Err = f.Write(file.Buff.Bytes()) if _, file.Err = f.Write(file.Buff.Bytes()); file.Err == nil {
gs.refs[file.Path] = true
}
f.Close() f.Close()
} }
} }
@ -174,5 +204,7 @@ func (gs *goldsmith) Complete() ([]*File, error) {
files = append(files, file) files = append(files, file)
} }
gs.clean()
return files, gs.err return files, gs.err
} }

23
util.go
View File

@ -22,7 +22,10 @@
package goldsmith package goldsmith
import "path/filepath" import (
"os"
"path/filepath"
)
func globMatch(globs []string, name string) (bool, error) { func globMatch(globs []string, name string) (bool, error) {
var ( var (
@ -52,3 +55,21 @@ func skipFile(file *File, globs []string) bool {
return !matched return !matched
} }
func scanDir(root string) (files, dirs []string, err error) {
err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
dirs = append(dirs, path)
} else {
files = append(files, path)
}
return nil
})
return
}