Interface refactoring

This commit is contained in:
Alex Yatskov 2015-11-11 14:21:47 +09:00
parent 1c8f6109f9
commit 187f25cddd
2 changed files with 54 additions and 46 deletions

View File

@ -55,6 +55,25 @@ func New(srcDir, dstDir string) Goldsmith {
return gs return gs
} }
func NewFile(path string) *File {
return &File{
Path: cleanPath(path),
Meta: make(map[string]interface{}),
}
}
func NewFileStatic(path string) *File {
file := NewFile(path)
file.Type = FileStatic
return file
}
func NewFileRef(path string) *File {
file := NewFile(path)
file.Type = FileReference
return file
}
func (gs *goldsmith) scanFs() error { func (gs *goldsmith) scanFs() error {
fileMatches, _, err := scanDir(gs.srcDir) fileMatches, _, err := scanDir(gs.srcDir)
if err != nil { if err != nil {
@ -72,7 +91,7 @@ func (gs *goldsmith) scanFs() error {
panic(err) panic(err)
} }
file := gs.NewFile(relPath) file := NewFile(relPath)
var f *os.File var f *os.File
if f, file.Err = os.Open(match); file.Err == nil { if f, file.Err = os.Open(match); file.Err == nil {
@ -120,6 +139,11 @@ func (gs *goldsmith) exportFile(file *File) {
return return
} }
if file.Type == FileReference {
gs.refFile(file.Path)
return
}
absPath := filepath.Join(gs.dstDir, file.Path) absPath := filepath.Join(gs.dstDir, file.Path)
if file.Err = os.MkdirAll(path.Dir(absPath), 0755); file.Err != nil { if file.Err = os.MkdirAll(path.Dir(absPath), 0755); file.Err != nil {
return return
@ -129,7 +153,7 @@ func (gs *goldsmith) exportFile(file *File) {
if f, file.Err = os.Create(absPath); file.Err == nil { if f, file.Err = os.Create(absPath); file.Err == nil {
defer f.Close() defer f.Close()
if _, file.Err = f.Write(file.Buff.Bytes()); file.Err == nil { if _, file.Err = f.Write(file.Buff.Bytes()); file.Err == nil {
gs.RefFile(file.Path) gs.refFile(file.Path)
} }
} }
} }
@ -162,12 +186,12 @@ func (gs *goldsmith) chain(s stage, c Chainer) {
wg.Add(1) wg.Add(1)
go func() { go func() {
f, _ := c.(Filterer) a, _ := c.(Accepter)
for file := range s.input { for file := range s.input {
if file.flags&FileFlagStatic != 0 || (f != nil && f.Filter(file.Path)) { if file.Type == FileNormal && (a == nil || a.Accept(file)) {
s.output <- file
} else {
input <- file input <- file
} else {
s.output <- file
} }
} }
@ -183,37 +207,8 @@ func (gs *goldsmith) chain(s stage, c Chainer) {
}() }()
} }
func (gs *goldsmith) NewFile(path string) *File { func (gs *goldsmith) refFile(path string) {
if filepath.IsAbs(path) { path = cleanPath(path)
var err error
path, err = filepath.Rel("/", path)
if err != nil {
panic(err)
}
}
return &File{
Path: filepath.Clean(path),
Meta: make(map[string]interface{}),
}
}
func (gs *goldsmith) NewFileStatic(path string) *File {
file := gs.NewFile(path)
file.flags |= FileFlagStatic
return file
}
func (gs *goldsmith) RefFile(path string) {
if filepath.IsAbs(path) {
var err error
path, err = filepath.Rel("/", path)
if err != nil {
panic(err)
}
}
path = filepath.Clean(path)
for { for {
gs.refs[path] = true gs.refs[path] = true
@ -262,6 +257,17 @@ func (gs *goldsmith) Complete() ([]*File, error) {
return files, gs.err return files, gs.err
} }
func cleanPath(path string) string {
if filepath.IsAbs(path) {
var err error
if path, err = filepath.Rel("/", path); err != nil {
panic(err)
}
}
return filepath.Clean(path)
}
func scanDir(root string) (files, dirs []string, err error) { func scanDir(root string) (files, dirs []string, err error) {
err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error { err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil { if err != nil {

View File

@ -33,25 +33,27 @@ type Chainer interface {
Chain(ctx Context, input, output chan *File) Chain(ctx Context, input, output chan *File)
} }
type Filterer interface { type Accepter interface {
Filter(path string) bool Accept(file *File) bool
} }
type FileType int
const (
FileNormal FileType = iota
FileStatic
FileReference
)
type File struct { type File struct {
Path string Path string
Meta map[string]interface{} Meta map[string]interface{}
Buff bytes.Buffer Buff bytes.Buffer
Err error Err error
Type FileType
flags uint32
} }
type Context interface { type Context interface {
NewFileStatic(path string) *File
NewFile(path string) *File
RefFile(path string)
SrcDir() string SrcDir() string
DstDir() string DstDir() string
} }